zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 5ba03369ee11b6b57dcad99ab7ed8ce3b08c7456 (tree)
parent 219fa192c6311c627d4b507c928ebcf2920af9e8
Author: Luuk de Gram <luuk@degram.dev>
Date:   Sat,  2 Apr 2022 16:50:39 +0200

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:
Msrc/arch/wasm/CodeGen.zig | 26+++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)

diff --git 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); +}