diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-11-12 18:10:06 -0500 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2023-11-12 18:12:41 -0500 |
| commit | 80b73e3e8fd5ef8b46152e929153ad45fc6220fd (patch) | |
| tree | d0039cf8a3f515e471e747329977666fdd2b27f6 /src | |
| parent | 3d3153c58e9ab808c8b1899d3a9de9d1a1030a67 (diff) | |
| download | zig-80b73e3e8fd5ef8b46152e929153ad45fc6220fd.tar.gz zig-80b73e3e8fd5ef8b46152e929153ad45fc6220fd.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 34 | ||||
| -rw-r--r-- | src/codegen.zig | 3 |
2 files changed, 32 insertions, 5 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 1faeeced95..2e3209f64a 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1107,6 +1107,7 @@ fn formatWipMir( .cc = .Unspecified, .src_loc = data.self.src_loc, }; + var first = true; for ((lower.lowerMir(data.inst) catch |err| switch (err) { error.LowerFail => { defer { @@ -1125,7 +1126,11 @@ fn formatWipMir( return; }, else => |e| return e, - }).insts) |lowered_inst| try writer.print(" | {}", .{lowered_inst}); + }).insts) |lowered_inst| { + if (!first) try writer.writeAll("\ndebug(wip_mir): "); + try writer.print(" | {}", .{lowered_inst}); + first = false; + } } fn fmtWipMir(self: *Self, inst: Mir.Inst.Index) std.fmt.Formatter(formatWipMir) { return .{ .data = .{ .self = self, .inst = inst } }; @@ -15798,11 +15803,30 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { } else mcv: { const ip_index = Air.refToInterned(ref).?; const gop = try self.const_tracking.getOrPut(self.gpa, ip_index); - const mcv = try self.genTypedValue(.{ - .ty = ty, - .val = ip_index.toValue(), + if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(init: { + const const_mcv = try self.genTypedValue(.{ .ty = ty, .val = ip_index.toValue() }); + switch (const_mcv) { + .lea_tlv => |tlv_sym| if (self.bin_file.cast(link.File.Elf)) |_| { + if (self.bin_file.options.pic) { + try self.spillRegisters(&.{ .rdi, .rax }); + } else { + try self.spillRegisters(&.{.rax}); + } + const frame_index = try self.allocFrameIndex(FrameAlloc.init(.{ + .size = 8, + .alignment = .@"8", + })); + try self.genSetMem( + .{ .frame = frame_index }, + 0, + Type.usize, + .{ .lea_symbol = .{ .sym = tlv_sym } }, + ); + break :init .{ .load_frame = .{ .index = frame_index } }; + } else break :init const_mcv, + else => break :init const_mcv, + } }); - if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(mcv); break :mcv gop.value_ptr.short; }; diff --git a/src/codegen.zig b/src/codegen.zig index 9420e8ca14..94f1f6ea0e 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -912,6 +912,9 @@ fn genDeclRef( } const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index); const sym = elf_file.symbol(sym_index); + if (is_threadlocal) { + return GenResult.mcv(.{ .load_tlv = sym.esym_index }); + } return GenResult.mcv(.{ .load_symbol = sym.esym_index }); } else if (bin_file.cast(link.File.MachO)) |macho_file| { if (is_extern) { |
