authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-12 12:06:49+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-13 11:47:51+02:00
logfd52d4537a86fc312e4491206228ab3aeabe0f2c
treed36e275293e26a30b623ceb2440a8826060f203e
parent1f6165f6211885d3f5392cdfcc15f990284159de

x86_64: emit pointer to TLV for macho


5 files changed, 68 insertions(+), 3 deletions(-)

src/arch/aarch64/CodeGen.zig+4
......@@ -3982,6 +3982,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
39823982 .got => .load_memory_ptr_got,
39833983 .direct => .load_memory_ptr_direct,
39843984 .import => unreachable,
3985 .tlv => @panic("TODO TLV support"),
39853986 };
39863987 const atom_index = switch (self.bin_file.tag) {
39873988 .macho => blk: {
......@@ -5510,6 +5511,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
55105511 .got => .load_memory_ptr_got,
55115512 .direct => .load_memory_ptr_direct,
55125513 .import => unreachable,
5514 .tlv => @panic("TODO TLV support"),
55135515 };
55145516 const atom_index = switch (self.bin_file.tag) {
55155517 .macho => blk: {
......@@ -5630,6 +5632,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
56305632 .got => .load_memory_got,
56315633 .direct => .load_memory_direct,
56325634 .import => .load_memory_import,
5635 .tlv => @panic("TODO TLV support"),
56335636 };
56345637 const atom_index = switch (self.bin_file.tag) {
56355638 .macho => blk: {
......@@ -5830,6 +5833,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
58305833 .got => .load_memory_ptr_got,
58315834 .direct => .load_memory_ptr_direct,
58325835 .import => unreachable,
5836 .tlv => @panic("TODO TLV support"),
58335837 };
58345838 const atom_index = switch (self.bin_file.tag) {
58355839 .macho => blk: {
src/arch/x86_64/CodeGen.zig+55-2
......@@ -736,6 +736,7 @@ fn asmMovLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege
736736 .got => .got_reloc,
737737 .direct => .direct_reloc,
738738 .import => .import_reloc,
739 .tlv => .tlv_reloc,
739740 };
740741 _ = try self.addInst(.{
741742 .tag = .mov_linker,
......@@ -753,6 +754,7 @@ fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege
753754 .got => .got_reloc,
754755 .direct => .direct_reloc,
755756 .import => .import_reloc,
757 .tlv => .tlv_reloc,
756758 };
757759 _ = try self.addInst(.{
758760 .tag = .lea_linker,
......@@ -765,6 +767,15 @@ fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege
765767 });
766768}
767769
770fn genTlvPtr(self: *Self, reg: Register, atom_index: u32, linker_load: codegen.LinkerLoad) !void {
771 assert(linker_load.type == .tlv);
772 if (self.bin_file.cast(link.File.MachO)) |_| {
773 try self.asmMovLinker(.rdi, atom_index, linker_load);
774 try self.asmMemory(.call, Memory.sib(.qword, .{ .base = .rdi }));
775 try self.genSetReg(Type.usize, reg, .{ .register = .rax });
776 } else return self.fail("TODO emit ptr-to-TLV sequence on {s}", .{@tagName(self.bin_file.tag)});
777}
778
768779fn gen(self: *Self) InnerError!void {
769780 const cc = self.fn_type.fnCallingConvention();
770781 if (cc != .Naked) {
......@@ -2931,6 +2942,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
29312942 .import => unreachable,
29322943 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
29332944 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
2945 .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct),
29342946 }
29352947 },
29362948 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
......@@ -3805,6 +3817,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38053817 .import => unreachable,
38063818 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
38073819 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
3820 .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct),
38083821 }
38093822 },
38103823 else => unreachable,
......@@ -3866,6 +3879,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38663879 switch (load_struct.type) {
38673880 .import => unreachable,
38683881 .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct),
3882 .tlv => {
3883 try self.genTlvPtr(addr_reg, atom_index, load_struct);
3884 // Load the pointer, which is stored in memory
3885 try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg }));
3886 },
38693887 }
38703888 },
38713889 else => unreachable,
......@@ -4221,6 +4239,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue
42214239 .import => unreachable,
42224240 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
42234241 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
4242 .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct),
42244243 }
42254244 },
42264245 else => unreachable,
......@@ -4896,6 +4915,7 @@ fn genBinOp(
48964915 .import => unreachable,
48974916 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
48984917 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
4918 .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct),
48994919 }
49004920 },
49014921 else => unreachable,
......@@ -5042,6 +5062,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
50425062 .import => unreachable,
50435063 .got => try self.asmMovLinker(dst_addr_reg, atom_index, load_struct),
50445064 .direct => try self.asmLeaLinker(dst_addr_reg, atom_index, load_struct),
5065 .tlv => try self.genTlvPtr(dst_addr_reg, atom_index, load_struct),
50455066 }
50465067 },
50475068 else => unreachable,
......@@ -5087,6 +5108,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
50875108 .import => unreachable,
50885109 .got => try self.asmMovLinker(src_addr_reg, atom_index, load_struct),
50895110 .direct => try self.asmLeaLinker(src_addr_reg, atom_index, load_struct),
5111 .tlv => try self.genTlvPtr(src_addr_reg, atom_index, load_struct),
50905112 }
50915113 },
50925114 else => unreachable,
......@@ -6124,6 +6146,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
61246146 .import => unreachable,
61256147 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
61266148 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
6149 .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct),
61276150 }
61286151 },
61296152 else => unreachable,
......@@ -7081,6 +7104,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
70817104 .import => unreachable,
70827105 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
70837106 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
7107 .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct),
70847108 }
70857109 },
70867110 else => unreachable,
......@@ -7308,6 +7332,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
73087332 .import => unreachable,
73097333 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
73107334 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
7335 .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct),
73117336 }
73127337 },
73137338 else => unreachable,
......@@ -7439,6 +7464,11 @@ fn genInlineMemcpy(
74397464 switch (load_struct.type) {
74407465 .import => unreachable,
74417466 .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct),
7467 .tlv => {
7468 try self.genTlvPtr(.rdi, atom_index, load_struct);
7469 // Load the pointer, which is stored in memory
7470 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
7471 },
74427472 }
74437473 },
74447474 .stack_offset, .ptr_stack_offset => |off| {
......@@ -7481,6 +7511,11 @@ fn genInlineMemcpy(
74817511 switch (load_struct.type) {
74827512 .import => unreachable,
74837513 .got, .direct => try self.asmMovLinker(.rsi, atom_index, load_struct),
7514 .tlv => {
7515 try self.genTlvPtr(.rsi, atom_index, load_struct);
7516 // Load the pointer, which is stored in memory
7517 try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi }));
7518 },
74847519 }
74857520 },
74867521 .stack_offset, .ptr_stack_offset => |off| {
......@@ -7546,6 +7581,11 @@ fn genInlineMemset(
75467581 switch (load_struct.type) {
75477582 .import => unreachable,
75487583 .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct),
7584 .tlv => {
7585 try self.genTlvPtr(.rdi, atom_index, load_struct);
7586 // Load the pointer, which is stored in memory
7587 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
7588 },
75497589 }
75507590 },
75517591 .stack_offset, .ptr_stack_offset => |off| {
......@@ -7735,7 +7775,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
77357775 switch (ty.zigTypeTag()) {
77367776 .Float => {
77377777 const base_reg = (try self.register_manager.allocReg(null, gp)).to64();
7738 try self.asmLeaLinker(base_reg, atom_index, load_struct);
7778 switch (load_struct.type) {
7779 .tlv => try self.genTlvPtr(base_reg, atom_index, load_struct),
7780 else => try self.asmLeaLinker(base_reg, atom_index, load_struct),
7781 }
77397782
77407783 if (intrinsicsAllowed(self.target.*, ty)) {
77417784 return self.asmRegisterMemory(
......@@ -7753,7 +7796,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
77537796
77547797 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
77557798 },
7756 else => try self.asmMovLinker(registerAlias(reg, abi_size), atom_index, load_struct),
7799 else => switch (load_struct.type) {
7800 .tlv => {
7801 try self.genTlvPtr(reg.to64(), atom_index, load_struct);
7802 try self.asmRegisterMemory(
7803 .mov,
7804 registerAlias(reg, abi_size),
7805 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }),
7806 );
7807 },
7808 else => try self.asmMovLinker(registerAlias(reg, abi_size), atom_index, load_struct),
7809 },
77577810 }
77587811 },
77597812 .stack_offset => |off| {
src/arch/x86_64/Emit.zig+1
......@@ -76,6 +76,7 @@ pub fn emitMir(emit: *Emit) Error!void {
7676 .type = switch (inst.ops) {
7777 .got_reloc => .got,
7878 .direct_reloc => .signed,
79 .tlv_reloc => .tlv,
7980 else => unreachable,
8081 },
8182 .target = .{ .sym_index = metadata.sym_index, .file = null },
src/arch/x86_64/Mir.zig+3
......@@ -404,6 +404,9 @@ pub const Inst = struct {
404404 /// Linker relocation - imports table indirection (binding).
405405 /// Uses `payload` payload with extra data of type `LeaRegisterReloc`.
406406 import_reloc,
407 /// Linker relocation - threadlocal variable via GOT indirection.
408 /// Uses `payload` payload with extra data of type `LeaRegisterReloc`.
409 tlv_reloc,
407410 };
408411
409412 pub const Data = union {
src/codegen.zig+5-1
......@@ -912,11 +912,13 @@ fn lowerDeclRef(
912912/// * got - the value is referenced indirectly via GOT entry index (the linker emits a got-type reloc)
913913/// * direct - the value is referenced directly via symbol index index (the linker emits a displacement reloc)
914914/// * import - the value is referenced indirectly via import entry index (the linker emits an import-type reloc)
915/// * tlv - the value is a threadlocal variable referenced indirectly via GOT (the linker emits a got-type reloc)
915916pub const LinkerLoad = struct {
916917 type: enum {
917918 got,
918919 direct,
919920 import,
921 tlv,
920922 },
921923 sym_index: u32,
922924};
......@@ -991,6 +993,8 @@ fn genDeclRef(
991993
992994 module.markDeclAlive(decl);
993995
996 const is_threadlocal = tv.val.isPtrToThreadLocal(module) and !bin_file.options.single_threaded;
997
994998 if (bin_file.cast(link.File.Elf)) |elf_file| {
995999 const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
9961000 const atom = elf_file.getAtom(atom_index);
......@@ -999,7 +1003,7 @@ fn genDeclRef(
9991003 const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
10001004 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
10011005 return GenResult.mcv(.{ .linker_load = .{
1002 .type = .got,
1006 .type = if (is_threadlocal) .tlv else .got,
10031007 .sym_index = sym_index,
10041008 } });
10051009 } else if (bin_file.cast(link.File.Coff)) |coff_file| {