aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2023-05-18 18:08:10 +0200
committerLuuk de Gram <luuk@degram.dev>2023-05-19 20:22:47 +0200
commitca870aa00504accd49e7f1d2fceed1e4b8d21100 (patch)
treeb4c9d80002a7017ab61bfd91dde3239850e5b025 /src
parent4a33aa922e90b76248b259a89be86966eb4898c2 (diff)
downloadzig-ca870aa00504accd49e7f1d2fceed1e4b8d21100.tar.gz
zig-ca870aa00504accd49e7f1d2fceed1e4b8d21100.zip
wasm: fix `div_trunc` for floats
For floats we would previously only do the division, but not the truncation for floats. This would result in incorrect values being returned.
Diffstat (limited to 'src')
-rw-r--r--src/arch/wasm/CodeGen.zig26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index 78e722f794..5e36bb3f89 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -1814,10 +1814,8 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
.subwrap => func.airWrapBinOp(inst, .sub),
.mul => func.airBinOp(inst, .mul),
.mulwrap => func.airWrapBinOp(inst, .mul),
- .div_float,
- .div_exact,
- .div_trunc,
- => func.airDiv(inst),
+ .div_float, .div_exact => func.airDiv(inst),
+ .div_trunc => func.airDivTrunc(inst),
.div_floor => func.airDivFloor(inst),
.bit_and => func.airBinOp(inst, .@"and"),
.bit_or => func.airBinOp(inst, .@"or"),
@@ -6138,6 +6136,26 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
}
+fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
+ const bin_op = func.air.instructions.items(.data)[inst].bin_op;
+
+ const ty = func.air.typeOfIndex(inst);
+ const lhs = try func.resolveInst(bin_op.lhs);
+ const rhs = try func.resolveInst(bin_op.rhs);
+
+ const div_result = if (ty.isSignedInt())
+ try func.divSigned(lhs, rhs, ty)
+ else
+ try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
+
+ if (ty.isAnyFloat()) {
+ const trunc_result = try (try func.floatOp(.trunc, ty, &.{div_result})).toLocal(func, ty);
+ return func.finishAir(inst, trunc_result, &.{ bin_op.lhs, bin_op.rhs });
+ }
+
+ return func.finishAir(inst, div_result, &.{ bin_op.lhs, bin_op.rhs });
+}
+
fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;