authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-07-26 17:24:18+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-08-11 11:08:00+02:00
log3cd0cd12a08435fca5f5b2b6788ff519abfc6184
tree695eaae863342f882405691364145fd446980cde
parentcde16f61eb41f2beda85e838331a30869e420c68
signaturelock-open Commit is signed but in an unrecognized format.

wasm: leave `signedAbsValue` values on the stack


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

src/arch/wasm/CodeGen.zig+18-14
...@@ -4309,10 +4309,10 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!W...@@ -4309,10 +4309,10 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!W
4309 // for signed integers, we first apply signed shifts by the difference in bits4309 // for signed integers, we first apply signed shifts by the difference in bits
4310 // to get the signed value, as we store it internally as 2's complement.4310 // to get the signed value, as we store it internally as 2's complement.
4311 const lhs = if (wasm_bits != int_info.bits and is_signed) blk: {4311 const lhs = if (wasm_bits != int_info.bits and is_signed) blk: {
4312 break :blk try self.signAbsValue(lhs_op, lhs_ty);4312 break :blk try (try self.signAbsValue(lhs_op, lhs_ty)).toLocal(self, lhs_ty);
4313 } else lhs_op;4313 } else lhs_op;
4314 const rhs = if (wasm_bits != int_info.bits and is_signed) blk: {4314 const rhs = if (wasm_bits != int_info.bits and is_signed) blk: {
4315 break :blk try self.signAbsValue(rhs_op, lhs_ty);4315 break :blk try (try self.signAbsValue(rhs_op, lhs_ty)).toLocal(self, lhs_ty);
4316 } else rhs_op;4316 } else rhs_op;
43174317
4318 const bin_op = try (try self.binOp(lhs, rhs, lhs_ty, op)).toLocal(self, lhs_ty);4318 const bin_op = try (try self.binOp(lhs, rhs, lhs_ty, op)).toLocal(self, lhs_ty);
...@@ -4420,9 +4420,9 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -4420,9 +4420,9 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
4420 } else shl;4420 } else shl;
44214421
4422 const overflow_bit = if (wasm_bits != int_info.bits and is_signed) blk: {4422 const overflow_bit = if (wasm_bits != int_info.bits and is_signed) blk: {
4423 const abs = try self.signAbsValue(shl, lhs_ty);
4424 // emit lhs to stack to we can keep 'wrapped' on the stack also4423 // emit lhs to stack to we can keep 'wrapped' on the stack also
4425 try self.emitWValue(lhs);4424 try self.emitWValue(lhs);
4425 const abs = try self.signAbsValue(shl, lhs_ty);
4426 const wrapped = try self.wrapBinOp(abs, rhs, lhs_ty, .shr);4426 const wrapped = try self.wrapBinOp(abs, rhs, lhs_ty, .shr);
4427 break :blk try self.cmp(.{ .stack = {} }, wrapped, lhs_ty, .neq);4427 break :blk try self.cmp(.{ .stack = {} }, wrapped, lhs_ty, .neq);
4428 } else blk: {4428 } else blk: {
...@@ -4909,10 +4909,10 @@ fn airDivFloor(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -4909,10 +4909,10 @@ fn airDivFloor(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
4909 return self.fail("TODO: `@divFloor` for signed integers larger than '{d}' bits", .{int_bits});4909 return self.fail("TODO: `@divFloor` for signed integers larger than '{d}' bits", .{int_bits});
4910 };4910 };
4911 const lhs_res = if (wasm_bits != int_bits) blk: {4911 const lhs_res = if (wasm_bits != int_bits) blk: {
4912 break :blk try self.signAbsValue(lhs, ty);4912 break :blk try (try self.signAbsValue(lhs, ty)).toLocal(self, ty);
4913 } else lhs;4913 } else lhs;
4914 const rhs_res = if (wasm_bits != int_bits) blk: {4914 const rhs_res = if (wasm_bits != int_bits) blk: {
4915 break :blk try self.signAbsValue(rhs, ty);4915 break :blk try (try self.signAbsValue(rhs, ty)).toLocal(self, ty);
4916 } else rhs;4916 } else rhs;
49174917
4918 const zero = switch (wasm_bits) {4918 const zero = switch (wasm_bits) {
...@@ -4994,10 +4994,9 @@ fn divSigned(self: *Self, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue...@@ -4994,10 +4994,9 @@ fn divSigned(self: *Self, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue
4994 }4994 }
49954995
4996 if (wasm_bits != int_bits) {4996 if (wasm_bits != int_bits) {
4997 const lhs_abs = try self.signAbsValue(lhs, ty);4997 // Leave both values on the stack
4998 const rhs_abs = try self.signAbsValue(rhs, ty);4998 _ = try self.signAbsValue(lhs, ty);
4999 try self.emitWValue(lhs_abs);4999 _ = try self.signAbsValue(rhs, ty);
5000 try self.emitWValue(rhs_abs);
5001 } else {5000 } else {
5002 try self.emitWValue(lhs);5001 try self.emitWValue(lhs);
5003 try self.emitWValue(rhs);5002 try self.emitWValue(rhs);
...@@ -5009,6 +5008,8 @@ fn divSigned(self: *Self, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue...@@ -5009,6 +5008,8 @@ fn divSigned(self: *Self, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue
5009 return result;5008 return result;
5010}5009}
50115010
5011/// Retrieves the absolute value of a signed integer
5012/// NOTE: Leaves the result value on the stack.
5012fn signAbsValue(self: *Self, operand: WValue, ty: Type) InnerError!WValue {5013fn signAbsValue(self: *Self, operand: WValue, ty: Type) InnerError!WValue {
5013 const int_bits = ty.intInfo(self.target).bits;5014 const int_bits = ty.intInfo(self.target).bits;
5014 const wasm_bits = toWasmBits(int_bits) orelse {5015 const wasm_bits = toWasmBits(int_bits) orelse {
...@@ -5037,9 +5038,8 @@ fn signAbsValue(self: *Self, operand: WValue, ty: Type) InnerError!WValue {...@@ -5037,9 +5038,8 @@ fn signAbsValue(self: *Self, operand: WValue, ty: Type) InnerError!WValue {
5037 },5038 },
5038 else => unreachable,5039 else => unreachable,
5039 }5040 }
5040 const result = try self.allocLocal(ty);5041
5041 try self.addLabel(.local_set, result.local);5042 return WValue{ .stack = {} };
5042 return result;
5043}5043}
50445044
5045fn airCeilFloorTrunc(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {5045fn airCeilFloorTrunc(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!WValue {
...@@ -5130,8 +5130,12 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op...@@ -5130,8 +5130,12 @@ fn signedSat(self: *Self, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op
5130 const wasm_bits = toWasmBits(int_info.bits).?;5130 const wasm_bits = toWasmBits(int_info.bits).?;
5131 const is_wasm_bits = wasm_bits == int_info.bits;5131 const is_wasm_bits = wasm_bits == int_info.bits;
51325132
5133 const lhs = if (!is_wasm_bits) try self.signAbsValue(lhs_operand, ty) else lhs_operand;5133 const lhs = if (!is_wasm_bits) lhs: {
5134 const rhs = if (!is_wasm_bits) try self.signAbsValue(rhs_operand, ty) else rhs_operand;5134 break :lhs try (try self.signAbsValue(lhs_operand, ty)).toLocal(self, ty);
5135 } else lhs_operand;
5136 const rhs = if (!is_wasm_bits) rhs: {
5137 break :rhs try (try self.signAbsValue(rhs_operand, ty)).toLocal(self, ty);
5138 } else rhs_operand;
51355139
5136 const max_val: u64 = @intCast(u64, (@as(u65, 1) << @intCast(u7, int_info.bits - 1)) - 1);5140 const max_val: u64 = @intCast(u64, (@as(u65, 1) << @intCast(u7, int_info.bits - 1)) - 1);
5137 const min_val: i64 = (-@intCast(i64, @intCast(u63, max_val))) - 1;5141 const min_val: i64 = (-@intCast(i64, @intCast(u63, max_val))) - 1;