authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-07-25 16:27:26+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-08-11 11:08:00+02:00
log699bc6171dcc18d681de754ca2eeb63645aea889
tree0b98b208a1375aad3d44ebed9b377e969369fab4
parent305b113a53cd5905d837ea620e2bcae8912c5938
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Keep `intcast` values on stack


1 files changed, 9 insertions(+), 10 deletions(-)

src/arch/wasm/CodeGen.zig+9-10
...@@ -2153,8 +2153,8 @@ fn binOpBigInt(self: *Self, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerErr...@@ -2153,8 +2153,8 @@ fn binOpBigInt(self: *Self, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerErr
2153 const rhs_high_bit = try self.load(rhs, Type.u64, 0);2153 const rhs_high_bit = try self.load(rhs, Type.u64, 0);
2154 const rhs_low_bit = try self.load(rhs, Type.u64, 8);2154 const rhs_low_bit = try self.load(rhs, Type.u64, 8);
21552155
2156 const low_op_res = try (try self.binOp(lhs_low_bit, rhs_low_bit, Type.u64, op)).toLocal(self, Type.u64);
2157 const high_op_res = try (try self.binOp(lhs_high_bit, rhs_high_bit, Type.u64, op)).toLocal(self, Type.u64);2156 const high_op_res = try (try self.binOp(lhs_high_bit, rhs_high_bit, Type.u64, op)).toLocal(self, Type.u64);
2157 const low_op_res = try self.binOp(lhs_low_bit, rhs_low_bit, Type.u64, op);
21582158
2159 const lt = if (op == .add) blk: {2159 const lt = if (op == .add) blk: {
2160 break :blk try self.cmp(high_op_res, rhs_high_bit, Type.u64, .lt);2160 break :blk try self.cmp(high_op_res, rhs_high_bit, Type.u64, .lt);
...@@ -3190,12 +3190,13 @@ fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3190,12 +3190,13 @@ fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3190 return self.fail("todo Wasm intcast for bitsize > 128", .{});3190 return self.fail("todo Wasm intcast for bitsize > 128", .{});
3191 }3191 }
31923192
3193 return self.intcast(operand, operand_ty, ty);3193 return (try self.intcast(operand, operand_ty, ty)).toLocal(self, ty);
3194}3194}
31953195
3196/// Upcasts or downcasts an integer based on the given and wanted types,3196/// Upcasts or downcasts an integer based on the given and wanted types,
3197/// and stores the result in a new operand.3197/// and stores the result in a new operand.
3198/// Asserts type's bitsize <= 1283198/// Asserts type's bitsize <= 128
3199/// NOTE: May leave the result on the top of the stack.
3199fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!WValue {3200fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
3200 const given_info = given.intInfo(self.target);3201 const given_info = given.intInfo(self.target);
3201 const wanted_info = wanted.intInfo(self.target);3202 const wanted_info = wanted.intInfo(self.target);
...@@ -3227,7 +3228,7 @@ fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!W...@@ -3227,7 +3228,7 @@ fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!W
3227 given,3228 given,
3228 if (wanted.isSignedInt()) Type.i64 else Type.u64,3229 if (wanted.isSignedInt()) Type.i64 else Type.u64,
3229 );3230 );
3230 break :blk tmp;3231 break :blk try tmp.toLocal(self, Type.u64);
3231 } else operand;3232 } else operand;
32323233
3233 // store msb first3234 // store msb first
...@@ -3244,9 +3245,7 @@ fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!W...@@ -3244,9 +3245,7 @@ fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!W
3244 return stack_ptr;3245 return stack_ptr;
3245 } else return self.load(operand, wanted, 0);3246 } else return self.load(operand, wanted, 0);
32463247
3247 const result = try self.allocLocal(wanted);3248 return WValue{ .stack = {} };
3248 try self.addLabel(.local_set, result.local);
3249 return result;
3250}3249}
32513250
3252fn airIsNull(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!WValue {3251fn airIsNull(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!WValue {
...@@ -3478,7 +3477,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3478,7 +3477,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3478 if (wasm_bits != wanted_bits) {3477 if (wasm_bits != wanted_bits) {
3479 return self.wrapOperand(result, wanted_ty);3478 return self.wrapOperand(result, wanted_ty);
3480 }3479 }
3481 return result;3480 return result.toLocal(self, wanted_ty);
3482}3481}
34833482
3484fn airBoolToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue {3483fn airBoolToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
...@@ -4387,7 +4386,7 @@ fn airAddSubWithOverflowBigInt(self: *Self, lhs: WValue, rhs: WValue, ty: Type,...@@ -4387,7 +4386,7 @@ fn airAddSubWithOverflowBigInt(self: *Self, lhs: WValue, rhs: WValue, ty: Type,
4387 } else if (op == .sub) blk: {4386 } else if (op == .sub) blk: {
4388 break :blk try (try self.cmp(lhs_high_bit, rhs_high_bit, Type.u64, .lt)).toLocal(self, Type.u32);4387 break :blk try (try self.cmp(lhs_high_bit, rhs_high_bit, Type.u64, .lt)).toLocal(self, Type.u32);
4389 } else unreachable;4388 } else unreachable;
4390 const tmp = try self.intcast(lt, Type.u32, Type.u64);4389 const tmp = try (try self.intcast(lt, Type.u32, Type.u64)).toLocal(self, Type.u64);
4391 const tmp_op = try (try self.binOp(low_op_res, tmp, Type.u64, op)).toLocal(self, Type.u64);4390 const tmp_op = try (try self.binOp(low_op_res, tmp, Type.u64, op)).toLocal(self, Type.u64);
43924391
4393 const overflow_bit = if (is_signed) blk: {4392 const overflow_bit = if (is_signed) blk: {
...@@ -4500,9 +4499,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -4500,9 +4499,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
4500 const wrap = try self.intcast(shr, new_ty, lhs_ty);4499 const wrap = try self.intcast(shr, new_ty, lhs_ty);
4501 _ = try self.cmp(wrap, zero, lhs_ty, .neq);4500 _ = try self.cmp(wrap, zero, lhs_ty, .neq);
4502 try self.addLabel(.local_set, overflow_bit.local);4501 try self.addLabel(.local_set, overflow_bit.local);
4503 break :blk try self.intcast(bin_op, new_ty, lhs_ty);4502 break :blk try (try self.intcast(bin_op, new_ty, lhs_ty)).toLocal(self, lhs_ty);
4504 } else {4503 } else {
4505 const down_cast = try self.intcast(bin_op, new_ty, lhs_ty);4504 const down_cast = try (try self.intcast(bin_op, new_ty, lhs_ty)).toLocal(self, lhs_ty);
4506 const shr = try (try self.binOp(down_cast, .{ .imm32 = int_info.bits - 1 }, lhs_ty, .shr)).toLocal(self, lhs_ty);4505 const shr = try (try self.binOp(down_cast, .{ .imm32 = int_info.bits - 1 }, lhs_ty, .shr)).toLocal(self, lhs_ty);
45074506
4508 const shr_res = try self.binOp(bin_op, .{ .imm64 = int_info.bits }, new_ty, .shr);4507 const shr_res = try self.binOp(bin_op, .{ .imm64 = int_info.bits }, new_ty, .shr);