authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-11-12 18:10:06-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-11-12 18:12:41-05:00
log80b73e3e8fd5ef8b46152e929153ad45fc6220fd
treed0039cf8a3f515e471e747329977666fdd2b27f6
parent3d3153c58e9ab808c8b1899d3a9de9d1a1030a67

x86_64: resolve tlv references on first use and spill to the stack

This avoids any arbitrary memory operand possibly clobbering rax and sometime rdi with no warning.

2 files changed, 32 insertions(+), 5 deletions(-)

src/arch/x86_64/CodeGen.zig+29-5
...@@ -1107,6 +1107,7 @@ fn formatWipMir(...@@ -1107,6 +1107,7 @@ fn formatWipMir(
1107 .cc = .Unspecified,1107 .cc = .Unspecified,
1108 .src_loc = data.self.src_loc,1108 .src_loc = data.self.src_loc,
1109 };1109 };
1110 var first = true;
1110 for ((lower.lowerMir(data.inst) catch |err| switch (err) {1111 for ((lower.lowerMir(data.inst) catch |err| switch (err) {
1111 error.LowerFail => {1112 error.LowerFail => {
1112 defer {1113 defer {
...@@ -1125,7 +1126,11 @@ fn formatWipMir(...@@ -1125,7 +1126,11 @@ fn formatWipMir(
1125 return;1126 return;
1126 },1127 },
1127 else => |e| return e,1128 else => |e| return e,
1128 }).insts) |lowered_inst| try writer.print(" | {}", .{lowered_inst});1129 }).insts) |lowered_inst| {
1130 if (!first) try writer.writeAll("\ndebug(wip_mir): ");
1131 try writer.print(" | {}", .{lowered_inst});
1132 first = false;
1133 }
1129}1134}
1130fn fmtWipMir(self: *Self, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMir) {1135fn fmtWipMir(self: *Self, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMir) {
1131 return .{ .data = .{ .self = self, .inst = inst } };1136 return .{ .data = .{ .self = self, .inst = inst } };
...@@ -15798,11 +15803,30 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {...@@ -15798,11 +15803,30 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
15798 } else mcv: {15803 } else mcv: {
15799 const ip_index = Air.refToInterned(ref).?;15804 const ip_index = Air.refToInterned(ref).?;
15800 const gop = try self.const_tracking.getOrPut(self.gpa, ip_index);15805 const gop = try self.const_tracking.getOrPut(self.gpa, ip_index);
15801 const mcv = try self.genTypedValue(.{15806 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(init: {
15802 .ty = ty,15807 const const_mcv = try self.genTypedValue(.{ .ty = ty, .val = ip_index.toValue() });
15803 .val = ip_index.toValue(),15808 switch (const_mcv) {
15809 .lea_tlv => |tlv_sym| if (self.bin_file.cast(link.File.Elf)) |_| {
15810 if (self.bin_file.options.pic) {
15811 try self.spillRegisters(&.{ .rdi, .rax });
15812 } else {
15813 try self.spillRegisters(&.{.rax});
15814 }
15815 const frame_index = try self.allocFrameIndex(FrameAlloc.init(.{
15816 .size = 8,
15817 .alignment = .@"8",
15818 }));
15819 try self.genSetMem(
15820 .{ .frame = frame_index },
15821 0,
15822 Type.usize,
15823 .{ .lea_symbol = .{ .sym = tlv_sym } },
15824 );
15825 break :init .{ .load_frame = .{ .index = frame_index } };
15826 } else break :init const_mcv,
15827 else => break :init const_mcv,
15828 }
15804 });15829 });
15805 if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(mcv);
15806 break :mcv gop.value_ptr.short;15830 break :mcv gop.value_ptr.short;
15807 };15831 };
1580815832
src/codegen.zig+3
...@@ -912,6 +912,9 @@ fn genDeclRef(...@@ -912,6 +912,9 @@ fn genDeclRef(
912 }912 }
913 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);913 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
914 const sym = elf_file.symbol(sym_index);914 const sym = elf_file.symbol(sym_index);
915 if (is_threadlocal) {
916 return GenResult.mcv(.{ .load_tlv = sym.esym_index });
917 }
915 return GenResult.mcv(.{ .load_symbol = sym.esym_index });918 return GenResult.mcv(.{ .load_symbol = sym.esym_index });
916 } else if (bin_file.cast(link.File.MachO)) |macho_file| {919 } else if (bin_file.cast(link.File.MachO)) |macho_file| {
917 if (is_extern) {920 if (is_extern) {