authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-11 16:14:52+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-11 19:38:00+02:00
log13123afedbf05cf4646a7e5f39a95a4b06b45285
treeb3cce7666ffacde3f5e915e9c6f35ebf32d85be5
parentf05e09a0cf7870fda463d9a0ceb42be4c3100825

wasm: implement `@ceil`, `@floor` and `@trunc`


1 files changed, 31 insertions(+), 3 deletions(-)

src/arch/wasm/CodeGen.zig+31-3
...@@ -1446,6 +1446,9 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1446,6 +1446,9 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1446 .div_trunc,1446 .div_trunc,
1447 => self.airDiv(inst),1447 => self.airDiv(inst),
1448 .div_floor => self.airDivFloor(inst),1448 .div_floor => self.airDivFloor(inst),
1449 .ceil => self.airCeilFloorTrunc(inst, .ceil),
1450 .floor => self.airCeilFloorTrunc(inst, .floor),
1451 .trunc_float => self.airCeilFloorTrunc(inst, .trunc),
1449 .bit_and => self.airBinOp(inst, .@"and"),1452 .bit_and => self.airBinOp(inst, .@"and"),
1450 .bit_or => self.airBinOp(inst, .@"or"),1453 .bit_or => self.airBinOp(inst, .@"or"),
1451 .bool_and => self.airBinOp(inst, .@"and"),1454 .bool_and => self.airBinOp(inst, .@"and"),
...@@ -1606,10 +1609,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1606,10 +1609,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1606 .log2,1609 .log2,
1607 .log10,1610 .log10,
1608 .fabs,1611 .fabs,
1609 .floor,
1610 .ceil,
1611 .round,1612 .round,
1612 .trunc_float,
16131613
1614 .cmpxchg_weak,1614 .cmpxchg_weak,
1615 .cmpxchg_strong,1615 .cmpxchg_strong,
...@@ -4872,3 +4872,31 @@ fn signAbsValue(self: *Self, operand: WValue, ty: Type) InnerError!WValue {...@@ -4872,3 +4872,31 @@ fn signAbsValue(self: *Self, operand: WValue, ty: Type) InnerError!WValue {
4872 try self.addLabel(.local_set, result.local);4872 try self.addLabel(.local_set, result.local);
4873 return result;4873 return result;
4874}4874}
4875
4876fn airCeilFloorTrunc(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {
4877 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
4878
4879 const un_op = self.air.instructions.items(.data)[inst].un_op;
4880 const ty = self.air.typeOfIndex(inst);
4881
4882 if (ty.zigTypeTag() == .Vector) {
4883 return self.fail("TODO: Implement `@ceil` for vectors", .{});
4884 }
4885
4886 const operand = try self.resolveInst(un_op);
4887 try self.emitWValue(operand);
4888 switch (ty.floatBits(self.target)) {
4889 32, 64 => {
4890 const opcode = buildOpcode(.{
4891 .op = op,
4892 .valtype1 = typeToValtype(ty, self.target),
4893 });
4894 try self.addTag(Mir.Inst.Tag.fromOpcode(opcode));
4895 },
4896 else => |bit_size| return self.fail("TODO: Implement `@ceil` for floats with bitsize {d}", .{bit_size}),
4897 }
4898
4899 const result = try self.allocLocal(ty);
4900 try self.addLabel(.local_set, result.local);
4901 return result;
4902}