| ... | ... | @@ -3263,25 +3263,51 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3263 | 3263 | defer self.register_manager.unlockReg(tmp_lock); |
| 3264 | 3264 | |
| 3265 | 3265 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 3266 | | if (lhs_mcv.isMemory()) try self.asmRegisterMemory( |
| 3266 | const mat_lhs_mcv = switch (lhs_mcv) { |
| 3267 | .load_symbol => mat_lhs_mcv: { |
| 3268 | // TODO clean this up! |
| 3269 | const addr_reg = try self.copyToTmpRegister(Type.usize, lhs_mcv.address()); |
| 3270 | break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 3271 | }, |
| 3272 | else => lhs_mcv, |
| 3273 | }; |
| 3274 | const mat_lhs_lock = switch (mat_lhs_mcv) { |
| 3275 | .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg), |
| 3276 | else => null, |
| 3277 | }; |
| 3278 | defer if (mat_lhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 3279 | if (mat_lhs_mcv.isMemory()) try self.asmRegisterMemory( |
| 3267 | 3280 | .{ ._, .mov }, |
| 3268 | 3281 | tmp_reg, |
| 3269 | | lhs_mcv.address().offset(8).deref().mem(.qword), |
| 3282 | mat_lhs_mcv.address().offset(8).deref().mem(.qword), |
| 3270 | 3283 | ) else try self.asmRegisterRegister( |
| 3271 | 3284 | .{ ._, .mov }, |
| 3272 | 3285 | tmp_reg, |
| 3273 | | lhs_mcv.register_pair[1], |
| 3286 | mat_lhs_mcv.register_pair[1], |
| 3274 | 3287 | ); |
| 3275 | 3288 | |
| 3276 | 3289 | const rhs_mcv = try self.resolveInst(bin_op.rhs); |
| 3277 | | if (rhs_mcv.isMemory()) try self.asmRegisterMemory( |
| 3290 | const mat_rhs_mcv = switch (rhs_mcv) { |
| 3291 | .load_symbol => mat_rhs_mcv: { |
| 3292 | // TODO clean this up! |
| 3293 | const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address()); |
| 3294 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 3295 | }, |
| 3296 | else => rhs_mcv, |
| 3297 | }; |
| 3298 | const mat_rhs_lock = switch (mat_rhs_mcv) { |
| 3299 | .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg), |
| 3300 | else => null, |
| 3301 | }; |
| 3302 | defer if (mat_rhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 3303 | if (mat_rhs_mcv.isMemory()) try self.asmRegisterMemory( |
| 3278 | 3304 | .{ ._, .xor }, |
| 3279 | 3305 | tmp_reg, |
| 3280 | | rhs_mcv.address().offset(8).deref().mem(.qword), |
| 3306 | mat_rhs_mcv.address().offset(8).deref().mem(.qword), |
| 3281 | 3307 | ) else try self.asmRegisterRegister( |
| 3282 | 3308 | .{ ._, .xor }, |
| 3283 | 3309 | tmp_reg, |
| 3284 | | rhs_mcv.register_pair[1], |
| 3310 | mat_rhs_mcv.register_pair[1], |
| 3285 | 3311 | ); |
| 3286 | 3312 | const reloc = try self.asmJccReloc(.ns, undefined); |
| 3287 | 3313 | |
| ... | ... | @@ -3355,20 +3381,37 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3355 | 3381 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); |
| 3356 | 3382 | |
| 3357 | 3383 | const rhs_mcv = try self.resolveInst(bin_op.rhs); |
| 3384 | const mat_rhs_mcv = switch (rhs_mcv) { |
| 3385 | .load_symbol => mat_rhs_mcv: { |
| 3386 | // TODO clean this up! |
| 3387 | const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address()); |
| 3388 | break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } }; |
| 3389 | }, |
| 3390 | else => rhs_mcv, |
| 3391 | }; |
| 3392 | const mat_rhs_lock = switch (mat_rhs_mcv) { |
| 3393 | .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg), |
| 3394 | else => null, |
| 3395 | }; |
| 3396 | defer if (mat_rhs_lock) |lock| self.register_manager.unlockReg(lock); |
| 3358 | 3397 | |
| 3359 | 3398 | for (tmp_regs, dst_regs) |tmp_reg, dst_reg| |
| 3360 | 3399 | try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_reg); |
| 3361 | | if (rhs_mcv.isMemory()) { |
| 3362 | | try self.asmRegisterMemory(.{ ._, .add }, tmp_regs[0], rhs_mcv.mem(.qword)); |
| 3400 | if (mat_rhs_mcv.isMemory()) { |
| 3401 | try self.asmRegisterMemory( |
| 3402 | .{ ._, .add }, |
| 3403 | tmp_regs[0], |
| 3404 | mat_rhs_mcv.mem(.qword), |
| 3405 | ); |
| 3363 | 3406 | try self.asmRegisterMemory( |
| 3364 | 3407 | .{ ._, .adc }, |
| 3365 | 3408 | tmp_regs[1], |
| 3366 | | rhs_mcv.address().offset(8).deref().mem(.qword), |
| 3409 | mat_rhs_mcv.address().offset(8).deref().mem(.qword), |
| 3367 | 3410 | ); |
| 3368 | 3411 | } else for ( |
| 3369 | 3412 | [_]Mir.Inst.Tag{ .add, .adc }, |
| 3370 | 3413 | tmp_regs, |
| 3371 | | rhs_mcv.register_pair, |
| 3414 | mat_rhs_mcv.register_pair, |
| 3372 | 3415 | ) |op, tmp_reg, rhs_reg| |
| 3373 | 3416 | try self.asmRegisterRegister(.{ ._, op }, tmp_reg, rhs_reg); |
| 3374 | 3417 | try self.asmRegisterRegister(.{ ._, .@"test" }, dst_regs[1], dst_regs[1]); |
| ... | ... | @@ -12265,7 +12308,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 12265 | 12308 | .register_pair => |dst_regs| { |
| 12266 | 12309 | const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) { |
| 12267 | 12310 | .register_pair, .memory, .indirect, .load_frame => null, |
| 12268 | | .load_direct, .load_got, .load_extern_got, .load_tlv => src: { |
| 12311 | .load_symbol, .load_direct, .load_got, .load_tlv => src: { |
| 12269 | 12312 | const src_addr_reg = |
| 12270 | 12313 | (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64(); |
| 12271 | 12314 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| ... | ... | @@ -12295,18 +12338,12 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 12295 | 12338 | class_ty, |
| 12296 | 12339 | .{ .register = src_regs[dst_reg_i] }, |
| 12297 | 12340 | ), |
| 12298 | | .load_symbol => { |
| 12299 | | const addr_reg = try self.copyToTmpRegister(Type.usize, src_mcv.address()); |
| 12300 | | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 12301 | | defer self.register_manager.unlockReg(addr_lock); |
| 12302 | | try self.genCopy(ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } }); |
| 12303 | | }, |
| 12304 | 12341 | .memory, .indirect, .load_frame => try self.genSetReg( |
| 12305 | 12342 | dst_reg, |
| 12306 | 12343 | class_ty, |
| 12307 | 12344 | src_mcv.address().offset(off).deref(), |
| 12308 | 12345 | ), |
| 12309 | | .load_direct, .load_got, .load_extern_got, .load_tlv => try self.genSetReg( |
| 12346 | .load_symbol, .load_direct, .load_got, .load_tlv => try self.genSetReg( |
| 12310 | 12347 | dst_reg, |
| 12311 | 12348 | class_ty, |
| 12312 | 12349 | .{ .indirect = .{ .reg = src_info.?.addr_reg, .off = off } }, |