authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-15 14:57:38+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-15 20:59:51+02:00
logecc52d859f7f1e400c8bfc08aea971f4596649cf
treed476d85eb2c7085656e20c266910d3ca3f33abf9
parentb82130709d121222f793c082dbbe6c29e7f2ec41

x86_64: fix loading/storing pointers from linker deferred memory locations


1 files changed, 69 insertions(+), 47 deletions(-)

src/arch/x86_64/CodeGen.zig+69-47
...@@ -3619,11 +3619,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -3619,11 +3619,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
3619 else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}),3619 else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}),
3620 }3620 }
3621 },3621 },
3622 .load_direct, .load_tlv => |sym_index| try self.load(dst_mcv, switch (ptr) {3622 .load_direct => |sym_index| {
3623 .load_direct => .{ .lea_direct = sym_index },3623 const addr_reg = try self.copyToTmpRegister(Type.usize, .{ .lea_direct = sym_index });
3624 .load_tlv => .{ .lea_tlv = sym_index },3624 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
3625 else => unreachable,3625 defer self.register_manager.unlockReg(addr_reg_lock);
3626 }, ptr_ty),3626 // Load the pointer, which is stored in memory
3627 try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg }));
3628 try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty);
3629 },
3630 .load_tlv => |sym_index| try self.load(dst_mcv, .{ .lea_tlv = sym_index }, ptr_ty),
3627 .memory, .load_got, .lea_direct, .lea_tlv => {3631 .memory, .load_got, .lea_direct, .lea_tlv => {
3628 const reg = try self.copyToTmpRegister(ptr_ty, ptr);3632 const reg = try self.copyToTmpRegister(ptr_ty, ptr);
3629 try self.load(dst_mcv, .{ .register = reg }, ptr_ty);3633 try self.load(dst_mcv, .{ .register = reg }, ptr_ty);
...@@ -3817,15 +3821,15 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -3817,15 +3821,15 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
3817 defer self.register_manager.unlockReg(addr_reg_lock);3821 defer self.register_manager.unlockReg(addr_reg_lock);
38183822
3819 switch (ptr) {3823 switch (ptr) {
3820 .memory => |addr| {3824 .memory => |addr| try self.genSetReg(ptr_ty, addr_reg, .{ .immediate = addr }),
3821 try self.genSetReg(ptr_ty, addr_reg, .{ .immediate = addr });
3822 // Load the pointer, which is stored in memory
3823 try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg }));
3824 },
3825 .load_direct => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_direct = sym_index }),3825 .load_direct => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_direct = sym_index }),
3826 .load_tlv => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_tlv = sym_index }),3826 .load_tlv => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_tlv = sym_index }),
3827 else => unreachable,3827 else => unreachable,
3828 }3828 }
3829 if (ptr != .load_tlv) {
3830 // Load the pointer, which is stored in memory
3831 try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg }));
3832 }
38293833
3830 const new_ptr = MCValue{ .register = addr_reg };3834 const new_ptr = MCValue{ .register = addr_reg };
3831 try self.store(new_ptr, value, ptr_ty, value_ty);3835 try self.store(new_ptr, value, ptr_ty, value_ty);
...@@ -7223,6 +7227,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -7223,6 +7227,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
7223 .memory,7227 .memory,
7224 .load_direct,7228 .load_direct,
7225 .load_tlv,7229 .load_tlv,
7230 .lea_direct,
7231 .lea_tlv,
7226 => if (abi_size <= 8) {7232 => if (abi_size <= 8) {
7227 const reg = try self.copyToTmpRegister(ty, mcv);7233 const reg = try self.copyToTmpRegister(ty, mcv);
7228 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts);7234 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts);
...@@ -7235,7 +7241,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -7235,7 +7241,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
7235 .memory => |addr| .{ .immediate = addr },7241 .memory => |addr| .{ .immediate = addr },
7236 .load_direct => |sym_index| .{ .lea_direct = sym_index },7242 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7237 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },7243 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7238 else => unreachable,7244 else => mcv,
7239 });7245 });
7240 try self.genInlineMemcpy(7246 try self.genInlineMemcpy(
7241 .{ .ptr_stack_offset = stack_offset },7247 .{ .ptr_stack_offset = stack_offset },
...@@ -7258,8 +7264,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -7258,8 +7264,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
7258 ),7264 ),
7259 .ptr_stack_offset,7265 .ptr_stack_offset,
7260 .load_got,7266 .load_got,
7261 .lea_direct,
7262 .lea_tlv,
7263 => {7267 => {
7264 const tmp_reg = try self.copyToTmpRegister(ty, mcv);7268 const tmp_reg = try self.copyToTmpRegister(ty, mcv);
7265 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);7269 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
...@@ -7350,21 +7354,27 @@ fn genInlineMemcpy(...@@ -7350,21 +7354,27 @@ fn genInlineMemcpy(
7350 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });7354 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });
73517355
7352 switch (dst_ptr) {7356 switch (dst_ptr) {
7353 .memory => |addr| {7357 .lea_tlv,
7354 try self.genSetReg(Type.usize, .rdi, .{ .immediate = addr });7358 .load_tlv,
7355 // Load the pointer, which is stored in memory7359 => {
7356 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));7360 try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7361 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7362 else => dst_ptr,
7363 });
7357 },7364 },
7365 .memory,
7358 .load_got,7366 .load_got,
7359 .lea_direct,7367 .lea_direct,
7360 .load_direct,7368 .load_direct,
7361 .lea_tlv,7369 => {
7362 .load_tlv,7370 try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7363 => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {7371 .memory => |addr| .{ .immediate = addr },
7364 .load_direct => |sym_index| .{ .lea_direct = sym_index },7372 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7365 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },7373 else => dst_ptr,
7366 else => dst_ptr,7374 });
7367 }),7375 // Load the pointer, which is stored in memory
7376 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
7377 },
7368 .stack_offset, .ptr_stack_offset => |off| {7378 .stack_offset, .ptr_stack_offset => |off| {
7369 try self.asmRegisterMemory(switch (dst_ptr) {7379 try self.asmRegisterMemory(switch (dst_ptr) {
7370 .stack_offset => .mov,7380 .stack_offset => .mov,
...@@ -7388,21 +7398,27 @@ fn genInlineMemcpy(...@@ -7388,21 +7398,27 @@ fn genInlineMemcpy(
7388 }7398 }
73897399
7390 switch (src_ptr) {7400 switch (src_ptr) {
7391 .memory => |addr| {7401 .lea_tlv,
7392 try self.genSetReg(Type.usize, .rsi, .{ .immediate = addr });7402 .load_tlv,
7393 // Load the pointer, which is stored in memory7403 => {
7394 try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi }));7404 try self.genSetReg(Type.usize, .rsi, switch (src_ptr) {
7405 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7406 else => dst_ptr,
7407 });
7395 },7408 },
7409 .memory,
7396 .load_got,7410 .load_got,
7397 .lea_direct,7411 .lea_direct,
7398 .load_direct,7412 .load_direct,
7399 .lea_tlv,7413 => {
7400 .load_tlv,7414 try self.genSetReg(Type.usize, .rsi, switch (src_ptr) {
7401 => try self.genSetReg(Type.usize, .rsi, switch (src_ptr) {7415 .memory => |addr| .{ .immediate = addr },
7402 .load_direct => |sym_index| .{ .lea_direct = sym_index },7416 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7403 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },7417 else => src_ptr,
7404 else => src_ptr,7418 });
7405 }),7419 // Load the pointer, which is stored in memory
7420 try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi }));
7421 },
7406 .stack_offset, .ptr_stack_offset => |off| {7422 .stack_offset, .ptr_stack_offset => |off| {
7407 try self.asmRegisterMemory(switch (src_ptr) {7423 try self.asmRegisterMemory(switch (src_ptr) {
7408 .stack_offset => .mov,7424 .stack_offset => .mov,
...@@ -7449,21 +7465,27 @@ fn genInlineMemset(...@@ -7449,21 +7465,27 @@ fn genInlineMemset(
7449 try self.spillRegisters(&.{ .rdi, .al, .rcx });7465 try self.spillRegisters(&.{ .rdi, .al, .rcx });
74507466
7451 switch (dst_ptr) {7467 switch (dst_ptr) {
7452 .memory => |addr| {7468 .lea_tlv,
7453 try self.genSetReg(Type.usize, .rdi, .{ .immediate = addr });7469 .load_tlv,
7454 // Load the pointer, which is stored in memory7470 => {
7455 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));7471 try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7472 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7473 else => dst_ptr,
7474 });
7456 },7475 },
7457 .load_got,7476 .load_got => try self.genSetReg(Type.usize, .rdi, dst_ptr),
7477 .memory,
7458 .lea_direct,7478 .lea_direct,
7459 .load_direct,7479 .load_direct,
7460 .lea_tlv,7480 => {
7461 .load_tlv,7481 try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7462 => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {7482 .memory => |addr| .{ .immediate = addr },
7463 .load_direct => |sym_index| .{ .lea_direct = sym_index },7483 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7464 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },7484 else => dst_ptr,
7465 else => dst_ptr,7485 });
7466 }),7486 // Load the pointer, which is stored in memory
7487 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
7488 },
7467 .stack_offset, .ptr_stack_offset => |off| {7489 .stack_offset, .ptr_stack_offset => |off| {
7468 try self.asmRegisterMemory(switch (dst_ptr) {7490 try self.asmRegisterMemory(switch (dst_ptr) {
7469 .stack_offset => .mov,7491 .stack_offset => .mov,