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 {...@@ -6168,10 +6168,11 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6168 .mcv => |mcv| switch (mcv) {6168 .mcv => |mcv| switch (mcv) {
6169 .none => .none,6169 .none => .none,
6170 .undef => .undef,6170 .undef => .undef,
6171 .linker_load => |ll| .{ .linker_load = ll },
6172 .immediate => |imm| .{ .immediate = imm },6171 .immediate => |imm| .{ .immediate = imm },
6173 .memory => |addr| .{ .memory = addr },6172 .memory => |addr| .{ .memory = addr },
6174 .tlv_reloc => unreachable, // TODO6173 .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
6175 },6176 },
6176 .fail => |msg| {6177 .fail => |msg| {
6177 self.err_msg = msg;6178 self.err_msg = msg;
src/arch/arm/CodeGen.zig+1-1
...@@ -6114,7 +6114,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {...@@ -6114,7 +6114,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6114 .mcv => |mcv| switch (mcv) {6114 .mcv => |mcv| switch (mcv) {
6115 .none => .none,6115 .none => .none,
6116 .undef => .undef,6116 .undef => .undef,
6117 .tlv_reloc, .linker_load => unreachable, // TODO6117 .load_got, .load_direct, .load_tlv => unreachable, // TODO
6118 .immediate => |imm| .{ .immediate = @truncate(u32, imm) },6118 .immediate => |imm| .{ .immediate = @truncate(u32, imm) },
6119 .memory => |addr| .{ .memory = addr },6119 .memory => |addr| .{ .memory = addr },
6120 },6120 },
src/arch/riscv64/CodeGen.zig+1-1
...@@ -2572,7 +2572,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2572,7 +2572,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2572 .mcv => |mcv| switch (mcv) {2572 .mcv => |mcv| switch (mcv) {
2573 .none => .none,2573 .none => .none,
2574 .undef => .undef,2574 .undef => .undef,
2575 .tlv_reloc, .linker_load => unreachable, // TODO2575 .load_got, .load_direct, .load_tlv => unreachable, // TODO
2576 .immediate => |imm| .{ .immediate = imm },2576 .immediate => |imm| .{ .immediate = imm },
2577 .memory => |addr| .{ .memory = addr },2577 .memory => |addr| .{ .memory = addr },
2578 },2578 },
src/arch/sparc64/CodeGen.zig+1-1
...@@ -3931,7 +3931,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -3931,7 +3931,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3931 .mcv => |mcv| switch (mcv) {3931 .mcv => |mcv| switch (mcv) {
3932 .none => .none,3932 .none => .none,
3933 .undef => .undef,3933 .undef => .undef,
3934 .tlv_reloc, .linker_load => unreachable, // TODO3934 .load_got, .load_direct, .load_tlv => unreachable, // TODO
3935 .immediate => |imm| .{ .immediate = imm },3935 .immediate => |imm| .{ .immediate = imm },
3936 .memory => |addr| .{ .memory = addr },3936 .memory => |addr| .{ .memory = addr },
3937 },3937 },
src/arch/x86_64/CodeGen.zig+382-430
...@@ -130,12 +130,21 @@ pub const MCValue = union(enum) {...@@ -130,12 +130,21 @@ pub const MCValue = union(enum) {
130 /// The value is in memory at a hard-coded address.130 /// The value is in memory at a hard-coded address.
131 /// If the type is a pointer, it means the pointer address is at this memory location.131 /// If the type is a pointer, it means the pointer address is at this memory location.
132 memory: u64,132 memory: u64,
133 /// The value is in memory but requires a linker relocation fixup.133 /// The value is in memory.
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.
137 /// Payload is a symbol index.134 /// 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,
139 /// The value is one of the stack variables.148 /// The value is one of the stack variables.
140 /// If the type is a pointer, it means the pointer address is in the stack at this offset.149 /// If the type is a pointer, it means the pointer address is in the stack at this offset.
141 stack_offset: i32,150 stack_offset: i32,
...@@ -149,8 +158,11 @@ pub const MCValue = union(enum) {...@@ -149,8 +158,11 @@ pub const MCValue = union(enum) {
149 .memory,158 .memory,
150 .stack_offset,159 .stack_offset,
151 .ptr_stack_offset,160 .ptr_stack_offset,
152 .linker_load,161 .load_direct,
153 .tlv_reloc,162 .lea_direct,
163 .load_got,
164 .load_tlv,
165 .lea_tlv,
154 => true,166 => true,
155 else => false,167 else => false,
156 };168 };
...@@ -736,40 +748,6 @@ fn asmMemoryRegisterImmediate(...@@ -736,40 +748,6 @@ fn asmMemoryRegisterImmediate(
736 });748 });
737}749}
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
773fn gen(self: *Self) InnerError!void {751fn gen(self: *Self) InnerError!void {
774 const cc = self.fn_type.fnCallingConvention();752 const cc = self.fn_type.fnCallingConvention();
775 if (cc != .Naked) {753 if (cc != .Naked) {
...@@ -2922,23 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2922,23 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
2922 .disp = -off,2900 .disp = -off,
2923 }));2901 }));
2924 },2902 },
2925 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),2903 .load_got => try self.genSetReg(array_ty, addr_reg, array),
2926 .tlv_reloc => try self.genSetReg(array_ty, addr_reg, array),2904 .memory, .load_direct, .load_tlv => try self.genSetReg(Type.usize, addr_reg, switch (array) {
2927 .linker_load => |load_struct| {2905 .memory => |addr| .{ .immediate = addr },
2928 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {2906 .load_direct => |sym_index| .{ .lea_direct = sym_index },
2929 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);2907 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
2930 break :blk macho_file.getAtom(atom).getSymbolIndex().?;2908 else => unreachable,
2931 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {2909 }),
2932 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);2910 .lea_direct, .lea_tlv => unreachable,
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 },
2942 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),2911 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
2943 }2912 }
29442913
...@@ -3650,30 +3619,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -3650,30 +3619,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
3650 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}),
3651 }3620 }
3652 },3621 },
3653 .memory, .tlv_reloc => {3622 .load_direct => |sym_index| {
3654 const reg = try self.copyToTmpRegister(ptr_ty, ptr);3623 const addr_reg = try self.copyToTmpRegister(Type.usize, .{ .lea_direct = sym_index });
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();
3659 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);3624 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
3660 defer self.register_manager.unlockReg(addr_reg_lock);3625 defer self.register_manager.unlockReg(addr_reg_lock);
36613626 // Load the pointer, which is stored in memory
3662 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {3627 try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg }));
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
3675 try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty);3628 try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty);
3676 },3629 },
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 },
3677 }3635 }
3678}3636}
36793637
...@@ -3806,7 +3764,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -3806,7 +3764,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
3806 -@intCast(i32, overflow_bit_offset),3764 -@intCast(i32, overflow_bit_offset),
3807 );3765 );
3808 },3766 },
3809 .memory, .linker_load => if (abi_size <= 8) {3767 .memory, .load_tlv, .load_direct => if (abi_size <= 8) {
3810 const tmp_reg = try self.copyToTmpRegister(value_ty, value);3768 const tmp_reg = try self.copyToTmpRegister(value_ty, value);
3811 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);3769 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
3812 defer self.register_manager.unlockReg(tmp_lock);3770 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...@@ -3817,25 +3775,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
3817 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);3775 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
3818 defer self.register_manager.unlockReg(addr_lock);3776 defer self.register_manager.unlockReg(addr_lock);
38193777
3820 switch (value) {3778 try self.genSetReg(Type.usize, addr_reg, switch (value) {
3821 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),3779 .memory => |addr| .{ .immediate = addr },
3822 .linker_load => |load_struct| {3780 .load_direct => |sym_index| .{ .lea_direct = sym_index },
3823 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {3781 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
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 },
3836 else => unreachable,3782 else => unreachable,
3837 }3783 });
3838
3839 try self.genInlineMemcpy(3784 try self.genInlineMemcpy(
3840 ptr,3785 ptr,
3841 .{ .register = addr_reg },3786 .{ .register = addr_reg },
...@@ -3855,7 +3800,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -3855,7 +3800,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
3855 .{ .immediate = abi_size },3800 .{ .immediate = abi_size },
3856 .{},3801 .{},
3857 ),3802 ),
3858 .ptr_stack_offset, .tlv_reloc => {3803 .ptr_stack_offset, .load_got, .lea_direct, .lea_tlv => {
3859 const tmp_reg = try self.copyToTmpRegister(value_ty, value);3804 const tmp_reg = try self.copyToTmpRegister(value_ty, value);
3860 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);3805 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
3861 defer self.register_manager.unlockReg(tmp_lock);3806 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...@@ -3864,7 +3809,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
3864 },3809 },
3865 }3810 }
3866 },3811 },
3867 .memory, .linker_load => {3812 .memory, .load_direct, .load_tlv => {
3868 const value_lock: ?RegisterLock = switch (value) {3813 const value_lock: ?RegisterLock = switch (value) {
3869 .register => |reg| self.register_manager.lockReg(reg),3814 .register => |reg| self.register_manager.lockReg(reg),
3870 else => null,3815 else => null,
...@@ -3876,32 +3821,21 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -3876,32 +3821,21 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
3876 defer self.register_manager.unlockReg(addr_reg_lock);3821 defer self.register_manager.unlockReg(addr_reg_lock);
38773822
3878 switch (ptr) {3823 switch (ptr) {
3879 .memory => |addr| {3824 .memory => |addr| try self.genSetReg(ptr_ty, addr_reg, .{ .immediate = addr }),
3880 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 }),
3881 // Load the pointer, which is stored in memory3826 .load_tlv => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_tlv = sym_index }),
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 },
3897 else => unreachable,3827 else => unreachable,
3898 }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 }
38993833
3900 const new_ptr = MCValue{ .register = addr_reg };3834 const new_ptr = MCValue{ .register = addr_reg };
3901 try self.store(new_ptr, value, ptr_ty, value_ty);3835 try self.store(new_ptr, value, ptr_ty, value_ty);
3902 },3836 },
3903 .tlv_reloc => {3837 .load_got, .lea_direct, .lea_tlv => {
3904 const addr_reg = try self.copyToTmpRegister(Type.usize, ptr);3838 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr);
3905 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);3839 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
3906 defer self.register_manager.unlockReg(addr_reg_lock);3840 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...@@ -3953,14 +3887,17 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
39533887
3954 const dst_mcv: MCValue = result: {3888 const dst_mcv: MCValue = result: {
3955 switch (mcv) {3889 switch (mcv) {
3956 .stack_offset, .tlv_reloc => {3890 .stack_offset, .lea_tlv, .load_tlv => {
3957 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{3891 const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
3958 .immediate = field_offset,3892 .immediate = field_offset,
3959 });3893 });
3960 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);3894 const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
3961 defer self.register_manager.unlockReg(offset_reg_lock);3895 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 });
3964 try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg });3901 try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg });
3965 break :result dst_mcv;3902 break :result dst_mcv;
3966 },3903 },
...@@ -4235,31 +4172,18 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue...@@ -4235,31 +4172,18 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue
4235 }));4172 }));
4236 },4173 },
4237 .ptr_stack_offset => unreachable,4174 .ptr_stack_offset => unreachable,
4238 .tlv_reloc => unreachable,4175 .load_got, .lea_direct, .lea_tlv => unreachable,
4239 .memory, .linker_load => {4176 .memory, .load_direct, .load_tlv => {
4240 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();4177 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
4241 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);4178 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
4242 defer self.register_manager.unlockReg(addr_reg_lock);4179 defer self.register_manager.unlockReg(addr_reg_lock);
42434180
4244 switch (dst_mcv) {4181 try self.genSetReg(Type.usize, addr_reg, switch (dst_mcv) {
4245 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),4182 .memory => |addr| .{ .immediate = addr },
4246 .linker_load => |load_struct| {4183 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4247 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {4184 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
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 },
4261 else => unreachable,4185 else => unreachable,
4262 }4186 });
4263 try self.asmMemory(4187 try self.asmMemory(
4264 mir_tag,4188 mir_tag,
4265 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),4189 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),
...@@ -4756,7 +4680,11 @@ fn genBinOp(...@@ -4756,7 +4680,11 @@ fn genBinOp(
4756 }4680 }
4757 }4681 }
4758 const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true);4682 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 });
4760 break :dst dst_mcv;4688 break :dst dst_mcv;
4761 };4689 };
4762 const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) {4690 const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) {
...@@ -4897,7 +4825,9 @@ fn genBinOp(...@@ -4897,7 +4825,9 @@ fn genBinOp(
4897 .eflags,4825 .eflags,
4898 .register_overflow,4826 .register_overflow,
4899 .ptr_stack_offset,4827 .ptr_stack_offset,
4900 .tlv_reloc,4828 .load_got,
4829 .lea_direct,
4830 .lea_tlv,
4901 => unreachable,4831 => unreachable,
4902 .register => |src_reg| try self.asmCmovccRegisterRegister(4832 .register => |src_reg| try self.asmCmovccRegisterRegister(
4903 registerAlias(tmp_reg, cmov_abi_size),4833 registerAlias(tmp_reg, cmov_abi_size),
...@@ -4912,31 +4842,17 @@ fn genBinOp(...@@ -4912,31 +4842,17 @@ fn genBinOp(
4912 }),4842 }),
4913 cc,4843 cc,
4914 ),4844 ),
4915 .memory, .linker_load => {4845 .memory, .load_direct, .load_tlv => {
4916 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();4846 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
4917 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);4847 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
4918 defer self.register_manager.unlockReg(addr_reg_lock);4848 defer self.register_manager.unlockReg(addr_reg_lock);
49194849
4920 switch (mat_src_mcv) {4850 try self.genSetReg(Type.usize, addr_reg, switch (mat_src_mcv) {
4921 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),4851 .memory => |addr| .{ .immediate = addr },
4922 .linker_load => |load_struct| {4852 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4923 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {4853 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
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 },
4937 else => unreachable,4854 else => unreachable,
4938 }4855 });
4939
4940 try self.asmCmovccRegisterMemory(4856 try self.asmCmovccRegisterMemory(
4941 registerAlias(tmp_reg, cmov_abi_size),4857 registerAlias(tmp_reg, cmov_abi_size),
4942 Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), .{ .base = addr_reg }),4858 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...@@ -4982,13 +4898,6 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4982 .undef => unreachable,4898 .undef => unreachable,
4983 .dead, .unreach => unreachable,4899 .dead, .unreach => unreachable,
4984 .register_overflow => unreachable,4900 .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 },
4992 .register => |src_reg| switch (ty.zigTypeTag()) {4901 .register => |src_reg| switch (ty.zigTypeTag()) {
4993 .Float => {4902 .Float => {
4994 if (intrinsicsAllowed(self.target.*, ty)) {4903 if (intrinsicsAllowed(self.target.*, ty)) {
...@@ -5037,7 +4946,15 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -5037,7 +4946,15 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
5037 )),4946 )),
5038 else => unreachable,4947 else => unreachable,
5039 },4948 },
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 => {
5041 assert(abi_size <= 8);4958 assert(abi_size <= 8);
5042 const dst_reg_lock = self.register_manager.lockReg(dst_reg);4959 const dst_reg_lock = self.register_manager.lockReg(dst_reg);
5043 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);4960 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...@@ -5052,36 +4969,23 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
5052 ),4969 ),
5053 }4970 }
5054 },4971 },
5055 .memory, .linker_load, .stack_offset => {4972 .memory, .load_got, .load_direct, .load_tlv, .stack_offset => {
5056 const dst: ?struct {4973 const dst: ?struct {
5057 addr_reg: Register,4974 addr_reg: Register,
5058 addr_lock: RegisterLock,4975 addr_lock: RegisterLock,
5059 } = switch (dst_mcv) {4976 } = switch (dst_mcv) {
5060 else => unreachable,4977 else => unreachable,
5061 .memory, .linker_load => dst: {4978 .memory, .load_got, .load_direct, .load_tlv => dst: {
5062 const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64();4979 const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
5063 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);4980 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
5064 errdefer self.register_manager.unlockReg(dst_addr_lock);4981 errdefer self.register_manager.unlockReg(dst_addr_lock);
50654982
5066 switch (dst_mcv) {4983 try self.genSetReg(Type.usize, dst_addr_reg, switch (dst_mcv) {
5067 .memory => |addr| try self.genSetReg(Type.usize, dst_addr_reg, .{ .immediate = addr }),4984 .memory => |addr| .{ .immediate = addr },
5068 .linker_load => |load_struct| {4985 .load_direct => |sym_index| .{ .lea_direct = sym_index },
5069 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {4986 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
5070 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);4987 else => dst_mcv,
5071 break :blk macho_file.getAtom(atom).getSymbolIndex().?;4988 });
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 }
50854989
5086 break :dst .{4990 break :dst .{
5087 .addr_reg = dst_addr_reg,4991 .addr_reg = dst_addr_reg,
...@@ -5099,7 +5003,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -5099,7 +5003,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
5099 addr_lock: RegisterLock,5003 addr_lock: RegisterLock,
5100 } = switch (src_mcv) {5004 } = switch (src_mcv) {
5101 else => null,5005 else => null,
5102 .memory, .linker_load => src: {5006 .memory, .load_got, .load_direct, .load_tlv => src: {
5103 const src_limb_reg = try self.register_manager.allocReg(null, gp);5007 const src_limb_reg = try self.register_manager.allocReg(null, gp);
5104 const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg);5008 const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg);
5105 errdefer self.register_manager.unlockReg(src_limb_lock);5009 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...@@ -5108,25 +5012,12 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
5108 const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg);5012 const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg);
5109 errdefer self.register_manager.unlockReg(src_addr_lock);5013 errdefer self.register_manager.unlockReg(src_addr_lock);
51105014
5111 switch (src_mcv) {5015 try self.genSetReg(Type.usize, src_addr_reg, switch (src_mcv) {
5112 .memory => |addr| try self.genSetReg(Type.usize, src_addr_reg, .{ .immediate = addr }),5016 .memory => |addr| .{ .immediate = addr },
5113 .linker_load => |load_struct| {5017 .load_direct => |sym_index| .{ .lea_direct = sym_index },
5114 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {5018 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
5115 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);5019 else => src_mcv,
5116 break :blk macho_file.getAtom(atom).getSymbolIndex().?;5020 });
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 }
51305021
5131 break :src .{5022 break :src .{
5132 .addr_reg = src_addr_reg,5023 .addr_reg = src_addr_reg,
...@@ -5169,7 +5060,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -5169,7 +5060,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
5169 .base = .rbp,5060 .base = .rbp,
5170 .disp = off - dst_off,5061 .disp = off - dst_off,
5171 },5062 },
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 },
5173 },5068 },
5174 );5069 );
5175 switch (src_mcv) {5070 switch (src_mcv) {
...@@ -5233,7 +5128,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -5233,7 +5128,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
5233 else => unreachable,5128 else => unreachable,
5234 }5129 }
5235 },5130 },
5236 .memory, .linker_load, .tlv_reloc => {5131 .memory,
5132 .load_got,
5133 .load_direct,
5134 .load_tlv,
5135 => {
5237 try self.asmRegisterMemory(5136 try self.asmRegisterMemory(
5238 .mov,5137 .mov,
5239 registerAlias(src.?.limb_reg, limb_abi_size),5138 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...@@ -5248,11 +5147,19 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
5248 registerAlias(src.?.limb_reg, limb_abi_size),5147 registerAlias(src.?.limb_reg, limb_abi_size),
5249 );5148 );
5250 },5149 },
5251 .stack_offset, .ptr_stack_offset, .eflags => {5150 .stack_offset,
5151 .ptr_stack_offset,
5152 .eflags,
5153 .lea_direct,
5154 .lea_tlv,
5155 => {
5252 const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) {5156 const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) {
5253 .stack_offset => |src_off| .{ .stack_offset = src_off - off },5157 .stack_offset => |src_off| .{ .stack_offset = src_off - off },
5254 .ptr_stack_offset,5158 .ptr_stack_offset,
5255 .eflags,5159 .eflags,
5160 .load_got,
5161 .lea_direct,
5162 .lea_tlv,
5256 => off: {5163 => off: {
5257 assert(off == 0);5164 assert(off == 0);
5258 break :off src_mcv;5165 break :off src_mcv;
...@@ -5272,7 +5179,8 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -5272,7 +5179,8 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
5272 }5179 }
5273 },5180 },
5274 .ptr_stack_offset => unreachable,5181 .ptr_stack_offset => unreachable,
5275 .tlv_reloc => unreachable,5182 .lea_tlv => unreachable,
5183 .lea_direct => unreachable,
5276 }5184 }
5277}5185}
52785186
...@@ -5286,7 +5194,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -5286,7 +5194,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
5286 .dead, .unreach, .immediate => unreachable,5194 .dead, .unreach, .immediate => unreachable,
5287 .eflags => unreachable,5195 .eflags => unreachable,
5288 .ptr_stack_offset => unreachable,5196 .ptr_stack_offset => unreachable,
5289 .tlv_reloc => unreachable,5197 .lea_direct => unreachable,
5198 .lea_tlv => unreachable,
5290 .register_overflow => unreachable,5199 .register_overflow => unreachable,
5291 .register => |dst_reg| {5200 .register => |dst_reg| {
5292 const dst_alias = registerAlias(dst_reg, abi_size);5201 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...@@ -5298,7 +5207,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
5298 .undef => try self.genSetReg(dst_ty, dst_reg, .undef),5207 .undef => try self.genSetReg(dst_ty, dst_reg, .undef),
5299 .dead, .unreach => unreachable,5208 .dead, .unreach => unreachable,
5300 .ptr_stack_offset => unreachable,5209 .ptr_stack_offset => unreachable,
5301 .tlv_reloc => unreachable,5210 .lea_direct => unreachable,
5211 .lea_tlv => unreachable,
5302 .register_overflow => unreachable,5212 .register_overflow => unreachable,
5303 .register => |src_reg| try self.asmRegisterRegister(5213 .register => |src_reg| try self.asmRegisterRegister(
5304 .imul,5214 .imul,
...@@ -5325,12 +5235,13 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -5325,12 +5235,13 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
5325 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }),5235 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }),
5326 );5236 );
5327 },5237 },
5328 .memory => {5238 .memory,
5239 .load_got,
5240 .load_direct,
5241 .load_tlv,
5242 => {
5329 return self.fail("TODO implement x86 multiply source memory", .{});5243 return self.fail("TODO implement x86 multiply source memory", .{});
5330 },5244 },
5331 .linker_load => {
5332 return self.fail("TODO implement x86 multiply source symbol at index in linker", .{});
5333 },
5334 .eflags => {5245 .eflags => {
5335 return self.fail("TODO implement x86 multiply source eflags", .{});5246 return self.fail("TODO implement x86 multiply source eflags", .{});
5336 },5247 },
...@@ -5342,7 +5253,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -5342,7 +5253,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
5342 .undef => return self.genSetStack(dst_ty, off, .undef, .{}),5253 .undef => return self.genSetStack(dst_ty, off, .undef, .{}),
5343 .dead, .unreach => unreachable,5254 .dead, .unreach => unreachable,
5344 .ptr_stack_offset => unreachable,5255 .ptr_stack_offset => unreachable,
5345 .tlv_reloc => unreachable,5256 .lea_direct => unreachable,
5257 .lea_tlv => unreachable,
5346 .register_overflow => unreachable,5258 .register_overflow => unreachable,
5347 .register => |src_reg| {5259 .register => |src_reg| {
5348 // copy dst to a register5260 // copy dst to a register
...@@ -5365,23 +5277,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -5365,23 +5277,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
53655277
5366 return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{});5278 return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{});
5367 },5279 },
5368 .memory, .stack_offset => {5280 .memory,
5281 .load_got,
5282 .load_direct,
5283 .load_tlv,
5284 .stack_offset,
5285 => {
5369 return self.fail("TODO implement x86 multiply source memory", .{});5286 return self.fail("TODO implement x86 multiply source memory", .{});
5370 },5287 },
5371 .linker_load => {
5372 return self.fail("TODO implement x86 multiply source symbol at index in linker", .{});
5373 },
5374 .eflags => {5288 .eflags => {
5375 return self.fail("TODO implement x86 multiply source eflags", .{});5289 return self.fail("TODO implement x86 multiply source eflags", .{});
5376 },5290 },
5377 }5291 }
5378 },5292 },
5379 .memory => {5293 .memory,
5294 .load_got,
5295 .load_direct,
5296 .load_tlv,
5297 => {
5380 return self.fail("TODO implement x86 multiply destination memory", .{});5298 return self.fail("TODO implement x86 multiply destination memory", .{});
5381 },5299 },
5382 .linker_load => {
5383 return self.fail("TODO implement x86 multiply destination symbol at index in linker", .{});
5384 },
5385 }5300 }
5386}5301}
53875302
...@@ -5461,7 +5376,8 @@ fn genVarDbgInfo(...@@ -5461,7 +5376,8 @@ fn genVarDbgInfo(
5461 .offset = -off,5376 .offset = -off,
5462 } },5377 } },
5463 .memory => |address| .{ .memory = address },5378 .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 } },
5465 .immediate => |x| .{ .immediate = x },5381 .immediate => |x| .{ .immediate = x },
5466 .undef => .undef,5382 .undef => .undef,
5467 .none => .none,5383 .none => .none,
...@@ -5562,10 +5478,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -5562,10 +5478,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
5562 .unreach => unreachable,5478 .unreach => unreachable,
5563 .dead => unreachable,5479 .dead => unreachable,
5564 .memory => unreachable,5480 .memory => unreachable,
5565 .linker_load => unreachable,
5566 .eflags => unreachable,5481 .eflags => unreachable,
5567 .register_overflow => unreachable,5482 .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,
5569 }5488 }
5570 }5489 }
55715490
...@@ -5601,10 +5520,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -5601,10 +5520,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
5601 .unreach => unreachable,5520 .unreach => unreachable,
5602 .dead => unreachable,5521 .dead => unreachable,
5603 .memory => unreachable,5522 .memory => unreachable,
5604 .linker_load => unreachable,
5605 .eflags => unreachable,5523 .eflags => unreachable,
5606 .register_overflow => unreachable,5524 .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,
5608 }5530 }
5609 }5531 }
56105532
...@@ -5627,21 +5549,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -5627,21 +5549,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
5627 .base = .ds,5549 .base = .ds,
5628 .disp = @intCast(i32, got_addr),5550 .disp = @intCast(i32, got_addr),
5629 }));5551 }));
5630 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {5552 } else if (self.bin_file.cast(link.File.Coff)) |_| {
5631 const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl);5553 const sym_index = try self.getSymbolIndexForDecl(func.owner_decl);
5632 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;5554 try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index });
5633 try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{
5634 .type = .got,
5635 .sym_index = sym_index,
5636 } });
5637 try self.asmRegister(.call, .rax);5555 try self.asmRegister(.call, .rax);
5638 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {5556 } else if (self.bin_file.cast(link.File.MachO)) |_| {
5639 const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl);5557 const sym_index = try self.getSymbolIndexForDecl(func.owner_decl);
5640 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;5558 try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index });
5641 try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{
5642 .type = .got,
5643 .sym_index = sym_index,
5644 } });
5645 try self.asmRegister(.call, .rax);5559 try self.asmRegister(.call, .rax);
5646 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {5560 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
5647 const decl_block_index = try p9.seeDecl(func.owner_decl);5561 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...@@ -5661,18 +5575,21 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
5661 const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0);5575 const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0);
5662 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);5576 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);
5663 if (self.bin_file.cast(link.File.Coff)) |coff_file| {5577 if (self.bin_file.cast(link.File.Coff)) |coff_file| {
5578 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
5664 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);5579 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);
5665 try self.genSetReg(Type.usize, .rax, .{5580 _ = try self.addInst(.{
5666 .linker_load = .{5581 .tag = .mov_linker,
5667 .type = .import,5582 .ops = .import_reloc,
5583 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
5584 .reg = @enumToInt(Register.rax),
5585 .atom_index = atom_index,
5668 .sym_index = sym_index,5586 .sym_index = sym_index,
5669 },5587 }) },
5670 });5588 });
5671 try self.asmRegister(.call, .rax);5589 try self.asmRegister(.call, .rax);
5672 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {5590 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
5673 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);5591 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
5674 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);5592 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
5675 const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
5676 _ = try self.addInst(.{5593 _ = try self.addInst(.{
5677 .tag = .call_extern,5594 .tag = .call_extern,
5678 .ops = undefined,5595 .ops = undefined,
...@@ -5871,20 +5788,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {...@@ -5871,20 +5788,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
5871 4, // dword alignment5788 4, // dword alignment
5872 );5789 );
5873 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;5790 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
5874 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{5791 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
5875 .type = .got,
5876 .sym_index = sym_index,
5877 } });
5878 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {5792 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
5879 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(5793 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(
5880 .{ .kind = .const_data, .ty = Type.anyerror },5794 .{ .kind = .const_data, .ty = Type.anyerror },
5881 4, // dword alignment5795 4, // dword alignment
5882 );5796 );
5883 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;5797 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
5884 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{5798 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
5885 .type = .got,
5886 .sym_index = sym_index,
5887 } });
5888 } else {5799 } else {
5889 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});5800 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
5890 }5801 }
...@@ -6126,7 +6037,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -6126,7 +6037,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
6126 .register_overflow,6037 .register_overflow,
6127 .ptr_stack_offset,6038 .ptr_stack_offset,
6128 .eflags,6039 .eflags,
6129 .tlv_reloc,6040 .lea_direct,
6041 .lea_tlv,
6130 => unreachable,6042 => unreachable,
61316043
6132 .register => |opt_reg| {6044 .register => |opt_reg| {
...@@ -6147,30 +6059,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -6147,30 +6059,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
6147 return .{ .eflags = .nc };6059 return .{ .eflags = .nc };
6148 },6060 },
61496061
6150 .memory, .linker_load => {6062 .memory,
6063 .load_got,
6064 .load_direct,
6065 .load_tlv,
6066 => {
6151 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();6067 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
6152 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);6068 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
6153 defer self.register_manager.unlockReg(addr_reg_lock);6069 defer self.register_manager.unlockReg(addr_reg_lock);
61546070
6155 switch (opt_mcv) {6071 try self.genSetReg(Type.usize, addr_reg, switch (opt_mcv) {
6156 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),6072 .memory => |addr| .{ .immediate = addr },
6157 .linker_load => |load_struct| {6073 .load_direct => |sym_index| .{ .lea_direct = sym_index },
6158 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {6074 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
6159 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);6075 else => opt_mcv,
6160 break :blk macho_file.getAtom(atom).getSymbolIndex().?;6076 });
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 }
61746077
6175 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));6078 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));
6176 try self.asmMemoryImmediate(.cmp, Memory.sib(6079 try self.asmMemoryImmediate(.cmp, Memory.sib(
...@@ -7099,7 +7002,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE...@@ -7099,7 +7002,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
7099 else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}),7002 else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}),
7100 }7003 }
7101 },7004 },
7102 .memory, .linker_load => {7005 .memory,
7006 .load_direct,
7007 .load_tlv,
7008 => {
7103 if (abi_size <= 8) {7009 if (abi_size <= 8) {
7104 const reg = try self.copyToTmpRegister(ty, mcv);7010 const reg = try self.copyToTmpRegister(ty, mcv);
7105 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });7011 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...@@ -7109,26 +7015,12 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
7109 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);7015 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
7110 defer self.register_manager.unlockReg(addr_lock);7016 defer self.register_manager.unlockReg(addr_lock);
71117017
7112 switch (mcv) {7018 try self.genSetReg(Type.usize, addr_reg, switch (mcv) {
7113 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),7019 .memory => |addr| .{ .immediate = addr },
7114 .linker_load => |load_struct| {7020 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7115 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {7021 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
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 },
7129 else => unreachable,7022 else => unreachable,
7130 }7023 });
7131
7132 try self.genInlineMemcpy(7024 try self.genInlineMemcpy(
7133 .{ .ptr_stack_offset = stack_offset },7025 .{ .ptr_stack_offset = stack_offset },
7134 .{ .register = addr_reg },7026 .{ .register = addr_reg },
...@@ -7170,7 +7062,11 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE...@@ -7170,7 +7062,11 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
7170 },7062 },
7171 }7063 }
7172 },7064 },
7173 .ptr_stack_offset, .tlv_reloc => {7065 .ptr_stack_offset,
7066 .load_got,
7067 .lea_direct,
7068 .lea_tlv,
7069 => {
7174 const reg = try self.copyToTmpRegister(ty, mcv);7070 const reg = try self.copyToTmpRegister(ty, mcv);
7175 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });7071 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
7176 },7072 },
...@@ -7328,7 +7224,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -7328,7 +7224,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
7328 },7224 },
7329 }7225 }
7330 },7226 },
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) {
7332 const reg = try self.copyToTmpRegister(ty, mcv);7233 const reg = try self.copyToTmpRegister(ty, mcv);
7333 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts);7234 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts);
7334 } else {7235 } else {
...@@ -7336,26 +7237,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -7336,26 +7237,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
7336 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);7237 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
7337 defer self.register_manager.unlockReg(addr_lock);7238 defer self.register_manager.unlockReg(addr_lock);
73387239
7339 switch (mcv) {7240 try self.genSetReg(Type.usize, addr_reg, switch (mcv) {
7340 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),7241 .memory => |addr| .{ .immediate = addr },
7341 .linker_load => |load_struct| {7242 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7342 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {7243 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
7343 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);7244 else => mcv,
7344 break :blk macho_file.getAtom(atom).getSymbolIndex().?;7245 });
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
7359 try self.genInlineMemcpy(7246 try self.genInlineMemcpy(
7360 .{ .ptr_stack_offset = stack_offset },7247 .{ .ptr_stack_offset = stack_offset },
7361 .{ .register = addr_reg },7248 .{ .register = addr_reg },
...@@ -7375,7 +7262,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -7375,7 +7262,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
7375 .{ .immediate = abi_size },7262 .{ .immediate = abi_size },
7376 .{},7263 .{},
7377 ),7264 ),
7378 .ptr_stack_offset, .tlv_reloc => {7265 .ptr_stack_offset,
7266 .load_got,
7267 => {
7379 const tmp_reg = try self.copyToTmpRegister(ty, mcv);7268 const tmp_reg = try self.copyToTmpRegister(ty, mcv);
7380 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);7269 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
7381 defer self.register_manager.unlockReg(tmp_lock);7270 defer self.register_manager.unlockReg(tmp_lock);
...@@ -7465,26 +7354,27 @@ fn genInlineMemcpy(...@@ -7465,26 +7354,27 @@ fn genInlineMemcpy(
7465 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });7354 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });
74667355
7467 switch (dst_ptr) {7356 switch (dst_ptr) {
7468 .memory => |addr| {7357 .lea_tlv,
7469 try self.genSetReg(Type.usize, .rdi, .{ .immediate = addr });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 });
7470 // Load the pointer, which is stored in memory7375 // Load the pointer, which is stored in memory
7471 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));7376 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
7472 },7377 },
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),
7488 .stack_offset, .ptr_stack_offset => |off| {7378 .stack_offset, .ptr_stack_offset => |off| {
7489 try self.asmRegisterMemory(switch (dst_ptr) {7379 try self.asmRegisterMemory(switch (dst_ptr) {
7490 .stack_offset => .mov,7380 .stack_offset => .mov,
...@@ -7508,26 +7398,27 @@ fn genInlineMemcpy(...@@ -7508,26 +7398,27 @@ fn genInlineMemcpy(
7508 }7398 }
75097399
7510 switch (src_ptr) {7400 switch (src_ptr) {
7511 .memory => |addr| {7401 .lea_tlv,
7512 try self.genSetReg(Type.usize, .rsi, .{ .immediate = addr });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 });
7513 // Load the pointer, which is stored in memory7419 // Load the pointer, which is stored in memory
7514 try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi }));7420 try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi }));
7515 },7421 },
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),
7531 .stack_offset, .ptr_stack_offset => |off| {7422 .stack_offset, .ptr_stack_offset => |off| {
7532 try self.asmRegisterMemory(switch (src_ptr) {7423 try self.asmRegisterMemory(switch (src_ptr) {
7533 .stack_offset => .mov,7424 .stack_offset => .mov,
...@@ -7574,26 +7465,27 @@ fn genInlineMemset(...@@ -7574,26 +7465,27 @@ fn genInlineMemset(
7574 try self.spillRegisters(&.{ .rdi, .al, .rcx });7465 try self.spillRegisters(&.{ .rdi, .al, .rcx });
75757466
7576 switch (dst_ptr) {7467 switch (dst_ptr) {
7577 .memory => |addr| {7468 .lea_tlv,
7578 try self.genSetReg(Type.usize, .rdi, .{ .immediate = addr });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 });
7579 // Load the pointer, which is stored in memory7486 // Load the pointer, which is stored in memory
7580 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));7487 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
7581 },7488 },
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),
7597 .stack_offset, .ptr_stack_offset => |off| {7489 .stack_offset, .ptr_stack_offset => |off| {
7598 try self.asmRegisterMemory(switch (dst_ptr) {7490 try self.asmRegisterMemory(switch (dst_ptr) {
7599 .stack_offset => .mov,7491 .stack_offset => .mov,
...@@ -7769,43 +7661,31 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -7769,43 +7661,31 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
7769 }7661 }
7770 },7662 },
7771 },7663 },
7772 .tlv_reloc => |sym_index| {7664 .load_got, .lea_direct => |sym_index| {
7773 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {7665 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
7774 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);7666 _ = try self.addInst(.{
7775 break :blk macho_file.getAtom(atom).getSymbolIndex().?;7667 .tag = switch (mcv) {
7776 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {7668 .load_got => .mov_linker,
7777 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);7669 .lea_direct => .lea_linker,
7778 break :blk coff_file.getAtom(atom).getSymbolIndex().?;7670 else => unreachable,
7779 } else unreachable;7671 },
77807672 .ops = switch (mcv) {
7781 if (self.bin_file.cast(link.File.MachO)) |_| {7673 .load_got => .got_reloc,
7782 _ = try self.addInst(.{7674 .lea_direct => .direct_reloc,
7783 .tag = .mov_linker,7675 else => unreachable,
7784 .ops = .tlv_reloc,7676 },
7785 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{7677 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
7786 .reg = @enumToInt(Register.rdi),7678 .reg = @enumToInt(reg),
7787 .atom_index = atom_index,7679 .atom_index = atom_index,
7788 .sym_index = sym_index,7680 .sym_index = sym_index,
7789 }) },7681 }) },
7790 });7682 });
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)});
7795 },7683 },
7796 .linker_load => |load_struct| {7684 .load_direct => |sym_index| {
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
7805 switch (ty.zigTypeTag()) {7685 switch (ty.zigTypeTag()) {
7806 .Float => {7686 .Float => {
7807 const base_reg = (try self.register_manager.allocReg(null, gp)).to64();7687 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
7808 try self.asmLeaLinker(base_reg, atom_index, load_struct);7688 try self.genSetReg(Type.usize, addr_reg, .{ .lea_direct = sym_index });
78097689
7810 if (intrinsicsAllowed(self.target.*, ty)) {7690 if (intrinsicsAllowed(self.target.*, ty)) {
7811 return self.asmRegisterMemory(7691 return self.asmRegisterMemory(
...@@ -7817,13 +7697,68 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -7817,13 +7697,68 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
7817 }),7697 }),
7818 },7698 },
7819 reg.to128(),7699 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 }),
7821 );7701 );
7822 }7702 }
78237703
7824 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});7704 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
7825 },7705 },
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 ),
7827 }7762 }
7828 },7763 },
7829 .stack_offset => |off| {7764 .stack_offset => |off| {
...@@ -8464,20 +8399,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -8464,20 +8399,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
8464 4, // dword alignment8399 4, // dword alignment
8465 );8400 );
8466 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;8401 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
8467 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{8402 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
8468 .type = .got,
8469 .sym_index = sym_index,
8470 } });
8471 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {8403 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
8472 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(8404 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(
8473 .{ .kind = .const_data, .ty = Type.anyerror },8405 .{ .kind = .const_data, .ty = Type.anyerror },
8474 4, // dword alignment8406 4, // dword alignment
8475 );8407 );
8476 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;8408 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
8477 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{8409 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
8478 .type = .got,
8479 .sym_index = sym_index,
8480 } });
8481 } else {8410 } else {
8482 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});8411 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
8483 }8412 }
...@@ -8586,7 +8515,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -8586,7 +8515,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
8586 const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size);8515 const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size);
8587 const elem_bit_off = elem_off % elem_abi_bits;8516 const elem_bit_off = elem_off % elem_abi_bits;
8588 const elem_mcv = try self.resolveInst(elem);8517 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) {
8590 .register => |reg| self.register_manager.lockReg(reg),8523 .register => |reg| self.register_manager.lockReg(reg),
8591 .immediate => |imm| lock: {8524 .immediate => |imm| lock: {
8592 if (imm == 0) continue;8525 if (imm == 0) continue;
...@@ -8596,7 +8529,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -8596,7 +8529,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
8596 };8529 };
8597 defer if (elem_lock) |lock| self.register_manager.unlockReg(lock);8530 defer if (elem_lock) |lock| self.register_manager.unlockReg(lock);
8598 const elem_reg = registerAlias(8531 const elem_reg = registerAlias(
8599 try self.copyToTmpRegister(elem_ty, elem_mcv),8532 try self.copyToTmpRegister(elem_ty, mat_elem_mcv),
8600 elem_abi_size,8533 elem_abi_size,
8601 );8534 );
8602 const elem_extra_bits = self.regExtraBits(elem_ty);8535 const elem_extra_bits = self.regExtraBits(elem_ty);
...@@ -8616,7 +8549,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -8616,7 +8549,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
8616 .{ .register = elem_reg },8549 .{ .register = elem_reg },
8617 );8550 );
8618 if (elem_bit_off > elem_extra_bits) {8551 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);
8620 if (elem_extra_bits > 0) {8553 if (elem_extra_bits > 0) {
8621 try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size));8554 try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size));
8622 }8555 }
...@@ -8641,7 +8574,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -8641,7 +8574,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
8641 const elem_ty = result_ty.structFieldType(elem_i);8574 const elem_ty = result_ty.structFieldType(elem_i);
8642 const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*));8575 const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*));
8643 const elem_mcv = try self.resolveInst(elem);8576 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, .{});
8645 }8582 }
8646 break :res .{ .stack_offset = stack_offset };8583 break :res .{ .stack_offset = stack_offset };
8647 },8584 },
...@@ -8652,8 +8589,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {...@@ -8652,8 +8589,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
86528589
8653 for (elements, 0..) |elem, elem_i| {8590 for (elements, 0..) |elem, elem_i| {
8654 const elem_mcv = try self.resolveInst(elem);8591 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 };
8655 const elem_off = @intCast(i32, elem_size * elem_i);8596 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, .{});
8657 }8598 }
8658 break :res MCValue{ .stack_offset = stack_offset };8599 break :res MCValue{ .stack_offset = stack_offset };
8659 },8600 },
...@@ -8776,10 +8717,11 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {...@@ -8776,10 +8717,11 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
8776 .mcv => |mcv| switch (mcv) {8717 .mcv => |mcv| switch (mcv) {
8777 .none => .none,8718 .none => .none,
8778 .undef => .undef,8719 .undef => .undef,
8779 .linker_load => |ll| .{ .linker_load = ll },
8780 .immediate => |imm| .{ .immediate = imm },8720 .immediate => |imm| .{ .immediate = imm },
8781 .memory => |addr| .{ .memory = addr },8721 .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 },
8783 },8725 },
8784 .fail => |msg| {8726 .fail => |msg| {
8785 self.err_msg = msg;8727 self.err_msg = msg;
...@@ -9077,3 +9019,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool {...@@ -9077,3 +9019,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool {
9077fn hasAvxSupport(target: Target) bool {9019fn hasAvxSupport(target: Target) bool {
9078 return Target.x86.featureSetHasAny(target.cpu.features, .{ .avx, .avx2 });9020 return Target.x86.featureSetHasAny(target.cpu.features, .{ .avx, .avx2 });
9079}9021}
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) {...@@ -931,11 +931,17 @@ pub const GenResult = union(enum) {
931 /// The bit-width of the immediate may be smaller than `u64`. For example, on 32-bit targets931 /// The bit-width of the immediate may be smaller than `u64`. For example, on 32-bit targets
932 /// such as ARM, the immediate will never exceed 32-bits.932 /// such as ARM, the immediate will never exceed 32-bits.
933 immediate: u64,933 immediate: u64,
934 linker_load: LinkerLoad,934 /// Threadlocal variable with address deferred until the linker allocates
935 /// Pointer to a threadlocal variable.935 /// everything in virtual memory.
936 /// The address resolution will be deferred until the linker allocates everything in virtual memory.
937 /// Payload is a symbol index.936 /// 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,
939 /// Direct by-address reference to memory location.945 /// Direct by-address reference to memory location.
940 memory: u64,946 memory: u64,
941 };947 };
...@@ -1005,19 +1011,13 @@ fn genDeclRef(...@@ -1005,19 +1011,13 @@ fn genDeclRef(
1005 const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);1011 const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
1006 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;1012 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
1007 if (is_threadlocal) {1013 if (is_threadlocal) {
1008 return GenResult.mcv(.{ .tlv_reloc = sym_index });1014 return GenResult.mcv(.{ .load_tlv = sym_index });
1009 }1015 }
1010 return GenResult.mcv(.{ .linker_load = .{1016 return GenResult.mcv(.{ .load_got = sym_index });
1011 .type = .got,
1012 .sym_index = sym_index,
1013 } });
1014 } else if (bin_file.cast(link.File.Coff)) |coff_file| {1017 } else if (bin_file.cast(link.File.Coff)) |coff_file| {
1015 const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);1018 const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);
1016 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;1019 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
1017 return GenResult.mcv(.{ .linker_load = .{1020 return GenResult.mcv(.{ .load_got = sym_index });
1018 .type = .got,
1019 .sym_index = sym_index,
1020 } });
1021 } else if (bin_file.cast(link.File.Plan9)) |p9| {1021 } else if (bin_file.cast(link.File.Plan9)) |p9| {
1022 const decl_block_index = try p9.seeDecl(decl_index);1022 const decl_block_index = try p9.seeDecl(decl_index);
1023 const decl_block = p9.getDeclBlock(decl_block_index);1023 const decl_block = p9.getDeclBlock(decl_block_index);
...@@ -1044,15 +1044,9 @@ fn genUnnamedConst(...@@ -1044,15 +1044,9 @@ fn genUnnamedConst(
1044 if (bin_file.cast(link.File.Elf)) |elf_file| {1044 if (bin_file.cast(link.File.Elf)) |elf_file| {
1045 return GenResult.mcv(.{ .memory = elf_file.getSymbol(local_sym_index).st_value });1045 return GenResult.mcv(.{ .memory = elf_file.getSymbol(local_sym_index).st_value });
1046 } else if (bin_file.cast(link.File.MachO)) |_| {1046 } else if (bin_file.cast(link.File.MachO)) |_| {
1047 return GenResult.mcv(.{ .linker_load = .{1047 return GenResult.mcv(.{ .load_direct = local_sym_index });
1048 .type = .direct,
1049 .sym_index = local_sym_index,
1050 } });
1051 } else if (bin_file.cast(link.File.Coff)) |_| {1048 } else if (bin_file.cast(link.File.Coff)) |_| {
1052 return GenResult.mcv(.{ .linker_load = .{1049 return GenResult.mcv(.{ .load_direct = local_sym_index });
1053 .type = .direct,
1054 .sym_index = local_sym_index,
1055 } });
1056 } else if (bin_file.cast(link.File.Plan9)) |p9| {1050 } else if (bin_file.cast(link.File.Plan9)) |p9| {
1057 const ptr_bits = target.cpu.arch.ptrBitWidth();1051 const ptr_bits = target.cpu.arch.ptrBitWidth();
1058 const ptr_bytes: u64 = @divExact(ptr_bits, 8);1052 const ptr_bytes: u64 = @divExact(ptr_bits, 8);