diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-04-02 16:50:39 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-04-02 21:54:01 +0200 |
| commit | 5ba03369ee11b6b57dcad99ab7ed8ce3b08c7456 (patch) | |
| tree | 7c22ab203d3eaa3fb7d92736e02d2320cc89f6ec /src/arch/wasm/CodeGen.zig | |
| parent | 219fa192c6311c627d4b507c928ebcf2920af9e8 (diff) | |
| download | zig-5ba03369ee11b6b57dcad99ab7ed8ce3b08c7456.tar.gz zig-5ba03369ee11b6b57dcad99ab7ed8ce3b08c7456.zip | |
wasm: Implement `@mulAdd` for f32, f64
This implements the `mul_add` AIR instruction for floats of bitsize 32 and 64.
f16's will require us being able to extend and truncate f16's to correctly
store and load them without losing the accuracy.
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index d3bae94102..9cb61ca4ee 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1309,6 +1309,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .xor => self.airBinOp(inst, .xor), .max => self.airMaxMin(inst, .max), .min => self.airMaxMin(inst, .min), + .mul_add => self.airMulAdd(inst), .add_with_overflow => self.airBinOpOverflow(inst, .add), .sub_with_overflow => self.airBinOpOverflow(inst, .sub), @@ -1468,7 +1469,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .atomic_store_seq_cst, .atomic_rmw, .tag_name, - .mul_add, => |tag| return self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}), }; } @@ -1721,8 +1721,7 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue { else .signed; - // TODO: Revisit below to determine if optional zero-sized pointers should still have abi-size 4. - const abi_size = if (ty.isPtrLikeOptional()) @as(u8, 4) else @intCast(u8, ty.abiSize(self.target)); + const abi_size = @intCast(u8, ty.abiSize(self.target)); const opcode = buildOpcode(.{ .valtype1 = typeToValtype(ty, self.target), @@ -3912,3 +3911,24 @@ fn airMaxMin(self: *Self, inst: Air.Inst.Index, op: enum { max, min }) InnerErro return result; } + +fn airMulAdd(self: *Self, inst: Air.Inst.Index) InnerError!WValue { + if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; + const pl_op = self.air.instructions.items(.data)[inst].pl_op; + const bin_op = self.air.extraData(Air.Bin, pl_op.payload).data; + const ty = self.air.typeOfIndex(inst); + if (ty.zigTypeTag() == .Vector) { + return self.fail("TODO: `@mulAdd` for vectors", .{}); + } + + if (ty.floatBits(self.target) == 16) { + return self.fail("TODO: `@mulAdd` for f16", .{}); + } + + const addend = try self.resolveInst(pl_op.operand); + const lhs = try self.resolveInst(bin_op.lhs); + const rhs = try self.resolveInst(bin_op.rhs); + + const mul_result = try self.binOp(lhs, rhs, ty, .mul); + return self.binOp(mul_result, addend, ty, .add); +} |
