mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 00:08:56 +00:00
stage2-wasm: airRem + airMod for floats
This commit is contained in:
parent
b00cbecfd3
commit
4b89a4c7cb
@ -2783,6 +2783,7 @@ const FloatOp = enum {
|
||||
.sqrt => .sqrt,
|
||||
.sub => .sub,
|
||||
.trunc => .trunc,
|
||||
.rem => .fmod,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
@ -6808,30 +6809,37 @@ fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
const lhs = try func.resolveInst(bin_op.lhs);
|
||||
const rhs = try func.resolveInst(bin_op.rhs);
|
||||
|
||||
if (ty.isUnsignedInt(zcu)) {
|
||||
_ = try func.binOp(lhs, rhs, ty, .rem);
|
||||
} else if (ty.isSignedInt(zcu)) {
|
||||
// The wasm rem instruction gives the remainder after truncating division (rounding towards
|
||||
// 0), equivalent to @rem.
|
||||
// We make use of the fact that:
|
||||
// @mod(a, b) = @rem(@rem(a, b) + b, b)
|
||||
const int_bits = ty.intInfo(zcu).bits;
|
||||
const wasm_bits = toWasmBits(int_bits) orelse {
|
||||
return func.fail("TODO: `@mod` for signed integers larger than 64 bits ({d} bits requested)", .{int_bits});
|
||||
};
|
||||
|
||||
if (wasm_bits > 64) {
|
||||
return func.fail("TODO: `@mod` for signed integers larger than 64 bits ({d} bits requested)", .{int_bits});
|
||||
const result = result: {
|
||||
if (ty.isUnsignedInt(zcu)) {
|
||||
break :result try func.binOp(lhs, rhs, ty, .rem);
|
||||
}
|
||||
if (ty.isSignedInt(zcu)) {
|
||||
// The wasm rem instruction gives the remainder after truncating division (rounding towards
|
||||
// 0), equivalent to @rem.
|
||||
// We make use of the fact that:
|
||||
// @mod(a, b) = @rem(@rem(a, b) + b, b)
|
||||
const int_bits = ty.intInfo(zcu).bits;
|
||||
const wasm_bits = toWasmBits(int_bits) orelse {
|
||||
return func.fail("TODO: `@mod` for signed integers larger than 64 bits ({d} bits requested)", .{int_bits});
|
||||
};
|
||||
|
||||
_ = try func.binOp(lhs, rhs, ty, .rem);
|
||||
_ = try func.binOp(.stack, rhs, ty, .add);
|
||||
_ = try func.binOp(.stack, rhs, ty, .rem);
|
||||
} else {
|
||||
return func.fail("TODO: implement `@mod` on floating point types for {}", .{func.target.cpu.arch});
|
||||
}
|
||||
if (wasm_bits > 64) {
|
||||
return func.fail("TODO: `@mod` for signed integers larger than 64 bits ({d} bits requested)", .{int_bits});
|
||||
}
|
||||
|
||||
return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
|
||||
_ = try func.binOp(lhs, rhs, ty, .rem);
|
||||
_ = try func.binOp(.stack, rhs, ty, .add);
|
||||
break :result try func.binOp(.stack, rhs, ty, .rem);
|
||||
}
|
||||
if (ty.isAnyFloat()) {
|
||||
const rem = try func.binOp(lhs, rhs, ty, .rem);
|
||||
const add = try func.binOp(rem, rhs, ty, .add);
|
||||
break :result try func.binOp(add, rhs, ty, .rem);
|
||||
}
|
||||
return func.fail("TODO: @mod for {}", .{ty.fmt(pt)});
|
||||
};
|
||||
|
||||
return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
|
||||
}
|
||||
|
||||
fn airSatMul(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
|
||||
@ -167,7 +167,6 @@ fn testOneCtz(comptime T: type, x: T) u32 {
|
||||
}
|
||||
|
||||
test "@ctz 128-bit integers" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
@ -776,7 +775,6 @@ fn should_not_be_zero(x: f128) !void {
|
||||
}
|
||||
|
||||
test "128-bit multiplication" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1204,7 +1202,6 @@ test "allow signed integer division/remainder when values are comptime-known and
|
||||
}
|
||||
|
||||
test "quad hex float literal parsing accurate" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1363,7 +1360,6 @@ test "comptime float rem int" {
|
||||
}
|
||||
|
||||
test "remainder division" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1403,7 +1399,6 @@ fn remdivOne(comptime T: type, a: T, b: T, c: T) !void {
|
||||
}
|
||||
|
||||
test "float remainder division using @rem" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -1447,7 +1442,6 @@ fn fremOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void {
|
||||
}
|
||||
|
||||
test "float modulo division using @mod" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user