| ... | @@ -3250,34 +3250,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3250,34 +3250,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3250 | self.regExtraBits(dst_ty) | 3250 | self.regExtraBits(dst_ty) |
| 3251 | else | 3251 | else |
| 3252 | dst_info.bits % 64; | 3252 | dst_info.bits % 64; |
| 3253 | const partial_mcv = if (dst_info.signedness == .signed and extra_bits > 0) dst: { | 3253 | const partial_mcv = try self.genMulDivBinOp(.mul, null, dst_ty, src_ty, lhs, rhs); |
| 3254 | const rhs_lock: ?RegisterLock = switch (rhs) { | | |
| 3255 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), | | |
| 3256 | else => null, | | |
| 3257 | }; | | |
| 3258 | defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 3259 | | | |
| 3260 | const dst_reg: Register = blk: { | | |
| 3261 | if (lhs.isRegister()) break :blk lhs.register; | | |
| 3262 | break :blk try self.copyToTmpRegister(dst_ty, lhs); | | |
| 3263 | }; | | |
| 3264 | const dst_mcv = MCValue{ .register = dst_reg }; | | |
| 3265 | const dst_reg_lock = self.register_manager.lockRegAssumeUnused(dst_reg); | | |
| 3266 | defer self.register_manager.unlockReg(dst_reg_lock); | | |
| 3267 | | | |
| 3268 | const rhs_mcv: MCValue = blk: { | | |
| 3269 | if (rhs.isRegister() or rhs.isMemory()) break :blk rhs; | | |
| 3270 | break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, rhs) }; | | |
| 3271 | }; | | |
| 3272 | const rhs_mcv_lock: ?RegisterLock = switch (rhs_mcv) { | | |
| 3273 | .register => |reg| self.register_manager.lockReg(reg), | | |
| 3274 | else => null, | | |
| 3275 | }; | | |
| 3276 | defer if (rhs_mcv_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 3277 | | | |
| 3278 | try self.genIntMulComplexOpMir(Type.isize, dst_mcv, rhs_mcv); | | |
| 3279 | break :dst dst_mcv; | | |
| 3280 | } else try self.genMulDivBinOp(.mul, null, dst_ty, src_ty, lhs, rhs); | | |
| 3281 | | 3254 | |
| 3282 | switch (partial_mcv) { | 3255 | switch (partial_mcv) { |
| 3283 | .register => |reg| if (extra_bits == 0) { | 3256 | .register => |reg| if (extra_bits == 0) { |
| ... | @@ -3290,9 +3263,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3290,9 +3263,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3290 | break :result .{ .load_frame = .{ .index = frame_index } }; | 3263 | break :result .{ .load_frame = .{ .index = frame_index } }; |
| 3291 | }, | 3264 | }, |
| 3292 | else => { | 3265 | else => { |
| 3293 | // For now, this is the only supported multiply that doesn't fit in a register, | 3266 | // For now, this is the only supported multiply that doesn't fit in a register. |
| 3294 | // so cc being set is impossible. | | |
| 3295 | | | |
| 3296 | assert(dst_info.bits <= 128 and src_pl.data == 64); | 3267 | assert(dst_info.bits <= 128 and src_pl.data == 64); |
| 3297 | | 3268 | |
| 3298 | const frame_index = | 3269 | const frame_index = |
| ... | @@ -3308,7 +3279,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3308,7 +3279,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3308 | .{ .frame = frame_index }, | 3279 | .{ .frame = frame_index }, |
| 3309 | @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)), | 3280 | @intCast(i32, tuple_ty.structFieldOffset(1, self.target.*)), |
| 3310 | tuple_ty.structFieldType(1), | 3281 | tuple_ty.structFieldType(1), |
| 3311 | .{ .immediate = 0 }, | 3282 | .{ .immediate = 0 }, // cc being set is impossible |
| 3312 | ); | 3283 | ); |
| 3313 | } else try self.genSetFrameTruncatedOverflowCompare( | 3284 | } else try self.genSetFrameTruncatedOverflowCompare( |
| 3314 | tuple_ty, | 3285 | tuple_ty, |
| ... | @@ -5586,31 +5557,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5586,31 +5557,13 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5586 | const dst_lock = self.register_manager.lockReg(dst_reg); | 5557 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 5587 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); | 5558 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 5588 | | 5559 | |
| 5589 | // Shift by struct_field_offset. | | |
| 5590 | try self.genShiftBinOpMir( | 5560 | try self.genShiftBinOpMir( |
| 5591 | .{ ._r, .sh }, | 5561 | .{ ._r, .sh }, |
| 5592 | Type.usize, | 5562 | Type.usize, |
| 5593 | dst_mcv, | 5563 | dst_mcv, |
| 5594 | .{ .immediate = field_off }, | 5564 | .{ .immediate = field_off }, |
| 5595 | ); | 5565 | ); |
| 5596 | | 5566 | if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(field_ty, dst_reg); |
| 5597 | // Mask to field_bit_size bits | | |
| 5598 | const field_bit_size = field_ty.bitSize(self.target.*); | | |
| 5599 | const mask = ~@as(u64, 0) >> @intCast(u6, 64 - field_bit_size); | | |
| 5600 | | | |
| 5601 | const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask }); | | |
| 5602 | try self.genBinOpMir(.{ ._, .@"and" }, Type.usize, dst_mcv, .{ .register = tmp_reg }); | | |
| 5603 | | | |
| 5604 | const signedness = | | |
| 5605 | if (field_ty.isAbiInt()) field_ty.intInfo(self.target.*).signedness else .unsigned; | | |
| 5606 | const field_byte_size = @intCast(u32, field_ty.abiSize(self.target.*)); | | |
| 5607 | if (signedness == .signed and field_byte_size < 8) { | | |
| 5608 | try self.asmRegisterRegister( | | |
| 5609 | if (field_byte_size >= 4) .{ ._d, .movsx } else .{ ._, .movsx }, | | |
| 5610 | dst_mcv.register, | | |
| 5611 | registerAlias(dst_mcv.register, field_byte_size), | | |
| 5612 | ); | | |
| 5613 | } | | |
| 5614 | | 5567 | |
| 5615 | break :result if (field_rc.supersetOf(gp)) | 5568 | break :result if (field_rc.supersetOf(gp)) |
| 5616 | dst_mcv | 5569 | dst_mcv |