| ... | ... | @@ -130,8 +130,15 @@ pub const MCValue = union(enum) { |
| 130 | 130 | /// The value is in memory at a hard-coded address. |
| 131 | 131 | /// If the type is a pointer, it means the pointer address is at this memory location. |
| 132 | 132 | 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, |
| 135 | 142 | /// The value is a threadlocal variable. |
| 136 | 143 | /// Payload is a symbol index. |
| 137 | 144 | load_tlv: u32, |
| ... | ... | @@ -151,7 +158,9 @@ pub const MCValue = union(enum) { |
| 151 | 158 | .memory, |
| 152 | 159 | .stack_offset, |
| 153 | 160 | .ptr_stack_offset, |
| 154 | | .linker_load, |
| 161 | .load_direct, |
| 162 | .lea_direct, |
| 163 | .load_got, |
| 155 | 164 | .load_tlv, |
| 156 | 165 | .lea_tlv, |
| 157 | 166 | => true, |
| ... | ... | @@ -739,40 +748,6 @@ fn asmMemoryRegisterImmediate( |
| 739 | 748 | }); |
| 740 | 749 | } |
| 741 | 750 | |
| 742 | | fn 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 | | |
| 759 | | fn 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 | | |
| 776 | 751 | fn gen(self: *Self) InnerError!void { |
| 777 | 752 | const cc = self.fn_type.fnCallingConvention(); |
| 778 | 753 | if (cc != .Naked) { |
| ... | ... | @@ -2925,24 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2925 | 2900 | .disp = -off, |
| 2926 | 2901 | })); |
| 2927 | 2902 | }, |
| 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, |
| 2946 | 2911 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), |
| 2947 | 2912 | } |
| 2948 | 2913 | |
| ... | ... | @@ -3654,31 +3619,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 3654 | 3619 | else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), |
| 3655 | 3620 | } |
| 3656 | 3621 | }, |
| 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 => { |
| 3659 | 3628 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3660 | 3629 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); |
| 3661 | 3630 | }, |
| 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 | | }, |
| 3682 | 3631 | } |
| 3683 | 3632 | } |
| 3684 | 3633 | |
| ... | ... | @@ -3811,7 +3760,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3811 | 3760 | -@intCast(i32, overflow_bit_offset), |
| 3812 | 3761 | ); |
| 3813 | 3762 | }, |
| 3814 | | .memory, .load_tlv, .linker_load => if (abi_size <= 8) { |
| 3763 | .memory, .load_tlv, .load_direct => if (abi_size <= 8) { |
| 3815 | 3764 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 3816 | 3765 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3817 | 3766 | 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 |
| 3822 | 3771 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3823 | 3772 | defer self.register_manager.unlockReg(addr_lock); |
| 3824 | 3773 | |
| 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 }, |
| 3842 | 3778 | else => unreachable, |
| 3843 | | } |
| 3844 | | |
| 3779 | }); |
| 3845 | 3780 | try self.genInlineMemcpy( |
| 3846 | 3781 | ptr, |
| 3847 | 3782 | .{ .register = addr_reg }, |
| ... | ... | @@ -3861,7 +3796,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3861 | 3796 | .{ .immediate = abi_size }, |
| 3862 | 3797 | .{}, |
| 3863 | 3798 | ), |
| 3864 | | .ptr_stack_offset, .lea_tlv => { |
| 3799 | .ptr_stack_offset, .load_got, .lea_direct, .lea_tlv => { |
| 3865 | 3800 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 3866 | 3801 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3867 | 3802 | 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 |
| 3870 | 3805 | }, |
| 3871 | 3806 | } |
| 3872 | 3807 | }, |
| 3873 | | .memory, .load_tlv, .linker_load => { |
| 3808 | .memory, .load_direct, .load_tlv => { |
| 3874 | 3809 | const value_lock: ?RegisterLock = switch (value) { |
| 3875 | 3810 | .register => |reg| self.register_manager.lockReg(reg), |
| 3876 | 3811 | else => null, |
| ... | ... | @@ -3887,27 +3822,15 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3887 | 3822 | // Load the pointer, which is stored in memory |
| 3888 | 3823 | try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg })); |
| 3889 | 3824 | }, |
| 3825 | .load_direct => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_direct = sym_index }), |
| 3890 | 3826 | .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 | | }, |
| 3904 | 3827 | else => unreachable, |
| 3905 | 3828 | } |
| 3906 | 3829 | |
| 3907 | 3830 | const new_ptr = MCValue{ .register = addr_reg }; |
| 3908 | 3831 | try self.store(new_ptr, value, ptr_ty, value_ty); |
| 3909 | 3832 | }, |
| 3910 | | .lea_tlv => { |
| 3833 | .load_got, .lea_direct, .lea_tlv => { |
| 3911 | 3834 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3912 | 3835 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3913 | 3836 | 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 |
| 4245 | 4168 | })); |
| 4246 | 4169 | }, |
| 4247 | 4170 | .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 => { |
| 4250 | 4173 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 4251 | 4174 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 4252 | 4175 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 4253 | 4176 | |
| 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 }, |
| 4272 | 4181 | else => unreachable, |
| 4273 | | } |
| 4182 | }); |
| 4274 | 4183 | try self.asmMemory( |
| 4275 | 4184 | mir_tag, |
| 4276 | 4185 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), |
| ... | ... | @@ -4768,6 +4677,7 @@ fn genBinOp( |
| 4768 | 4677 | } |
| 4769 | 4678 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); |
| 4770 | 4679 | try self.setRegOrMem(lhs_ty, dst_mcv, switch (lhs) { |
| 4680 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 4771 | 4681 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 4772 | 4682 | else => lhs, |
| 4773 | 4683 | }); |
| ... | ... | @@ -4911,6 +4821,8 @@ fn genBinOp( |
| 4911 | 4821 | .eflags, |
| 4912 | 4822 | .register_overflow, |
| 4913 | 4823 | .ptr_stack_offset, |
| 4824 | .load_got, |
| 4825 | .lea_direct, |
| 4914 | 4826 | .lea_tlv, |
| 4915 | 4827 | => unreachable, |
| 4916 | 4828 | .register => |src_reg| try self.asmCmovccRegisterRegister( |
| ... | ... | @@ -4926,32 +4838,17 @@ fn genBinOp( |
| 4926 | 4838 | }), |
| 4927 | 4839 | cc, |
| 4928 | 4840 | ), |
| 4929 | | .memory, .load_tlv, .linker_load => { |
| 4841 | .memory, .load_direct, .load_tlv => { |
| 4930 | 4842 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 4931 | 4843 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 4932 | 4844 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 4933 | 4845 | |
| 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 }, |
| 4952 | 4850 | else => unreachable, |
| 4953 | | } |
| 4954 | | |
| 4851 | }); |
| 4955 | 4852 | try self.asmCmovccRegisterMemory( |
| 4956 | 4853 | registerAlias(tmp_reg, cmov_abi_size), |
| 4957 | 4854 | 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 |
| 5045 | 4942 | )), |
| 5046 | 4943 | else => unreachable, |
| 5047 | 4944 | }, |
| 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 | => { |
| 5049 | 4954 | assert(abi_size <= 8); |
| 5050 | 4955 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); |
| 5051 | 4956 | 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 |
| 5060 | 4965 | ), |
| 5061 | 4966 | } |
| 5062 | 4967 | }, |
| 5063 | | .memory, .load_tlv, .linker_load, .stack_offset => { |
| 4968 | .memory, .load_got, .load_direct, .load_tlv, .stack_offset => { |
| 5064 | 4969 | const dst: ?struct { |
| 5065 | 4970 | addr_reg: Register, |
| 5066 | 4971 | addr_lock: RegisterLock, |
| 5067 | 4972 | } = switch (dst_mcv) { |
| 5068 | 4973 | else => unreachable, |
| 5069 | | .memory, .load_tlv, .linker_load => dst: { |
| 4974 | .memory, .load_got, .load_direct, .load_tlv => dst: { |
| 5070 | 4975 | const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 5071 | 4976 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| 5072 | 4977 | errdefer self.register_manager.unlockReg(dst_addr_lock); |
| 5073 | 4978 | |
| 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 | }); |
| 5094 | 4985 | |
| 5095 | 4986 | break :dst .{ |
| 5096 | 4987 | .addr_reg = dst_addr_reg, |
| ... | ... | @@ -5108,7 +4999,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5108 | 4999 | addr_lock: RegisterLock, |
| 5109 | 5000 | } = switch (src_mcv) { |
| 5110 | 5001 | else => null, |
| 5111 | | .memory, .load_tlv, .linker_load => src: { |
| 5002 | .memory, .load_got, .load_direct, .load_tlv => src: { |
| 5112 | 5003 | const src_limb_reg = try self.register_manager.allocReg(null, gp); |
| 5113 | 5004 | const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); |
| 5114 | 5005 | 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 |
| 5117 | 5008 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 5118 | 5009 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 5119 | 5010 | |
| 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 | }); |
| 5140 | 5017 | |
| 5141 | 5018 | break :src .{ |
| 5142 | 5019 | .addr_reg = src_addr_reg, |
| ... | ... | @@ -5179,7 +5056,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5179 | 5056 | .base = .rbp, |
| 5180 | 5057 | .disp = off - dst_off, |
| 5181 | 5058 | }, |
| 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 }, |
| 5183 | 5064 | }, |
| 5184 | 5065 | ); |
| 5185 | 5066 | switch (src_mcv) { |
| ... | ... | @@ -5243,7 +5124,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5243 | 5124 | else => unreachable, |
| 5244 | 5125 | } |
| 5245 | 5126 | }, |
| 5246 | | .memory, .linker_load, .lea_tlv, .load_tlv => { |
| 5127 | .memory, |
| 5128 | .load_got, |
| 5129 | .load_direct, |
| 5130 | .load_tlv, |
| 5131 | => { |
| 5247 | 5132 | try self.asmRegisterMemory( |
| 5248 | 5133 | .mov, |
| 5249 | 5134 | 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 |
| 5258 | 5143 | registerAlias(src.?.limb_reg, limb_abi_size), |
| 5259 | 5144 | ); |
| 5260 | 5145 | }, |
| 5261 | | .stack_offset, .ptr_stack_offset, .eflags => { |
| 5146 | .stack_offset, |
| 5147 | .ptr_stack_offset, |
| 5148 | .eflags, |
| 5149 | .lea_direct, |
| 5150 | .lea_tlv, |
| 5151 | => { |
| 5262 | 5152 | const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) { |
| 5263 | 5153 | .stack_offset => |src_off| .{ .stack_offset = src_off - off }, |
| 5264 | 5154 | .ptr_stack_offset, |
| 5265 | 5155 | .eflags, |
| 5156 | .load_got, |
| 5157 | .lea_direct, |
| 5158 | .lea_tlv, |
| 5266 | 5159 | => off: { |
| 5267 | 5160 | assert(off == 0); |
| 5268 | 5161 | break :off src_mcv; |
| ... | ... | @@ -5283,6 +5176,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5283 | 5176 | }, |
| 5284 | 5177 | .ptr_stack_offset => unreachable, |
| 5285 | 5178 | .lea_tlv => unreachable, |
| 5179 | .lea_direct => unreachable, |
| 5286 | 5180 | } |
| 5287 | 5181 | } |
| 5288 | 5182 | |
| ... | ... | @@ -5296,6 +5190,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5296 | 5190 | .dead, .unreach, .immediate => unreachable, |
| 5297 | 5191 | .eflags => unreachable, |
| 5298 | 5192 | .ptr_stack_offset => unreachable, |
| 5193 | .lea_direct => unreachable, |
| 5299 | 5194 | .lea_tlv => unreachable, |
| 5300 | 5195 | .register_overflow => unreachable, |
| 5301 | 5196 | .register => |dst_reg| { |
| ... | ... | @@ -5308,6 +5203,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5308 | 5203 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), |
| 5309 | 5204 | .dead, .unreach => unreachable, |
| 5310 | 5205 | .ptr_stack_offset => unreachable, |
| 5206 | .lea_direct => unreachable, |
| 5311 | 5207 | .lea_tlv => unreachable, |
| 5312 | 5208 | .register_overflow => unreachable, |
| 5313 | 5209 | .register => |src_reg| try self.asmRegisterRegister( |
| ... | ... | @@ -5335,12 +5231,13 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5335 | 5231 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), |
| 5336 | 5232 | ); |
| 5337 | 5233 | }, |
| 5338 | | .memory, .load_tlv => { |
| 5234 | .memory, |
| 5235 | .load_got, |
| 5236 | .load_direct, |
| 5237 | .load_tlv, |
| 5238 | => { |
| 5339 | 5239 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 5340 | 5240 | }, |
| 5341 | | .linker_load => { |
| 5342 | | return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); |
| 5343 | | }, |
| 5344 | 5241 | .eflags => { |
| 5345 | 5242 | return self.fail("TODO implement x86 multiply source eflags", .{}); |
| 5346 | 5243 | }, |
| ... | ... | @@ -5352,6 +5249,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5352 | 5249 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), |
| 5353 | 5250 | .dead, .unreach => unreachable, |
| 5354 | 5251 | .ptr_stack_offset => unreachable, |
| 5252 | .lea_direct => unreachable, |
| 5355 | 5253 | .lea_tlv => unreachable, |
| 5356 | 5254 | .register_overflow => unreachable, |
| 5357 | 5255 | .register => |src_reg| { |
| ... | ... | @@ -5375,23 +5273,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5375 | 5273 | |
| 5376 | 5274 | return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{}); |
| 5377 | 5275 | }, |
| 5378 | | .memory, .load_tlv, .stack_offset => { |
| 5276 | .memory, |
| 5277 | .load_got, |
| 5278 | .load_direct, |
| 5279 | .load_tlv, |
| 5280 | .stack_offset, |
| 5281 | => { |
| 5379 | 5282 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 5380 | 5283 | }, |
| 5381 | | .linker_load => { |
| 5382 | | return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); |
| 5383 | | }, |
| 5384 | 5284 | .eflags => { |
| 5385 | 5285 | return self.fail("TODO implement x86 multiply source eflags", .{}); |
| 5386 | 5286 | }, |
| 5387 | 5287 | } |
| 5388 | 5288 | }, |
| 5389 | | .memory, .load_tlv => { |
| 5289 | .memory, |
| 5290 | .load_got, |
| 5291 | .load_direct, |
| 5292 | .load_tlv, |
| 5293 | => { |
| 5390 | 5294 | return self.fail("TODO implement x86 multiply destination memory", .{}); |
| 5391 | 5295 | }, |
| 5392 | | .linker_load => { |
| 5393 | | return self.fail("TODO implement x86 multiply destination symbol at index in linker", .{}); |
| 5394 | | }, |
| 5395 | 5296 | } |
| 5396 | 5297 | } |
| 5397 | 5298 | |
| ... | ... | @@ -5471,7 +5372,8 @@ fn genVarDbgInfo( |
| 5471 | 5372 | .offset = -off, |
| 5472 | 5373 | } }, |
| 5473 | 5374 | .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 } }, |
| 5475 | 5377 | .immediate => |x| .{ .immediate = x }, |
| 5476 | 5378 | .undef => .undef, |
| 5477 | 5379 | .none => .none, |
| ... | ... | @@ -5572,9 +5474,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5572 | 5474 | .unreach => unreachable, |
| 5573 | 5475 | .dead => unreachable, |
| 5574 | 5476 | .memory => unreachable, |
| 5575 | | .linker_load => unreachable, |
| 5576 | 5477 | .eflags => unreachable, |
| 5577 | 5478 | .register_overflow => unreachable, |
| 5479 | .load_got => unreachable, |
| 5480 | .lea_direct => unreachable, |
| 5481 | .load_direct => unreachable, |
| 5578 | 5482 | .lea_tlv => unreachable, |
| 5579 | 5483 | .load_tlv => unreachable, |
| 5580 | 5484 | } |
| ... | ... | @@ -5612,9 +5516,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5612 | 5516 | .unreach => unreachable, |
| 5613 | 5517 | .dead => unreachable, |
| 5614 | 5518 | .memory => unreachable, |
| 5615 | | .linker_load => unreachable, |
| 5616 | 5519 | .eflags => unreachable, |
| 5617 | 5520 | .register_overflow => unreachable, |
| 5521 | .load_got => unreachable, |
| 5522 | .lea_direct => unreachable, |
| 5523 | .load_direct => unreachable, |
| 5618 | 5524 | .lea_tlv => unreachable, |
| 5619 | 5525 | .load_tlv => unreachable, |
| 5620 | 5526 | } |
| ... | ... | @@ -5639,21 +5545,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5639 | 5545 | .base = .ds, |
| 5640 | 5546 | .disp = @intCast(i32, got_addr), |
| 5641 | 5547 | })); |
| 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 }); |
| 5649 | 5551 | 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 }); |
| 5657 | 5555 | try self.asmRegister(.call, .rax); |
| 5658 | 5556 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 5659 | 5557 | 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 |
| 5673 | 5571 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); |
| 5674 | 5572 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); |
| 5675 | 5573 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 5574 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| 5676 | 5575 | 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, |
| 5680 | 5582 | .sym_index = sym_index, |
| 5681 | | }, |
| 5583 | }) }, |
| 5682 | 5584 | }); |
| 5683 | 5585 | try self.asmRegister(.call, .rax); |
| 5684 | 5586 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 5685 | 5587 | 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); |
| 5688 | 5589 | _ = try self.addInst(.{ |
| 5689 | 5590 | .tag = .call_extern, |
| 5690 | 5591 | .ops = undefined, |
| ... | ... | @@ -5883,20 +5784,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 5883 | 5784 | 4, // dword alignment |
| 5884 | 5785 | ); |
| 5885 | 5786 | 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 }); |
| 5890 | 5788 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 5891 | 5789 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( |
| 5892 | 5790 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| 5893 | 5791 | 4, // dword alignment |
| 5894 | 5792 | ); |
| 5895 | 5793 | 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 }); |
| 5900 | 5795 | } else { |
| 5901 | 5796 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); |
| 5902 | 5797 | } |
| ... | ... | @@ -6138,6 +6033,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6138 | 6033 | .register_overflow, |
| 6139 | 6034 | .ptr_stack_offset, |
| 6140 | 6035 | .eflags, |
| 6036 | .lea_direct, |
| 6141 | 6037 | .lea_tlv, |
| 6142 | 6038 | => unreachable, |
| 6143 | 6039 | |
| ... | ... | @@ -6159,31 +6055,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6159 | 6055 | return .{ .eflags = .nc }; |
| 6160 | 6056 | }, |
| 6161 | 6057 | |
| 6162 | | .memory, .load_tlv, .linker_load => { |
| 6058 | .memory, |
| 6059 | .load_got, |
| 6060 | .load_direct, |
| 6061 | .load_tlv, |
| 6062 | => { |
| 6163 | 6063 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 6164 | 6064 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 6165 | 6065 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 6166 | 6066 | |
| 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 | }); |
| 6187 | 6073 | |
| 6188 | 6074 | const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); |
| 6189 | 6075 | try self.asmMemoryImmediate(.cmp, Memory.sib( |
| ... | ... | @@ -7112,7 +6998,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7112 | 6998 | else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}), |
| 7113 | 6999 | } |
| 7114 | 7000 | }, |
| 7115 | | .memory, .load_tlv, .linker_load => { |
| 7001 | .memory, |
| 7002 | .load_direct, |
| 7003 | .load_tlv, |
| 7004 | => { |
| 7116 | 7005 | if (abi_size <= 8) { |
| 7117 | 7006 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7118 | 7007 | 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 |
| 7122 | 7011 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7123 | 7012 | defer self.register_manager.unlockReg(addr_lock); |
| 7124 | 7013 | |
| 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 }, |
| 7143 | 7018 | else => unreachable, |
| 7144 | | } |
| 7145 | | |
| 7019 | }); |
| 7146 | 7020 | try self.genInlineMemcpy( |
| 7147 | 7021 | .{ .ptr_stack_offset = stack_offset }, |
| 7148 | 7022 | .{ .register = addr_reg }, |
| ... | ... | @@ -7184,7 +7058,11 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7184 | 7058 | }, |
| 7185 | 7059 | } |
| 7186 | 7060 | }, |
| 7187 | | .ptr_stack_offset, .lea_tlv => { |
| 7061 | .ptr_stack_offset, |
| 7062 | .load_got, |
| 7063 | .lea_direct, |
| 7064 | .lea_tlv, |
| 7065 | => { |
| 7188 | 7066 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7189 | 7067 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 7190 | 7068 | }, |
| ... | ... | @@ -7342,7 +7220,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7342 | 7220 | }, |
| 7343 | 7221 | } |
| 7344 | 7222 | }, |
| 7345 | | .memory, .load_tlv, .linker_load => if (abi_size <= 8) { |
| 7223 | .memory, |
| 7224 | .load_direct, |
| 7225 | .load_tlv, |
| 7226 | => if (abi_size <= 8) { |
| 7346 | 7227 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7347 | 7228 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); |
| 7348 | 7229 | } else { |
| ... | ... | @@ -7350,27 +7231,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7350 | 7231 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7351 | 7232 | defer self.register_manager.unlockReg(addr_lock); |
| 7352 | 7233 | |
| 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 }, |
| 7371 | 7238 | else => unreachable, |
| 7372 | | } |
| 7373 | | |
| 7239 | }); |
| 7374 | 7240 | try self.genInlineMemcpy( |
| 7375 | 7241 | .{ .ptr_stack_offset = stack_offset }, |
| 7376 | 7242 | .{ .register = addr_reg }, |
| ... | ... | @@ -7390,7 +7256,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7390 | 7256 | .{ .immediate = abi_size }, |
| 7391 | 7257 | .{}, |
| 7392 | 7258 | ), |
| 7393 | | .ptr_stack_offset, .lea_tlv => { |
| 7259 | .ptr_stack_offset, |
| 7260 | .load_got, |
| 7261 | .lea_direct, |
| 7262 | .lea_tlv, |
| 7263 | => { |
| 7394 | 7264 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); |
| 7395 | 7265 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7396 | 7266 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | ... | @@ -7485,21 +7355,13 @@ fn genInlineMemcpy( |
| 7485 | 7355 | // Load the pointer, which is stored in memory |
| 7486 | 7356 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| 7487 | 7357 | }, |
| 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 }, |
| 7503 | 7365 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 7504 | 7366 | else => dst_ptr, |
| 7505 | 7367 | }), |
| ... | ... | @@ -7531,21 +7393,13 @@ fn genInlineMemcpy( |
| 7531 | 7393 | // Load the pointer, which is stored in memory |
| 7532 | 7394 | try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi })); |
| 7533 | 7395 | }, |
| 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 }, |
| 7549 | 7403 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 7550 | 7404 | else => src_ptr, |
| 7551 | 7405 | }), |
| ... | ... | @@ -7600,21 +7454,13 @@ fn genInlineMemset( |
| 7600 | 7454 | // Load the pointer, which is stored in memory |
| 7601 | 7455 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| 7602 | 7456 | }, |
| 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 }, |
| 7618 | 7464 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 7619 | 7465 | else => dst_ptr, |
| 7620 | 7466 | }), |
| ... | ... | @@ -7793,15 +7639,64 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 7793 | 7639 | } |
| 7794 | 7640 | }, |
| 7795 | 7641 | }, |
| 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 | } |
| 7804 | 7681 | |
| 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); |
| 7805 | 7700 | if (self.bin_file.cast(link.File.MachO)) |_| { |
| 7806 | 7701 | _ = try self.addInst(.{ |
| 7807 | 7702 | .tag = .mov_linker, |
| ... | ... | @@ -7844,39 +7739,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 7844 | 7739 | ), |
| 7845 | 7740 | } |
| 7846 | 7741 | }, |
| 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 | | }, |
| 7880 | 7742 | .stack_offset => |off| { |
| 7881 | 7743 | switch (ty.zigTypeTag()) { |
| 7882 | 7744 | .Int => switch (ty.intInfo(self.target.*).signedness) { |
| ... | ... | @@ -8515,20 +8377,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 8515 | 8377 | 4, // dword alignment |
| 8516 | 8378 | ); |
| 8517 | 8379 | 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 }); |
| 8522 | 8381 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 8523 | 8382 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( |
| 8524 | 8383 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| 8525 | 8384 | 4, // dword alignment |
| 8526 | 8385 | ); |
| 8527 | 8386 | 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 }); |
| 8532 | 8388 | } else { |
| 8533 | 8389 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); |
| 8534 | 8390 | } |
| ... | ... | @@ -8839,9 +8695,10 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 8839 | 8695 | .mcv => |mcv| switch (mcv) { |
| 8840 | 8696 | .none => .none, |
| 8841 | 8697 | .undef => .undef, |
| 8842 | | .linker_load => |ll| .{ .linker_load = ll }, |
| 8843 | 8698 | .immediate => |imm| .{ .immediate = imm }, |
| 8844 | 8699 | .memory => |addr| .{ .memory = addr }, |
| 8700 | .load_direct => |sym_index| .{ .load_direct = sym_index }, |
| 8701 | .load_got => |sym_index| .{ .load_got = sym_index }, |
| 8845 | 8702 | .load_tlv => |sym_index| .{ .load_tlv = sym_index }, |
| 8846 | 8703 | }, |
| 8847 | 8704 | .fail => |msg| { |
| ... | ... | @@ -9140,3 +8997,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool { |
| 9140 | 8997 | fn hasAvxSupport(target: Target) bool { |
| 9141 | 8998 | return Target.x86.featureSetHasAny(target.cpu.features, .{ .avx, .avx2 }); |
| 9142 | 8999 | } |
| 9000 | |
| 9001 | fn 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 | } |