aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig1
-rw-r--r--src/codegen/llvm.zig14
-rw-r--r--src/codegen/llvm/bindings.zig9
3 files changed, 24 insertions, 0 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 2084b1e1ce..fd964f2829 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -858,6 +858,7 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM
// TODO use a different strategy for div that communicates to the optimizer
// that wrapping is UB.
.div => try airBinOp( o, inst, " / "),
+ .rem => try airBinOp( o, inst, " % "),
.cmp_eq => try airBinOp(o, inst, " == "),
.cmp_gt => try airBinOp(o, inst, " > "),
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 8e6c064e5c..8b7fd5dc54 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -979,6 +979,7 @@ pub const FuncGen = struct {
.mul => try self.airMul(inst, false),
.mulwrap => try self.airMul(inst, true),
.div => try self.airDiv(inst),
+ .rem => try self.airRem(inst),
.ptr_add => try self.airPtrAdd(inst),
.ptr_sub => try self.airPtrSub(inst),
@@ -1721,6 +1722,19 @@ pub const FuncGen = struct {
return self.builder.buildUDiv(lhs, rhs, "");
}
+ fn airRem(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
+ if (self.liveness.isUnused(inst)) return null;
+
+ const bin_op = self.air.instructions.items(.data)[inst].bin_op;
+ const lhs = try self.resolveInst(bin_op.lhs);
+ const rhs = try self.resolveInst(bin_op.rhs);
+ const inst_ty = self.air.typeOfIndex(inst);
+
+ if (inst_ty.isFloat()) return self.builder.buildFRem(lhs, rhs, "");
+ if (inst_ty.isSignedInt()) return self.builder.buildSRem(lhs, rhs, "");
+ return self.builder.buildURem(lhs, rhs, "");
+ }
+
fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
if (self.liveness.isUnused(inst))
return null;
diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig
index f632b9c2ce..a10002b5d6 100644
--- a/src/codegen/llvm/bindings.zig
+++ b/src/codegen/llvm/bindings.zig
@@ -386,6 +386,15 @@ pub const Builder = opaque {
pub const buildFDiv = LLVMBuildFDiv;
extern fn LLVMBuildFDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
+ pub const buildURem = LLVMBuildURem;
+ extern fn LLVMBuildURem(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
+
+ pub const buildSRem = LLVMBuildSRem;
+ extern fn LLVMBuildSRem(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
+
+ pub const buildFRem = LLVMBuildFRem;
+ extern fn LLVMBuildFRem(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
+
pub const buildAnd = LLVMBuildAnd;
extern fn LLVMBuildAnd(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;