diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-05-18 18:08:10 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2023-05-19 20:22:47 +0200 |
| commit | ca870aa00504accd49e7f1d2fceed1e4b8d21100 (patch) | |
| tree | b4c9d80002a7017ab61bfd91dde3239850e5b025 /src | |
| parent | 4a33aa922e90b76248b259a89be86966eb4898c2 (diff) | |
| download | zig-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.zig | 26 |
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; |
