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 {
32633263 defer self.register_manager.unlockReg(tmp_lock);
32643264
32653265 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(
32673280 .{ ._, .mov },
32683281 tmp_reg,
3269 lhs_mcv.address().offset(8).deref().mem(.qword),
3282 mat_lhs_mcv.address().offset(8).deref().mem(.qword),
32703283 ) else try self.asmRegisterRegister(
32713284 .{ ._, .mov },
32723285 tmp_reg,
3273 lhs_mcv.register_pair[1],
3286 mat_lhs_mcv.register_pair[1],
32743287 );
32753288
32763289 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(
32783304 .{ ._, .xor },
32793305 tmp_reg,
3280 rhs_mcv.address().offset(8).deref().mem(.qword),
3306 mat_rhs_mcv.address().offset(8).deref().mem(.qword),
32813307 ) else try self.asmRegisterRegister(
32823308 .{ ._, .xor },
32833309 tmp_reg,
3284 rhs_mcv.register_pair[1],
3310 mat_rhs_mcv.register_pair[1],
32853311 );
32863312 const reloc = try self.asmJccReloc(.ns, undefined);
32873313
......@@ -3355,20 +3381,37 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
33553381 defer for (tmp_locks) |lock| self.register_manager.unlockReg(lock);
33563382
33573383 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
33593398 for (tmp_regs, dst_regs) |tmp_reg, dst_reg|
33603399 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 );
33633406 try self.asmRegisterMemory(
33643407 .{ ._, .adc },
33653408 tmp_regs[1],
3366 rhs_mcv.address().offset(8).deref().mem(.qword),
3409 mat_rhs_mcv.address().offset(8).deref().mem(.qword),
33673410 );
33683411 } else for (
33693412 [_]Mir.Inst.Tag{ .add, .adc },
33703413 tmp_regs,
3371 rhs_mcv.register_pair,
3414 mat_rhs_mcv.register_pair,
33723415 ) |op, tmp_reg, rhs_reg|
33733416 try self.asmRegisterRegister(.{ ._, op }, tmp_reg, rhs_reg);
33743417 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
1226512308 .register_pair => |dst_regs| {
1226612309 const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) {
1226712310 .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: {
1226912312 const src_addr_reg =
1227012313 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
1227112314 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
1229512338 class_ty,
1229612339 .{ .register = src_regs[dst_reg_i] },
1229712340 ),
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 },
1230412341 .memory, .indirect, .load_frame => try self.genSetReg(
1230512342 dst_reg,
1230612343 class_ty,
1230712344 src_mcv.address().offset(off).deref(),
1230812345 ),
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(
1231012347 dst_reg,
1231112348 class_ty,
1231212349 .{ .indirect = .{ .reg = src_info.?.addr_reg, .off = off } },