| ... | @@ -3263,25 +3263,51 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3263,25 +3263,51 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3263 | defer self.register_manager.unlockReg(tmp_lock); | 3263 | defer self.register_manager.unlockReg(tmp_lock); |
| 3264 | | 3264 | |
| 3265 | const lhs_mcv = try self.resolveInst(bin_op.lhs); | 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 | .{ ._, .mov }, | 3280 | .{ ._, .mov }, |
| 3268 | tmp_reg, | 3281 | tmp_reg, |
| 3269 | lhs_mcv.address().offset(8).deref().mem(.qword), | 3282 | mat_lhs_mcv.address().offset(8).deref().mem(.qword), |
| 3270 | ) else try self.asmRegisterRegister( | 3283 | ) else try self.asmRegisterRegister( |
| 3271 | .{ ._, .mov }, | 3284 | .{ ._, .mov }, |
| 3272 | tmp_reg, | 3285 | tmp_reg, |
| 3273 | lhs_mcv.register_pair[1], | 3286 | mat_lhs_mcv.register_pair[1], |
| 3274 | ); | 3287 | ); |
| 3275 | | 3288 | |
| 3276 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | 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 | .{ ._, .xor }, | 3304 | .{ ._, .xor }, |
| 3279 | tmp_reg, | 3305 | tmp_reg, |
| 3280 | rhs_mcv.address().offset(8).deref().mem(.qword), | 3306 | mat_rhs_mcv.address().offset(8).deref().mem(.qword), |
| 3281 | ) else try self.asmRegisterRegister( | 3307 | ) else try self.asmRegisterRegister( |
| 3282 | .{ ._, .xor }, | 3308 | .{ ._, .xor }, |
| 3283 | tmp_reg, | 3309 | tmp_reg, |
| 3284 | rhs_mcv.register_pair[1], | 3310 | mat_rhs_mcv.register_pair[1], |
| 3285 | ); | 3311 | ); |
| 3286 | const reloc = try self.asmJccReloc(.ns, undefined); | 3312 | const reloc = try self.asmJccReloc(.ns, undefined); |
| 3287 | | 3313 | |
| ... | @@ -3355,20 +3381,37 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3355,20 +3381,37 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3355 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); | 3381 | defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock); |
| 3356 | | 3382 | |
| 3357 | const rhs_mcv = try self.resolveInst(bin_op.rhs); | 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 | for (tmp_regs, dst_regs) |tmp_reg, dst_reg| | 3398 | for (tmp_regs, dst_regs) |tmp_reg, dst_reg| |
| 3360 | try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_reg); | 3399 | try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_reg); |
| 3361 | if (rhs_mcv.isMemory()) { | 3400 | if (mat_rhs_mcv.isMemory()) { |
| 3362 | try self.asmRegisterMemory(.{ ._, .add }, tmp_regs[0], rhs_mcv.mem(.qword)); | 3401 | try self.asmRegisterMemory( |
| | 3402 | .{ ._, .add }, |
| | 3403 | tmp_regs[0], |
| | 3404 | mat_rhs_mcv.mem(.qword), |
| | 3405 | ); |
| 3363 | try self.asmRegisterMemory( | 3406 | try self.asmRegisterMemory( |
| 3364 | .{ ._, .adc }, | 3407 | .{ ._, .adc }, |
| 3365 | tmp_regs[1], | 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 | } else for ( | 3411 | } else for ( |
| 3369 | [_]Mir.Inst.Tag{ .add, .adc }, | 3412 | [_]Mir.Inst.Tag{ .add, .adc }, |
| 3370 | tmp_regs, | 3413 | tmp_regs, |
| 3371 | rhs_mcv.register_pair, | 3414 | mat_rhs_mcv.register_pair, |
| 3372 | ) |op, tmp_reg, rhs_reg| | 3415 | ) |op, tmp_reg, rhs_reg| |
| 3373 | try self.asmRegisterRegister(.{ ._, op }, tmp_reg, rhs_reg); | 3416 | try self.asmRegisterRegister(.{ ._, op }, tmp_reg, rhs_reg); |
| 3374 | try self.asmRegisterRegister(.{ ._, .@"test" }, dst_regs[1], dst_regs[1]); | 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,7 +12308,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 12265 | .register_pair => |dst_regs| { | 12308 | .register_pair => |dst_regs| { |
| 12266 | const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) { | 12309 | const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) { |
| 12267 | .register_pair, .memory, .indirect, .load_frame => null, | 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 | const src_addr_reg = | 12312 | const src_addr_reg = |
| 12270 | (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64(); | 12313 | (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64(); |
| 12271 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); | 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,18 +12338,12 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError |
| 12295 | class_ty, | 12338 | class_ty, |
| 12296 | .{ .register = src_regs[dst_reg_i] }, | 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 | .memory, .indirect, .load_frame => try self.genSetReg( | 12341 | .memory, .indirect, .load_frame => try self.genSetReg( |
| 12305 | dst_reg, | 12342 | dst_reg, |
| 12306 | class_ty, | 12343 | class_ty, |
| 12307 | src_mcv.address().offset(off).deref(), | 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 | dst_reg, | 12347 | dst_reg, |
| 12311 | class_ty, | 12348 | class_ty, |
| 12312 | .{ .indirect = .{ .reg = src_info.?.addr_reg, .off = off } }, | 12349 | .{ .indirect = .{ .reg = src_info.?.addr_reg, .off = off } }, |