aboutsummaryrefslogtreecommitdiff
path: root/src/arch/wasm/CodeGen.zig
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-06-08 20:00:04 +0200
committerLuuk de Gram <luuk@degram.dev>2022-06-11 19:38:00 +0200
commit9b84f29503ede2088238e39daa4cf17a571ed790 (patch)
treef7b3ac911ebcd5c71966a09fed9aed76807f32d9 /src/arch/wasm/CodeGen.zig
parent180baa05465df6440f9953d8ff4d7880322b03f0 (diff)
downloadzig-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.zig36
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;
+}