| ... | @@ -130,8 +130,15 @@ pub const MCValue = union(enum) { | ... | @@ -130,8 +130,15 @@ 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, | 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 | /// The value is a threadlocal variable. | 142 | /// The value is a threadlocal variable. |
| 136 | /// Payload is a symbol index. | 143 | /// Payload is a symbol index. |
| 137 | load_tlv: u32, | 144 | load_tlv: u32, |
| ... | @@ -151,7 +158,9 @@ pub const MCValue = union(enum) { | ... | @@ -151,7 +158,9 @@ pub const MCValue = union(enum) { |
| 151 | .memory, | 158 | .memory, |
| 152 | .stack_offset, | 159 | .stack_offset, |
| 153 | .ptr_stack_offset, | 160 | .ptr_stack_offset, |
| 154 | .linker_load, | 161 | .load_direct, |
| | 162 | .lea_direct, |
| | 163 | .load_got, |
| 155 | .load_tlv, | 164 | .load_tlv, |
| 156 | .lea_tlv, | 165 | .lea_tlv, |
| 157 | => true, | 166 | => true, |
| ... | @@ -739,40 +748,6 @@ fn asmMemoryRegisterImmediate( | ... | @@ -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 | fn gen(self: *Self) InnerError!void { | 751 | fn gen(self: *Self) InnerError!void { |
| 777 | const cc = self.fn_type.fnCallingConvention(); | 752 | const cc = self.fn_type.fnCallingConvention(); |
| 778 | if (cc != .Naked) { | 753 | if (cc != .Naked) { |
| ... | @@ -2925,24 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2925,24 +2900,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2925 | .disp = -off, | 2900 | .disp = -off, |
| 2926 | })); | 2901 | })); |
| 2927 | }, | 2902 | }, |
| 2928 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 2903 | .load_got => try self.genSetReg(array_ty, addr_reg, array), |
| 2929 | .lea_tlv => unreachable, | 2904 | .memory, .load_direct, .load_tlv => try self.genSetReg(Type.usize, addr_reg, switch (array) { |
| 2930 | .load_tlv => |sym_index| try self.genSetReg(array_ty, addr_reg, .{ .lea_tlv = sym_index }), | 2905 | .memory => |addr| .{ .immediate = addr }, |
| 2931 | .linker_load => |load_struct| { | 2906 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 2932 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 2907 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 2933 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 2908 | else => unreachable, |
| 2934 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 2909 | }), |
| 2935 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | 2910 | .lea_direct, .lea_tlv => unreachable, |
| 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 | }, | | |
| 2946 | 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}), |
| 2947 | } | 2912 | } |
| 2948 | | 2913 | |
| ... | @@ -3654,31 +3619,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -3654,31 +3619,15 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 3654 | 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}), |
| 3655 | } | 3620 | } |
| 3656 | }, | 3621 | }, |
| 3657 | .load_tlv => |sym_index| try self.load(dst_mcv, .{ .lea_tlv = sym_index }, ptr_ty), | 3622 | .load_direct, .load_tlv => |sym_index| try self.load(dst_mcv, switch (ptr) { |
| 3658 | .memory, .lea_tlv => { | 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 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); | 3628 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3660 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); | 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,7 +3760,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3811 | -@intCast(i32, overflow_bit_offset), | 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 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 3764 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 3816 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 3765 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3817 | defer self.register_manager.unlockReg(tmp_lock); | 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,26 +3771,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3822 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 3771 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3823 | defer self.register_manager.unlockReg(addr_lock); | 3772 | defer self.register_manager.unlockReg(addr_lock); |
| 3824 | | 3773 | |
| 3825 | switch (value) { | 3774 | try self.genSetReg(Type.usize, addr_reg, switch (value) { |
| 3826 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 3775 | .memory => |addr| .{ .immediate = addr }, |
| 3827 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), | 3776 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 3828 | .linker_load => |load_struct| { | 3777 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 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 | }, | | |
| 3842 | else => unreachable, | 3778 | else => unreachable, |
| 3843 | } | 3779 | }); |
| 3844 | | | |
| 3845 | try self.genInlineMemcpy( | 3780 | try self.genInlineMemcpy( |
| 3846 | ptr, | 3781 | ptr, |
| 3847 | .{ .register = addr_reg }, | 3782 | .{ .register = addr_reg }, |
| ... | @@ -3861,7 +3796,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3861,7 +3796,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3861 | .{ .immediate = abi_size }, | 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 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 3800 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 3866 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 3801 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3867 | defer self.register_manager.unlockReg(tmp_lock); | 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,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 | const value_lock: ?RegisterLock = switch (value) { | 3809 | const value_lock: ?RegisterLock = switch (value) { |
| 3875 | .register => |reg| self.register_manager.lockReg(reg), | 3810 | .register => |reg| self.register_manager.lockReg(reg), |
| 3876 | else => null, | 3811 | else => null, |
| ... | @@ -3887,27 +3822,15 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3887,27 +3822,15 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3887 | // Load the pointer, which is stored in memory | 3822 | // Load the pointer, which is stored in memory |
| 3888 | try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg })); | 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 | .load_tlv => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_tlv = sym_index }), | 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 | else => unreachable, | 3827 | else => unreachable, |
| 3905 | } | 3828 | } |
| 3906 | | 3829 | |
| 3907 | const new_ptr = MCValue{ .register = addr_reg }; | 3830 | const new_ptr = MCValue{ .register = addr_reg }; |
| 3908 | try self.store(new_ptr, value, ptr_ty, value_ty); | 3831 | try self.store(new_ptr, value, ptr_ty, value_ty); |
| 3909 | }, | 3832 | }, |
| 3910 | .lea_tlv => { | 3833 | .load_got, .lea_direct, .lea_tlv => { |
| 3911 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); | 3834 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3912 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 3835 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3913 | defer self.register_manager.unlockReg(addr_reg_lock); | 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,32 +4168,18 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue |
| 4245 | })); | 4168 | })); |
| 4246 | }, | 4169 | }, |
| 4247 | .ptr_stack_offset => unreachable, | 4170 | .ptr_stack_offset => unreachable, |
| 4248 | .lea_tlv => unreachable, | 4171 | .load_got, .lea_direct, .lea_tlv => unreachable, |
| 4249 | .memory, .load_tlv, .linker_load => { | 4172 | .memory, .load_direct, .load_tlv => { |
| 4250 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 4173 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 4251 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 4174 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 4252 | defer self.register_manager.unlockReg(addr_reg_lock); | 4175 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 4253 | | 4176 | |
| 4254 | switch (dst_mcv) { | 4177 | try self.genSetReg(Type.usize, addr_reg, switch (dst_mcv) { |
| 4255 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 4178 | .memory => |addr| .{ .immediate = addr }, |
| 4256 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), | 4179 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 4257 | .linker_load => |load_struct| { | 4180 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 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 | }, | | |
| 4272 | else => unreachable, | 4181 | else => unreachable, |
| 4273 | } | 4182 | }); |
| 4274 | try self.asmMemory( | 4183 | try self.asmMemory( |
| 4275 | mir_tag, | 4184 | mir_tag, |
| 4276 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), | 4185 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }), |
| ... | @@ -4768,6 +4677,7 @@ fn genBinOp( | ... | @@ -4768,6 +4677,7 @@ fn genBinOp( |
| 4768 | } | 4677 | } |
| 4769 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); | 4678 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); |
| 4770 | try self.setRegOrMem(lhs_ty, dst_mcv, switch (lhs) { | 4679 | try self.setRegOrMem(lhs_ty, dst_mcv, switch (lhs) { |
| | 4680 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 4771 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, | 4681 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 4772 | else => lhs, | 4682 | else => lhs, |
| 4773 | }); | 4683 | }); |
| ... | @@ -4911,6 +4821,8 @@ fn genBinOp( | ... | @@ -4911,6 +4821,8 @@ fn genBinOp( |
| 4911 | .eflags, | 4821 | .eflags, |
| 4912 | .register_overflow, | 4822 | .register_overflow, |
| 4913 | .ptr_stack_offset, | 4823 | .ptr_stack_offset, |
| | 4824 | .load_got, |
| | 4825 | .lea_direct, |
| 4914 | .lea_tlv, | 4826 | .lea_tlv, |
| 4915 | => unreachable, | 4827 | => unreachable, |
| 4916 | .register => |src_reg| try self.asmCmovccRegisterRegister( | 4828 | .register => |src_reg| try self.asmCmovccRegisterRegister( |
| ... | @@ -4926,32 +4838,17 @@ fn genBinOp( | ... | @@ -4926,32 +4838,17 @@ fn genBinOp( |
| 4926 | }), | 4838 | }), |
| 4927 | cc, | 4839 | cc, |
| 4928 | ), | 4840 | ), |
| 4929 | .memory, .load_tlv, .linker_load => { | 4841 | .memory, .load_direct, .load_tlv => { |
| 4930 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 4842 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 4931 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 4843 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 4932 | defer self.register_manager.unlockReg(addr_reg_lock); | 4844 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 4933 | | 4845 | |
| 4934 | switch (mat_src_mcv) { | 4846 | try self.genSetReg(Type.usize, addr_reg, switch (mat_src_mcv) { |
| 4935 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 4847 | .memory => |addr| .{ .immediate = addr }, |
| 4936 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), | 4848 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 4937 | .linker_load => |load_struct| { | 4849 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 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 | }, | | |
| 4952 | else => unreachable, | 4850 | else => unreachable, |
| 4953 | } | 4851 | }); |
| 4954 | | | |
| 4955 | try self.asmCmovccRegisterMemory( | 4852 | try self.asmCmovccRegisterMemory( |
| 4956 | registerAlias(tmp_reg, cmov_abi_size), | 4853 | registerAlias(tmp_reg, cmov_abi_size), |
| 4957 | Memory.sib(Memory.PtrSize.fromSize(cmov_abi_size), .{ .base = addr_reg }), | 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,7 +4942,15 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5045 | )), | 4942 | )), |
| 5046 | else => unreachable, | 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 | assert(abi_size <= 8); | 4954 | assert(abi_size <= 8); |
| 5050 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); | 4955 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); |
| 5051 | defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); | 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,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 | const dst: ?struct { | 4969 | const dst: ?struct { |
| 5065 | addr_reg: Register, | 4970 | addr_reg: Register, |
| 5066 | addr_lock: RegisterLock, | 4971 | addr_lock: RegisterLock, |
| 5067 | } = switch (dst_mcv) { | 4972 | } = switch (dst_mcv) { |
| 5068 | else => unreachable, | 4973 | else => unreachable, |
| 5069 | .memory, .load_tlv, .linker_load => dst: { | 4974 | .memory, .load_got, .load_direct, .load_tlv => dst: { |
| 5070 | const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 4975 | const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 5071 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); | 4976 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| 5072 | errdefer self.register_manager.unlockReg(dst_addr_lock); | 4977 | errdefer self.register_manager.unlockReg(dst_addr_lock); |
| 5073 | | 4978 | |
| 5074 | switch (dst_mcv) { | 4979 | try self.genSetReg(Type.usize, dst_addr_reg, switch (dst_mcv) { |
| 5075 | .memory => |addr| try self.genSetReg(Type.usize, dst_addr_reg, .{ .immediate = addr }), | 4980 | .memory => |addr| .{ .immediate = addr }, |
| 5076 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, dst_addr_reg, .{ .lea_tlv = sym_index }), | 4981 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 5077 | .linker_load => |load_struct| { | 4982 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 5078 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 4983 | else => dst_mcv, |
| 5079 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 4984 | }); |
| 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 | } | | |
| 5094 | | 4985 | |
| 5095 | break :dst .{ | 4986 | break :dst .{ |
| 5096 | .addr_reg = dst_addr_reg, | 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,7 +4999,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5108 | addr_lock: RegisterLock, | 4999 | addr_lock: RegisterLock, |
| 5109 | } = switch (src_mcv) { | 5000 | } = switch (src_mcv) { |
| 5110 | else => null, | 5001 | else => null, |
| 5111 | .memory, .load_tlv, .linker_load => src: { | 5002 | .memory, .load_got, .load_direct, .load_tlv => src: { |
| 5112 | const src_limb_reg = try self.register_manager.allocReg(null, gp); | 5003 | const src_limb_reg = try self.register_manager.allocReg(null, gp); |
| 5113 | const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); | 5004 | const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); |
| 5114 | errdefer self.register_manager.unlockReg(src_limb_lock); | 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,26 +5008,12 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5117 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); | 5008 | const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 5118 | errdefer self.register_manager.unlockReg(src_addr_lock); | 5009 | errdefer self.register_manager.unlockReg(src_addr_lock); |
| 5119 | | 5010 | |
| 5120 | switch (src_mcv) { | 5011 | try self.genSetReg(Type.usize, src_addr_reg, switch (src_mcv) { |
| 5121 | .memory => |addr| try self.genSetReg(Type.usize, src_addr_reg, .{ .immediate = addr }), | 5012 | .memory => |addr| .{ .immediate = addr }, |
| 5122 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, src_addr_reg, .{ .lea_tlv = sym_index }), | 5013 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 5123 | .linker_load => |load_struct| { | 5014 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 5124 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 5015 | else => src_mcv, |
| 5125 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 5016 | }); |
| 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 | } | | |
| 5140 | | 5017 | |
| 5141 | break :src .{ | 5018 | break :src .{ |
| 5142 | .addr_reg = src_addr_reg, | 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,7 +5056,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5179 | .base = .rbp, | 5056 | .base = .rbp, |
| 5180 | .disp = off - dst_off, | 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 | switch (src_mcv) { | 5066 | switch (src_mcv) { |
| ... | @@ -5243,7 +5124,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5243,7 +5124,11 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5243 | else => unreachable, | 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 | try self.asmRegisterMemory( | 5132 | try self.asmRegisterMemory( |
| 5248 | .mov, | 5133 | .mov, |
| 5249 | registerAlias(src.?.limb_reg, limb_abi_size), | 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,11 +5143,19 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5258 | registerAlias(src.?.limb_reg, limb_abi_size), | 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 | const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) { | 5152 | const src_limb_reg = try self.copyToTmpRegister(limb_ty, switch (src_mcv) { |
| 5263 | .stack_offset => |src_off| .{ .stack_offset = src_off - off }, | 5153 | .stack_offset => |src_off| .{ .stack_offset = src_off - off }, |
| 5264 | .ptr_stack_offset, | 5154 | .ptr_stack_offset, |
| 5265 | .eflags, | 5155 | .eflags, |
| | 5156 | .load_got, |
| | 5157 | .lea_direct, |
| | 5158 | .lea_tlv, |
| 5266 | => off: { | 5159 | => off: { |
| 5267 | assert(off == 0); | 5160 | assert(off == 0); |
| 5268 | break :off src_mcv; | 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,6 +5176,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5283 | }, | 5176 | }, |
| 5284 | .ptr_stack_offset => unreachable, | 5177 | .ptr_stack_offset => unreachable, |
| 5285 | .lea_tlv => unreachable, | 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,6 +5190,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5296 | .dead, .unreach, .immediate => unreachable, | 5190 | .dead, .unreach, .immediate => unreachable, |
| 5297 | .eflags => unreachable, | 5191 | .eflags => unreachable, |
| 5298 | .ptr_stack_offset => unreachable, | 5192 | .ptr_stack_offset => unreachable, |
| | 5193 | .lea_direct => unreachable, |
| 5299 | .lea_tlv => unreachable, | 5194 | .lea_tlv => unreachable, |
| 5300 | .register_overflow => unreachable, | 5195 | .register_overflow => unreachable, |
| 5301 | .register => |dst_reg| { | 5196 | .register => |dst_reg| { |
| ... | @@ -5308,6 +5203,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5308,6 +5203,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5308 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), | 5203 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), |
| 5309 | .dead, .unreach => unreachable, | 5204 | .dead, .unreach => unreachable, |
| 5310 | .ptr_stack_offset => unreachable, | 5205 | .ptr_stack_offset => unreachable, |
| | 5206 | .lea_direct => unreachable, |
| 5311 | .lea_tlv => unreachable, | 5207 | .lea_tlv => unreachable, |
| 5312 | .register_overflow => unreachable, | 5208 | .register_overflow => unreachable, |
| 5313 | .register => |src_reg| try self.asmRegisterRegister( | 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,12 +5231,13 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5335 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), | 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 | return self.fail("TODO implement x86 multiply source memory", .{}); | 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 | .eflags => { | 5241 | .eflags => { |
| 5345 | return self.fail("TODO implement x86 multiply source eflags", .{}); | 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,6 +5249,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5352 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), | 5249 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), |
| 5353 | .dead, .unreach => unreachable, | 5250 | .dead, .unreach => unreachable, |
| 5354 | .ptr_stack_offset => unreachable, | 5251 | .ptr_stack_offset => unreachable, |
| | 5252 | .lea_direct => unreachable, |
| 5355 | .lea_tlv => unreachable, | 5253 | .lea_tlv => unreachable, |
| 5356 | .register_overflow => unreachable, | 5254 | .register_overflow => unreachable, |
| 5357 | .register => |src_reg| { | 5255 | .register => |src_reg| { |
| ... | @@ -5375,23 +5273,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5375,23 +5273,26 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5375 | | 5273 | |
| 5376 | return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{}); | 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 | return self.fail("TODO implement x86 multiply source memory", .{}); | 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 | .eflags => { | 5284 | .eflags => { |
| 5385 | return self.fail("TODO implement x86 multiply source eflags", .{}); | 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 | return self.fail("TODO implement x86 multiply destination memory", .{}); | 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,7 +5372,8 @@ fn genVarDbgInfo( |
| 5471 | .offset = -off, | 5372 | .offset = -off, |
| 5472 | } }, | 5373 | } }, |
| 5473 | .memory => |address| .{ .memory = address }, | 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 | .immediate => |x| .{ .immediate = x }, | 5377 | .immediate => |x| .{ .immediate = x }, |
| 5476 | .undef => .undef, | 5378 | .undef => .undef, |
| 5477 | .none => .none, | 5379 | .none => .none, |
| ... | @@ -5572,9 +5474,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5572,9 +5474,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5572 | .unreach => unreachable, | 5474 | .unreach => unreachable, |
| 5573 | .dead => unreachable, | 5475 | .dead => unreachable, |
| 5574 | .memory => unreachable, | 5476 | .memory => unreachable, |
| 5575 | .linker_load => unreachable, | | |
| 5576 | .eflags => unreachable, | 5477 | .eflags => unreachable, |
| 5577 | .register_overflow => unreachable, | 5478 | .register_overflow => unreachable, |
| | 5479 | .load_got => unreachable, |
| | 5480 | .lea_direct => unreachable, |
| | 5481 | .load_direct => unreachable, |
| 5578 | .lea_tlv => unreachable, | 5482 | .lea_tlv => unreachable, |
| 5579 | .load_tlv => unreachable, | 5483 | .load_tlv => unreachable, |
| 5580 | } | 5484 | } |
| ... | @@ -5612,9 +5516,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5612,9 +5516,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5612 | .unreach => unreachable, | 5516 | .unreach => unreachable, |
| 5613 | .dead => unreachable, | 5517 | .dead => unreachable, |
| 5614 | .memory => unreachable, | 5518 | .memory => unreachable, |
| 5615 | .linker_load => unreachable, | | |
| 5616 | .eflags => unreachable, | 5519 | .eflags => unreachable, |
| 5617 | .register_overflow => unreachable, | 5520 | .register_overflow => unreachable, |
| | 5521 | .load_got => unreachable, |
| | 5522 | .lea_direct => unreachable, |
| | 5523 | .load_direct => unreachable, |
| 5618 | .lea_tlv => unreachable, | 5524 | .lea_tlv => unreachable, |
| 5619 | .load_tlv => unreachable, | 5525 | .load_tlv => unreachable, |
| 5620 | } | 5526 | } |
| ... | @@ -5639,21 +5545,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5639,21 +5545,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5639 | .base = .ds, | 5545 | .base = .ds, |
| 5640 | .disp = @intCast(i32, got_addr), | 5546 | .disp = @intCast(i32, got_addr), |
| 5641 | })); | 5547 | })); |
| 5642 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 5548 | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| 5643 | const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl); | 5549 | const sym_index = try self.getSymbolIndexForDecl(func.owner_decl); |
| 5644 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 5550 | try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index }); |
| 5645 | try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ | | |
| 5646 | .type = .got, | | |
| 5647 | .sym_index = sym_index, | | |
| 5648 | } }); | | |
| 5649 | try self.asmRegister(.call, .rax); | 5551 | try self.asmRegister(.call, .rax); |
| 5650 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 5552 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 5651 | const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl); | 5553 | const sym_index = try self.getSymbolIndexForDecl(func.owner_decl); |
| 5652 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; | 5554 | try self.genSetReg(Type.usize, .rax, .{ .load_got = sym_index }); |
| 5653 | try self.genSetReg(Type.usize, .rax, .{ .linker_load = .{ | | |
| 5654 | .type = .got, | | |
| 5655 | .sym_index = sym_index, | | |
| 5656 | } }); | | |
| 5657 | try self.asmRegister(.call, .rax); | 5555 | try self.asmRegister(.call, .rax); |
| 5658 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 5556 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 5659 | const decl_block_index = try p9.seeDecl(func.owner_decl); | 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,18 +5571,21 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5673 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); | 5571 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); |
| 5674 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); | 5572 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); |
| 5675 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 5573 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| | 5574 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| 5676 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); | 5575 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); |
| 5677 | try self.genSetReg(Type.usize, .rax, .{ | 5576 | _ = try self.addInst(.{ |
| 5678 | .linker_load = .{ | 5577 | .tag = .mov_linker, |
| 5679 | .type = .import, | 5578 | .ops = .import_reloc, |
| | 5579 | .data = .{ .payload = try self.addExtra(Mir.LeaRegisterReloc{ |
| | 5580 | .reg = @enumToInt(Register.rax), |
| | 5581 | .atom_index = atom_index, |
| 5680 | .sym_index = sym_index, | 5582 | .sym_index = sym_index, |
| 5681 | }, | 5583 | }) }, |
| 5682 | }); | 5584 | }); |
| 5683 | try self.asmRegister(.call, .rax); | 5585 | try self.asmRegister(.call, .rax); |
| 5684 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 5586 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 5685 | const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); | 5587 | const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); |
| 5686 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 5588 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| 5687 | const atom_index = macho_file.getAtom(atom).getSymbolIndex().?; | | |
| 5688 | _ = try self.addInst(.{ | 5589 | _ = try self.addInst(.{ |
| 5689 | .tag = .call_extern, | 5590 | .tag = .call_extern, |
| 5690 | .ops = undefined, | 5591 | .ops = undefined, |
| ... | @@ -5883,20 +5784,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -5883,20 +5784,14 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 5883 | 4, // dword alignment | 5784 | 4, // dword alignment |
| 5884 | ); | 5785 | ); |
| 5885 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 5786 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 5886 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ | 5787 | try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index }); |
| 5887 | .type = .got, | | |
| 5888 | .sym_index = sym_index, | | |
| 5889 | } }); | | |
| 5890 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 5788 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 5891 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( | 5789 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( |
| 5892 | .{ .kind = .const_data, .ty = Type.anyerror }, | 5790 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| 5893 | 4, // dword alignment | 5791 | 4, // dword alignment |
| 5894 | ); | 5792 | ); |
| 5895 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; | 5793 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| 5896 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ | 5794 | try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index }); |
| 5897 | .type = .got, | | |
| 5898 | .sym_index = sym_index, | | |
| 5899 | } }); | | |
| 5900 | } else { | 5795 | } else { |
| 5901 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); | 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,6 +6033,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6138 | .register_overflow, | 6033 | .register_overflow, |
| 6139 | .ptr_stack_offset, | 6034 | .ptr_stack_offset, |
| 6140 | .eflags, | 6035 | .eflags, |
| | 6036 | .lea_direct, |
| 6141 | .lea_tlv, | 6037 | .lea_tlv, |
| 6142 | => unreachable, | 6038 | => unreachable, |
| 6143 | | 6039 | |
| ... | @@ -6159,31 +6055,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -6159,31 +6055,21 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6159 | return .{ .eflags = .nc }; | 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 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 6063 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 6164 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 6064 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 6165 | defer self.register_manager.unlockReg(addr_reg_lock); | 6065 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 6166 | | 6066 | |
| 6167 | switch (opt_mcv) { | 6067 | try self.genSetReg(Type.usize, addr_reg, switch (opt_mcv) { |
| 6168 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 6068 | .memory => |addr| .{ .immediate = addr }, |
| 6169 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), | 6069 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 6170 | .linker_load => |load_struct| { | 6070 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 6171 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 6071 | else => opt_mcv, |
| 6172 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 6072 | }); |
| 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 | } | | |
| 6187 | | 6073 | |
| 6188 | const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); | 6074 | const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*)); |
| 6189 | try self.asmMemoryImmediate(.cmp, Memory.sib( | 6075 | try self.asmMemoryImmediate(.cmp, Memory.sib( |
| ... | @@ -7112,7 +6998,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -7112,7 +6998,10 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7112 | else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}), | 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 | if (abi_size <= 8) { | 7005 | if (abi_size <= 8) { |
| 7117 | const reg = try self.copyToTmpRegister(ty, mcv); | 7006 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7118 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 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,27 +7011,12 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7122 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 7011 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7123 | defer self.register_manager.unlockReg(addr_lock); | 7012 | defer self.register_manager.unlockReg(addr_lock); |
| 7124 | | 7013 | |
| 7125 | switch (mcv) { | 7014 | try self.genSetReg(Type.usize, addr_reg, switch (mcv) { |
| 7126 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 7015 | .memory => |addr| .{ .immediate = addr }, |
| 7127 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), | 7016 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 7128 | .linker_load => |load_struct| { | 7017 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 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 | }, | | |
| 7143 | else => unreachable, | 7018 | else => unreachable, |
| 7144 | } | 7019 | }); |
| 7145 | | | |
| 7146 | try self.genInlineMemcpy( | 7020 | try self.genInlineMemcpy( |
| 7147 | .{ .ptr_stack_offset = stack_offset }, | 7021 | .{ .ptr_stack_offset = stack_offset }, |
| 7148 | .{ .register = addr_reg }, | 7022 | .{ .register = addr_reg }, |
| ... | @@ -7184,7 +7058,11 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -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 | const reg = try self.copyToTmpRegister(ty, mcv); | 7066 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7189 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 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,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 | const reg = try self.copyToTmpRegister(ty, mcv); | 7227 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7347 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); | 7228 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); |
| 7348 | } else { | 7229 | } else { |
| ... | @@ -7350,27 +7231,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7350,27 +7231,12 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7350 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 7231 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 7351 | defer self.register_manager.unlockReg(addr_lock); | 7232 | defer self.register_manager.unlockReg(addr_lock); |
| 7352 | | 7233 | |
| 7353 | switch (mcv) { | 7234 | try self.genSetReg(Type.usize, addr_reg, switch (mcv) { |
| 7354 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 7235 | .memory => |addr| .{ .immediate = addr }, |
| 7355 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), | 7236 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 7356 | .linker_load => |load_struct| { | 7237 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 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 | }, | | |
| 7371 | else => unreachable, | 7238 | else => unreachable, |
| 7372 | } | 7239 | }); |
| 7373 | | | |
| 7374 | try self.genInlineMemcpy( | 7240 | try self.genInlineMemcpy( |
| 7375 | .{ .ptr_stack_offset = stack_offset }, | 7241 | .{ .ptr_stack_offset = stack_offset }, |
| 7376 | .{ .register = addr_reg }, | 7242 | .{ .register = addr_reg }, |
| ... | @@ -7390,7 +7256,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7390,7 +7256,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7390 | .{ .immediate = abi_size }, | 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 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); | 7264 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); |
| 7395 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7265 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7396 | defer self.register_manager.unlockReg(tmp_lock); | 7266 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -7485,21 +7355,13 @@ fn genInlineMemcpy( | ... | @@ -7485,21 +7355,13 @@ fn genInlineMemcpy( |
| 7485 | // Load the pointer, which is stored in memory | 7355 | // Load the pointer, which is stored in memory |
| 7486 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); | 7356 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| 7487 | }, | 7357 | }, |
| 7488 | .linker_load => |load_struct| { | 7358 | .load_got, |
| 7489 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7359 | .lea_direct, |
| 7490 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7360 | .load_direct, |
| 7491 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 7361 | .lea_tlv, |
| 7492 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | 7362 | .load_tlv, |
| 7493 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7363 | => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) { |
| 7494 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | 7364 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 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) { | | |
| 7503 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, | 7365 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 7504 | else => dst_ptr, | 7366 | else => dst_ptr, |
| 7505 | }), | 7367 | }), |
| ... | @@ -7531,21 +7393,13 @@ fn genInlineMemcpy( | ... | @@ -7531,21 +7393,13 @@ fn genInlineMemcpy( |
| 7531 | // Load the pointer, which is stored in memory | 7393 | // Load the pointer, which is stored in memory |
| 7532 | try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi })); | 7394 | try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi })); |
| 7533 | }, | 7395 | }, |
| 7534 | .linker_load => |load_struct| { | 7396 | .load_got, |
| 7535 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7397 | .lea_direct, |
| 7536 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7398 | .load_direct, |
| 7537 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 7399 | .lea_tlv, |
| 7538 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | 7400 | .load_tlv, |
| 7539 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7401 | => try self.genSetReg(Type.usize, .rsi, switch (src_ptr) { |
| 7540 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | 7402 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 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) { | | |
| 7549 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, | 7403 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 7550 | else => src_ptr, | 7404 | else => src_ptr, |
| 7551 | }), | 7405 | }), |
| ... | @@ -7600,21 +7454,13 @@ fn genInlineMemset( | ... | @@ -7600,21 +7454,13 @@ fn genInlineMemset( |
| 7600 | // Load the pointer, which is stored in memory | 7454 | // Load the pointer, which is stored in memory |
| 7601 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); | 7455 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| 7602 | }, | 7456 | }, |
| 7603 | .linker_load => |load_struct| { | 7457 | .load_got, |
| 7604 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7458 | .lea_direct, |
| 7605 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7459 | .load_direct, |
| 7606 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 7460 | .lea_tlv, |
| 7607 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | 7461 | .load_tlv, |
| 7608 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7462 | => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) { |
| 7609 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | 7463 | .load_direct => |sym_index| .{ .lea_direct = sym_index }, |
| 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) { | | |
| 7618 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, | 7464 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| 7619 | else => dst_ptr, | 7465 | else => dst_ptr, |
| 7620 | }), | 7466 | }), |
| ... | @@ -7793,15 +7639,64 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -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| { | 7642 | .load_got, .lea_direct => |sym_index| { |
| 7797 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7643 | const atom_index = try self.getSymbolIndexForDecl(self.mod_fn.owner_decl); |
| 7798 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7644 | _ = try self.addInst(.{ |
| 7799 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 7645 | .tag = switch (mcv) { |
| 7800 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { | 7646 | .load_got => .mov_linker, |
| 7801 | const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7647 | .lea_direct => .lea_linker, |
| 7802 | break :blk coff_file.getAtom(atom).getSymbolIndex().?; | 7648 | else => unreachable, |
| 7803 | } 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 | if (self.bin_file.cast(link.File.MachO)) |_| { | 7700 | if (self.bin_file.cast(link.File.MachO)) |_| { |
| 7806 | _ = try self.addInst(.{ | 7701 | _ = try self.addInst(.{ |
| 7807 | .tag = .mov_linker, | 7702 | .tag = .mov_linker, |
| ... | @@ -7844,39 +7739,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -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 | .stack_offset => |off| { | 7742 | .stack_offset => |off| { |
| 7881 | switch (ty.zigTypeTag()) { | 7743 | switch (ty.zigTypeTag()) { |
| 7882 | .Int => switch (ty.intInfo(self.target.*).signedness) { | 7744 | .Int => switch (ty.intInfo(self.target.*).signedness) { |
| ... | @@ -8515,20 +8377,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8515,20 +8377,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 8515 | 4, // dword alignment | 8377 | 4, // dword alignment |
| 8516 | ); | 8378 | ); |
| 8517 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; | 8379 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 8518 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ | 8380 | try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index }); |
| 8519 | .type = .got, | | |
| 8520 | .sym_index = sym_index, | | |
| 8521 | } }); | | |
| 8522 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 8381 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 8523 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( | 8382 | const atom_index = try macho_file.getOrCreateAtomForLazySymbol( |
| 8524 | .{ .kind = .const_data, .ty = Type.anyerror }, | 8383 | .{ .kind = .const_data, .ty = Type.anyerror }, |
| 8525 | 4, // dword alignment | 8384 | 4, // dword alignment |
| 8526 | ); | 8385 | ); |
| 8527 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; | 8386 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| 8528 | try self.genSetReg(Type.usize, addr_reg, .{ .linker_load = .{ | 8387 | try self.genSetReg(Type.usize, addr_reg, .{ .load_got = sym_index }); |
| 8529 | .type = .got, | | |
| 8530 | .sym_index = sym_index, | | |
| 8531 | } }); | | |
| 8532 | } else { | 8388 | } else { |
| 8533 | return self.fail("TODO implement airErrorName for x86_64 {s}", .{@tagName(self.bin_file.tag)}); | 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,9 +8695,10 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 8839 | .mcv => |mcv| switch (mcv) { | 8695 | .mcv => |mcv| switch (mcv) { |
| 8840 | .none => .none, | 8696 | .none => .none, |
| 8841 | .undef => .undef, | 8697 | .undef => .undef, |
| 8842 | .linker_load => |ll| .{ .linker_load = ll }, | | |
| 8843 | .immediate => |imm| .{ .immediate = imm }, | 8698 | .immediate => |imm| .{ .immediate = imm }, |
| 8844 | .memory => |addr| .{ .memory = addr }, | 8699 | .memory => |addr| .{ .memory = addr }, |
| | 8700 | .load_direct => |sym_index| .{ .load_direct = sym_index }, |
| | 8701 | .load_got => |sym_index| .{ .load_got = sym_index }, |
| 8845 | .load_tlv => |sym_index| .{ .load_tlv = sym_index }, | 8702 | .load_tlv => |sym_index| .{ .load_tlv = sym_index }, |
| 8846 | }, | 8703 | }, |
| 8847 | .fail => |msg| { | 8704 | .fail => |msg| { |
| ... | @@ -9140,3 +8997,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool { | ... | @@ -9140,3 +8997,13 @@ fn intrinsicsAllowed(target: Target, ty: Type) bool { |
| 9140 | fn hasAvxSupport(target: Target) bool { | 8997 | fn hasAvxSupport(target: Target) bool { |
| 9141 | return Target.x86.featureSetHasAny(target.cpu.features, .{ .avx, .avx2 }); | 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 | } |