authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-15 11:10:20+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-15 11:10:24+02:00
logb82130709d121222f793c082dbbe6c29e7f2ec41
treeaefd8d64c71850c27106823feabd50feb35b908a
parent179117c114ca44d977f794961762e110c1955911

x86_64: cleanup different memory load types

Split `MCValue.linker_load` into `.load_got`, `.load_direct`, and `.lea_direct`.

6 files changed, 288 insertions(+), 426 deletions(-)

src/arch/aarch64/CodeGen.zig+2-1
......@@ -6168,9 +6168,10 @@ 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 },
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 } },
61746175 .load_tlv => unreachable, // TODO
61756176 },
61766177 .fail => |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 .load_tlv, .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 .load_tlv, .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 .load_tlv, .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+272-405
......@@ -130,8 +130,15 @@ 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,
133 /// The value is in memory.
134 /// Payload is a symbol index.
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,
135142 /// The value is a threadlocal variable.
136143 /// Payload is a symbol index.
137144 load_tlv: u32,
......@@ -151,7 +158,9 @@ pub const MCValue = union(enum) {
151158 .memory,
152159 .stack_offset,
153160 .ptr_stack_offset,
154 .linker_load,
161 .load_direct,
162 .lea_direct,
163 .load_got,
155164 .load_tlv,
156165 .lea_tlv,
157166 => true,
......@@ -739,40 +748,6 @@ fn asmMemoryRegisterImmediate(
739748 });
740749}
741750
742fn asmMovLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codegen.LinkerLoad) !void {
743 const ops: Mir.Inst.Ops = switch (linker_load.type) {
744 .got => .got_reloc,
745 .direct => .direct_reloc,
746 .import => .import_reloc,
747 };
748 _ = try self.addInst(.{
749 .tag = .mov_linker,
750 .ops = ops,
751 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
752 .reg = @enumToInt(reg),
753 .atom_index = atom_index,
754 .sym_index = linker_load.sym_index,
755 }) },
756 });
757}
758
759fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codegen.LinkerLoad) !void {
760 const ops: Mir.Inst.Ops = switch (linker_load.type) {
761 .got => .got_reloc,
762 .direct => .direct_reloc,
763 .import => .import_reloc,
764 };
765 _ = try self.addInst(.{
766 .tag = .lea_linker,
767 .ops = ops,
768 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
769 .reg = @enumToInt(reg),
770 .atom_index = atom_index,
771 .sym_index = linker_load.sym_index,
772 }) },
773 });
774}
775
776751fn gen(self: *Self) InnerError!void {
777752 const cc = self.fn_type.fnCallingConvention();
778753 if (cc != .Naked) {
......@@ -2925,24 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
29252900 .disp = -off,
29262901 }));
29272902 },
2928 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
2929 .lea_tlv => unreachable,
2930 .load_tlv => |sym_index| try self.genSetReg(array_ty, addr_reg, .{ .lea_tlv = sym_index }),
2931 .linker_load => |load_struct| {
2932 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
2933 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
2934 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
2935 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
2936 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
2937 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
2938 } else unreachable;
2939
2940 switch (load_struct.type) {
2941 .import => unreachable,
2942 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
2943 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
2944 }
2945 },
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,
29462911 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
29472912 }
29482913
......@@ -3654,31 +3619,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
36543619 else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}),
36553620 }
36563621 },
3657 .load_tlv => |sym_index| try self.load(dst_mcv, .{ .lea_tlv = sym_index }, ptr_ty),
3658 .memory, .lea_tlv => {
3622 .load_direct, .load_tlv => |sym_index| try self.load(dst_mcv, switch (ptr) {
3623 .load_direct => .{ .lea_direct = sym_index },
3624 .load_tlv => .{ .lea_tlv = sym_index },
3625 else => unreachable,
3626 }, ptr_ty),
3627 .memory, .load_got, .lea_direct, .lea_tlv => {
36593628 const reg = try self.copyToTmpRegister(ptr_ty, ptr);
36603629 try self.load(dst_mcv, .{ .register = reg }, ptr_ty);
36613630 },
3662 .linker_load => |load_struct| {
3663 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
3664 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
3665 defer self.register_manager.unlockReg(addr_reg_lock);
3666
3667 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
3668 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3669 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
3670 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
3671 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3672 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
3673 } else unreachable;
3674
3675 switch (load_struct.type) {
3676 .import => unreachable,
3677 .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct),
3678 }
3679
3680 try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty);
3681 },
36823631 }
36833632}
36843633
......@@ -3811,7 +3760,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38113760 -@intCast(i32, overflow_bit_offset),
38123761 );
38133762 },
3814 .memory, .load_tlv, .linker_load => if (abi_size <= 8) {
3763 .memory, .load_tlv, .load_direct => if (abi_size <= 8) {
38153764 const tmp_reg = try self.copyToTmpRegister(value_ty, value);
38163765 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
38173766 defer self.register_manager.unlockReg(tmp_lock);
......@@ -3822,26 +3771,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38223771 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
38233772 defer self.register_manager.unlockReg(addr_lock);
38243773
3825 switch (value) {
3826 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
3827 .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }),
3828 .linker_load => |load_struct| {
3829 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
3830 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3831 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
3832 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
3833 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3834 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
3835 } else unreachable;
3836 switch (load_struct.type) {
3837 .import => unreachable,
3838 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
3839 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
3840 }
3841 },
3774 try self.genSetReg(Type.usize, addr_reg, switch (value) {
3775 .memory => |addr| .{ .immediate = addr },
3776 .load_direct => |sym_index| .{ .lea_direct = sym_index },
3777 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
38423778 else => unreachable,
3843 }
3844
3779 });
38453780 try self.genInlineMemcpy(
38463781 ptr,
38473782 .{ .register = addr_reg },
......@@ -3861,7 +3796,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38613796 .{ .immediate = abi_size },
38623797 .{},
38633798 ),
3864 .ptr_stack_offset, .lea_tlv => {
3799 .ptr_stack_offset, .load_got, .lea_direct, .lea_tlv => {
38653800 const tmp_reg = try self.copyToTmpRegister(value_ty, value);
38663801 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
38673802 defer self.register_manager.unlockReg(tmp_lock);
......@@ -3870,7 +3805,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38703805 },
38713806 }
38723807 },
3873 .memory, .load_tlv, .linker_load => {
3808 .memory, .load_direct, .load_tlv => {
38743809 const value_lock: ?RegisterLock = switch (value) {
38753810 .register => |reg| self.register_manager.lockReg(reg),
38763811 else => null,
......@@ -3887,27 +3822,15 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
38873822 // Load the pointer, which is stored in memory
38883823 try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg }));
38893824 },
3825 .load_direct => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_direct = sym_index }),
38903826 .load_tlv => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_tlv = sym_index }),
3891 .linker_load => |load_struct| {
3892 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
3893 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3894 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
3895 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
3896 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
3897 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
3898 } else unreachable;
3899 switch (load_struct.type) {
3900 .import => unreachable,
3901 .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct),
3902 }
3903 },
39043827 else => unreachable,
39053828 }
39063829
39073830 const new_ptr = MCValue{ .register = addr_reg };
39083831 try self.store(new_ptr, value, ptr_ty, value_ty);
39093832 },
3910 .lea_tlv => {
3833 .load_got, .lea_direct, .lea_tlv => {
39113834 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr);
39123835 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
39133836 defer self.register_manager.unlockReg(addr_reg_lock);
......@@ -4245,32 +4168,18 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue
42454168 }));
42464169 },
42474170 .ptr_stack_offset => unreachable,
4248 .lea_tlv => unreachable,
4249 .memory, .load_tlv, .linker_load => {
4171 .load_got, .lea_direct, .lea_tlv => unreachable,
4172 .memory, .load_direct, .load_tlv => {
42504173 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
42514174 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
42524175 defer self.register_manager.unlockReg(addr_reg_lock);
42534176
4254 switch (dst_mcv) {
4255 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
4256 .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }),
4257 .linker_load => |load_struct| {
4258 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
4259 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4260 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
4261 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
4262 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4263 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
4264 } else unreachable;
4265
4266 switch (load_struct.type) {
4267 .import => unreachable,
4268 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
4269 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
4270 }
4271 },
4177 try self.genSetReg(Type.usize, addr_reg, switch (dst_mcv) {
4178 .memory => |addr| .{ .immediate = addr },
4179 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4180 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
42724181 else => unreachable,
4273 }
4182 });
42744183 try self.asmMemory(
42754184 mir_tag,
42764185 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),
......@@ -4768,6 +4677,7 @@ fn genBinOp(
47684677 }
47694678 const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true);
47704679 try self.setRegOrMem(lhs_ty, dst_mcv, switch (lhs) {
4680 .load_direct => |sym_index| .{ .lea_direct = sym_index },
47714681 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
47724682 else => lhs,
47734683 });
......@@ -4911,6 +4821,8 @@ fn genBinOp(
49114821 .eflags,
49124822 .register_overflow,
49134823 .ptr_stack_offset,
4824 .load_got,
4825 .lea_direct,
49144826 .lea_tlv,
49154827 => unreachable,
49164828 .register => |src_reg| try self.asmCmovccRegisterRegister(
......@@ -4926,32 +4838,17 @@ fn genBinOp(
49264838 }),
49274839 cc,
49284840 ),
4929 .memory, .load_tlv, .linker_load => {
4841 .memory, .load_direct, .load_tlv => {
49304842 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
49314843 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
49324844 defer self.register_manager.unlockReg(addr_reg_lock);
49334845
4934 switch (mat_src_mcv) {
4935 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
4936 .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }),
4937 .linker_load => |load_struct| {
4938 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
4939 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4940 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
4941 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
4942 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
4943 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
4944 } else unreachable;
4945
4946 switch (load_struct.type) {
4947 .import => unreachable,
4948 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
4949 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
4950 }
4951 },
4846 try self.genSetReg(Type.usize, addr_reg, switch (mat_src_mcv) {
4847 .memory => |addr| .{ .immediate = addr },
4848 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4849 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
49524850 else => unreachable,
4953 }
4954
4851 });
49554852 try self.asmCmovccRegisterMemory(
49564853 registerAlias(tmp_reg, cmov_abi_size),
49574854 Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), .{ .base = addr_reg }),
......@@ -5045,7 +4942,15 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
50454942 )),
50464943 else => unreachable,
50474944 },
5048 .ptr_stack_offset, .memory, .lea_tlv, .load_tlv, .linker_load, .eflags => {
4945 .ptr_stack_offset,
4946 .memory,
4947 .load_got,
4948 .lea_direct,
4949 .load_direct,
4950 .lea_tlv,
4951 .load_tlv,
4952 .eflags,
4953 => {
50494954 assert(abi_size <= 8);
50504955 const dst_reg_lock = self.register_manager.lockReg(dst_reg);
50514956 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);
......@@ -5060,37 +4965,23 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
50604965 ),
50614966 }
50624967 },
5063 .memory, .load_tlv, .linker_load, .stack_offset => {
4968 .memory, .load_got, .load_direct, .load_tlv, .stack_offset => {
50644969 const dst: ?struct {
50654970 addr_reg: Register,
50664971 addr_lock: RegisterLock,
50674972 } = switch (dst_mcv) {
50684973 else => unreachable,
5069 .memory, .load_tlv, .linker_load => dst: {
4974 .memory, .load_got, .load_direct, .load_tlv => dst: {
50704975 const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
50714976 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
50724977 errdefer self.register_manager.unlockReg(dst_addr_lock);
50734978
5074 switch (dst_mcv) {
5075 .memory => |addr| try self.genSetReg(Type.usize, dst_addr_reg, .{ .immediate = addr }),
5076 .load_tlv => |sym_index| try self.genSetReg(Type.usize, dst_addr_reg, .{ .lea_tlv = sym_index }),
5077 .linker_load => |load_struct| {
5078 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
5079 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5080 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5081 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
5082 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5083 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5084 } else unreachable;
5085
5086 switch (load_struct.type) {
5087 .import => unreachable,
5088 .got => try self.asmMovLinker(dst_addr_reg, atom_index, load_struct),
5089 .direct => try self.asmLeaLinker(dst_addr_reg, atom_index, load_struct),
5090 }
5091 },
5092 else => unreachable,
5093 }
4979 try self.genSetReg(Type.usize, dst_addr_reg, switch (dst_mcv) {
4980 .memory => |addr| .{ .immediate = addr },
4981 .load_direct => |sym_index| .{ .lea_direct = sym_index },
4982 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
4983 else => dst_mcv,
4984 });
50944985
50954986 break :dst .{
50964987 .addr_reg = dst_addr_reg,
......@@ -5108,7 +4999,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
51084999 addr_lock: RegisterLock,
51095000 } = switch (src_mcv) {
51105001 else => null,
5111 .memory, .load_tlv, .linker_load => src: {
5002 .memory, .load_got, .load_direct, .load_tlv => src: {
51125003 const src_limb_reg = try self.register_manager.allocReg(null, gp);
51135004 const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg);
51145005 errdefer self.register_manager.unlockReg(src_limb_lock);
......@@ -5117,26 +5008,12 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
51175008 const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg);
51185009 errdefer self.register_manager.unlockReg(src_addr_lock);
51195010
5120 switch (src_mcv) {
5121 .memory => |addr| try self.genSetReg(Type.usize, src_addr_reg, .{ .immediate = addr }),
5122 .load_tlv => |sym_index| try self.genSetReg(Type.usize, src_addr_reg, .{ .lea_tlv = sym_index }),
5123 .linker_load => |load_struct| {
5124 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
5125 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5126 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
5127 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
5128 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5129 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
5130 } else unreachable;
5131
5132 switch (load_struct.type) {
5133 .import => unreachable,
5134 .got => try self.asmMovLinker(src_addr_reg, atom_index, load_struct),
5135 .direct => try self.asmLeaLinker(src_addr_reg, atom_index, load_struct),
5136 }
5137 },
5138 else => unreachable,
5139 }
5011 try self.genSetReg(Type.usize, src_addr_reg, switch (src_mcv) {
5012 .memory => |addr| .{ .immediate = addr },
5013 .load_direct => |sym_index| .{ .lea_direct = sym_index },
5014 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
5015 else => src_mcv,
5016 });
51405017
51415018 break :src .{
51425019 .addr_reg = src_addr_reg,
......@@ -5179,7 +5056,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
51795056 .base = .rbp,
51805057 .disp = off - dst_off,
51815058 },
5182 .memory, .linker_load => .{ .base = dst.?.addr_reg, .disp = off },
5059 .memory,
5060 .load_got,
5061 .load_direct,
5062 .load_tlv,
5063 => .{ .base = dst.?.addr_reg, .disp = off },
51835064 },
51845065 );
51855066 switch (src_mcv) {
......@@ -5243,7 +5124,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
52435124 else => unreachable,
52445125 }
52455126 },
5246 .memory, .linker_load, .lea_tlv, .load_tlv => {
5127 .memory,
5128 .load_got,
5129 .load_direct,
5130 .load_tlv,
5131 => {
52475132 try self.asmRegisterMemory(
52485133 .mov,
52495134 registerAlias(src.?.limb_reg, limb_abi_size),
......@@ -5258,11 +5143,19 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
52585143 registerAlias(src.?.limb_reg, limb_abi_size),
52595144 );
52605145 },
5261 .stack_offset, .ptr_stack_offset, .eflags => {
5146 .stack_offset,
5147 .ptr_stack_offset,
5148 .eflags,
5149 .lea_direct,
5150 .lea_tlv,
5151 => {
52625152 const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) {
52635153 .stack_offset => |src_off| .{ .stack_offset = src_off - off },
52645154 .ptr_stack_offset,
52655155 .eflags,
5156 .load_got,
5157 .lea_direct,
5158 .lea_tlv,
52665159 => off: {
52675160 assert(off == 0);
52685161 break :off src_mcv;
......@@ -5283,6 +5176,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
52835176 },
52845177 .ptr_stack_offset => unreachable,
52855178 .lea_tlv => unreachable,
5179 .lea_direct => unreachable,
52865180 }
52875181}
52885182
......@@ -5296,6 +5190,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
52965190 .dead, .unreach, .immediate => unreachable,
52975191 .eflags => unreachable,
52985192 .ptr_stack_offset => unreachable,
5193 .lea_direct => unreachable,
52995194 .lea_tlv => unreachable,
53005195 .register_overflow => unreachable,
53015196 .register => |dst_reg| {
......@@ -5308,6 +5203,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
53085203 .undef => try self.genSetReg(dst_ty, dst_reg, .undef),
53095204 .dead, .unreach => unreachable,
53105205 .ptr_stack_offset => unreachable,
5206 .lea_direct => unreachable,
53115207 .lea_tlv => unreachable,
53125208 .register_overflow => unreachable,
53135209 .register => |src_reg| try self.asmRegisterRegister(
......@@ -5335,12 +5231,13 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
53355231 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }),
53365232 );
53375233 },
5338 .memory, .load_tlv => {
5234 .memory,
5235 .load_got,
5236 .load_direct,
5237 .load_tlv,
5238 => {
53395239 return self.fail("TODO implement x86 multiply source memory", .{});
53405240 },
5341 .linker_load => {
5342 return self.fail("TODO implement x86 multiply source symbol at index in linker", .{});
5343 },
53445241 .eflags => {
53455242 return self.fail("TODO implement x86 multiply source eflags", .{});
53465243 },
......@@ -5352,6 +5249,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
53525249 .undef => return self.genSetStack(dst_ty, off, .undef, .{}),
53535250 .dead, .unreach => unreachable,
53545251 .ptr_stack_offset => unreachable,
5252 .lea_direct => unreachable,
53555253 .lea_tlv => unreachable,
53565254 .register_overflow => unreachable,
53575255 .register => |src_reg| {
......@@ -5375,23 +5273,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
53755273
53765274 return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{});
53775275 },
5378 .memory, .load_tlv, .stack_offset => {
5276 .memory,
5277 .load_got,
5278 .load_direct,
5279 .load_tlv,
5280 .stack_offset,
5281 => {
53795282 return self.fail("TODO implement x86 multiply source memory", .{});
53805283 },
5381 .linker_load => {
5382 return self.fail("TODO implement x86 multiply source symbol at index in linker", .{});
5383 },
53845284 .eflags => {
53855285 return self.fail("TODO implement x86 multiply source eflags", .{});
53865286 },
53875287 }
53885288 },
5389 .memory, .load_tlv => {
5289 .memory,
5290 .load_got,
5291 .load_direct,
5292 .load_tlv,
5293 => {
53905294 return self.fail("TODO implement x86 multiply destination memory", .{});
53915295 },
5392 .linker_load => {
5393 return self.fail("TODO implement x86 multiply destination symbol at index in linker", .{});
5394 },
53955296 }
53965297}
53975298
......@@ -5471,7 +5372,8 @@ fn genVarDbgInfo(
54715372 .offset = -off,
54725373 } },
54735374 .memory => |address| .{ .memory = address },
5474 .linker_load => |linker_load| .{ .linker_load = linker_load },
5375 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
5376 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
54755377 .immediate => |x| .{ .immediate = x },
54765378 .undef => .undef,
54775379 .none => .none,
......@@ -5572,9 +5474,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
55725474 .unreach => unreachable,
55735475 .dead => unreachable,
55745476 .memory => unreachable,
5575 .linker_load => unreachable,
55765477 .eflags => unreachable,
55775478 .register_overflow => unreachable,
5479 .load_got => unreachable,
5480 .lea_direct => unreachable,
5481 .load_direct => unreachable,
55785482 .lea_tlv => unreachable,
55795483 .load_tlv => unreachable,
55805484 }
......@@ -5612,9 +5516,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
56125516 .unreach => unreachable,
56135517 .dead => unreachable,
56145518 .memory => unreachable,
5615 .linker_load => unreachable,
56165519 .eflags => unreachable,
56175520 .register_overflow => unreachable,
5521 .load_got => unreachable,
5522 .lea_direct => unreachable,
5523 .load_direct => unreachable,
56185524 .lea_tlv => unreachable,
56195525 .load_tlv => unreachable,
56205526 }
......@@ -5639,21 +5545,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
56395545 .base = .ds,
56405546 .disp = @intCast(i32, got_addr),
56415547 }));
5642 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
5643 const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
5644 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
5645 try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{
5646 .type = .got,
5647 .sym_index = sym_index,
5648 } });
5548 } else if (self.bin_file.cast(link.File.Coff)) |_| {
5549 const sym_index = try self.getSymbolIndexForDecl(func.owner_decl);
5550 try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index });
56495551 try self.asmRegister(.call, .rax);
5650 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
5651 const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
5652 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
5653 try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{
5654 .type = .got,
5655 .sym_index = sym_index,
5656 } });
5552 } else if (self.bin_file.cast(link.File.MachO)) |_| {
5553 const sym_index = try self.getSymbolIndexForDecl(func.owner_decl);
5554 try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index });
56575555 try self.asmRegister(.call, .rax);
56585556 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
56595557 const decl_block_index = try p9.seeDecl(func.owner_decl);
......@@ -5673,18 +5571,21 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
56735571 const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0);
56745572 const lib_name = mem.sliceTo(extern_fn.lib_name, 0);
56755573 if (self.bin_file.cast(link.File.Coff)) |coff_file| {
5574 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
56765575 const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);
5677 try self.genSetReg(Type.usize, .rax, .{
5678 .linker_load = .{
5679 .type = .import,
5576 _ = try self.addInst(.{
5577 .tag = .mov_linker,
5578 .ops = .import_reloc,
5579 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
5580 .reg = @enumToInt(Register.rax),
5581 .atom_index = atom_index,
56805582 .sym_index = sym_index,
5681 },
5583 }) },
56825584 });
56835585 try self.asmRegister(.call, .rax);
56845586 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
56855587 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
5686 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
5687 const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
5588 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
56885589 _ = try self.addInst(.{
56895590 .tag = .call_extern,
56905591 .ops = undefined,
......@@ -5883,20 +5784,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
58835784 4, // dword alignment
58845785 );
58855786 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
5886 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
5887 .type = .got,
5888 .sym_index = sym_index,
5889 } });
5787 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
58905788 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
58915789 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(
58925790 .{ .kind = .const_data, .ty = Type.anyerror },
58935791 4, // dword alignment
58945792 );
58955793 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
5896 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
5897 .type = .got,
5898 .sym_index = sym_index,
5899 } });
5794 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
59005795 } else {
59015796 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
59025797 }
......@@ -6138,6 +6033,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
61386033 .register_overflow,
61396034 .ptr_stack_offset,
61406035 .eflags,
6036 .lea_direct,
61416037 .lea_tlv,
61426038 => unreachable,
61436039
......@@ -6159,31 +6055,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
61596055 return .{ .eflags = .nc };
61606056 },
61616057
6162 .memory, .load_tlv, .linker_load => {
6058 .memory,
6059 .load_got,
6060 .load_direct,
6061 .load_tlv,
6062 => {
61636063 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
61646064 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
61656065 defer self.register_manager.unlockReg(addr_reg_lock);
61666066
6167 switch (opt_mcv) {
6168 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
6169 .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }),
6170 .linker_load => |load_struct| {
6171 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
6172 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
6173 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
6174 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
6175 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
6176 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
6177 } else unreachable;
6178
6179 switch (load_struct.type) {
6180 .import => unreachable,
6181 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
6182 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
6183 }
6184 },
6185 else => unreachable,
6186 }
6067 try self.genSetReg(Type.usize, addr_reg, switch (opt_mcv) {
6068 .memory => |addr| .{ .immediate = addr },
6069 .load_direct => |sym_index| .{ .lea_direct = sym_index },
6070 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
6071 else => opt_mcv,
6072 });
61876073
61886074 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));
61896075 try self.asmMemoryImmediate(.cmp, Memory.sib(
......@@ -7112,7 +6998,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
71126998 else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}),
71136999 }
71147000 },
7115 .memory, .load_tlv, .linker_load => {
7001 .memory,
7002 .load_direct,
7003 .load_tlv,
7004 => {
71167005 if (abi_size <= 8) {
71177006 const reg = try self.copyToTmpRegister(ty, mcv);
71187007 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
......@@ -7122,27 +7011,12 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
71227011 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
71237012 defer self.register_manager.unlockReg(addr_lock);
71247013
7125 switch (mcv) {
7126 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
7127 .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }),
7128 .linker_load => |load_struct| {
7129 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7130 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7131 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7132 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7133 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7134 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7135 } else unreachable;
7136
7137 switch (load_struct.type) {
7138 .import => unreachable,
7139 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
7140 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
7141 }
7142 },
7014 try self.genSetReg(Type.usize, addr_reg, switch (mcv) {
7015 .memory => |addr| .{ .immediate = addr },
7016 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7017 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
71437018 else => unreachable,
7144 }
7145
7019 });
71467020 try self.genInlineMemcpy(
71477021 .{ .ptr_stack_offset = stack_offset },
71487022 .{ .register = addr_reg },
......@@ -7184,7 +7058,11 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
71847058 },
71857059 }
71867060 },
7187 .ptr_stack_offset, .lea_tlv => {
7061 .ptr_stack_offset,
7062 .load_got,
7063 .lea_direct,
7064 .lea_tlv,
7065 => {
71887066 const reg = try self.copyToTmpRegister(ty, mcv);
71897067 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
71907068 },
......@@ -7342,7 +7220,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
73427220 },
73437221 }
73447222 },
7345 .memory, .load_tlv, .linker_load => if (abi_size <= 8) {
7223 .memory,
7224 .load_direct,
7225 .load_tlv,
7226 => if (abi_size <= 8) {
73467227 const reg = try self.copyToTmpRegister(ty, mcv);
73477228 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts);
73487229 } else {
......@@ -7350,27 +7231,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
73507231 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
73517232 defer self.register_manager.unlockReg(addr_lock);
73527233
7353 switch (mcv) {
7354 .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }),
7355 .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }),
7356 .linker_load => |load_struct| {
7357 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7358 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7359 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7360 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7361 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7362 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7363 } else unreachable;
7364
7365 switch (load_struct.type) {
7366 .import => unreachable,
7367 .got => try self.asmMovLinker(addr_reg, atom_index, load_struct),
7368 .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct),
7369 }
7370 },
7234 try self.genSetReg(Type.usize, addr_reg, switch (mcv) {
7235 .memory => |addr| .{ .immediate = addr },
7236 .load_direct => |sym_index| .{ .lea_direct = sym_index },
7237 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
73717238 else => unreachable,
7372 }
7373
7239 });
73747240 try self.genInlineMemcpy(
73757241 .{ .ptr_stack_offset = stack_offset },
73767242 .{ .register = addr_reg },
......@@ -7390,7 +7256,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
73907256 .{ .immediate = abi_size },
73917257 .{},
73927258 ),
7393 .ptr_stack_offset, .lea_tlv => {
7259 .ptr_stack_offset,
7260 .load_got,
7261 .lea_direct,
7262 .lea_tlv,
7263 => {
73947264 const tmp_reg = try self.copyToTmpRegister(ty, mcv);
73957265 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
73967266 defer self.register_manager.unlockReg(tmp_lock);
......@@ -7485,21 +7355,13 @@ fn genInlineMemcpy(
74857355 // Load the pointer, which is stored in memory
74867356 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
74877357 },
7488 .linker_load => |load_struct| {
7489 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7490 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7491 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7492 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7493 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7494 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7495 } else unreachable;
7496
7497 switch (load_struct.type) {
7498 .import => unreachable,
7499 .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct),
7500 }
7501 },
7502 .lea_tlv, .load_tlv => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7358 .load_got,
7359 .lea_direct,
7360 .load_direct,
7361 .lea_tlv,
7362 .load_tlv,
7363 => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7364 .load_direct => |sym_index| .{ .lea_direct = sym_index },
75037365 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
75047366 else => dst_ptr,
75057367 }),
......@@ -7531,21 +7393,13 @@ fn genInlineMemcpy(
75317393 // Load the pointer, which is stored in memory
75327394 try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi }));
75337395 },
7534 .linker_load => |load_struct| {
7535 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7536 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7537 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7538 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7539 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7540 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7541 } else unreachable;
7542
7543 switch (load_struct.type) {
7544 .import => unreachable,
7545 .got, .direct => try self.asmMovLinker(.rsi, atom_index, load_struct),
7546 }
7547 },
7548 .lea_tlv, .load_tlv => try self.genSetReg(Type.usize, .rsi, switch (src_ptr) {
7396 .load_got,
7397 .lea_direct,
7398 .load_direct,
7399 .lea_tlv,
7400 .load_tlv,
7401 => try self.genSetReg(Type.usize, .rsi, switch (src_ptr) {
7402 .load_direct => |sym_index| .{ .lea_direct = sym_index },
75497403 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
75507404 else => src_ptr,
75517405 }),
......@@ -7600,21 +7454,13 @@ fn genInlineMemset(
76007454 // Load the pointer, which is stored in memory
76017455 try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi }));
76027456 },
7603 .linker_load => |load_struct| {
7604 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7605 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7606 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7607 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7608 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7609 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7610 } else unreachable;
7611
7612 switch (load_struct.type) {
7613 .import => unreachable,
7614 .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct),
7615 }
7616 },
7617 .lea_tlv, .load_tlv => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7457 .load_got,
7458 .lea_direct,
7459 .load_direct,
7460 .lea_tlv,
7461 .load_tlv,
7462 => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) {
7463 .load_direct => |sym_index| .{ .lea_direct = sym_index },
76187464 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
76197465 else => dst_ptr,
76207466 }),
......@@ -7793,15 +7639,64 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
77937639 }
77947640 },
77957641 },
7796 .lea_tlv => |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;
7642 .load_got, .lea_direct => |sym_index| {
7643 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
7644 _ = try self.addInst(.{
7645 .tag = switch (mcv) {
7646 .load_got => .mov_linker,
7647 .lea_direct => .lea_linker,
7648 else => unreachable,
7649 },
7650 .ops = switch (mcv) {
7651 .load_got => .got_reloc,
7652 .lea_direct => .direct_reloc,
7653 else => unreachable,
7654 },
7655 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
7656 .reg = @enumToInt(reg),
7657 .atom_index = atom_index,
7658 .sym_index = sym_index,
7659 }) },
7660 });
7661 },
7662 .load_direct => |sym_index| {
7663 switch (ty.zigTypeTag()) {
7664 .Float => {
7665 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
7666 try self.genSetReg(Type.usize, addr_reg, .{ .lea_direct = sym_index });
7667
7668 if (intrinsicsAllowed(self.target.*, ty)) {
7669 return self.asmRegisterMemory(
7670 switch (ty.tag()) {
7671 .f32 => .movss,
7672 .f64 => .movsd,
7673 else => return self.fail("TODO genSetReg from memory for {}", .{
7674 ty.fmt(self.bin_file.options.module.?),
7675 }),
7676 },
7677 reg.to128(),
7678 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),
7679 );
7680 }
78047681
7682 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
7683 },
7684 else => {
7685 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
7686 _ = try self.addInst(.{
7687 .tag = .mov_linker,
7688 .ops = .direct_reloc,
7689 .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{
7690 .reg = @enumToInt(registerAlias(reg, abi_size)),
7691 .atom_index = atom_index,
7692 .sym_index = sym_index,
7693 }) },
7694 });
7695 },
7696 }
7697 },
7698 .lea_tlv => |sym_index| {
7699 const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl);
78057700 if (self.bin_file.cast(link.File.MachO)) |_| {
78067701 _ = try self.addInst(.{
78077702 .tag = .mov_linker,
......@@ -7844,39 +7739,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
78447739 ),
78457740 }
78467741 },
7847 .linker_load => |load_struct| {
7848 const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
7849 const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7850 break :blk macho_file.getAtom(atom).getSymbolIndex().?;
7851 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: {
7852 const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
7853 break :blk coff_file.getAtom(atom).getSymbolIndex().?;
7854 } else unreachable;
7855
7856 switch (ty.zigTypeTag()) {
7857 .Float => {
7858 const base_reg = (try self.register_manager.allocReg(null, gp)).to64();
7859 try self.asmLeaLinker(base_reg, atom_index, load_struct);
7860
7861 if (intrinsicsAllowed(self.target.*, ty)) {
7862 return self.asmRegisterMemory(
7863 switch (ty.tag()) {
7864 .f32 => .movss,
7865 .f64 => .movsd,
7866 else => return self.fail("TODO genSetReg from memory for {}", .{
7867 ty.fmt(self.bin_file.options.module.?),
7868 }),
7869 },
7870 reg.to128(),
7871 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg.to64() }),
7872 );
7873 }
7874
7875 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
7876 },
7877 else => try self.asmMovLinker(registerAlias(reg, abi_size), atom_index, load_struct),
7878 }
7879 },
78807742 .stack_offset => |off| {
78817743 switch (ty.zigTypeTag()) {
78827744 .Int => switch (ty.intInfo(self.target.*).signedness) {
......@@ -8515,20 +8377,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
85158377 4, // dword alignment
85168378 );
85178379 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
8518 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
8519 .type = .got,
8520 .sym_index = sym_index,
8521 } });
8380 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
85228381 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
85238382 const atom_index = try macho_file.getOrCreateAtomForLazySymbol(
85248383 .{ .kind = .const_data, .ty = Type.anyerror },
85258384 4, // dword alignment
85268385 );
85278386 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
8528 try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{
8529 .type = .got,
8530 .sym_index = sym_index,
8531 } });
8387 try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index });
85328388 } else {
85338389 return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)});
85348390 }
......@@ -8839,9 +8695,10 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
88398695 .mcv => |mcv| switch (mcv) {
88408696 .none => .none,
88418697 .undef => .undef,
8842 .linker_load => |ll| .{ .linker_load = ll },
88438698 .immediate => |imm| .{ .immediate = imm },
88448699 .memory => |addr| .{ .memory = addr },
8700 .load_direct => |sym_index| .{ .load_direct = sym_index },
8701 .load_got => |sym_index| .{ .load_got = sym_index },
88458702 .load_tlv => |sym_index| .{ .load_tlv = sym_index },
88468703 },
88478704 .fail => |msg| {
......@@ -9140,3 +8997,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool {
91408997fn hasAvxSupport(target: Target) bool {
91418998 return Target.x86.featureSetHasAny(target.cpu.features, .{ .avx, .avx2 });
91428999}
9000
9001fn getSymbolIndexForDecl(self: *Self, decl_index: Module.Decl.Index) !u32 {
9002 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
9003 const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
9004 return macho_file.getAtom(atom).getSymbolIndex().?;
9005 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
9006 const atom = try coff_file.getOrCreateAtomForDecl(decl_index);
9007 return coff_file.getAtom(atom).getSymbolIndex().?;
9008 } else unreachable;
9009}
src/codegen.zig+11-17
......@@ -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,
935934 /// Threadlocal variable with address deferred until the linker allocates
936935 /// everything in virtual memory.
937936 /// Payload is a symbol index.
938937 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 };
......@@ -1007,17 +1013,11 @@ fn genDeclRef(
10071013 if (is_threadlocal) {
10081014 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);