authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-19 17:26:44+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-19 17:26:44+02:00
loga50147bfff1224d090b13ed934eda97dbfd6432b
tree0fed15a2ca79c8891e84b07362f16cedc6816118
parent05600a6d8438595bf7fc40ea21d0c47076d2935d
signaturelock-open Commit is signed but in an unrecognized format.

wasm: fixes for signed saturation


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

src/arch/wasm/CodeGen.zig+8-4
...@@ -4939,9 +4939,9 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op...@@ -4939,9 +4939,9 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op
4939 const rhs = if (!is_wasm_bits) try self.signAbsValue(rhs_operand, ty) else rhs_operand;4939 const rhs = if (!is_wasm_bits) try self.signAbsValue(rhs_operand, ty) else rhs_operand;
49404940
4941 const max_val: u64 = @intCast(u64, (@as(u65, 1) << @intCast(u7, int_info.bits - 1)) - 1);4941 const max_val: u64 = @intCast(u64, (@as(u65, 1) << @intCast(u7, int_info.bits - 1)) - 1);
4942 const min_val = @intCast(i64, ~@intCast(u63, max_val));4942 const min_val: i64 = (-@intCast(i64, @intCast(u63, max_val))) - 1;
4943 const max_wvalue = switch (wasm_bits) {4943 const max_wvalue = switch (wasm_bits) {
4944 32 => WValue{ .imm32 = @intCast(u32, max_val) },4944 32 => WValue{ .imm32 = @truncate(u32, max_val) },
4945 64 => WValue{ .imm64 = max_val },4945 64 => WValue{ .imm64 = max_val },
4946 else => unreachable,4946 else => unreachable,
4947 };4947 };
...@@ -4975,7 +4975,7 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op...@@ -4975,7 +4975,7 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op
4975 };4975 };
4976 const cmp_bin_result = try self.cmp(bin_result, lhs, ty, .lt);4976 const cmp_bin_result = try self.cmp(bin_result, lhs, ty, .lt);
4977 const cmp_zero_result = try self.cmp(rhs, zero, ty, if (op == .add) .lt else .gt);4977 const cmp_zero_result = try self.cmp(rhs, zero, ty, if (op == .add) .lt else .gt);
4978 const xor = try self.binOp(cmp_zero_result, cmp_bin_result, ty, .xor);4978 const xor = try self.binOp(cmp_zero_result, cmp_bin_result, Type.u32, .xor); // comparisons always return i32, so provide u32 as type to xor.
4979 const cmp_bin_zero_result = try self.cmp(bin_result, zero, ty, .lt);4979 const cmp_bin_zero_result = try self.cmp(bin_result, zero, ty, .lt);
4980 try self.emitWValue(max_wvalue);4980 try self.emitWValue(max_wvalue);
4981 try self.emitWValue(min_wvalue);4981 try self.emitWValue(min_wvalue);
...@@ -5084,6 +5084,10 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -5084,6 +5084,10 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
5084 try self.emitWValue(cmp_result);5084 try self.emitWValue(cmp_result);
5085 try self.addTag(.select);5085 try self.addTag(.select);
5086 try self.addLabel(.local_set, result.local);5086 try self.addLabel(.local_set, result.local);
5087 return self.binOp(result, shift_value, ty, .shr);5087 const shift_result = try self.binOp(result, shift_value, ty, .shr);
5088 if (is_signed) {
5089 return self.wrapOperand(shift_result, ty);
5090 }
5091 return shift_result;
5088 }5092 }
5089}5093}