diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-06-08 20:00:04 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-06-11 19:38:00 +0200 |
| commit | 9b84f29503ede2088238e39daa4cf17a571ed790 (patch) | |
| tree | f7b3ac911ebcd5c71966a09fed9aed76807f32d9 /src/arch/wasm/CodeGen.zig | |
| parent | 180baa05465df6440f9953d8ff4d7880322b03f0 (diff) | |
| download | zig-9b84f29503ede2088238e39daa4cf17a571ed790.tar.gz zig-9b84f29503ede2088238e39daa4cf17a571ed790.zip | |
wasm: support all `@div{trunc/floor/exact}` ops
This does however not support floats of bitsizes
different than 32 or 64. f16, f80, f126 will require
support for compiler-rt and are out-of-scope for this commit.
Signed integers are currently not supported either.
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index e628c42287..496c223970 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1441,7 +1441,11 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .subwrap => self.airWrapBinOp(inst, .sub), .mul => self.airBinOp(inst, .mul), .mulwrap => self.airWrapBinOp(inst, .mul), - .div_trunc => self.airBinOp(inst, .div), + .div_float, + .div_exact, + .div_trunc, + => self.airBinOp(inst, .div), + .div_floor => self.airDivFloor(inst), .bit_and => self.airBinOp(inst, .@"and"), .bit_or => self.airBinOp(inst, .@"or"), .bool_and => self.airBinOp(inst, .@"and"), @@ -1583,9 +1587,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .add_sat, .sub_sat, .mul_sat, - .div_float, - .div_floor, - .div_exact, .mod, .assembly, .shl_sat, @@ -4757,3 +4758,30 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) InnerError!WValue { else => return self.fail("TODO: @byteSwap for integers with bitsize {d}", .{int_info.bits}), } } + +fn airDivFloor(self: *Self, inst: Air.Inst.Index) InnerError!WValue { + if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; + + const bin_op = self.air.instructions.items(.data)[inst].bin_op; + const ty = self.air.typeOfIndex(inst); + const lhs = try self.resolveInst(bin_op.lhs); + const rhs = try self.resolveInst(bin_op.rhs); + + const div_result = try self.binOp(lhs, rhs, ty, .div); + if (ty.isUnsignedInt()) { + return div_result; + } else if (ty.isSignedInt()) { + return self.fail("TODO: `@divFloor` for signed integers", .{}); + } + + try self.emitWValue(div_result); + switch (ty.floatBits(self.target)) { + 32 => try self.addTag(.f32_floor), + 64 => try self.addTag(.f64_floor), + else => |bit_size| return self.fail("TODO: `@divFloor` for floats with bitsize: {d}", .{bit_size}), + } + + const result = try self.allocLocal(ty); + try self.addLabel(.local_set, result.local); + return result; +} |
