authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-08 20:00:04+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-11 19:38:00+02:00
log9b84f29503ede2088238e39daa4cf17a571ed790
treef7b3ac911ebcd5c71966a09fed9aed76807f32d9
parent180baa05465df6440f9953d8ff4d7880322b03f0

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.

1 files changed, 32 insertions(+), 4 deletions(-)

src/arch/wasm/CodeGen.zig+32-4
......@@ -1441,7 +1441,11 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
14411441 .subwrap => self.airWrapBinOp(inst, .sub),
14421442 .mul => self.airBinOp(inst, .mul),
14431443 .mulwrap => self.airWrapBinOp(inst, .mul),
1444 .div_trunc => self.airBinOp(inst, .div),
1444 .div_float,
1445 .div_exact,
1446 .div_trunc,
1447 => self.airBinOp(inst, .div),
1448 .div_floor => self.airDivFloor(inst),
14451449 .bit_and => self.airBinOp(inst, .@"and"),
14461450 .bit_or => self.airBinOp(inst, .@"or"),
14471451 .bool_and => self.airBinOp(inst, .@"and"),
......@@ -1583,9 +1587,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
15831587 .add_sat,
15841588 .sub_sat,
15851589 .mul_sat,
1586 .div_float,
1587 .div_floor,
1588 .div_exact,
15891590 .mod,
15901591 .assembly,
15911592 .shl_sat,
......@@ -4757,3 +4758,30 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
47574758 else => return self.fail("TODO: @byteSwap for integers with bitsize {d}", .{int_info.bits}),
47584759 }
47594760}
4761
4762fn airDivFloor(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
4763 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
4764
4765 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
4766 const ty = self.air.typeOfIndex(inst);
4767 const lhs = try self.resolveInst(bin_op.lhs);
4768 const rhs = try self.resolveInst(bin_op.rhs);
4769
4770 const div_result = try self.binOp(lhs, rhs, ty, .div);
4771 if (ty.isUnsignedInt()) {
4772 return div_result;
4773 } else if (ty.isSignedInt()) {
4774 return self.fail("TODO: `@divFloor` for signed integers", .{});
4775 }
4776
4777 try self.emitWValue(div_result);
4778 switch (ty.floatBits(self.target)) {
4779 32 => try self.addTag(.f32_floor),
4780 64 => try self.addTag(.f64_floor),
4781 else => |bit_size| return self.fail("TODO: `@divFloor` for floats with bitsize: {d}", .{bit_size}),
4782 }
4783
4784 const result = try self.allocLocal(ty);
4785 try self.addLabel(.local_set, result.local);
4786 return result;
4787}