authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-05-30 22:04:20+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-24 08:12:17+02:00
log9015efe4059b7e8448a9c09c3a116cb6b2550957
tree14f8793b49a1cf0b1a75a76bd0813372ebee37aa
parent5ebaf49ebb65f3b201e56ec7d89b7d91f189409e

wasm: Implement `@mulAdd` for f16

Implements `@mulAdd` for floats with bitsize 16, where it generates a call into compiler-rt's `fmaf` function. Note that arguments for fmaf are different in order than `@mulAdd`.

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

src/arch/wasm/CodeGen.zig+14-4
......@@ -4495,14 +4495,24 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
44954495 return self.fail("TODO: `@mulAdd` for vectors", .{});
44964496 }
44974497
4498 if (ty.floatBits(self.target) == 16) {
4499 return self.fail("TODO: `@mulAdd` for f16", .{});
4500 }
4501
45024498 const addend = try self.resolveInst(pl_op.operand);
45034499 const lhs = try self.resolveInst(bin_op.lhs);
45044500 const rhs = try self.resolveInst(bin_op.rhs);
45054501
4502 if (ty.floatBits(self.target) == 16) {
4503 const addend_ext = try self.fpext(addend, ty, Type.f32);
4504 const lhs_ext = try self.fpext(lhs, ty, Type.f32);
4505 const rhs_ext = try self.fpext(rhs, ty, Type.f32);
4506 // call to compiler-rt `fn fmaf(f32, f32, f32) f32`
4507 const result = try self.callIntrinsic(
4508 "fmaf",
4509 &.{ Type.f32, Type.f32, Type.f32 },
4510 Type.f32,
4511 &.{ rhs_ext, lhs_ext, addend_ext },
4512 );
4513 return try self.fptrunc(result, Type.f32, ty);
4514 }
4515
45064516 const mul_result = try self.binOp(lhs, rhs, ty, .mul);
45074517 return self.binOp(mul_result, addend, ty, .add);
45084518}