aboutsummaryrefslogtreecommitdiff
path: root/src/arch/wasm/CodeGen.zig
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-04-02 16:50:39 +0200
committerLuuk de Gram <luuk@degram.dev>2022-04-02 21:54:01 +0200
commit5ba03369ee11b6b57dcad99ab7ed8ce3b08c7456 (patch)
tree7c22ab203d3eaa3fb7d92736e02d2320cc89f6ec /src/arch/wasm/CodeGen.zig
parent219fa192c6311c627d4b507c928ebcf2920af9e8 (diff)
downloadzig-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.zig26
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);
+}