| ... | @@ -130,12 +130,21 @@ pub const MCValue = union(enum) { | ... | @@ -130,12 +130,21 @@ pub const MCValue = union(enum) { |
| 130 | /// The value is in memory at a hard-coded address. | 130 | /// The value is in memory at a hard-coded address. |
| 131 | /// If the type is a pointer, it means the pointer address is at this memory location. | 131 | /// If the type is a pointer, it means the pointer address is at this memory location. |
| 132 | memory: u64, | 132 | memory: u64, |
| 133 | /// The value is in memory but requires a linker relocation fixup. | 133 | /// The value is in memory. |
| 134 | linker_load: codegen.LinkerLoad, | | |
| 135 | /// Pointer to a threadlocal variable. | | |
| 136 | /// The address resolution will be deferred until the linker allocates everything in virtual memory. | | |
| 137 | /// Payload is a symbol index. | 134 | /// Payload is a symbol index. |
| 138 | tlv_reloc: u32, | 135 | load_direct: u32, |
| | 136 | /// The value is a pointer to value in memory. |
| | 137 | /// Payload is a symbol index. |
| | 138 | lea_direct: u32, |
| | 139 | /// The value is in memory referenced indirectly via GOT. |
| | 140 | /// Payload is a symbol index. |
| | 141 | load_got: u32, |
| | 142 | /// The value is a threadlocal variable. |
| | 143 | /// Payload is a symbol index. |
| | 144 | load_tlv: u32, |
| | 145 | /// The value is a pointer to threadlocal variable. |
| | 146 | /// Payload is a symbol index. |
| | 147 | lea_tlv: u32, |
| 139 | /// The value is one of the stack variables. | 148 | /// The value is one of the stack variables. |
| 140 | /// If the type is a pointer, it means the pointer address is in the stack at this offset. | 149 | /// If the type is a pointer, it means the pointer address is in the stack at this offset. |
| 141 | stack_offset: i32, | 150 | stack_offset: i32, |
| ... | @@ -149,8 +158,11 @@ pub const MCValue = union(enum) { | ... | @@ -149,8 +158,11 @@ pub const MCValue = union(enum) { |
| 149 | .memory, | 158 | .memory, |
| 150 | .stack_offset, | 159 | .stack_offset, |
| 151 | .ptr_stack_offset, | 160 | .ptr_stack_offset, |
| 152 | .linker_load, | 161 | .load_direct, |
| 153 | .tlv_reloc, | 162 | .lea_direct, |
| | 163 | .load_got, |
| | 164 | .load_tlv, |
| | 165 | .lea_tlv, |
| 154 | => true, | 166 | => true, |
| 155 | else => false, | 167 | else => false, |
| 156 | }; | 168 | }; |
| ... | @@ -736,40 +748,6 @@ fn asmMemoryRegisterImmediate( | ... | @@ -736,40 +748,6 @@ fn asmMemoryRegisterImmediate( |
| 736 | }); | 748 | }); |
| 737 | } | 749 | } |
| 738 | | 750 | |
| 739 | fn asmMovLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codegen.LinkerLoad) !void { | | |
| 740 | const ops: Mir.Inst.Ops = switch (linker_load.type) { | | |
| 741 | .got => .got_reloc, | | |
| 742 | .direct => .direct_reloc, | | |
| 743 | .import => .import_reloc, | | |
| 744 | }; | | |
| 745 | _ = try self.addInst(.{ | | |
| 746 | .tag = .mov_linker, | | |
| 747 | .ops = ops, | | |
| 748 | .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{ | | |
| 749 | .reg = @enumToInt(reg), | | |
| 750 | .atom_index = atom_index, | | |
| 751 | .sym_index = linker_load.sym_index, | | |
| 752 | }) }, | | |
| 753 | }); | | |
| 754 | } | | |
| 755 | | | |
| 756 | fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codegen.LinkerLoad) !void { | | |
| 757 | const ops: Mir.Inst.Ops = switch (linker_load.type) { | | |
| 758 | .got => .got_reloc, | | |
| 759 | .direct => .direct_reloc, | | |
| 760 | .import => .import_reloc, | | |
| 761 | }; | | |
| 762 | _ = try self.addInst(.{ | | |
| 763 | .tag = .lea_linker, | | |
| 764 | .ops = ops, | | |
| 765 | .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{ | | |
| 766 | .reg = @enumToInt(reg), | | |
| 767 | .atom_index = atom_index, | | |
| 768 | .sym_index = linker_load.sym_index, | | |
| 769 | }) }, | | |
| 770 | }); | | |
| 771 | } | | |
| 772 | | | |
| 773 | fn gen(self: *Self) InnerError!void { | 751 | fn gen(self: *Self) InnerError!void { |
| 774 | const cc = self.fn_type.fnCallingConvention(); | 752 | const cc = self.fn_type.fnCallingConvention(); |
| 775 | if (cc != .Naked) { | 753 | if (cc != .Naked) { |
| ... | @@ -2922,23 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2922,23 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2922 | .disp = -off, | 2900 | .disp = -off, |
| 2923 | })); | 2901 | })); |
| 2924 | }, | 2902 | }, |
| 2925 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 2903 | .load_got => try self.genSetReg(array_ty, addr_reg, array), |
| 2926 | .tlv_reloc => try self.genSetReg(array_ty, addr_reg, array), | 2904 | .memory, .load_direct, .load_tlv => try self.genSetReg(Type.usize, addr_reg, switch (array) { |
| 2927 | .linker_load => |load_struct| { | 2905 | .memory => |addr| .{ .immediate = addr }, |
| 2928 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 2906 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 2929 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 2907 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 2930 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 2908 | else => unreachable, |
| 2931 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | 2909 | }), |
| 2932 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 2910 | .lea_direct, .lea_tlv => unreachable, |
| 2933 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 2934 | } else unreachable; | | |
| 2935 | | | |
| 2936 | switch (load_struct.type) { | | |
| 2937 | .import => unreachable, | | |
| 2938 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 2939 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | | |
| 2940 | } | | |
| 2941 | }, | | |
| 2942 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), | 2911 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), |
| 2943 | } | 2912 | } |
| 2944 | | 2913 | |
| ... | @@ -3650,30 +3619,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -3650,30 +3619,19 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 3650 | else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), | 3619 | else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), |
| 3651 | } | 3620 | } |
| 3652 | }, | 3621 | }, |
| 3653 | .memory, .tlv_reloc => { | 3622 | .load_direct => |sym_index| { |
| 3654 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); | 3623 | const addr_reg = try self.copyToTmpRegister(Type.usize, .{ .lea_direct = sym_index }); |
| 3655 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); | | |
| 3656 | }, | | |
| 3657 | .linker_load => |load_struct| { | | |
| 3658 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | | |
| 3659 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 3624 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3660 | defer self.register_manager.unlockReg(addr_reg_lock); | 3625 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 3661 | | 3626 | // Load the pointer, which is stored in memory |
| 3662 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 3627 | try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg })); |
| 3663 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 3664 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 3665 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 3666 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 3667 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 3668 | } else unreachable; | | |
| 3669 | | | |
| 3670 | switch (load_struct.type) { | | |
| 3671 | .import => unreachable, | | |
| 3672 | .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 3673 | } | | |
| 3674 | | | |
| 3675 | try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty); | 3628 | try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty); |
| 3676 | }, | 3629 | }, |
| | 3630 | .load_tlv => |sym_index| try self.load(dst_mcv, .{ .lea_tlv = sym_index }, ptr_ty), |
| | 3631 | .memory, .load_got, .lea_direct, .lea_tlv => { |
| | 3632 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| | 3633 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); |
| | 3634 | }, |
| 3677 | } | 3635 | } |
| 3678 | } | 3636 | } |
| 3679 | | 3637 | |
| ... | @@ -3806,7 +3764,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3806,7 +3764,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3806 | -@intCast(i32, overflow_bit_offset), | 3764 | -@intCast(i32, overflow_bit_offset), |
| 3807 | ); | 3765 | ); |
| 3808 | }, | 3766 | }, |
| 3809 | .memory, .linker_load => if (abi_size <= 8) { | 3767 | .memory, .load_tlv, .load_direct => if (abi_size <= 8) { |
| 3810 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 3768 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 3811 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 3769 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3812 | defer self.register_manager.unlockReg(tmp_lock); | 3770 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -3817,25 +3775,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3817,25 +3775,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3817 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 3775 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3818 | defer self.register_manager.unlockReg(addr_lock); | 3776 | defer self.register_manager.unlockReg(addr_lock); |
| 3819 | | 3777 | |
| 3820 | switch (value) { | 3778 | try self.genSetReg(Type.usize, addr_reg, switch (value) { |
| 3821 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 3779 | .memory => |addr| .{ .immediate = addr }, |
| 3822 | .linker_load => |load_struct| { | 3780 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 3823 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 3781 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 3824 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 3825 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 3826 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 3827 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 3828 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 3829 | } else unreachable; | | |
| 3830 | switch (load_struct.type) { | | |
| 3831 | .import => unreachable, | | |
| 3832 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 3833 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | | |
| 3834 | } | | |
| 3835 | }, | | |
| 3836 | else => unreachable, | 3782 | else => unreachable, |
| 3837 | } | 3783 | }); |
| 3838 | | | |
| 3839 | try self.genInlineMemcpy( | 3784 | try self.genInlineMemcpy( |
| 3840 | ptr, | 3785 | ptr, |
| 3841 | .{ .register = addr_reg }, | 3786 | .{ .register = addr_reg }, |
| ... | @@ -3855,7 +3800,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3855,7 +3800,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3855 | .{ .immediate = abi_size }, | 3800 | .{ .immediate = abi_size }, |
| 3856 | .{}, | 3801 | .{}, |
| 3857 | ), | 3802 | ), |
| 3858 | .ptr_stack_offset, .tlv_reloc => { | 3803 | .ptr_stack_offset, .load_got, .lea_direct, .lea_tlv => { |
| 3859 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 3804 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 3860 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 3805 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3861 | defer self.register_manager.unlockReg(tmp_lock); | 3806 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -3864,7 +3809,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3864,7 +3809,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3864 | }, | 3809 | }, |
| 3865 | } | 3810 | } |
| 3866 | }, | 3811 | }, |
| 3867 | .memory, .linker_load => { | 3812 | .memory, .load_direct, .load_tlv => { |
| 3868 | const value_lock: ?RegisterLock = switch (value) { | 3813 | const value_lock: ?RegisterLock = switch (value) { |
| 3869 | .register => |reg| self.register_manager.lockReg(reg), | 3814 | .register => |reg| self.register_manager.lockReg(reg), |
| 3870 | else => null, | 3815 | else => null, |
| ... | @@ -3876,32 +3821,21 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3876,32 +3821,21 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3876 | defer self.register_manager.unlockReg(addr_reg_lock); | 3821 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 3877 | | 3822 | |
| 3878 | switch (ptr) { | 3823 | switch (ptr) { |
| 3879 | .memory => |addr| { | 3824 | .memory => |addr| try self.genSetReg(ptr_ty, addr_reg, .{ .immediate = addr }), |
| 3880 | try self.genSetReg(ptr_ty, addr_reg, .{ .immediate = addr }); | 3825 | .load_direct => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_direct = sym_index }), |
| 3881 | // Load the pointer, which is stored in memory | 3826 | .load_tlv => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_tlv = sym_index }), |
| 3882 | try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg })); | | |
| 3883 | }, | | |
| 3884 | .linker_load => |load_struct| { | | |
| 3885 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | | |
| 3886 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 3887 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 3888 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 3889 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 3890 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 3891 | } else unreachable; | | |
| 3892 | switch (load_struct.type) { | | |
| 3893 | .import => unreachable, | | |
| 3894 | .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 3895 | } | | |
| 3896 | }, | | |
| 3897 | else => unreachable, | 3827 | else => unreachable, |
| 3898 | } | 3828 | } |
| | 3829 | if (ptr != .load_tlv) { |
| | 3830 | // Load the pointer, which is stored in memory |
| | 3831 | try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg })); |
| | 3832 | } |
| 3899 | | 3833 | |
| 3900 | const new_ptr = MCValue{ .register = addr_reg }; | 3834 | const new_ptr = MCValue{ .register = addr_reg }; |
| 3901 | try self.store(new_ptr, value, ptr_ty, value_ty); | 3835 | try self.store(new_ptr, value, ptr_ty, value_ty); |
| 3902 | }, | 3836 | }, |
| 3903 | .tlv_reloc => { | 3837 | .load_got, .lea_direct, .lea_tlv => { |
| 3904 | const addr_reg = try self.copyToTmpRegister(Type.usize, ptr); | 3838 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3905 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 3839 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3906 | defer self.register_manager.unlockReg(addr_reg_lock); | 3840 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 3907 | | 3841 | |
| ... | @@ -3953,14 +3887,17 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 | ... | @@ -3953,14 +3887,17 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 |
| 3953 | | 3887 | |
| 3954 | const dst_mcv: MCValue = result: { | 3888 | const dst_mcv: MCValue = result: { |
| 3955 | switch (mcv) { | 3889 | switch (mcv) { |
| 3956 | .stack_offset, .tlv_reloc => { | 3890 | .stack_offset, .lea_tlv, .load_tlv => { |
| 3957 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ | 3891 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ |
| 3958 | .immediate = field_offset, | 3892 | .immediate = field_offset, |
| 3959 | }); | 3893 | }); |
| 3960 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); | 3894 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 3961 | defer self.register_manager.unlockReg(offset_reg_lock); | 3895 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 3962 | | 3896 | |
| 3963 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, mcv); | 3897 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, switch (mcv) { |
| | 3898 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 3899 | else => mcv, |
| | 3900 | }); |
| 3964 | try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); | 3901 | try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| 3965 | break :result dst_mcv; | 3902 | break :result dst_mcv; |
| 3966 | }, | 3903 | }, |
| ... | @@ -4235,31 +4172,18 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue | ... | @@ -4235,31 +4172,18 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue |
| 4235 | })); | 4172 | })); |
| 4236 | }, | 4173 | }, |
| 4237 | .ptr_stack_offset => unreachable, | 4174 | .ptr_stack_offset => unreachable, |
| 4238 | .tlv_reloc => unreachable, | 4175 | .load_got, .lea_direct, .lea_tlv => unreachable, |
| 4239 | .memory, .linker_load => { | 4176 | .memory, .load_direct, .load_tlv => { |
| 4240 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 4177 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 4241 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 4178 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 4242 | defer self.register_manager.unlockReg(addr_reg_lock); | 4179 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 4243 | | 4180 | |
| 4244 | switch (dst_mcv) { | 4181 | try self.genSetReg(Type.usize, addr_reg, switch (dst_mcv) { |
| 4245 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 4182 | .memory => |addr| .{ .immediate = addr }, |
| 4246 | .linker_load => |load_struct| { | 4183 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 4247 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 4184 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 4248 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 4249 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 4250 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 4251 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 4252 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 4253 | } else unreachable; | | |
| 4254 | | | |
| 4255 | switch (load_struct.type) { | | |
| 4256 | .import => unreachable, | | |
| 4257 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 4258 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | | |
| 4259 | } | | |
| 4260 | }, | | |
| 4261 | else => unreachable, | 4185 | else => unreachable, |
| 4262 | } | 4186 | }); |
| 4263 | try self.asmMemory( | 4187 | try self.asmMemory( |
| 4264 | mir_tag, | 4188 | mir_tag, |
| 4265 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), | 4189 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), |
| ... | @@ -4756,7 +4680,11 @@ fn genBinOp( | ... | @@ -4756,7 +4680,11 @@ fn genBinOp( |
| 4756 | } | 4680 | } |
| 4757 | } | 4681 | } |
| 4758 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); | 4682 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); |
| 4759 | try self.setRegOrMem(lhs_ty, dst_mcv, lhs); | 4683 | try self.setRegOrMem(lhs_ty, dst_mcv, switch (lhs) { |
| | 4684 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| | 4685 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 4686 | else => lhs, |
| | 4687 | }); |
| 4760 | break :dst dst_mcv; | 4688 | break :dst dst_mcv; |
| 4761 | }; | 4689 | }; |
| 4762 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { | 4690 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { |
| ... | @@ -4897,7 +4825,9 @@ fn genBinOp( | ... | @@ -4897,7 +4825,9 @@ fn genBinOp( |
| 4897 | .eflags, | 4825 | .eflags, |
| 4898 | .register_overflow, | 4826 | .register_overflow, |
| 4899 | .ptr_stack_offset, | 4827 | .ptr_stack_offset, |
| 4900 | .tlv_reloc, | 4828 | .load_got, |
| | 4829 | .lea_direct, |
| | 4830 | .lea_tlv, |
| 4901 | => unreachable, | 4831 | => unreachable, |
| 4902 | .register => |src_reg| try self.asmCmovccRegisterRegister( | 4832 | .register => |src_reg| try self.asmCmovccRegisterRegister( |
| 4903 | registerAlias(tmp_reg, cmov_abi_size), | 4833 | registerAlias(tmp_reg, cmov_abi_size), |
| ... | @@ -4912,31 +4842,17 @@ fn genBinOp( | ... | @@ -4912,31 +4842,17 @@ fn genBinOp( |
| 4912 | }), | 4842 | }), |
| 4913 | cc, | 4843 | cc, |
| 4914 | ), | 4844 | ), |
| 4915 | .memory, .linker_load => { | 4845 | .memory, .load_direct, .load_tlv => { |
| 4916 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 4846 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 4917 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 4847 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 4918 | defer self.register_manager.unlockReg(addr_reg_lock); | 4848 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 4919 | | 4849 | |
| 4920 | switch (mat_src_mcv) { | 4850 | try self.genSetReg(Type.usize, addr_reg, switch (mat_src_mcv) { |
| 4921 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 4851 | .memory => |addr| .{ .immediate = addr }, |
| 4922 | .linker_load => |load_struct| { | 4852 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 4923 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 4853 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 4924 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 4925 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 4926 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 4927 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 4928 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 4929 | } else unreachable; | | |
| 4930 | | | |
| 4931 | switch (load_struct.type) { | | |
| 4932 | .import => unreachable, | | |
| 4933 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 4934 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | | |
| 4935 | } | | |
| 4936 | }, | | |
| 4937 | else => unreachable, | 4854 | else => unreachable, |
| 4938 | } | 4855 | }); |
| 4939 | | | |
| 4940 | try self.asmCmovccRegisterMemory( | 4856 | try self.asmCmovccRegisterMemory( |
| 4941 | registerAlias(tmp_reg, cmov_abi_size), | 4857 | registerAlias(tmp_reg, cmov_abi_size), |
| 4942 | Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), .{ .base = addr_reg }), | 4858 | Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), .{ .base = addr_reg }), |
| ... | @@ -4982,13 +4898,6 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -4982,13 +4898,6 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 4982 | .undef => unreachable, | 4898 | .undef => unreachable, |
| 4983 | .dead, .unreach => unreachable, | 4899 | .dead, .unreach => unreachable, |
| 4984 | .register_overflow => unreachable, | 4900 | .register_overflow => unreachable, |
| 4985 | .ptr_stack_offset, .tlv_reloc => { | | |
| 4986 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); | | |
| 4987 | defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); | | |
| 4988 | | | |
| 4989 | const reg = try self.copyToTmpRegister(ty, src_mcv); | | |
| 4990 | return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .register = reg }); | | |
| 4991 | }, | | |
| 4992 | .register => |src_reg| switch (ty.zigTypeTag()) { | 4901 | .register => |src_reg| switch (ty.zigTypeTag()) { |
| 4993 | .Float => { | 4902 | .Float => { |
| 4994 | if (intrinsicsAllowed(self.target.*, ty)) { | 4903 | if (intrinsicsAllowed(self.target.*, ty)) { |
| ... | @@ -5037,7 +4946,15 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5037,7 +4946,15 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5037 | )), | 4946 | )), |
| 5038 | else => unreachable, | 4947 | else => unreachable, |
| 5039 | }, | 4948 | }, |
| 5040 | .memory, .linker_load, .eflags => { | 4949 | .ptr_stack_offset, |
| | 4950 | .memory, |
| | 4951 | .load_got, |
| | 4952 | .lea_direct, |
| | 4953 | .load_direct, |
| | 4954 | .lea_tlv, |
| | 4955 | .load_tlv, |
| | 4956 | .eflags, |
| | 4957 | => { |
| 5041 | assert(abi_size <= 8); | 4958 | assert(abi_size <= 8); |
| 5042 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); | 4959 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); |
| 5043 | defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); | 4960 | defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -5052,36 +4969,23 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5052,36 +4969,23 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5052 | ), | 4969 | ), |
| 5053 | } | 4970 | } |
| 5054 | }, | 4971 | }, |
| 5055 | .memory, .linker_load, .stack_offset => { | 4972 | .memory, .load_got, .load_direct, .load_tlv, .stack_offset => { |
| 5056 | const dst: ?struct { | 4973 | const dst: ?struct { |
| 5057 | addr_reg: Register, | 4974 | addr_reg: Register, |
| 5058 | addr_lock: RegisterLock, | 4975 | addr_lock: RegisterLock, |
| 5059 | } = switch (dst_mcv) { | 4976 | } = switch (dst_mcv) { |
| 5060 | else => unreachable, | 4977 | else => unreachable, |
| 5061 | .memory, .linker_load => dst: { | 4978 | .memory, .load_got, .load_direct, .load_tlv => dst: { |
| 5062 | const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 4979 | const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 5063 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); | 4980 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| 5064 | errdefer self.register_manager.unlockReg(dst_addr_lock); | 4981 | errdefer self.register_manager.unlockReg(dst_addr_lock); |
| 5065 | | 4982 | |
| 5066 | switch (dst_mcv) { | 4983 | try self.genSetReg(Type.usize, dst_addr_reg, switch (dst_mcv) { |
| 5067 | .memory => |addr| try self.genSetReg(Type.usize, dst_addr_reg, .{ .immediate = addr }), | 4984 | .memory => |addr| .{ .immediate = addr }, |
| 5068 | .linker_load => |load_struct| { | 4985 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 5069 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 4986 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 5070 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 4987 | else => dst_mcv, |
| 5071 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 4988 | }); |
| 5072 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 5073 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 5074 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 5075 | } else unreachable; | | |
| 5076 | | | |
| 5077 | switch (load_struct.type) { | | |
| 5078 | .import => unreachable, | | |
| 5079 | .got => try self.asmMovLinker(dst_addr_reg, atom_index, load_struct), | | |
| 5080 | .direct => try self.asmLeaLinker(dst_addr_reg, atom_index, load_struct), | | |
| 5081 | } | | |
| 5082 | }, | | |
| 5083 | else => unreachable, | | |
| 5084 | } | | |
| 5085 | | 4989 | |
| 5086 | break :dst .{ | 4990 | break :dst .{ |
| 5087 | .addr_reg = dst_addr_reg, | 4991 | .addr_reg = dst_addr_reg, |
| ... | @@ -5099,7 +5003,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5099,7 +5003,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5099 | addr_lock: RegisterLock, | 5003 | addr_lock: RegisterLock, |
| 5100 | } = switch (src_mcv) { | 5004 | } = switch (src_mcv) { |
| 5101 | else => null, | 5005 | else => null, |
| 5102 | .memory, .linker_load => src: { | 5006 | .memory, .load_got, .load_direct, .load_tlv => src: { |
| 5103 | const src_limb_reg = try self.register_manager.allocReg(null, gp); | 5007 | const src_limb_reg = try self.register_manager.allocReg(null, gp); |
| 5104 | const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); | 5008 | const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); |
| 5105 | errdefer self.register_manager.unlockReg(src_limb_lock); | 5009 | errdefer self.register_manager.unlockReg(src_limb_lock); |
| ... | @@ -5108,25 +5012,12 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5108,25 +5012,12 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5108 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); | 5012 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 5109 | errdefer self.register_manager.unlockReg(src_addr_lock); | 5013 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 5110 | | 5014 | |
| 5111 | switch (src_mcv) { | 5015 | try self.genSetReg(Type.usize, src_addr_reg, switch (src_mcv) { |
| 5112 | .memory => |addr| try self.genSetReg(Type.usize, src_addr_reg, .{ .immediate = addr }), | 5016 | .memory => |addr| .{ .immediate = addr }, |
| 5113 | .linker_load => |load_struct| { | 5017 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 5114 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 5018 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 5115 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 5019 | else => src_mcv, |
| 5116 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 5020 | }); |
| 5117 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 5118 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 5119 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 5120 | } else unreachable; | | |
| 5121 | | | |
| 5122 | switch (load_struct.type) { | | |
| 5123 | .import => unreachable, | | |
| 5124 | .got => try self.asmMovLinker(src_addr_reg, atom_index, load_struct), | | |
| 5125 | .direct => try self.asmLeaLinker(src_addr_reg, atom_index, load_struct), | | |
| 5126 | } | | |
| 5127 | }, | | |
| 5128 | else => unreachable, | | |
| 5129 | } | | |
| 5130 | | 5021 | |
| 5131 | break :src .{ | 5022 | break :src .{ |
| 5132 | .addr_reg = src_addr_reg, | 5023 | .addr_reg = src_addr_reg, |
| ... | @@ -5169,7 +5060,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5169,7 +5060,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5169 | .base = .rbp, | 5060 | .base = .rbp, |
| 5170 | .disp = off - dst_off, | 5061 | .disp = off - dst_off, |
| 5171 | }, | 5062 | }, |
| 5172 | .memory, .linker_load => .{ .base = dst.?.addr_reg, .disp = off }, | 5063 | .memory, |
| | 5064 | .load_got, |
| | 5065 | .load_direct, |
| | 5066 | .load_tlv, |
| | 5067 | => .{ .base = dst.?.addr_reg, .disp = off }, |
| 5173 | }, | 5068 | }, |
| 5174 | ); | 5069 | ); |
| 5175 | switch (src_mcv) { | 5070 | switch (src_mcv) { |
| ... | @@ -5233,7 +5128,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5233,7 +5128,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5233 | else => unreachable, | 5128 | else => unreachable, |
| 5234 | } | 5129 | } |
| 5235 | }, | 5130 | }, |
| 5236 | .memory, .linker_load, .tlv_reloc => { | 5131 | .memory, |
| | 5132 | .load_got, |
| | 5133 | .load_direct, |
| | 5134 | .load_tlv, |
| | 5135 | => { |
| 5237 | try self.asmRegisterMemory( | 5136 | try self.asmRegisterMemory( |
| 5238 | .mov, | 5137 | .mov, |
| 5239 | registerAlias(src.?.limb_reg, limb_abi_size), | 5138 | registerAlias(src.?.limb_reg, limb_abi_size), |
| ... | @@ -5248,11 +5147,19 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5248,11 +5147,19 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5248 | registerAlias(src.?.limb_reg, limb_abi_size), | 5147 | registerAlias(src.?.limb_reg, limb_abi_size), |
| 5249 | ); | 5148 | ); |
| 5250 | }, | 5149 | }, |
| 5251 | .stack_offset, .ptr_stack_offset, .eflags => { | 5150 | .stack_offset, |
| | 5151 | .ptr_stack_offset, |
| | 5152 | .eflags, |
| | 5153 | .lea_direct, |
| | 5154 | .lea_tlv, |
| | 5155 | => { |
| 5252 | const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) { | 5156 | const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) { |
| 5253 | .stack_offset => |src_off| .{ .stack_offset = src_off - off }, | 5157 | .stack_offset => |src_off| .{ .stack_offset = src_off - off }, |
| 5254 | .ptr_stack_offset, | 5158 | .ptr_stack_offset, |
| 5255 | .eflags, | 5159 | .eflags, |
| | 5160 | .load_got, |
| | 5161 | .lea_direct, |
| | 5162 | .lea_tlv, |
| 5256 | => off: { | 5163 | => off: { |
| 5257 | assert(off == 0); | 5164 | assert(off == 0); |
| 5258 | break :off src_mcv; | 5165 | break :off src_mcv; |
| ... | @@ -5272,7 +5179,8 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5272,7 +5179,8 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5272 | } | 5179 | } |
| 5273 | }, | 5180 | }, |
| 5274 | .ptr_stack_offset => unreachable, | 5181 | .ptr_stack_offset => unreachable, |
| 5275 | .tlv_reloc => unreachable, | 5182 | .lea_tlv => unreachable, |
| | 5183 | .lea_direct => unreachable, |
| 5276 | } | 5184 | } |
| 5277 | } | 5185 | } |
| 5278 | | 5186 | |
| ... | @@ -5286,7 +5194,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5286,7 +5194,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5286 | .dead, .unreach, .immediate => unreachable, | 5194 | .dead, .unreach, .immediate => unreachable, |
| 5287 | .eflags => unreachable, | 5195 | .eflags => unreachable, |
| 5288 | .ptr_stack_offset => unreachable, | 5196 | .ptr_stack_offset => unreachable, |
| 5289 | .tlv_reloc => unreachable, | 5197 | .lea_direct => unreachable, |
| | 5198 | .lea_tlv => unreachable, |
| 5290 | .register_overflow => unreachable, | 5199 | .register_overflow => unreachable, |
| 5291 | .register => |dst_reg| { | 5200 | .register => |dst_reg| { |
| 5292 | const dst_alias = registerAlias(dst_reg, abi_size); | 5201 | const dst_alias = registerAlias(dst_reg, abi_size); |
| ... | @@ -5298,7 +5207,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5298,7 +5207,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5298 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), | 5207 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), |
| 5299 | .dead, .unreach => unreachable, | 5208 | .dead, .unreach => unreachable, |
| 5300 | .ptr_stack_offset => unreachable, | 5209 | .ptr_stack_offset => unreachable, |
| 5301 | .tlv_reloc => unreachable, | 5210 | .lea_direct => unreachable, |
| | 5211 | .lea_tlv => unreachable, |
| 5302 | .register_overflow => unreachable, | 5212 | .register_overflow => unreachable, |
| 5303 | .register => |src_reg| try self.asmRegisterRegister( | 5213 | .register => |src_reg| try self.asmRegisterRegister( |
| 5304 | .imul, | 5214 | .imul, |
| ... | @@ -5325,12 +5235,13 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5325,12 +5235,13 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5325 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), | 5235 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), |
| 5326 | ); | 5236 | ); |
| 5327 | }, | 5237 | }, |
| 5328 | .memory => { | 5238 | .memory, |
| | 5239 | .load_got, |
| | 5240 | .load_direct, |
| | 5241 | .load_tlv, |
| | 5242 | => { |
| 5329 | return self.fail("TODO implement x86 multiply source memory", .{}); | 5243 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 5330 | }, | 5244 | }, |
| 5331 | .linker_load => { | | |
| 5332 | return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); | | |
| 5333 | }, | | |
| 5334 | .eflags => { | 5245 | .eflags => { |
| 5335 | return self.fail("TODO implement x86 multiply source eflags", .{}); | 5246 | return self.fail("TODO implement x86 multiply source eflags", .{}); |
| 5336 | }, | 5247 | }, |
| ... | @@ -5342,7 +5253,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5342,7 +5253,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5342 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), | 5253 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), |
| 5343 | .dead, .unreach => unreachable, | 5254 | .dead, .unreach => unreachable, |
| 5344 | .ptr_stack_offset => unreachable, | 5255 | .ptr_stack_offset => unreachable, |
| 5345 | .tlv_reloc => unreachable, | 5256 | .lea_direct => unreachable, |
| | 5257 | .lea_tlv => unreachable, |
| 5346 | .register_overflow => unreachable, | 5258 | .register_overflow => unreachable, |
| 5347 | .register => |src_reg| { | 5259 | .register => |src_reg| { |
| 5348 | // copy dst to a register | 5260 | // copy dst to a register |
| ... | @@ -5365,23 +5277,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5365,23 +5277,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5365 | | 5277 | |
| 5366 | return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{}); | 5278 | return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{}); |
| 5367 | }, | 5279 | }, |
| 5368 | .memory, .stack_offset => { | 5280 | .memory, |
| | 5281 | .load_got, |
| | 5282 | .load_direct, |
| | 5283 | .load_tlv, |
| | 5284 | .stack_offset, |
| | 5285 | => { |
| 5369 | return self.fail("TODO implement x86 multiply source memory", .{}); | 5286 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 5370 | }, | 5287 | }, |
| 5371 | .linker_load => { | | |
| 5372 | return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); | | |
| 5373 | }, | | |
| 5374 | .eflags => { | 5288 | .eflags => { |
| 5375 | return self.fail("TODO implement x86 multiply source eflags", .{}); | 5289 | return self.fail("TODO implement x86 multiply source eflags", .{}); |
| 5376 | }, | 5290 | }, |
| 5377 | } | 5291 | } |
| 5378 | }, | 5292 | }, |
| 5379 | .memory => { | 5293 | .memory, |
| | 5294 | .load_got, |
| | 5295 | .load_direct, |
| | 5296 | .load_tlv, |
| | 5297 | => { |
| 5380 | return self.fail("TODO implement x86 multiply destination memory", .{}); | 5298 | return self.fail("TODO implement x86 multiply destination memory", .{}); |
| 5381 | }, | 5299 | }, |
| 5382 | .linker_load => { | | |
| 5383 | return self.fail("TODO implement x86 multiply destination symbol at index in linker", .{}); | | |
| 5384 | }, | | |
| 5385 | } | 5300 | } |
| 5386 | } | 5301 | } |
| 5387 | | 5302 | |
| ... | @@ -5461,7 +5376,8 @@ fn genVarDbgInfo( | ... | @@ -5461,7 +5376,8 @@ fn genVarDbgInfo( |
| 5461 | .offset = -off, | 5376 | .offset = -off, |
| 5462 | } }, | 5377 | } }, |
| 5463 | .memory => |address| .{ .memory = address }, | 5378 | .memory => |address| .{ .memory = address }, |
| 5464 | .linker_load => |linker_load| .{ .linker_load = linker_load }, | 5379 | .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } }, |
| | 5380 | .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, |
| 5465 | .immediate => |x| .{ .immediate = x }, | 5381 | .immediate => |x| .{ .immediate = x }, |
| 5466 | .undef => .undef, | 5382 | .undef => .undef, |
| 5467 | .none => .none, | 5383 | .none => .none, |
| ... | @@ -5562,10 +5478,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5562,10 +5478,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5562 | .unreach => unreachable, | 5478 | .unreach => unreachable, |
| 5563 | .dead => unreachable, | 5479 | .dead => unreachable, |
| 5564 | .memory => unreachable, | 5480 | .memory => unreachable, |
| 5565 | .linker_load => unreachable, | | |
| 5566 | .eflags => unreachable, | 5481 | .eflags => unreachable, |
| 5567 | .register_overflow => unreachable, | 5482 | .register_overflow => unreachable, |
| 5568 | .tlv_reloc => unreachable, | 5483 | .load_got => unreachable, |
| | 5484 | .lea_direct => unreachable, |
| | 5485 | .load_direct => unreachable, |
| | 5486 | .lea_tlv => unreachable, |
| | 5487 | .load_tlv => unreachable, |
| 5569 | } | 5488 | } |
| 5570 | } | 5489 | } |
| 5571 | | 5490 | |
| ... | @@ -5601,10 +5520,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5601,10 +5520,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5601 | .unreach => unreachable, | 5520 | .unreach => unreachable, |
| 5602 | .dead => unreachable, | 5521 | .dead => unreachable, |
| 5603 | .memory => unreachable, | 5522 | .memory => unreachable, |
| 5604 | .linker_load => unreachable, | | |
| 5605 | .eflags => unreachable, | 5523 | .eflags => unreachable, |
| 5606 | .register_overflow => unreachable, | 5524 | .register_overflow => unreachable, |
| 5607 | .tlv_reloc => unreachable, | 5525 | .load_got => unreachable, |
| | 5526 | .lea_direct => unreachable, |
| | 5527 | .load_direct => unreachable, |
| | 5528 | .lea_tlv => unreachable, |
| | 5529 | .load_tlv => unreachable, |
| 5608 | } | 5530 | } |
| 5609 | } | 5531 | } |
| 5610 | | 5532 | |
| ... | @@ -5627,21 +5549,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5627,21 +5549,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5627 | .base = .ds, | 5549 | .base = .ds, |
| 5628 | .disp = @intCast(i32, got_addr), | 5550 | .disp = @intCast(i32, got_addr), |
| 5629 | })); | 5551 | })); |
| 5630 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 5552 | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| 5631 | const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl); | 5553 | const sym_index = try self.getSymbolIndexForDecl(func.owner_decl); |
| 5632 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 5554 | try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index }); |
| 5633 | try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ | | |
| 5634 | .type = .got, | | |
| 5635 | .sym_index = sym_index, | | |
| 5636 | } }); | | |
| 5637 | try self.asmRegister(.call, .rax); | 5555 | try self.asmRegister(.call, .rax); |
| 5638 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 5556 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 5639 | const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl); | 5557 | const sym_index = try self.getSymbolIndexForDecl(func.owner_decl); |
| 5640 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; | 5558 | try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index }); |
| 5641 | try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ | | |
| 5642 | .type = .got, | | |
| 5643 | .sym_index = sym_index, | | |
| 5644 | } }); | | |
| 5645 | try self.asmRegister(.call, .rax); | 5559 | try self.asmRegister(.call, .rax); |
| 5646 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 5560 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 5647 | const decl_block_index = try p9.seeDecl(func.owner_decl); | 5561 | const decl_block_index = try p9.seeDecl(func.owner_decl); |
| ... | @@ -5661,18 +5575,21 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5661,18 +5575,21 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5661 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); | 5575 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); |
| 5662 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); | 5576 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); |
| 5663 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 5577 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| | 5578 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| 5664 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); | 5579 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); |
| 5665 | try self.genSetReg(Type.usize, .rax, .{ | 5580 | _ = try self.addInst(.{ |
| 5666 | .linker_load = .{ | 5581 | .tag = .mov_linker, |
| 5667 | .type = .import, | 5582 | .ops = .import_reloc, |
| | 5583 | .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{ |
| | 5584 | .reg = @enumToInt(Register.rax), |
| | 5585 | .atom_index = atom_index, |
| 5668 | .sym_index = sym_index, | 5586 | .sym_index = sym_index, |
| 5669 | }, | 5587 | }) }, |
| 5670 | }); | 5588 | }); |
| 5671 | try self.asmRegister(.call, .rax); | 5589 | try self.asmRegister(.call, .rax); |
| 5672 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 5590 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 5673 | const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); | 5591 | const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); |
| 5674 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 5592 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| 5675 | const atom_index = macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 5676 | _ = try self.addInst(.{ | 5593 | _ = try self.addInst(.{ |
| 5677 | .tag = .call_extern, | 5594 | .tag = .call_extern, |
| 5678 | .ops = undefined, | 5595 | .ops = undefined, |
| ... | @@ -5871,20 +5788,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5871,20 +5788,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 5871 | 4, // dword alignment | 5788 | 4, // dword alignment |
| 5872 | ); | 5789 | ); |
| 5873 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 5790 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 5874 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ | 5791 | try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index }); |
| 5875 | .type = .got, | | |
| 5876 | .sym_index = sym_index, | | |
| 5877 | } }); | | |
| 5878 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 5792 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 5879 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( | 5793 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( |
| 5880 | .{ .kind = .const_data, .ty = Type.anyerror }, | 5794 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| 5881 | 4, // dword alignment | 5795 | 4, // dword alignment |
| 5882 | ); | 5796 | ); |
| 5883 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; | 5797 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| 5884 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ | 5798 | try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index }); |
| 5885 | .type = .got, | | |
| 5886 | .sym_index = sym_index, | | |
| 5887 | } }); | | |
| 5888 | } else { | 5799 | } else { |
| 5889 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); | 5800 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); |
| 5890 | } | 5801 | } |
| ... | @@ -6126,7 +6037,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -6126,7 +6037,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6126 | .register_overflow, | 6037 | .register_overflow, |
| 6127 | .ptr_stack_offset, | 6038 | .ptr_stack_offset, |
| 6128 | .eflags, | 6039 | .eflags, |
| 6129 | .tlv_reloc, | 6040 | .lea_direct, |
| | 6041 | .lea_tlv, |
| 6130 | => unreachable, | 6042 | => unreachable, |
| 6131 | | 6043 | |
| 6132 | .register => |opt_reg| { | 6044 | .register => |opt_reg| { |
| ... | @@ -6147,30 +6059,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -6147,30 +6059,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6147 | return .{ .eflags = .nc }; | 6059 | return .{ .eflags = .nc }; |
| 6148 | }, | 6060 | }, |
| 6149 | | 6061 | |
| 6150 | .memory, .linker_load => { | 6062 | .memory, |
| | 6063 | .load_got, |
| | 6064 | .load_direct, |
| | 6065 | .load_tlv, |
| | 6066 | => { |
| 6151 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 6067 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 6152 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 6068 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 6153 | defer self.register_manager.unlockReg(addr_reg_lock); | 6069 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 6154 | | 6070 | |
| 6155 | switch (opt_mcv) { | 6071 | try self.genSetReg(Type.usize, addr_reg, switch (opt_mcv) { |
| 6156 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 6072 | .memory => |addr| .{ .immediate = addr }, |
| 6157 | .linker_load => |load_struct| { | 6073 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 6158 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 6074 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 6159 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 6075 | else => opt_mcv, |
| 6160 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 6076 | }); |
| 6161 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 6162 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 6163 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 6164 | } else unreachable; | | |
| 6165 | | | |
| 6166 | switch (load_struct.type) { | | |
| 6167 | .import => unreachable, | | |
| 6168 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 6169 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | | |
| 6170 | } | | |
| 6171 | }, | | |
| 6172 | else => unreachable, | | |
| 6173 | } | | |
| 6174 | | 6077 | |
| 6175 | const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); | 6078 | const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); |
| 6176 | try self.asmMemoryImmediate(.cmp, Memory.sib( | 6079 | try self.asmMemoryImmediate(.cmp, Memory.sib( |
| ... | @@ -7099,7 +7002,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -7099,7 +7002,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7099 | else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}), | 7002 | else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}), |
| 7100 | } | 7003 | } |
| 7101 | }, | 7004 | }, |
| 7102 | .memory, .linker_load => { | 7005 | .memory, |
| | 7006 | .load_direct, |
| | 7007 | .load_tlv, |
| | 7008 | => { |
| 7103 | if (abi_size <= 8) { | 7009 | if (abi_size <= 8) { |
| 7104 | const reg = try self.copyToTmpRegister(ty, mcv); | 7010 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7105 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 7011 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| ... | @@ -7109,26 +7015,12 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -7109,26 +7015,12 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7109 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 7015 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7110 | defer self.register_manager.unlockReg(addr_lock); | 7016 | defer self.register_manager.unlockReg(addr_lock); |
| 7111 | | 7017 | |
| 7112 | switch (mcv) { | 7018 | try self.genSetReg(Type.usize, addr_reg, switch (mcv) { |
| 7113 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 7019 | .memory => |addr| .{ .immediate = addr }, |
| 7114 | .linker_load => |load_struct| { | 7020 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 7115 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7021 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 7116 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7117 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 7118 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 7119 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7120 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 7121 | } else unreachable; | | |
| 7122 | | | |
| 7123 | switch (load_struct.type) { | | |
| 7124 | .import => unreachable, | | |
| 7125 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 7126 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | | |
| 7127 | } | | |
| 7128 | }, | | |
| 7129 | else => unreachable, | 7022 | else => unreachable, |
| 7130 | } | 7023 | }); |
| 7131 | | | |
| 7132 | try self.genInlineMemcpy( | 7024 | try self.genInlineMemcpy( |
| 7133 | .{ .ptr_stack_offset = stack_offset }, | 7025 | .{ .ptr_stack_offset = stack_offset }, |
| 7134 | .{ .register = addr_reg }, | 7026 | .{ .register = addr_reg }, |
| ... | @@ -7170,7 +7062,11 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -7170,7 +7062,11 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7170 | }, | 7062 | }, |
| 7171 | } | 7063 | } |
| 7172 | }, | 7064 | }, |
| 7173 | .ptr_stack_offset, .tlv_reloc => { | 7065 | .ptr_stack_offset, |
| | 7066 | .load_got, |
| | 7067 | .lea_direct, |
| | 7068 | .lea_tlv, |
| | 7069 | => { |
| 7174 | const reg = try self.copyToTmpRegister(ty, mcv); | 7070 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7175 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 7071 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 7176 | }, | 7072 | }, |
| ... | @@ -7328,7 +7224,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7328,7 +7224,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7328 | }, | 7224 | }, |
| 7329 | } | 7225 | } |
| 7330 | }, | 7226 | }, |
| 7331 | .memory, .linker_load => if (abi_size <= 8) { | 7227 | .memory, |
| | 7228 | .load_direct, |
| | 7229 | .load_tlv, |
| | 7230 | .lea_direct, |
| | 7231 | .lea_tlv, |
| | 7232 | => if (abi_size <= 8) { |
| 7332 | const reg = try self.copyToTmpRegister(ty, mcv); | 7233 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7333 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); | 7234 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); |
| 7334 | } else { | 7235 | } else { |
| ... | @@ -7336,26 +7237,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7336,26 +7237,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7336 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 7237 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7337 | defer self.register_manager.unlockReg(addr_lock); | 7238 | defer self.register_manager.unlockReg(addr_lock); |
| 7338 | | 7239 | |
| 7339 | switch (mcv) { | 7240 | try self.genSetReg(Type.usize, addr_reg, switch (mcv) { |
| 7340 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 7241 | .memory => |addr| .{ .immediate = addr }, |
| 7341 | .linker_load => |load_struct| { | 7242 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 7342 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7243 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 7343 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7244 | else => mcv, |
| 7344 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 7245 | }); |
| 7345 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 7346 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7347 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 7348 | } else unreachable; | | |
| 7349 | | | |
| 7350 | switch (load_struct.type) { | | |
| 7351 | .import => unreachable, | | |
| 7352 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | | |
| 7353 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | | |
| 7354 | } | | |
| 7355 | }, | | |
| 7356 | else => unreachable, | | |
| 7357 | } | | |
| 7358 | | | |
| 7359 | try self.genInlineMemcpy( | 7246 | try self.genInlineMemcpy( |
| 7360 | .{ .ptr_stack_offset = stack_offset }, | 7247 | .{ .ptr_stack_offset = stack_offset }, |
| 7361 | .{ .register = addr_reg }, | 7248 | .{ .register = addr_reg }, |
| ... | @@ -7375,7 +7262,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7375,7 +7262,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7375 | .{ .immediate = abi_size }, | 7262 | .{ .immediate = abi_size }, |
| 7376 | .{}, | 7263 | .{}, |
| 7377 | ), | 7264 | ), |
| 7378 | .ptr_stack_offset, .tlv_reloc => { | 7265 | .ptr_stack_offset, |
| | 7266 | .load_got, |
| | 7267 | => { |
| 7379 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); | 7268 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); |
| 7380 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7269 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7381 | defer self.register_manager.unlockReg(tmp_lock); | 7270 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -7465,26 +7354,27 @@ fn genInlineMemcpy( | ... | @@ -7465,26 +7354,27 @@ fn genInlineMemcpy( |
| 7465 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); | 7354 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); |
| 7466 | | 7355 | |
| 7467 | switch (dst_ptr) { | 7356 | switch (dst_ptr) { |
| 7468 | .memory => |addr| { | 7357 | .lea_tlv, |
| 7469 | try self.genSetReg(Type.usize, .rdi, .{ .immediate = addr }); | 7358 | .load_tlv, |
| | 7359 | => { |
| | 7360 | try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) { |
| | 7361 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 7362 | else => dst_ptr, |
| | 7363 | }); |
| | 7364 | }, |
| | 7365 | .memory, |
| | 7366 | .load_got, |
| | 7367 | .lea_direct, |
| | 7368 | .load_direct, |
| | 7369 | => { |
| | 7370 | try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) { |
| | 7371 | .memory => |addr| .{ .immediate = addr }, |
| | 7372 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| | 7373 | else => dst_ptr, |
| | 7374 | }); |
| 7470 | // Load the pointer, which is stored in memory | 7375 | // Load the pointer, which is stored in memory |
| 7471 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); | 7376 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| 7472 | }, | 7377 | }, |
| 7473 | .linker_load => |load_struct| { | | |
| 7474 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | | |
| 7475 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7476 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 7477 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 7478 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7479 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 7480 | } else unreachable; | | |
| 7481 | | | |
| 7482 | switch (load_struct.type) { | | |
| 7483 | .import => unreachable, | | |
| 7484 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), | | |
| 7485 | } | | |
| 7486 | }, | | |
| 7487 | .tlv_reloc => try self.genSetReg(Type.usize, .rdi, dst_ptr), | | |
| 7488 | .stack_offset, .ptr_stack_offset => |off| { | 7378 | .stack_offset, .ptr_stack_offset => |off| { |
| 7489 | try self.asmRegisterMemory(switch (dst_ptr) { | 7379 | try self.asmRegisterMemory(switch (dst_ptr) { |
| 7490 | .stack_offset => .mov, | 7380 | .stack_offset => .mov, |
| ... | @@ -7508,26 +7398,27 @@ fn genInlineMemcpy( | ... | @@ -7508,26 +7398,27 @@ fn genInlineMemcpy( |
| 7508 | } | 7398 | } |
| 7509 | | 7399 | |
| 7510 | switch (src_ptr) { | 7400 | switch (src_ptr) { |
| 7511 | .memory => |addr| { | 7401 | .lea_tlv, |
| 7512 | try self.genSetReg(Type.usize, .rsi, .{ .immediate = addr }); | 7402 | .load_tlv, |
| | 7403 | => { |
| | 7404 | try self.genSetReg(Type.usize, .rsi, switch (src_ptr) { |
| | 7405 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 7406 | else => dst_ptr, |
| | 7407 | }); |
| | 7408 | }, |
| | 7409 | .memory, |
| | 7410 | .load_got, |
| | 7411 | .lea_direct, |
| | 7412 | .load_direct, |
| | 7413 | => { |
| | 7414 | try self.genSetReg(Type.usize, .rsi, switch (src_ptr) { |
| | 7415 | .memory => |addr| .{ .immediate = addr }, |
| | 7416 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| | 7417 | else => src_ptr, |
| | 7418 | }); |
| 7513 | // Load the pointer, which is stored in memory | 7419 | // Load the pointer, which is stored in memory |
| 7514 | try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi })); | 7420 | try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi })); |
| 7515 | }, | 7421 | }, |
| 7516 | .linker_load => |load_struct| { | | |
| 7517 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | | |
| 7518 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7519 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 7520 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 7521 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7522 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 7523 | } else unreachable; | | |
| 7524 | | | |
| 7525 | switch (load_struct.type) { | | |
| 7526 | .import => unreachable, | | |
| 7527 | .got, .direct => try self.asmMovLinker(.rsi, atom_index, load_struct), | | |
| 7528 | } | | |
| 7529 | }, | | |
| 7530 | .tlv_reloc => try self.genSetReg(Type.usize, .rsi, src_ptr), | | |
| 7531 | .stack_offset, .ptr_stack_offset => |off| { | 7422 | .stack_offset, .ptr_stack_offset => |off| { |
| 7532 | try self.asmRegisterMemory(switch (src_ptr) { | 7423 | try self.asmRegisterMemory(switch (src_ptr) { |
| 7533 | .stack_offset => .mov, | 7424 | .stack_offset => .mov, |
| ... | @@ -7574,26 +7465,27 @@ fn genInlineMemset( | ... | @@ -7574,26 +7465,27 @@ fn genInlineMemset( |
| 7574 | try self.spillRegisters(&.{ .rdi, .al, .rcx }); | 7465 | try self.spillRegisters(&.{ .rdi, .al, .rcx }); |
| 7575 | | 7466 | |
| 7576 | switch (dst_ptr) { | 7467 | switch (dst_ptr) { |
| 7577 | .memory => |addr| { | 7468 | .lea_tlv, |
| 7578 | try self.genSetReg(Type.usize, .rdi, .{ .immediate = addr }); | 7469 | .load_tlv, |
| | 7470 | => { |
| | 7471 | try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) { |
| | 7472 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 7473 | else => dst_ptr, |
| | 7474 | }); |
| | 7475 | }, |
| | 7476 | .load_got => try self.genSetReg(Type.usize, .rdi, dst_ptr), |
| | 7477 | .memory, |
| | 7478 | .lea_direct, |
| | 7479 | .load_direct, |
| | 7480 | => { |
| | 7481 | try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) { |
| | 7482 | .memory => |addr| .{ .immediate = addr }, |
| | 7483 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| | 7484 | else => dst_ptr, |
| | 7485 | }); |
| 7579 | // Load the pointer, which is stored in memory | 7486 | // Load the pointer, which is stored in memory |
| 7580 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); | 7487 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| 7581 | }, | 7488 | }, |
| 7582 | .linker_load => |load_struct| { | | |
| 7583 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | | |
| 7584 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7585 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 7586 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 7587 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7588 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 7589 | } else unreachable; | | |
| 7590 | | | |
| 7591 | switch (load_struct.type) { | | |
| 7592 | .import => unreachable, | | |
| 7593 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), | | |
| 7594 | } | | |
| 7595 | }, | | |
| 7596 | .tlv_reloc => try self.genSetReg(Type.usize, .rdi, dst_ptr), | | |
| 7597 | .stack_offset, .ptr_stack_offset => |off| { | 7489 | .stack_offset, .ptr_stack_offset => |off| { |
| 7598 | try self.asmRegisterMemory(switch (dst_ptr) { | 7490 | try self.asmRegisterMemory(switch (dst_ptr) { |
| 7599 | .stack_offset => .mov, | 7491 | .stack_offset => .mov, |
| ... | @@ -7769,43 +7661,31 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -7769,43 +7661,31 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 7769 | } | 7661 | } |
| 7770 | }, | 7662 | }, |
| 7771 | }, | 7663 | }, |
| 7772 | .tlv_reloc => |sym_index| { | 7664 | .load_got, .lea_direct => |sym_index| { |
| 7773 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7665 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| 7774 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7666 | _ = try self.addInst(.{ |
| 7775 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 7667 | .tag = switch (mcv) { |
| 7776 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | 7668 | .load_got => .mov_linker, |
| 7777 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7669 | .lea_direct => .lea_linker, |
| 7778 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | 7670 | else => unreachable, |
| 7779 | } else unreachable; | 7671 | }, |
| 7780 | | 7672 | .ops = switch (mcv) { |
| 7781 | if (self.bin_file.cast(link.File.MachO)) |_| { | 7673 | .load_got => .got_reloc, |
| 7782 | _ = try self.addInst(.{ | 7674 | .lea_direct => .direct_reloc, |
| 7783 | .tag = .mov_linker, | 7675 | else => unreachable, |
| 7784 | .ops = .tlv_reloc, | 7676 | }, |
| 7785 | .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{ | 7677 | .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{ |
| 7786 | .reg = @enumToInt(Register.rdi), | 7678 | .reg = @enumToInt(reg), |
| 7787 | .atom_index = atom_index, | 7679 | .atom_index = atom_index, |
| 7788 | .sym_index = sym_index, | 7680 | .sym_index = sym_index, |
| 7789 | }) }, | 7681 | }) }, |
| 7790 | }); | 7682 | }); |
| 7791 | // TODO: spill registers before calling | | |
| 7792 | try self.asmMemory(.call, Memory.sib(.qword, .{ .base = .rdi })); | | |
| 7793 | try self.genSetReg(Type.usize, reg, .{ .register = .rax }); | | |
| 7794 | } else return self.fail("TODO emit ptr to TLV sequence on {s}", .{@tagName(self.bin_file.tag)}); | | |
| 7795 | }, | 7683 | }, |
| 7796 | .linker_load => |load_struct| { | 7684 | .load_direct => |sym_index| { |
| 7797 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | | |
| 7798 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7799 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 7800 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | | |
| 7801 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | | |
| 7802 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | | |
| 7803 | } else unreachable; | | |
| 7804 | | | |
| 7805 | switch (ty.zigTypeTag()) { | 7685 | switch (ty.zigTypeTag()) { |
| 7806 | .Float => { | 7686 | .Float => { |
| 7807 | const base_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 7687 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 7808 | try self.asmLeaLinker(base_reg, atom_index, load_struct); | 7688 | try self.genSetReg(Type.usize, addr_reg, .{ .lea_direct = sym_index }); |
| 7809 | | 7689 | |
| 7810 | if (intrinsicsAllowed(self.target.*, ty)) { | 7690 | if (intrinsicsAllowed(self.target.*, ty)) { |
| 7811 | return self.asmRegisterMemory( | 7691 | return self.asmRegisterMemory( |
| ... | @@ -7817,13 +7697,68 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -7817,13 +7697,68 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 7817 | }), | 7697 | }), |
| 7818 | }, | 7698 | }, |
| 7819 | reg.to128(), | 7699 | reg.to128(), |
| 7820 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg.to64() }), | 7700 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), |
| 7821 | ); | 7701 | ); |
| 7822 | } | 7702 | } |
| 7823 | | 7703 | |
| 7824 | return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); | 7704 | return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); |
| 7825 | }, | 7705 | }, |
| 7826 | else => try self.asmMovLinker(registerAlias(reg, abi_size), atom_index, load_struct), | 7706 | else => { |
| | 7707 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| | 7708 | _ = try self.addInst(.{ |
| | 7709 | .tag = .mov_linker, |
| | 7710 | .ops = .direct_reloc, |
| | 7711 | .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{ |
| | 7712 | .reg = @enumToInt(registerAlias(reg, abi_size)), |
| | 7713 | .atom_index = atom_index, |
| | 7714 | .sym_index = sym_index, |
| | 7715 | }) }, |
| | 7716 | }); |
| | 7717 | }, |
| | 7718 | } |
| | 7719 | }, |
| | 7720 | .lea_tlv => |sym_index| { |
| | 7721 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| | 7722 | if (self.bin_file.cast(link.File.MachO)) |_| { |
| | 7723 | _ = try self.addInst(.{ |
| | 7724 | .tag = .mov_linker, |
| | 7725 | .ops = .tlv_reloc, |
| | 7726 | .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{ |
| | 7727 | .reg = @enumToInt(Register.rdi), |
| | 7728 | .atom_index = atom_index, |
| | 7729 | .sym_index = sym_index, |
| | 7730 | }) }, |
| | 7731 | }); |
| | 7732 | // TODO: spill registers before calling |
| | 7733 | try self.asmMemory(.call, Memory.sib(.qword, .{ .base = .rdi })); |
| | 7734 | try self.genSetReg(Type.usize, reg, .{ .register = .rax }); |
| | 7735 | } else return self.fail("TODO emit ptr to TLV sequence on {s}", .{@tagName(self.bin_file.tag)}); |
| | 7736 | }, |
| | 7737 | .load_tlv => |sym_index| { |
| | 7738 | const base_reg = switch (ty.zigTypeTag()) { |
| | 7739 | .Float => (try self.register_manager.allocReg(null, gp)).to64(), |
| | 7740 | else => reg.to64(), |
| | 7741 | }; |
| | 7742 | try self.genSetReg(Type.usize, base_reg, .{ .lea_tlv = sym_index }); |
| | 7743 | switch (ty.zigTypeTag()) { |
| | 7744 | .Float => if (intrinsicsAllowed(self.target.*, ty)) { |
| | 7745 | return self.asmRegisterMemory( |
| | 7746 | switch (ty.tag()) { |
| | 7747 | .f32 => .movss, |
| | 7748 | .f64 => .movsd, |
| | 7749 | else => return self.fail("TODO genSetReg from memory for {}", .{ |
| | 7750 | ty.fmt(self.bin_file.options.module.?), |
| | 7751 | }), |
| | 7752 | }, |
| | 7753 | reg.to128(), |
| | 7754 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg }), |
| | 7755 | ); |
| | 7756 | } else return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}), |
| | 7757 | else => try self.asmRegisterMemory( |
| | 7758 | .mov, |
| | 7759 | registerAlias(reg, abi_size), |
| | 7760 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg }), |
| | 7761 | ), |
| 7827 | } | 7762 | } |
| 7828 | }, | 7763 | }, |
| 7829 | .stack_offset => |off| { | 7764 | .stack_offset => |off| { |
| ... | @@ -8464,20 +8399,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8464,20 +8399,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 8464 | 4, // dword alignment | 8399 | 4, // dword alignment |
| 8465 | ); | 8400 | ); |
| 8466 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 8401 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 8467 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ | 8402 | try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index }); |
| 8468 | .type = .got, | | |
| 8469 | .sym_index = sym_index, | | |
| 8470 | } }); | | |
| 8471 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 8403 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 8472 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( | 8404 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( |
| 8473 | .{ .kind = .const_data, .ty = Type.anyerror }, | 8405 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| 8474 | 4, // dword alignment | 8406 | 4, // dword alignment |
| 8475 | ); | 8407 | ); |
| 8476 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; | 8408 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| 8477 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ | 8409 | try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index }); |
| 8478 | .type = .got, | | |
| 8479 | .sym_index = sym_index, | | |
| 8480 | } }); | | |
| 8481 | } else { | 8410 | } else { |
| 8482 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); | 8411 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); |
| 8483 | } | 8412 | } |
| ... | @@ -8586,7 +8515,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8586,7 +8515,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8586 | const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size); | 8515 | const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size); |
| 8587 | const elem_bit_off = elem_off % elem_abi_bits; | 8516 | const elem_bit_off = elem_off % elem_abi_bits; |
| 8588 | const elem_mcv = try self.resolveInst(elem); | 8517 | const elem_mcv = try self.resolveInst(elem); |
| 8589 | const elem_lock = switch (elem_mcv) { | 8518 | const mat_elem_mcv = switch (elem_mcv) { |
| | 8519 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| | 8520 | else => elem_mcv, |
| | 8521 | }; |
| | 8522 | const elem_lock = switch (mat_elem_mcv) { |
| 8590 | .register => |reg| self.register_manager.lockReg(reg), | 8523 | .register => |reg| self.register_manager.lockReg(reg), |
| 8591 | .immediate => |imm| lock: { | 8524 | .immediate => |imm| lock: { |
| 8592 | if (imm == 0) continue; | 8525 | if (imm == 0) continue; |
| ... | @@ -8596,7 +8529,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8596,7 +8529,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8596 | }; | 8529 | }; |
| 8597 | defer if (elem_lock) |lock| self.register_manager.unlockReg(lock); | 8530 | defer if (elem_lock) |lock| self.register_manager.unlockReg(lock); |
| 8598 | const elem_reg = registerAlias( | 8531 | const elem_reg = registerAlias( |
| 8599 | try self.copyToTmpRegister(elem_ty, elem_mcv), | 8532 | try self.copyToTmpRegister(elem_ty, mat_elem_mcv), |
| 8600 | elem_abi_size, | 8533 | elem_abi_size, |
| 8601 | ); | 8534 | ); |
| 8602 | const elem_extra_bits = self.regExtraBits(elem_ty); | 8535 | const elem_extra_bits = self.regExtraBits(elem_ty); |
| ... | @@ -8616,7 +8549,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8616,7 +8549,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8616 | .{ .register = elem_reg }, | 8549 | .{ .register = elem_reg }, |
| 8617 | ); | 8550 | ); |
| 8618 | if (elem_bit_off > elem_extra_bits) { | 8551 | if (elem_bit_off > elem_extra_bits) { |
| 8619 | const reg = try self.copyToTmpRegister(elem_ty, elem_mcv); | 8552 | const reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv); |
| 8620 | if (elem_extra_bits > 0) { | 8553 | if (elem_extra_bits > 0) { |
| 8621 | try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size)); | 8554 | try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size)); |
| 8622 | } | 8555 | } |
| ... | @@ -8641,7 +8574,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8641,7 +8574,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8641 | const elem_ty = result_ty.structFieldType(elem_i); | 8574 | const elem_ty = result_ty.structFieldType(elem_i); |
| 8642 | const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*)); | 8575 | const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*)); |
| 8643 | const elem_mcv = try self.resolveInst(elem); | 8576 | const elem_mcv = try self.resolveInst(elem); |
| 8644 | try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{}); | 8577 | const mat_elem_mcv = switch (elem_mcv) { |
| | 8578 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| | 8579 | else => elem_mcv, |
| | 8580 | }; |
| | 8581 | try self.genSetStack(elem_ty, stack_offset - elem_off, mat_elem_mcv, .{}); |
| 8645 | } | 8582 | } |
| 8646 | break :res .{ .stack_offset = stack_offset }; | 8583 | break :res .{ .stack_offset = stack_offset }; |
| 8647 | }, | 8584 | }, |
| ... | @@ -8652,8 +8589,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8652,8 +8589,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8652 | | 8589 | |
| 8653 | for (elements, 0..) |elem, elem_i| { | 8590 | for (elements, 0..) |elem, elem_i| { |
| 8654 | const elem_mcv = try self.resolveInst(elem); | 8591 | const elem_mcv = try self.resolveInst(elem); |
| | 8592 | const mat_elem_mcv = switch (elem_mcv) { |
| | 8593 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| | 8594 | else => elem_mcv, |
| | 8595 | }; |
| 8655 | const elem_off = @intCast(i32, elem_size * elem_i); | 8596 | const elem_off = @intCast(i32, elem_size * elem_i); |
| 8656 | try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{}); | 8597 | try self.genSetStack(elem_ty, stack_offset - elem_off, mat_elem_mcv, .{}); |
| 8657 | } | 8598 | } |
| 8658 | break :res MCValue{ .stack_offset = stack_offset }; | 8599 | break :res MCValue{ .stack_offset = stack_offset }; |
| 8659 | }, | 8600 | }, |
| ... | @@ -8776,10 +8717,11 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { | ... | @@ -8776,10 +8717,11 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 8776 | .mcv => |mcv| switch (mcv) { | 8717 | .mcv => |mcv| switch (mcv) { |
| 8777 | .none => .none, | 8718 | .none => .none, |
| 8778 | .undef => .undef, | 8719 | .undef => .undef, |
| 8779 | .linker_load => |ll| .{ .linker_load = ll }, | | |
| 8780 | .immediate => |imm| .{ .immediate = imm }, | 8720 | .immediate => |imm| .{ .immediate = imm }, |
| 8781 | .memory => |addr| .{ .memory = addr }, | 8721 | .memory => |addr| .{ .memory = addr }, |
| 8782 | .tlv_reloc => |sym_index| .{ .tlv_reloc = sym_index }, | 8722 | .load_direct => |sym_index| .{ .load_direct = sym_index }, |
| | 8723 | .load_got => |sym_index| .{ .load_got = sym_index }, |
| | 8724 | .load_tlv => |sym_index| .{ .load_tlv = sym_index }, |
| 8783 | }, | 8725 | }, |
| 8784 | .fail => |msg| { | 8726 | .fail => |msg| { |
| 8785 | self.err_msg = msg; | 8727 | self.err_msg = msg; |
| ... | @@ -9077,3 +9019,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool { | ... | @@ -9077,3 +9019,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool { |
| 9077 | fn hasAvxSupport(target: Target) bool { | 9019 | fn hasAvxSupport(target: Target) bool { |
| 9078 | return Target.x86.featureSetHasAny(target.cpu.features, .{ .avx, .avx2 }); | 9020 | return Target.x86.featureSetHasAny(target.cpu.features, .{ .avx, .avx2 }); |
| 9079 | } | 9021 | } |
| | 9022 | |
| | 9023 | fn getSymbolIndexForDecl(self: *Self, decl_index: Module.Decl.Index) !u32 { |
| | 9024 | if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| | 9025 | const atom = try macho_file.getOrCreateAtomForDecl(decl_index); |
| | 9026 | return macho_file.getAtom(atom).getSymbolIndex().?; |
| | 9027 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| | 9028 | const atom = try coff_file.getOrCreateAtomForDecl(decl_index); |
| | 9029 | return coff_file.getAtom(atom).getSymbolIndex().?; |
| | 9030 | } else unreachable; |
| | 9031 | } |