From e878a6633f2447666217a5f9247af7c34507dca0 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Mon, 30 Aug 2021 00:31:40 -0700 Subject: stage2: implement runtime `%` and `@rem` --- src/codegen/c.zig | 1 + src/codegen/llvm.zig | 14 ++++++++++++++ src/codegen/llvm/bindings.zig | 9 +++++++++ 3 files changed, 24 insertions(+) (limited to 'src/codegen') 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 d7aa2d45b3..5d20e380b4 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -985,6 +985,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), @@ -1727,6 +1728,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 d33ca29d4f..3c59fbe056 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; -- cgit v1.2.3