authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-16 15:02:08+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-04-16 15:02:08+02:00
logbc804eb8419156980ec920c1ccb502c257c679b4
tree4edceb28aa81f8a07eba46097886c321d388ba3b
parent23ac4dd87b740012ba33e8ab2ea6fb25c04b6268
parentecc52d859f7f1e400c8bfc08aea971f4596649cf
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15291 from ziglang/x86_64-more-memory

x86_64: fix memory loads some more

6 files changed, 403 insertions(+), 456 deletions(-)

src/arch/aarch64/CodeGen.zig+3-2
......@@ -6168,10 +6168,11 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
61686168 .mcv => |mcv| switch (mcv) {
61696169 .none => .none,
61706170 .undef => .undef,
6171 .linker_load => |ll| .{ .linker_load = ll },
61726171 .immediate => |imm| .{ .immediate = imm },
61736172 .memory => |addr| .{ .memory = addr },
6174 .tlv_reloc => unreachable, // TODO
6173 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
6174 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
6175 .load_tlv => unreachable, // TODO
61756176 },
61766177 .fail => |msg| {
61776178 self.err_msg = msg;
src/arch/arm/CodeGen.zig+1-1
......@@ -6114,7 +6114,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
61146114 .mcv => |mcv| switch (mcv) {
61156115 .none => .none,
61166116 .undef => .undef,
6117 .tlv_reloc, .linker_load => unreachable, // TODO
6117 .load_got, .load_direct, .load_tlv => unreachable, // TODO
61186118 .immediate => |imm| .{ .immediate = @truncate(u32, imm) },
61196119 .memory => |addr| .{ .memory = addr },
61206120 },
src/arch/riscv64/CodeGen.zig+1-1
......@@ -2572,7 +2572,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
25722572 .mcv => |mcv| switch (mcv) {
25732573 .none => .none,
25742574 .undef => .undef,
2575 .tlv_reloc, .linker_load => unreachable, // TODO
2575 .load_got, .load_direct, .load_tlv => unreachable, // TODO
25762576 .immediate => |imm| .{ .immediate = imm },
25772577 .memory => |addr| .{ .memory = addr },
25782578 },
src/arch/sparc64/CodeGen.zig+1-1
......@@ -3931,7 +3931,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
39313931 .mcv => |mcv| switch (mcv) {
39323932 .none => .none,
39333933 .undef => .undef,
3934 .tlv_reloc, .linker_load => unreachable, // TODO
3934 .load_got, .load_direct, .load_tlv => unreachable, // TODO
39353935 .immediate => |imm| .{ .immediate = imm },
39363936 .memory => |addr| .{ .memory = addr },
39373937 },
src/arch/x86_64/CodeGen.zig+382-430
......@@ -130,12 +130,21 @@ pub const MCValue = union(enum) {
130130 /// The value is in memory at a hard-coded address.
131131 /// If the type is a pointer, it means the pointer address is at this memory location.
132132 memory: u64,
133 /// The value is in memory but requires a linker relocation fixup.
134 linker_load: codegen.LinkerLoad,
135 /// Pointer to a threadlocal variable.
136 /// The address resolution will be deferred until the linker allocates everything in virtual memory.
133 /// The value is in memory.
137134 /// Payload is a symbol index.
138 tlv_reloc: u32,
135 load_direct: u32,
136 /// The value is a pointer to value in memory.
137 /// Payload is a symbol index.
138 lea_direct: u32,
139 /// The value is in memory referenced indirectly via GOT.
140 /// Payload is a symbol index.
141 load_got: u32,
142 /// The value is a threadlocal variable.
143 /// Payload is a symbol index.
144 load_tlv: u32,
145 /// The value is a pointer to threadlocal variable.
146 /// Payload is a symbol index.
147 lea_tlv: u32,
139148 /// The value is one of the stack variables.
140149 /// If the type is a pointer, it means the pointer address is in the stack at this offset.
141150 stack_offset: i32,
......@@ -149,8 +158,11 @@ pub const MCValue = union(enum) {
149158 .memory,
150159 .stack_offset,
151160 .ptr_stack_offset,
152 .linker_load,
153 .tlv_reloc,
161 .load_direct,
162 .lea_direct,
163 .load_got,
164 .load_tlv,
165 .lea_tlv,
154166 => true,
155167 else => false,
156168 };
......@@ -736,40 +748,6 @@ fn asmMemoryRegisterImmediate(
736748 });
737749}
738750
739fn asmMovLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codegen.LinkerLoad) !void {
740 const ops: Mir.Inst.Ops = switch (linker_load.type) {
741 .got => .got_reloc,
742 .direct => .direct_reloc,
743 .import => .import_reloc,
744 };
745 _ = try self.addInst(.{
746 .tag = .mov_linker,
747 .ops = ops,
748 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
749 .reg = @enumToInt(reg),
750 .atom_index = atom_index,
751 .sym_index = linker_load.sym_index,
752 }) },
753 });
754}
755
756fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codegen.LinkerLoad) !void {
757 const ops: Mir.Inst.Ops = switch (linker_load.type) {
758 .got => .got_reloc,
759 .direct => .direct_reloc,
760 .import => .import_reloc,
761 };
762 _ = try self.addInst(.{
763 .tag = .lea_linker,
764 .ops = ops,
765 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
766 .reg = @enumToInt(reg),
767 .atom_index = atom_index,
768 .sym_index = linker_load.sym_index,
769 }) },
770 });
771}
772
773751fn gen(self: *Self) InnerError!void {
774752 const cc = self.fn_type.fnCallingConvention();
775753 if (cc != .Naked) {
......@@ -2922,23 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
29222900 .disp = -off,
29232901 }));
29242902 },
2925 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
2926 .tlv_reloc => try self.genSetReg(array_ty, addr_reg, array),
2927 .linker_load => |load_struct| {
2928 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
2929 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
2930 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
2931 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
2932 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
2933 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
2934 } else unreachable;
2935
2936 switch (load_struct.type) {
2937 .import => unreachable,
2938 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
2939 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
2940 }
2941 },
2903 .load_got => try self.genSetReg(array_ty, addr_reg, array),
2904 .memory, .load_direct, .load_tlv => try self.genSetReg(Type.usize, addr_reg, switch (array) {
2905 .memory => |addr| .{ .immediate = addr },
2906 .load_direct => |sym_index| .{ .lea_direct = sym_index },
2907 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
2908 else => unreachable,
2909 }),
2910 .lea_direct, .lea_tlv => unreachable,
29422911 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
29432912 }
29442913
......@@ -3650,30 +3619,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
36503619 else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}),
36513620 }
36523621 },
3653 .memory, .tlv_reloc => {
3654 const reg = try self.copyToTmpRegister(ptr_ty, ptr);
3655 try self.load(dst_mcv, .{ .register = reg }, ptr_ty);
3656 },
3657 .linker_load => |load_struct| {
3658 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
3622 .load_direct => |sym_index| {
3623 const addr_reg = try self.copyToTmpRegister(Type.usize, .{ .lea_direct = sym_index });
36593624 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
36603625 defer self.register_manager.unlockReg(addr_reg_lock);
3661
3662 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
3663 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3664 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
3665 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
3666 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3667 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
3668 } else unreachable;
3669
3670 switch (load_struct.type) {
3671 .import => unreachable,
3672 .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct),
3673 }
3674
3626 // Load the pointer, which is stored in memory
3627 try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg }));
36753628 try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty);
36763629 },
3630 .load_tlv => |sym_index| try self.load(dst_mcv, .{ .lea_tlv = sym_index }, ptr_ty),
3631 .memory, .load_got, .lea_direct, .lea_tlv => {
3632 const reg = try self.copyToTmpRegister(ptr_ty, ptr);
3633 try self.load(dst_mcv, .{ .register = reg }, ptr_ty);
3634 },
36773635 }
36783636}
36793637
......@@ -3806,7 +3764,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38063764 -@intCast(i32, overflow_bit_offset),
38073765 );
38083766 },
3809 .memory, .linker_load => if (abi_size <= 8) {
3767 .memory, .load_tlv, .load_direct => if (abi_size <= 8) {
38103768 const tmp_reg = try self.copyToTmpRegister(value_ty, value);
38113769 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
38123770 defer self.register_manager.unlockReg(tmp_lock);
......@@ -3817,25 +3775,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38173775 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
38183776 defer self.register_manager.unlockReg(addr_lock);
38193777
3820 switch (value) {
3821 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
3822 .linker_load => |load_struct| {
3823 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
3824 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3825 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
3826 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
3827 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3828 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
3829 } else unreachable;
3830 switch (load_struct.type) {
3831 .import => unreachable,
3832 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
3833 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
3834 }
3835 },
3778 try self.genSetReg(Type.usize, addr_reg, switch (value) {
3779 .memory => |addr| .{ .immediate = addr },
3780 .load_direct => |sym_index| .{ .lea_direct = sym_index },
3781 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
38363782 else => unreachable,
3837 }
3838
3783 });
38393784 try self.genInlineMemcpy(
38403785 ptr,
38413786 .{ .register = addr_reg },
......@@ -3855,7 +3800,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38553800 .{ .immediate = abi_size },
38563801 .{},
38573802 ),
3858 .ptr_stack_offset, .tlv_reloc => {
3803 .ptr_stack_offset, .load_got, .lea_direct, .lea_tlv => {
38593804 const tmp_reg = try self.copyToTmpRegister(value_ty, value);
38603805 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
38613806 defer self.register_manager.unlockReg(tmp_lock);
......@@ -3864,7 +3809,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38643809 },
38653810 }
38663811 },
3867 .memory, .linker_load => {
3812 .memory, .load_direct, .load_tlv => {
38683813 const value_lock: ?RegisterLock = switch (value) {
38693814 .register => |reg| self.register_manager.lockReg(reg),
38703815 else => null,
......@@ -3876,32 +3821,21 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38763821 defer self.register_manager.unlockReg(addr_reg_lock);
38773822
38783823 switch (ptr) {
3879 .memory => |addr| {
3880 try self.genSetReg(ptr_ty, addr_reg, .{ .immediate = addr });
3881 // Load the pointer, which is stored in memory
3882 try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg }));
3883 },
3884 .linker_load => |load_struct| {
3885 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
3886 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3887 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
3888 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
3889 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3890 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
3891 } else unreachable;
3892 switch (load_struct.type) {
3893 .import => unreachable,
3894 .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct),
3895 }
3896 },
3824 .memory => |addr| try self.genSetReg(ptr_ty, addr_reg, .{ .immediate = addr }),
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 }),
38973827 else => unreachable,
38983828 }
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 }
38993833
39003834 const new_ptr = MCValue{ .register = addr_reg };
39013835 try self.store(new_ptr, value, ptr_ty, value_ty);
39023836 },
3903 .tlv_reloc => {
3904 const addr_reg = try self.copyToTmpRegister(Type.usize, ptr);
3837 .load_got, .lea_direct, .lea_tlv => {
3838 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr);
39053839 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
39063840 defer self.register_manager.unlockReg(addr_reg_lock);
39073841
......@@ -3953,14 +3887,17 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
39533887
39543888 const dst_mcv: MCValue = result: {
39553889 switch (mcv) {
3956 .stack_offset, .tlv_reloc => {
3890 .stack_offset, .lea_tlv, .load_tlv => {
39573891 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
39583892 .immediate = field_offset,
39593893 });
39603894 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
39613895 defer self.register_manager.unlockReg(offset_reg_lock);
39623896
3963 const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, mcv);
3897 const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, switch (mcv) {
3898 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
3899 else => mcv,
3900 });
39643901 try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg });
39653902 break :result dst_mcv;
39663903 },
......@@ -4235,31 +4172,18 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue
42354172 }));
42364173 },
42374174 .ptr_stack_offset => unreachable,
4238 .tlv_reloc => unreachable,
4239 .memory, .linker_load => {
4175 .load_got, .lea_direct, .lea_tlv => unreachable,
4176 .memory, .load_direct, .load_tlv => {
42404177 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
42414178 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
42424179 defer self.register_manager.unlockReg(addr_reg_lock);
42434180
4244 switch (dst_mcv) {
4245 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
4246 .linker_load => |load_struct| {
4247 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
4248 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4249 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
4250 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
4251 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4252 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
4253 } else unreachable;
4254
4255 switch (load_struct.type) {
4256 .import => unreachable,
4257 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
4258 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
4259 }
4260 },
4181 try self.genSetReg(Type.usize, addr_reg, switch (dst_mcv) {
4182 .memory => |addr| .{ .immediate = addr },
4183 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4184 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
42614185 else => unreachable,
4262 }
4186 });
42634187 try self.asmMemory(
42644188 mir_tag,
42654189 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),
......@@ -4756,7 +4680,11 @@ fn genBinOp(
47564680 }
47574681 }
47584682 const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true);
4759 try self.setRegOrMem(lhs_ty, dst_mcv, lhs);
4683 try self.setRegOrMem(lhs_ty, dst_mcv, switch (lhs) {
4684 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4685 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
4686 else => lhs,
4687 });
47604688 break :dst dst_mcv;
47614689 };
47624690 const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) {
......@@ -4897,7 +4825,9 @@ fn genBinOp(
48974825 .eflags,
48984826 .register_overflow,
48994827 .ptr_stack_offset,
4900 .tlv_reloc,
4828 .load_got,
4829 .lea_direct,
4830 .lea_tlv,
49014831 => unreachable,
49024832 .register => |src_reg| try self.asmCmovccRegisterRegister(
49034833 registerAlias(tmp_reg, cmov_abi_size),
......@@ -4912,31 +4842,17 @@ fn genBinOp(
49124842 }),
49134843 cc,
49144844 ),
4915 .memory, .linker_load => {
4845 .memory, .load_direct, .load_tlv => {
49164846 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
49174847 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
49184848 defer self.register_manager.unlockReg(addr_reg_lock);
49194849
4920 switch (mat_src_mcv) {
4921 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
4922 .linker_load => |load_struct| {
4923 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
4924 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4925 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
4926 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
4927 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4928 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
4929 } else unreachable;
4930
4931 switch (load_struct.type) {
4932 .import => unreachable,
4933 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
4934 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
4935 }
4936 },
4850 try self.genSetReg(Type.usize, addr_reg, switch (mat_src_mcv) {
4851 .memory => |addr| .{ .immediate = addr },
4852 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4853 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
49374854 else => unreachable,
4938 }
4939
4855 });
49404856 try self.asmCmovccRegisterMemory(
49414857 registerAlias(tmp_reg, cmov_abi_size),
49424858 Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), .{ .base = addr_reg }),
......@@ -4982,13 +4898,6 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
49824898 .undef => unreachable,
49834899 .dead, .unreach => unreachable,
49844900 .register_overflow => unreachable,
4985 .ptr_stack_offset, .tlv_reloc => {
4986 const dst_reg_lock = self.register_manager.lockReg(dst_reg);
4987 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);
4988
4989 const reg = try self.copyToTmpRegister(ty, src_mcv);
4990 return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .register = reg });
4991 },
49924901 .register => |src_reg| switch (ty.zigTypeTag()) {
49934902 .Float => {
49944903 if (intrinsicsAllowed(self.target.*, ty)) {
......@@ -5037,7 +4946,15 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
50374946 )),
50384947 else => unreachable,
50394948 },
5040 .memory, .linker_load, .eflags => {
4949 .ptr_stack_offset,
4950 .memory,
4951 .load_got,
4952 .lea_direct,
4953 .load_direct,
4954 .lea_tlv,
4955 .load_tlv,
4956 .eflags,
4957 => {
50414958 assert(abi_size <= 8);
50424959 const dst_reg_lock = self.register_manager.lockReg(dst_reg);
50434960 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);
......@@ -5052,36 +4969,23 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
50524969 ),
50534970 }
50544971 },
5055 .memory, .linker_load, .stack_offset => {
4972 .memory, .load_got, .load_direct, .load_tlv, .stack_offset => {
50564973 const dst: ?struct {
50574974 addr_reg: Register,
50584975 addr_lock: RegisterLock,
50594976 } = switch (dst_mcv) {
50604977 else => unreachable,
5061 .memory, .linker_load => dst: {
4978 .memory, .load_got, .load_direct, .load_tlv => dst: {
50624979 const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
50634980 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
50644981 errdefer self.register_manager.unlockReg(dst_addr_lock);
50654982
5066 switch (dst_mcv) {
5067 .memory => |addr| try self.genSetReg(Type.usize, dst_addr_reg, .{ .immediate = addr }),
5068 .linker_load => |load_struct| {
5069 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
5070 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5071 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5072 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
5073 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5074 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5075 } else unreachable;
5076
5077 switch (load_struct.type) {
5078 .import => unreachable,
5079 .got => try self.asmMovLinker(dst_addr_reg, atom_index, load_struct),
5080 .direct => try self.asmLeaLinker(dst_addr_reg, atom_index, load_struct),
5081 }
5082 },
5083 else => unreachable,
5084 }
4983 try self.genSetReg(Type.usize, dst_addr_reg, switch (dst_mcv) {
4984 .memory => |addr| .{ .immediate = addr },
4985 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4986 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
4987 else => dst_mcv,
4988 });
50854989
50864990 break :dst .{
50874991 .addr_reg = dst_addr_reg,
......@@ -5099,7 +5003,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
50995003 addr_lock: RegisterLock,
51005004 } = switch (src_mcv) {
51015005 else => null,
5102 .memory, .linker_load => src: {
5006 .memory, .load_got, .load_direct, .load_tlv => src: {
51035007 const src_limb_reg = try self.register_manager.allocReg(null, gp);
51045008 const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg);
51055009 errdefer self.register_manager.unlockReg(src_limb_lock);
......@@ -5108,25 +5012,12 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
51085012 const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg);
51095013 errdefer self.register_manager.unlockReg(src_addr_lock);
51105014
5111 switch (src_mcv) {
5112 .memory => |addr| try self.genSetReg(Type.usize, src_addr_reg, .{ .immediate = addr }),
5113 .linker_load => |load_struct| {
5114 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
5115 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5116 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5117 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
5118 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5119 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5120 } else unreachable;
5121
5122 switch (load_struct.type) {
5123 .import => unreachable,
5124 .got => try self.asmMovLinker(src_addr_reg, atom_index, load_struct),
5125 .direct => try self.asmLeaLinker(src_addr_reg, atom_index, load_struct),
5126 }
5127 },
5128 else => unreachable,
5129 }
5015 try self.genSetReg(Type.usize, src_addr_reg, switch (src_mcv) {
5016 .memory => |addr| .{ .immediate = addr },
5017 .load_direct => |sym_index| .{ .lea_direct = sym_index },
5018 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
5019 else => src_mcv,
5020 });
51305021
51315022 break :src .{
51325023 .addr_reg = src_addr_reg,
......@@ -5169,7 +5060,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
51695060 .base = .rbp,
51705061 .disp = off - dst_off,
51715062 },
5172 .memory, .linker_load => .{ .base = dst.?.addr_reg, .disp = off },
5063 .memory,
5064 .load_got,
5065 .load_direct,
5066 .load_tlv,
5067 => .{ .base = dst.?.addr_reg, .disp = off },
51735068 },
51745069 );
51755070 switch (src_mcv) {
......@@ -5233,7 +5128,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
52335128 else => unreachable,
52345129 }
52355130 },
5236 .memory, .linker_load, .tlv_reloc => {
5131 .memory,
5132 .load_got,
5133 .load_direct,
5134 .load_tlv,
5135 => {
52375136 try self.asmRegisterMemory(
52385137 .mov,
52395138 registerAlias(src.?.limb_reg, limb_abi_size),
......@@ -5248,11 +5147,19 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
52485147 registerAlias(src.?.limb_reg, limb_abi_size),
52495148 );
52505149 },
5251 .stack_offset, .ptr_stack_offset, .eflags => {
5150 .stack_offset,
5151 .ptr_stack_offset,
5152 .eflags,
5153 .lea_direct,
5154 .lea_tlv,
5155 => {
52525156 const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) {
52535157 .stack_offset => |src_off| .{ .stack_offset = src_off - off },
52545158 .ptr_stack_offset,
52555159 .eflags,
5160 .load_got,
5161 .lea_direct,
5162 .lea_tlv,
52565163 => off: {
52575164 assert(off == 0);
52585165 break :off src_mcv;
......@@ -5272,7 +5179,8 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
52725179 }
52735180 },
52745181 .ptr_stack_offset => unreachable,
5275 .tlv_reloc => unreachable,
5182 .lea_tlv => unreachable,
5183 .lea_direct => unreachable,
52765184 }
52775185}
52785186
......@@ -5286,7 +5194,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
52865194 .dead, .unreach, .immediate => unreachable,
52875195 .eflags => unreachable,
52885196 .ptr_stack_offset => unreachable,
5289 .tlv_reloc => unreachable,
5197 .lea_direct => unreachable,
5198 .lea_tlv => unreachable,
52905199 .register_overflow => unreachable,
52915200 .register => |dst_reg| {
52925201 const dst_alias = registerAlias(dst_reg, abi_size);
......@@ -5298,7 +5207,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
52985207 .undef => try self.genSetReg(dst_ty, dst_reg, .undef),
52995208 .dead, .unreach => unreachable,
53005209 .ptr_stack_offset => unreachable,
5301 .tlv_reloc => unreachable,
5210 .lea_direct => unreachable,
5211 .lea_tlv => unreachable,
53025212 .register_overflow => unreachable,
53035213 .register => |src_reg| try self.asmRegisterRegister(
53045214 .imul,
......@@ -5325,12 +5235,13 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
53255235 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }),
53265236 );
53275237 },
5328 .memory => {
5238 .memory,
5239 .load_got,
5240 .load_direct,
5241 .load_tlv,
5242 => {
53295243 return self.fail("TODO implement x86 multiply source memory", .{});
53305244 },
5331 .linker_load => {
5332 return self.fail("TODO implement x86 multiply source symbol at index in linker", .{});
5333 },
53345245 .eflags => {
53355246 return self.fail("TODO implement x86 multiply source eflags", .{});
53365247 },
......@@ -5342,7 +5253,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
53425253 .undef => return self.genSetStack(dst_ty, off, .undef, .{}),
53435254 .dead, .unreach => unreachable,
53445255 .ptr_stack_offset => unreachable,
5345 .tlv_reloc => unreachable,
5256 .lea_direct => unreachable,
5257 .lea_tlv => unreachable,
53465258 .register_overflow => unreachable,
53475259 .register => |src_reg| {
53485260 // copy dst to a register
......@@ -5365,23 +5277,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
53655277
53665278 return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{});
53675279 },
5368 .memory, .stack_offset => {
5280 .memory,
5281 .load_got,
5282 .load_direct,
5283 .load_tlv,
5284 .stack_offset,
5285 => {
53695286 return self.fail("TODO implement x86 multiply source memory", .{});
53705287 },
5371 .linker_load => {
5372 return self.fail("TODO implement x86 multiply source symbol at index in linker", .{});
5373 },
53745288 .eflags => {
53755289 return self.fail("TODO implement x86 multiply source eflags", .{});
53765290 },
53775291 }
53785292 },
5379 .memory => {
5293 .memory,
5294 .load_got,
5295 .load_direct,
5296 .load_tlv,
5297 => {
53805298 return self.fail("TODO implement x86 multiply destination memory", .{});
53815299 },
5382 .linker_load => {
5383 return self.fail("TODO implement x86 multiply destination symbol at index in linker", .{});
5384 },
53855300 }
53865301}
53875302
......@@ -5461,7 +5376,8 @@ fn genVarDbgInfo(
54615376 .offset = -off,
54625377 } },
54635378 .memory => |address| .{ .memory = address },
5464 .linker_load => |linker_load| .{ .linker_load = linker_load },
5379 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
5380 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
54655381 .immediate => |x| .{ .immediate = x },
54665382 .undef => .undef,
54675383 .none => .none,
......@@ -5562,10 +5478,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
55625478 .unreach => unreachable,
55635479 .dead => unreachable,
55645480 .memory => unreachable,
5565 .linker_load => unreachable,
55665481 .eflags => unreachable,
55675482 .register_overflow => unreachable,
5568 .tlv_reloc => unreachable,
5483 .load_got => unreachable,
5484 .lea_direct => unreachable,
5485 .load_direct => unreachable,
5486 .lea_tlv => unreachable,
5487 .load_tlv => unreachable,
55695488 }
55705489 }
55715490
......@@ -5601,10 +5520,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
56015520 .unreach => unreachable,
56025521 .dead => unreachable,
56035522 .memory => unreachable,
5604 .linker_load => unreachable,
56055523 .eflags => unreachable,
56065524 .register_overflow => unreachable,
5607 .tlv_reloc => unreachable,
5525 .load_got => unreachable,
5526 .lea_direct => unreachable,
5527 .load_direct => unreachable,
5528 .lea_tlv => unreachable,
5529 .load_tlv => unreachable,
56085530 }
56095531 }
56105532
......@@ -5627,21 +5549,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
56275549 .base = .ds,
56285550 .disp = @intCast(i32, got_addr),
56295551 }));
5630 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
5631 const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
5632 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
5633 try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{
5634 .type = .got,
5635 .sym_index = sym_index,
5636 } });
5552 } else if (self.bin_file.cast(link.File.Coff)) |_| {
5553 const sym_index = try self.getSymbolIndexForDecl(func.owner_decl);
5554 try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index });
56375555 try self.asmRegister(.call, .rax);
5638 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
5639 const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
5640 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
5641 try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{
5642 .type = .got,
5643 .sym_index = sym_index,
5644 } });
5556 } else if (self.bin_file.cast(link.File.MachO)) |_| {
5557 const sym_index = try self.getSymbolIndexForDecl(func.owner_decl);
5558 try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index });
56455559 try self.asmRegister(.call, .rax);
56465560 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
56475561 const decl_block_index = try p9.seeDecl(func.owner_decl);
......@@ -5661,18 +5575,21 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
56615575 const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0);
56625576 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);
56635577 if (self.bin_file.cast(link.File.Coff)) |coff_file| {
5578 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
56645579 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);
5665 try self.genSetReg(Type.usize, .rax, .{
5666 .linker_load = .{
5667 .type = .import,
5580 _ = try self.addInst(.{
5581 .tag = .mov_linker,
5582 .ops = .import_reloc,
5583 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
5584 .reg = @enumToInt(Register.rax),
5585 .atom_index = atom_index,
56685586 .sym_index = sym_index,
5669 },
5587 }) },
56705588 });
56715589 try self.asmRegister(.call, .rax);
56725590 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
56735591 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
5674 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5675 const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
5592 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
56765593 _ = try self.addInst(.{
56775594 .tag = .call_extern,
56785595 .ops = undefined,
......@@ -5871,20 +5788,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
58715788 4, // dword alignment
58725789 );
58735790 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
5874 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
5875 .type = .got,
5876 .sym_index = sym_index,
5877 } });
5791 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
58785792 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
58795793 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(
58805794 .{ .kind = .const_data, .ty = Type.anyerror },
58815795 4, // dword alignment
58825796 );
58835797 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
5884 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
5885 .type = .got,
5886 .sym_index = sym_index,
5887 } });
5798 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
58885799 } else {
58895800 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
58905801 }
......@@ -6126,7 +6037,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
61266037 .register_overflow,
61276038 .ptr_stack_offset,
61286039 .eflags,
6129 .tlv_reloc,
6040 .lea_direct,
6041 .lea_tlv,
61306042 => unreachable,
61316043
61326044 .register => |opt_reg| {
......@@ -6147,30 +6059,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
61476059 return .{ .eflags = .nc };
61486060 },
61496061
6150 .memory, .linker_load => {
6062 .memory,
6063 .load_got,
6064 .load_direct,
6065 .load_tlv,
6066 => {
61516067 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
61526068 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
61536069 defer self.register_manager.unlockReg(addr_reg_lock);
61546070
6155 switch (opt_mcv) {
6156 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
6157 .linker_load => |load_struct| {
6158 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
6159 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
6160 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
6161 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
6162 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
6163 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
6164 } else unreachable;
6165
6166 switch (load_struct.type) {
6167 .import => unreachable,
6168 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
6169 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
6170 }
6171 },
6172 else => unreachable,
6173 }
6071 try self.genSetReg(Type.usize, addr_reg, switch (opt_mcv) {
6072 .memory => |addr| .{ .immediate = addr },
6073 .load_direct => |sym_index| .{ .lea_direct = sym_index },
6074 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
6075 else => opt_mcv,
6076 });
61746077
61756078 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));
61766079 try self.asmMemoryImmediate(.cmp, Memory.sib(
......@@ -7099,7 +7002,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
70997002 else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}),
71007003 }
71017004 },
7102 .memory, .linker_load => {
7005 .memory,
7006 .load_direct,
7007 .load_tlv,
7008 => {
71037009 if (abi_size <= 8) {
71047010 const reg = try self.copyToTmpRegister(ty, mcv);
71057011 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
......@@ -7109,26 +7015,12 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
71097015 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
71107016 defer self.register_manager.unlockReg(addr_lock);
71117017
7112 switch (mcv) {
7113 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
7114 .linker_load => |load_struct| {
7115 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7116 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7117 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7118 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7119 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7120 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7121 } else unreachable;
7122
7123 switch (load_struct.type) {
7124 .import => unreachable,
7125 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
7126 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
7127 }
7128 },
7018 try self.genSetReg(Type.usize, addr_reg, switch (mcv) {
7019 .memory => |addr| .{ .immediate = addr },
7020 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7021 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
71297022 else => unreachable,
7130 }
7131
7023 });
71327024 try self.genInlineMemcpy(
71337025 .{ .ptr_stack_offset = stack_offset },
71347026 .{ .register = addr_reg },
......@@ -7170,7 +7062,11 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
71707062 },
71717063 }
71727064 },
7173 .ptr_stack_offset, .tlv_reloc => {
7065 .ptr_stack_offset,
7066 .load_got,
7067 .lea_direct,
7068 .lea_tlv,
7069 => {
71747070 const reg = try self.copyToTmpRegister(ty, mcv);
71757071 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
71767072 },
......@@ -7328,7 +7224,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
73287224 },
73297225 }
73307226 },
7331 .memory, .linker_load => if (abi_size <= 8) {
7227 .memory,
7228 .load_direct,
7229 .load_tlv,
7230 .lea_direct,
7231 .lea_tlv,
7232 => if (abi_size <= 8) {
73327233 const reg = try self.copyToTmpRegister(ty, mcv);
73337234 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts);
73347235 } else {
......@@ -7336,26 +7237,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
73367237 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
73377238 defer self.register_manager.unlockReg(addr_lock);
73387239
7339 switch (mcv) {
7340 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
7341 .linker_load => |load_struct| {
7342 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7343 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7344 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7345 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7346 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7347 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7348 } else unreachable;
7349
7350 switch (load_struct.type) {
7351 .import => unreachable,
7352 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
7353 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
7354 }
7355 },
7356 else => unreachable,
7357 }
7358
7240 try self.genSetReg(Type.usize, addr_reg, switch (mcv) {
7241 .memory => |addr| .{ .immediate = addr },
7242 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7243 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7244 else => mcv,
7245 });
73597246 try self.genInlineMemcpy(
73607247 .{ .ptr_stack_offset = stack_offset },
73617248 .{ .register = addr_reg },
......@@ -7375,7 +7262,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
73757262 .{ .immediate = abi_size },
73767263 .{},
73777264 ),
7378 .ptr_stack_offset, .tlv_reloc => {
7265 .ptr_stack_offset,
7266 .load_got,
7267 => {
73797268 const tmp_reg = try self.copyToTmpRegister(ty, mcv);
73807269 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
73817270 defer self.register_manager.unlockReg(tmp_lock);
......@@ -7465,26 +7354,27 @@ fn genInlineMemcpy(
74657354 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });
74667355
74677356 switch (dst_ptr) {
7468 .memory => |addr| {
7469 try self.genSetReg(Type.usize, .rdi, .{ .immediate = addr });
7357 .lea_tlv,
7358 .load_tlv,
7359 => {
7360 try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7361 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7362 else => dst_ptr,
7363 });
7364 },
7365 .memory,
7366 .load_got,
7367 .lea_direct,
7368 .load_direct,
7369 => {
7370 try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7371 .memory => |addr| .{ .immediate = addr },
7372 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7373 else => dst_ptr,
7374 });
74707375 // Load the pointer, which is stored in memory
74717376 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
74727377 },
7473 .linker_load => |load_struct| {
7474 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7475 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7476 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7477 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7478 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7479 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7480 } else unreachable;
7481
7482 switch (load_struct.type) {
7483 .import => unreachable,
7484 .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct),
7485 }
7486 },
7487 .tlv_reloc => try self.genSetReg(Type.usize, .rdi, dst_ptr),
74887378 .stack_offset, .ptr_stack_offset => |off| {
74897379 try self.asmRegisterMemory(switch (dst_ptr) {
74907380 .stack_offset => .mov,
......@@ -7508,26 +7398,27 @@ fn genInlineMemcpy(
75087398 }
75097399
75107400 switch (src_ptr) {
7511 .memory => |addr| {
7512 try self.genSetReg(Type.usize, .rsi, .{ .immediate = addr });
7401 .lea_tlv,
7402 .load_tlv,
7403 => {
7404 try self.genSetReg(Type.usize, .rsi, switch (src_ptr) {
7405 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7406 else => dst_ptr,
7407 });
7408 },
7409 .memory,
7410 .load_got,
7411 .lea_direct,
7412 .load_direct,
7413 => {
7414 try self.genSetReg(Type.usize, .rsi, switch (src_ptr) {
7415 .memory => |addr| .{ .immediate = addr },
7416 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7417 else => src_ptr,
7418 });
75137419 // Load the pointer, which is stored in memory
75147420 try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi }));
75157421 },
7516 .linker_load => |load_struct| {
7517 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7518 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7519 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7520 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7521 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7522 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7523 } else unreachable;
7524
7525 switch (load_struct.type) {
7526 .import => unreachable,
7527 .got, .direct => try self.asmMovLinker(.rsi, atom_index, load_struct),
7528 }
7529 },
7530 .tlv_reloc => try self.genSetReg(Type.usize, .rsi, src_ptr),
75317422 .stack_offset, .ptr_stack_offset => |off| {
75327423 try self.asmRegisterMemory(switch (src_ptr) {
75337424 .stack_offset => .mov,
......@@ -7574,26 +7465,27 @@ fn genInlineMemset(
75747465 try self.spillRegisters(&.{ .rdi, .al, .rcx });
75757466
75767467 switch (dst_ptr) {
7577 .memory => |addr| {
7578 try self.genSetReg(Type.usize, .rdi, .{ .immediate = addr });
7468 .lea_tlv,
7469 .load_tlv,
7470 => {
7471 try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7472 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7473 else => dst_ptr,
7474 });
7475 },
7476 .load_got => try self.genSetReg(Type.usize, .rdi, dst_ptr),
7477 .memory,
7478 .lea_direct,
7479 .load_direct,
7480 => {
7481 try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7482 .memory => |addr| .{ .immediate = addr },
7483 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7484 else => dst_ptr,
7485 });
75797486 // Load the pointer, which is stored in memory
75807487 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
75817488 },
7582 .linker_load => |load_struct| {
7583 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7584 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7585 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7586 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7587 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7588 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7589 } else unreachable;
7590
7591 switch (load_struct.type) {
7592 .import => unreachable,
7593 .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct),
7594 }
7595 },
7596 .tlv_reloc => try self.genSetReg(Type.usize, .rdi, dst_ptr),
75977489 .stack_offset, .ptr_stack_offset => |off| {
75987490 try self.asmRegisterMemory(switch (dst_ptr) {
75997491 .stack_offset => .mov,
......@@ -7769,43 +7661,31 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
77697661 }
77707662 },
77717663 },
7772 .tlv_reloc => |sym_index| {
7773 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7774 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7775 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7776 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7777 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7778 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7779 } else unreachable;
7780
7781 if (self.bin_file.cast(link.File.MachO)) |_| {
7782 _ = try self.addInst(.{
7783 .tag = .mov_linker,
7784 .ops = .tlv_reloc,
7785 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
7786 .reg = @enumToInt(Register.rdi),
7787 .atom_index = atom_index,
7788 .sym_index = sym_index,
7789 }) },
7790 });
7791 // TODO: spill registers before calling
7792 try self.asmMemory(.call, Memory.sib(.qword, .{ .base = .rdi }));
7793 try self.genSetReg(Type.usize, reg, .{ .register = .rax });
7794 } else return self.fail("TODO emit ptr to TLV sequence on {s}", .{@tagName(self.bin_file.tag)});
7664 .load_got, .lea_direct => |sym_index| {
7665 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
7666 _ = try self.addInst(.{
7667 .tag = switch (mcv) {
7668 .load_got => .mov_linker,
7669 .lea_direct => .lea_linker,
7670 else => unreachable,
7671 },
7672 .ops = switch (mcv) {
7673 .load_got => .got_reloc,
7674 .lea_direct => .direct_reloc,
7675 else => unreachable,
7676 },
7677 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
7678 .reg = @enumToInt(reg),
7679 .atom_index = atom_index,
7680 .sym_index = sym_index,
7681 }) },
7682 });
77957683 },
7796 .linker_load => |load_struct| {
7797 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7798 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7799 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7800 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7801 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7802 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7803 } else unreachable;
7804
7684 .load_direct => |sym_index| {
78057685 switch (ty.zigTypeTag()) {
78067686 .Float => {
7807 const base_reg = (try self.register_manager.allocReg(null, gp)).to64();
7808 try self.asmLeaLinker(base_reg, atom_index, load_struct);
7687 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
7688 try self.genSetReg(Type.usize, addr_reg, .{ .lea_direct = sym_index });
78097689
78107690 if (intrinsicsAllowed(self.target.*, ty)) {
78117691 return self.asmRegisterMemory(
......@@ -7817,13 +7697,68 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
78177697 }),
78187698 },
78197699 reg.to128(),
7820 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg.to64() }),
7700 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),
78217701 );
78227702 }
78237703
78247704 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
78257705 },
7826 else => try self.asmMovLinker(registerAlias(reg, abi_size), atom_index, load_struct),
7706 else => {
7707 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
7708 _ = try self.addInst(.{
7709 .tag = .mov_linker,
7710 .ops = .direct_reloc,
7711 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
7712 .reg = @enumToInt(registerAlias(reg, abi_size)),
7713 .atom_index = atom_index,
7714 .sym_index = sym_index,
7715 }) },
7716 });
7717 },
7718 }
7719 },
7720 .lea_tlv => |sym_index| {
7721 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
7722 if (self.bin_file.cast(link.File.MachO)) |_| {
7723 _ = try self.addInst(.{
7724 .tag = .mov_linker,
7725 .ops = .tlv_reloc,
7726 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
7727 .reg = @enumToInt(Register.rdi),
7728 .atom_index = atom_index,
7729 .sym_index = sym_index,
7730 }) },
7731 });
7732 // TODO: spill registers before calling
7733 try self.asmMemory(.call, Memory.sib(.qword, .{ .base = .rdi }));
7734 try self.genSetReg(Type.usize, reg, .{ .register = .rax });
7735 } else return self.fail("TODO emit ptr to TLV sequence on {s}", .{@tagName(self.bin_file.tag)});
7736 },
7737 .load_tlv => |sym_index| {
7738 const base_reg = switch (ty.zigTypeTag()) {
7739 .Float => (try self.register_manager.allocReg(null, gp)).to64(),
7740 else => reg.to64(),
7741 };
7742 try self.genSetReg(Type.usize, base_reg, .{ .lea_tlv = sym_index });
7743 switch (ty.zigTypeTag()) {
7744 .Float => if (intrinsicsAllowed(self.target.*, ty)) {
7745 return self.asmRegisterMemory(
7746 switch (ty.tag()) {
7747 .f32 => .movss,
7748 .f64 => .movsd,
7749 else => return self.fail("TODO genSetReg from memory for {}", .{
7750 ty.fmt(self.bin_file.options.module.?),
7751 }),
7752 },
7753 reg.to128(),
7754 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg }),
7755 );
7756 } else return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}),
7757 else => try self.asmRegisterMemory(
7758 .mov,
7759 registerAlias(reg, abi_size),
7760 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg }),
7761 ),
78277762 }
78287763 },
78297764 .stack_offset => |off| {
......@@ -8464,20 +8399,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
84648399 4, // dword alignment
84658400 );
84668401 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
8467 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
8468 .type = .got,
8469 .sym_index = sym_index,
8470 } });
8402 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
84718403 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
84728404 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(
84738405 .{ .kind = .const_data, .ty = Type.anyerror },
84748406 4, // dword alignment
84758407 );
84768408 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
8477 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
8478 .type = .got,
8479 .sym_index = sym_index,
8480 } });
8409 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
84818410 } else {
84828411 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
84838412 }
......@@ -8586,7 +8515,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
85868515 const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size);
85878516 const elem_bit_off = elem_off % elem_abi_bits;
85888517 const elem_mcv = try self.resolveInst(elem);
8589 const elem_lock = switch (elem_mcv) {
8518 const mat_elem_mcv = switch (elem_mcv) {
8519 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
8520 else => elem_mcv,
8521 };
8522 const elem_lock = switch (mat_elem_mcv) {
85908523 .register => |reg| self.register_manager.lockReg(reg),
85918524 .immediate => |imm| lock: {
85928525 if (imm == 0) continue;
......@@ -8596,7 +8529,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
85968529 };
85978530 defer if (elem_lock) |lock| self.register_manager.unlockReg(lock);
85988531 const elem_reg = registerAlias(
8599 try self.copyToTmpRegister(elem_ty, elem_mcv),
8532 try self.copyToTmpRegister(elem_ty, mat_elem_mcv),
86008533 elem_abi_size,
86018534 );
86028535 const elem_extra_bits = self.regExtraBits(elem_ty);
......@@ -8616,7 +8549,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
86168549 .{ .register = elem_reg },
86178550 );
86188551 if (elem_bit_off > elem_extra_bits) {
8619 const reg = try self.copyToTmpRegister(elem_ty, elem_mcv);
8552 const reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv);
86208553 if (elem_extra_bits > 0) {
86218554 try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size));
86228555 }
......@@ -8641,7 +8574,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
86418574 const elem_ty = result_ty.structFieldType(elem_i);
86428575 const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*));
86438576 const elem_mcv = try self.resolveInst(elem);
8644 try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{});
8577 const mat_elem_mcv = switch (elem_mcv) {
8578 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
8579 else => elem_mcv,
8580 };
8581 try self.genSetStack(elem_ty, stack_offset - elem_off, mat_elem_mcv, .{});
86458582 }
86468583 break :res .{ .stack_offset = stack_offset };
86478584 },
......@@ -8652,8 +8589,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
86528589
86538590 for (elements, 0..) |elem, elem_i| {
86548591 const elem_mcv = try self.resolveInst(elem);
8592 const mat_elem_mcv = switch (elem_mcv) {
8593 .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index },
8594 else => elem_mcv,
8595 };
86558596 const elem_off = @intCast(i32, elem_size * elem_i);
8656 try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{});
8597 try self.genSetStack(elem_ty, stack_offset - elem_off, mat_elem_mcv, .{});
86578598 }
86588599 break :res MCValue{ .stack_offset = stack_offset };
86598600 },
......@@ -8776,10 +8717,11 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
87768717 .mcv => |mcv| switch (mcv) {
87778718 .none => .none,
87788719 .undef => .undef,
8779 .linker_load => |ll| .{ .linker_load = ll },
87808720 .immediate => |imm| .{ .immediate = imm },
87818721 .memory => |addr| .{ .memory = addr },
8782 .tlv_reloc => |sym_index| .{ .tlv_reloc = sym_index },
8722 .load_direct => |sym_index| .{ .load_direct = sym_index },
8723 .load_got => |sym_index| .{ .load_got = sym_index },
8724 .load_tlv => |sym_index| .{ .load_tlv = sym_index },
87838725 },
87848726 .fail => |msg| {
87858727 self.err_msg = msg;
......@@ -9077,3 +9019,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool {
90779019fn hasAvxSupport(target: Target) bool {
90789020 return Target.x86.featureSetHasAny(target.cpu.features, .{ .avx, .avx2 });
90799021}
9022
9023fn getSymbolIndexForDecl(self: *Self, decl_index: Module.Decl.Index) !u32 {
9024 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
9025 const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
9026 return macho_file.getAtom(atom).getSymbolIndex().?;
9027 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
9028 const atom = try coff_file.getOrCreateAtomForDecl(decl_index);
9029 return coff_file.getAtom(atom).getSymbolIndex().?;
9030 } else unreachable;
9031}
src/codegen.zig+15-21
......@@ -931,11 +931,17 @@ pub const GenResult = union(enum) {
931931 /// The bit-width of the immediate may be smaller than `u64`. For example, on 32-bit targets
932932 /// such as ARM, the immediate will never exceed 32-bits.
933933 immediate: u64,
934 linker_load: LinkerLoad,
935 /// Pointer to a threadlocal variable.
936 /// The address resolution will be deferred until the linker allocates everything in virtual memory.
934 /// Threadlocal variable with address deferred until the linker allocates
935 /// everything in virtual memory.
937936 /// Payload is a symbol index.
938 tlv_reloc: u32,
937 load_tlv: u32,
938 /// Decl with address deferred until the linker allocates everything in virtual memory.
939 /// Payload is a symbol index.
940 load_direct: u32,
941 /// Decl referenced via GOT with address deferred until the linker allocates
942 /// everything in virtual memory.
943 /// Payload is a symbol index.
944 load_got: u32,
939945 /// Direct by-address reference to memory location.
940946 memory: u64,
941947 };
......@@ -1005,19 +1011,13 @@ fn genDeclRef(
10051011 const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
10061012 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
10071013 if (is_threadlocal) {
1008 return GenResult.mcv(.{ .tlv_reloc = sym_index });
1014 return GenResult.mcv(.{ .load_tlv = sym_index });
10091015 }
1010 return GenResult.mcv(.{ .linker_load = .{
1011 .type = .got,
1012 .sym_index = sym_index,
1013 } });
1016 return GenResult.mcv(.{ .load_got = sym_index });
10141017 } else if (bin_file.cast(link.File.Coff)) |coff_file| {
10151018 const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);
10161019 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
1017 return GenResult.mcv(.{ .linker_load = .{
1018 .type = .got,
1019 .sym_index = sym_index,
1020 } });
1020 return GenResult.mcv(.{ .load_got = sym_index });
10211021 } else if (bin_file.cast(link.File.Plan9)) |p9| {
10221022 const decl_block_index = try p9.seeDecl(decl_index);
10231023 const decl_block = p9.getDeclBlock(decl_block_index);
......@@ -1044,15 +1044,9 @@ fn genUnnamedConst(
10441044 if (bin_file.cast(link.File.Elf)) |elf_file| {
10451045 return GenResult.mcv(.{ .memory = elf_file.getSymbol(local_sym_index).st_value });
10461046 } else if (bin_file.cast(link.File.MachO)) |_| {
1047 return GenResult.mcv(.{ .linker_load = .{
1048 .type = .direct,
1049 .sym_index = local_sym_index,
1050 } });
1047 return GenResult.mcv(.{ .load_direct = local_sym_index });
10511048 } else if (bin_file.cast(link.File.Coff)) |_| {
1052 return GenResult.mcv(.{ .linker_load = .{
1053 .type = .direct,
1054 .sym_index = local_sym_index,
1055 } });
1049 return GenResult.mcv(.{ .load_direct = local_sym_index });
10561050 } else if (bin_file.cast(link.File.Plan9)) |p9| {
10571051 const ptr_bits = target.cpu.arch.ptrBitWidth();
10581052 const ptr_bytes: u64 = @divExact(ptr_bits, 8);