diff --git a/src/Jit.zig b/src/Jit.zig index 04b29768..9b7272a7 100644 --- a/src/Jit.zig +++ b/src/Jit.zig @@ -2706,24 +2706,14 @@ fn generateBinary(self: *Self, node: Ast.Node.Index) Error!?m.MIR_op_t { }, .Percent => { if (left_type_def == .Float or right_type_def == .Float) { - const f_res = m.MIR_new_reg_op( - self.ctx, - try self.REG("f_res", m.MIR_T_D), - ); - - const pdt = m.MIR_new_reg_op( - self.ctx, - try self.REG("p", m.MIR_T_D), + try self.buildExternApiCall( + .fmod, + res, + &[_]m.MIR_op_t{ + left, + right, + }, ); - - // quotient - self.DDIV(f_res, left, right); - // product - self.DMUL(pdt, f_res, right); - // remainder - self.DSUB(f_res, f_res, pdt); - - self.wrap(.Float, f_res, res); } else { self.MODS(res, left, right); @@ -6526,3 +6516,7 @@ fn outputModule(self: *Self, name: []const u8, module: m.MIR_module_t) void { module, ); } + +pub fn fmod(lhs: f64, rhs: f64) Value { + return Value.fromFloat(@mod(lhs, rhs)); +} diff --git a/src/jit_extern_api.zig b/src/jit_extern_api.zig index 9b336259..691a0c36 100644 --- a/src/jit_extern_api.zig +++ b/src/jit_extern_api.zig @@ -80,6 +80,7 @@ pub const ExternApi = enum { dumpInt, bz_valueDump, + fmod, pub fn declare(self: ExternApi, jit: *JIT) !m.MIR_item_t { const prototype = jit.state.?.prototypes.get(self) orelse self.proto(jit.ctx); @@ -982,6 +983,25 @@ pub const ExternApi = enum { }, }, ), + .fmod => m.MIR_new_proto_arr( + ctx, + self.pname(), + 1, + &[_]m.MIR_type_t{m.MIR_T_I64}, + 2, + &[_]m.MIR_var_t{ + .{ + .type = m.MIR_T_D, + .name = "lhs", + .size = undefined, + }, + .{ + .type = m.MIR_T_D, + .name = "rhs", + .size = undefined, + }, + }, + ), }; } @@ -1054,6 +1074,7 @@ pub const ExternApi = enum { .dumpInt => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.dumpInt))), .bz_valueDump => @as(*anyopaque, @ptrFromInt(@intFromPtr(&api.Value.bz_valueDump))), + .fmod => @as(*anyopaque, @ptrFromInt(@intFromPtr(&JIT.fmod))), else => { io.print("{s}\n", .{self.name()}); unreachable; @@ -1061,6 +1082,7 @@ pub const ExternApi = enum { }; } + // FIXME: no need for this we can return @tagName pub fn name(self: ExternApi) [*:0]const u8 { return switch (self) { .nativefn => "NativeFn", @@ -1130,6 +1152,7 @@ pub const ExternApi = enum { .dumpInt => "dumpInt", .bz_valueDump => "bz_valueDump", + .fmod => "fmod", }; } @@ -1202,6 +1225,7 @@ pub const ExternApi = enum { .dumpInt => "p_dumpInt", .bz_valueDump => "p_bz_valueDump", + .fmod => "p_fmod", }; } }; diff --git a/src/vm.zig b/src/vm.zig index e6112748..bf706d74 100644 --- a/src/vm.zig +++ b/src/vm.zig @@ -3481,9 +3481,20 @@ pub const VM = struct { const left_i: ?i32 = if (left.isInteger()) left.integer() else null; if (right_f != null or left_f != null) { - self.push(Value.fromFloat(@mod((left_f orelse @as(f64, @floatFromInt(left_i.?))), (right_f orelse @as(f64, @floatFromInt(right_i.?)))))); + self.push( + Value.fromFloat( + @mod( + (left_f orelse @as(f64, @floatFromInt(left_i.?))), + (right_f orelse @as(f64, @floatFromInt(right_i.?))), + ), + ), + ); } else { - self.push(Value.fromInteger(@mod(left_i.?, right_i.?))); + self.push( + Value.fromInteger( + @mod(left_i.?, right_i.?), + ), + ); } const next_full_instruction: u32 = self.readInstruction();