| ... | @@ -4162,22 +4162,14 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!W | ... | @@ -4162,22 +4162,14 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!W |
| 4162 | 64 => WValue{ .imm64 = 0 }, | 4162 | 64 => WValue{ .imm64 = 0 }, |
| 4163 | else => unreachable, | 4163 | else => unreachable, |
| 4164 | }; | 4164 | }; |
| 4165 | const shift_amt = wasm_bits - int_info.bits; | | |
| 4166 | const shift_val = switch (wasm_bits) { | | |
| 4167 | 32 => WValue{ .imm32 = shift_amt }, | | |
| 4168 | 64 => WValue{ .imm64 = shift_amt }, | | |
| 4169 | else => unreachable, | | |
| 4170 | }; | | |
| 4171 | | 4165 | |
| 4172 | // for signed integers, we first apply signed shifts by the difference in bits | 4166 | // for signed integers, we first apply signed shifts by the difference in bits |
| 4173 | // to get the signed value, as we store it internally as 2's complement. | 4167 | // to get the signed value, as we store it internally as 2's complement. |
| 4174 | const lhs = if (wasm_bits != int_info.bits and is_signed) blk: { | 4168 | const lhs = if (wasm_bits != int_info.bits and is_signed) blk: { |
| 4175 | const shl = try self.binOp(lhs_op, shift_val, lhs_ty, .shl); | 4169 | break :blk try self.signAbsValue(lhs_op, lhs_ty); |
| 4176 | break :blk try self.binOp(shl, shift_val, lhs_ty, .shr); | | |
| 4177 | } else lhs_op; | 4170 | } else lhs_op; |
| 4178 | const rhs = if (wasm_bits != int_info.bits and is_signed) blk: { | 4171 | const rhs = if (wasm_bits != int_info.bits and is_signed) blk: { |
| 4179 | const shl = try self.binOp(rhs_op, shift_val, lhs_ty, .shl); | 4172 | break :blk try self.signAbsValue(rhs_op, lhs_ty); |
| 4180 | break :blk try self.binOp(shl, shift_val, lhs_ty, .shr); | | |
| 4181 | } else rhs_op; | 4173 | } else rhs_op; |
| 4182 | | 4174 | |
| 4183 | const bin_op = try self.binOp(lhs, rhs, lhs_ty, op); | 4175 | const bin_op = try self.binOp(lhs, rhs, lhs_ty, op); |
| ... | @@ -4192,9 +4184,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!W | ... | @@ -4192,9 +4184,8 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index, op: Op) InnerError!W |
| 4192 | const lt = try self.cmp(bin_op, lhs, lhs_ty, .lt); | 4184 | const lt = try self.cmp(bin_op, lhs, lhs_ty, .lt); |
| 4193 | break :blk try self.binOp(cmp_zero, lt, Type.u32, .xor); // result of cmp_zero and lt is always 32bit | 4185 | break :blk try self.binOp(cmp_zero, lt, Type.u32, .xor); // result of cmp_zero and lt is always 32bit |
| 4194 | } | 4186 | } |
| 4195 | const shl = try self.binOp(bin_op, shift_val, lhs_ty, .shl); | 4187 | const abs = try self.signAbsValue(bin_op, lhs_ty); |
| 4196 | const shr = try self.binOp(shl, shift_val, lhs_ty, .shr); | 4188 | break :blk try self.cmp(abs, bin_op, lhs_ty, .neq); |
| 4197 | break :blk try self.cmp(shr, bin_op, lhs_ty, .neq); | | |
| 4198 | } else if (wasm_bits == int_info.bits) | 4189 | } else if (wasm_bits == int_info.bits) |
| 4199 | try self.cmp(bin_op, lhs, lhs_ty, cmp_op) | 4190 | try self.cmp(bin_op, lhs, lhs_ty, cmp_op) |
| 4200 | else | 4191 | else |
| ... | @@ -4289,17 +4280,9 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | ... | @@ -4289,17 +4280,9 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 4289 | } else shl; | 4280 | } else shl; |
| 4290 | | 4281 | |
| 4291 | const overflow_bit = if (wasm_bits != int_info.bits and is_signed) blk: { | 4282 | const overflow_bit = if (wasm_bits != int_info.bits and is_signed) blk: { |
| 4292 | const shift_amt = wasm_bits - int_info.bits; | 4283 | const abs = try self.signAbsValue(shl, lhs_ty); |
| 4293 | const shift_val = switch (wasm_bits) { | 4284 | const wrapped = try self.wrapBinOp(abs, rhs, lhs_ty, .shr); |
| 4294 | 32 => WValue{ .imm32 = shift_amt }, | 4285 | break :blk try self.cmp(lhs, wrapped, lhs_ty, .neq); |
| 4295 | 64 => WValue{ .imm64 = shift_amt }, | | |
| 4296 | else => unreachable, | | |
| 4297 | }; | | |
| 4298 | | | |
| 4299 | const secondary_shl = try self.binOp(shl, shift_val, lhs_ty, .shl); | | |
| 4300 | const initial_shr = try self.binOp(secondary_shl, shift_val, lhs_ty, .shr); | | |
| 4301 | const shr = try self.wrapBinOp(initial_shr, rhs, lhs_ty, .shr); | | |
| 4302 | break :blk try self.cmp(lhs, shr, lhs_ty, .neq); | | |
| 4303 | } else blk: { | 4286 | } else blk: { |
| 4304 | const shr = try self.binOp(result, rhs, lhs_ty, .shr); | 4287 | const shr = try self.binOp(result, rhs, lhs_ty, .shr); |
| 4305 | break :blk try self.cmp(lhs, shr, lhs_ty, .neq); | 4288 | break :blk try self.cmp(lhs, shr, lhs_ty, .neq); |
| ... | @@ -4367,21 +4350,11 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue { | ... | @@ -4367,21 +4350,11 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 4367 | break :blk down_cast; | 4350 | break :blk down_cast; |
| 4368 | } | 4351 | } |
| 4369 | } else if (int_info.signedness == .signed) blk: { | 4352 | } else if (int_info.signedness == .signed) blk: { |
| 4370 | const shift_imm = if (wasm_bits == 32) | 4353 | const lhs_abs = try self.signAbsValue(lhs, lhs_ty); |
| 4371 | WValue{ .imm32 = wasm_bits - int_info.bits } | 4354 | const rhs_abs = try self.signAbsValue(rhs, lhs_ty); |
| 4372 | else | 4355 | const bin_op = try self.binOp(lhs_abs, rhs_abs, lhs_ty, .mul); |
| 4373 | WValue{ .imm64 = wasm_bits - int_info.bits }; | 4356 | const mul_abs = try self.signAbsValue(bin_op, lhs_ty); |
| 4374 | | 4357 | const cmp_op = try self.cmp(mul_abs, bin_op, lhs_ty, .neq); |
| 4375 | const lhs_shl = try self.binOp(lhs, shift_imm, lhs_ty, .shl); | | |
| 4376 | const lhs_shr = try self.binOp(lhs_shl, shift_imm, lhs_ty, .shr); | | |
| 4377 | const rhs_shl = try self.binOp(rhs, shift_imm, lhs_ty, .shl); | | |
| 4378 | const rhs_shr = try self.binOp(rhs_shl, shift_imm, lhs_ty, .shr); | | |
| 4379 | | | |
| 4380 | const bin_op = try self.binOp(lhs_shr, rhs_shr, lhs_ty, .mul); | | |
| 4381 | const shl = try self.binOp(bin_op, shift_imm, lhs_ty, .shl); | | |
| 4382 | const shr = try self.binOp(shl, shift_imm, lhs_ty, .shr); | | |
| 4383 | | | |
| 4384 | const cmp_op = try self.cmp(shr, bin_op, lhs_ty, .neq); | | |
| 4385 | try self.emitWValue(cmp_op); | 4358 | try self.emitWValue(cmp_op); |
| 4386 | try self.addLabel(.local_set, overflow_bit.local); | 4359 | try self.addLabel(.local_set, overflow_bit.local); |
| 4387 | break :blk try self.wrapOperand(bin_op, lhs_ty); | 4360 | break :blk try self.wrapOperand(bin_op, lhs_ty); |