authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-28 03:42:22-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-28 03:51:05-04:00
log12b5c8156a2ce9c2ef1e5e71a19e86d4876fd457
tree85aab7127e31a3b0b0bd842c90f9040918ca019e
parent20a36641534cfb88e656944cf3d84aa667cb7ad0

x86_64: handle .load_symbol in more places


1 files changed, 55 insertions(+), 18 deletions(-)

src/arch/x86_64/CodeGen.zig+55-18
...@@ -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);
32643264
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 );
32753288
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);
32873313
...@@ -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);
33563382
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);
33583397
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 } },