| ... | @@ -132,10 +132,12 @@ pub const MCValue = union(enum) { | ... | @@ -132,10 +132,12 @@ pub const MCValue = union(enum) { |
| 132 | memory: u64, | 132 | memory: u64, |
| 133 | /// The value is in memory but requires a linker relocation fixup. | 133 | /// The value is in memory but requires a linker relocation fixup. |
| 134 | linker_load: codegen.LinkerLoad, | 134 | linker_load: codegen.LinkerLoad, |
| 135 | /// Pointer to a threadlocal variable. | 135 | /// The value is a threadlocal variable. |
| 136 | /// The address resolution will be deferred until the linker allocates everything in virtual memory. | | |
| 137 | /// Payload is a symbol index. | 136 | /// Payload is a symbol index. |
| 138 | tlv_reloc: u32, | 137 | load_tlv: u32, |
| | 138 | /// The value is a pointer to threadlocal variable. |
| | 139 | /// Payload is a symbol index. |
| | 140 | lea_tlv: u32, |
| 139 | /// The value is one of the stack variables. | 141 | /// 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. | 142 | /// If the type is a pointer, it means the pointer address is in the stack at this offset. |
| 141 | stack_offset: i32, | 143 | stack_offset: i32, |
| ... | @@ -150,7 +152,8 @@ pub const MCValue = union(enum) { | ... | @@ -150,7 +152,8 @@ pub const MCValue = union(enum) { |
| 150 | .stack_offset, | 152 | .stack_offset, |
| 151 | .ptr_stack_offset, | 153 | .ptr_stack_offset, |
| 152 | .linker_load, | 154 | .linker_load, |
| 153 | .tlv_reloc, | 155 | .load_tlv, |
| | 156 | .lea_tlv, |
| 154 | => true, | 157 | => true, |
| 155 | else => false, | 158 | else => false, |
| 156 | }; | 159 | }; |
| ... | @@ -2923,7 +2926,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2923,7 +2926,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2923 | })); | 2926 | })); |
| 2924 | }, | 2927 | }, |
| 2925 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 2928 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), |
| 2926 | .tlv_reloc => try self.genSetReg(array_ty, addr_reg, array), | 2929 | .lea_tlv => unreachable, |
| | 2930 | .load_tlv => |sym_index| try self.genSetReg(array_ty, addr_reg, .{ .lea_tlv = sym_index }), |
| 2927 | .linker_load => |load_struct| { | 2931 | .linker_load => |load_struct| { |
| 2928 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 2932 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 2929 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 2933 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -3650,7 +3654,8 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -3650,7 +3654,8 @@ 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}), | 3654 | else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), |
| 3651 | } | 3655 | } |
| 3652 | }, | 3656 | }, |
| 3653 | .memory, .tlv_reloc => { | 3657 | .load_tlv => |sym_index| try self.load(dst_mcv, .{ .lea_tlv = sym_index }, ptr_ty), |
| | 3658 | .memory, .lea_tlv => { |
| 3654 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); | 3659 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3655 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); | 3660 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); |
| 3656 | }, | 3661 | }, |
| ... | @@ -3806,7 +3811,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3806,7 +3811,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3806 | -@intCast(i32, overflow_bit_offset), | 3811 | -@intCast(i32, overflow_bit_offset), |
| 3807 | ); | 3812 | ); |
| 3808 | }, | 3813 | }, |
| 3809 | .memory, .linker_load => if (abi_size <= 8) { | 3814 | .memory, .load_tlv, .linker_load => if (abi_size <= 8) { |
| 3810 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 3815 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 3811 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 3816 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3812 | defer self.register_manager.unlockReg(tmp_lock); | 3817 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -3819,6 +3824,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3819,6 +3824,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3819 | | 3824 | |
| 3820 | switch (value) { | 3825 | switch (value) { |
| 3821 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 3826 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), |
| | 3827 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), |
| 3822 | .linker_load => |load_struct| { | 3828 | .linker_load => |load_struct| { |
| 3823 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 3829 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 3824 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 3830 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -3855,7 +3861,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3855,7 +3861,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3855 | .{ .immediate = abi_size }, | 3861 | .{ .immediate = abi_size }, |
| 3856 | .{}, | 3862 | .{}, |
| 3857 | ), | 3863 | ), |
| 3858 | .ptr_stack_offset, .tlv_reloc => { | 3864 | .ptr_stack_offset, .lea_tlv => { |
| 3859 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); | 3865 | const tmp_reg = try self.copyToTmpRegister(value_ty, value); |
| 3860 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 3866 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3861 | defer self.register_manager.unlockReg(tmp_lock); | 3867 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -3864,7 +3870,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3864,7 +3870,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3864 | }, | 3870 | }, |
| 3865 | } | 3871 | } |
| 3866 | }, | 3872 | }, |
| 3867 | .memory, .linker_load => { | 3873 | .memory, .load_tlv, .linker_load => { |
| 3868 | const value_lock: ?RegisterLock = switch (value) { | 3874 | const value_lock: ?RegisterLock = switch (value) { |
| 3869 | .register => |reg| self.register_manager.lockReg(reg), | 3875 | .register => |reg| self.register_manager.lockReg(reg), |
| 3870 | else => null, | 3876 | else => null, |
| ... | @@ -3881,6 +3887,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3881,6 +3887,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3881 | // Load the pointer, which is stored in memory | 3887 | // Load the pointer, which is stored in memory |
| 3882 | try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg })); | 3888 | try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg })); |
| 3883 | }, | 3889 | }, |
| | 3890 | .load_tlv => |sym_index| try self.genSetReg(ptr_ty, addr_reg, .{ .lea_tlv = sym_index }), |
| 3884 | .linker_load => |load_struct| { | 3891 | .linker_load => |load_struct| { |
| 3885 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 3892 | 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); | 3893 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -3900,8 +3907,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3900,8 +3907,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3900 | const new_ptr = MCValue{ .register = addr_reg }; | 3907 | const new_ptr = MCValue{ .register = addr_reg }; |
| 3901 | try self.store(new_ptr, value, ptr_ty, value_ty); | 3908 | try self.store(new_ptr, value, ptr_ty, value_ty); |
| 3902 | }, | 3909 | }, |
| 3903 | .tlv_reloc => { | 3910 | .lea_tlv => { |
| 3904 | const addr_reg = try self.copyToTmpRegister(Type.usize, ptr); | 3911 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3905 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 3912 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3906 | defer self.register_manager.unlockReg(addr_reg_lock); | 3913 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 3907 | | 3914 | |
| ... | @@ -3953,14 +3960,17 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 | ... | @@ -3953,14 +3960,17 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 |
| 3953 | | 3960 | |
| 3954 | const dst_mcv: MCValue = result: { | 3961 | const dst_mcv: MCValue = result: { |
| 3955 | switch (mcv) { | 3962 | switch (mcv) { |
| 3956 | .stack_offset, .tlv_reloc => { | 3963 | .stack_offset, .lea_tlv, .load_tlv => { |
| 3957 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ | 3964 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ |
| 3958 | .immediate = field_offset, | 3965 | .immediate = field_offset, |
| 3959 | }); | 3966 | }); |
| 3960 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); | 3967 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 3961 | defer self.register_manager.unlockReg(offset_reg_lock); | 3968 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 3962 | | 3969 | |
| 3963 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, mcv); | 3970 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, switch (mcv) { |
| | 3971 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 3972 | else => mcv, |
| | 3973 | }); |
| 3964 | try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); | 3974 | try self.genBinOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| 3965 | break :result dst_mcv; | 3975 | break :result dst_mcv; |
| 3966 | }, | 3976 | }, |
| ... | @@ -4235,14 +4245,15 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue | ... | @@ -4235,14 +4245,15 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue |
| 4235 | })); | 4245 | })); |
| 4236 | }, | 4246 | }, |
| 4237 | .ptr_stack_offset => unreachable, | 4247 | .ptr_stack_offset => unreachable, |
| 4238 | .tlv_reloc => unreachable, | 4248 | .lea_tlv => unreachable, |
| 4239 | .memory, .linker_load => { | 4249 | .memory, .load_tlv, .linker_load => { |
| 4240 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 4250 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 4241 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 4251 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 4242 | defer self.register_manager.unlockReg(addr_reg_lock); | 4252 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 4243 | | 4253 | |
| 4244 | switch (dst_mcv) { | 4254 | switch (dst_mcv) { |
| 4245 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 4255 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), |
| | 4256 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), |
| 4246 | .linker_load => |load_struct| { | 4257 | .linker_load => |load_struct| { |
| 4247 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 4258 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 4248 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 4259 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -4756,7 +4767,10 @@ fn genBinOp( | ... | @@ -4756,7 +4767,10 @@ fn genBinOp( |
| 4756 | } | 4767 | } |
| 4757 | } | 4768 | } |
| 4758 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); | 4769 | const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true); |
| 4759 | try self.setRegOrMem(lhs_ty, dst_mcv, lhs); | 4770 | try self.setRegOrMem(lhs_ty, dst_mcv, switch (lhs) { |
| | 4771 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 4772 | else => lhs, |
| | 4773 | }); |
| 4760 | break :dst dst_mcv; | 4774 | break :dst dst_mcv; |
| 4761 | }; | 4775 | }; |
| 4762 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { | 4776 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { |
| ... | @@ -4897,7 +4911,7 @@ fn genBinOp( | ... | @@ -4897,7 +4911,7 @@ fn genBinOp( |
| 4897 | .eflags, | 4911 | .eflags, |
| 4898 | .register_overflow, | 4912 | .register_overflow, |
| 4899 | .ptr_stack_offset, | 4913 | .ptr_stack_offset, |
| 4900 | .tlv_reloc, | 4914 | .lea_tlv, |
| 4901 | => unreachable, | 4915 | => unreachable, |
| 4902 | .register => |src_reg| try self.asmCmovccRegisterRegister( | 4916 | .register => |src_reg| try self.asmCmovccRegisterRegister( |
| 4903 | registerAlias(tmp_reg, cmov_abi_size), | 4917 | registerAlias(tmp_reg, cmov_abi_size), |
| ... | @@ -4912,13 +4926,14 @@ fn genBinOp( | ... | @@ -4912,13 +4926,14 @@ fn genBinOp( |
| 4912 | }), | 4926 | }), |
| 4913 | cc, | 4927 | cc, |
| 4914 | ), | 4928 | ), |
| 4915 | .memory, .linker_load => { | 4929 | .memory, .load_tlv, .linker_load => { |
| 4916 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 4930 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 4917 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 4931 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 4918 | defer self.register_manager.unlockReg(addr_reg_lock); | 4932 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 4919 | | 4933 | |
| 4920 | switch (mat_src_mcv) { | 4934 | switch (mat_src_mcv) { |
| 4921 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 4935 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), |
| | 4936 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), |
| 4922 | .linker_load => |load_struct| { | 4937 | .linker_load => |load_struct| { |
| 4923 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 4938 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 4924 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 4939 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -4982,13 +4997,6 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -4982,13 +4997,6 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 4982 | .undef => unreachable, | 4997 | .undef => unreachable, |
| 4983 | .dead, .unreach => unreachable, | 4998 | .dead, .unreach => unreachable, |
| 4984 | .register_overflow => unreachable, | 4999 | .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()) { | 5000 | .register => |src_reg| switch (ty.zigTypeTag()) { |
| 4993 | .Float => { | 5001 | .Float => { |
| 4994 | if (intrinsicsAllowed(self.target.*, ty)) { | 5002 | if (intrinsicsAllowed(self.target.*, ty)) { |
| ... | @@ -5037,7 +5045,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5037,7 +5045,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5037 | )), | 5045 | )), |
| 5038 | else => unreachable, | 5046 | else => unreachable, |
| 5039 | }, | 5047 | }, |
| 5040 | .memory, .linker_load, .eflags => { | 5048 | .ptr_stack_offset, .memory, .lea_tlv, .load_tlv, .linker_load, .eflags => { |
| 5041 | assert(abi_size <= 8); | 5049 | assert(abi_size <= 8); |
| 5042 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); | 5050 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); |
| 5043 | defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); | 5051 | defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -5052,19 +5060,20 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5052,19 +5060,20 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5052 | ), | 5060 | ), |
| 5053 | } | 5061 | } |
| 5054 | }, | 5062 | }, |
| 5055 | .memory, .linker_load, .stack_offset => { | 5063 | .memory, .load_tlv, .linker_load, .stack_offset => { |
| 5056 | const dst: ?struct { | 5064 | const dst: ?struct { |
| 5057 | addr_reg: Register, | 5065 | addr_reg: Register, |
| 5058 | addr_lock: RegisterLock, | 5066 | addr_lock: RegisterLock, |
| 5059 | } = switch (dst_mcv) { | 5067 | } = switch (dst_mcv) { |
| 5060 | else => unreachable, | 5068 | else => unreachable, |
| 5061 | .memory, .linker_load => dst: { | 5069 | .memory, .load_tlv, .linker_load => dst: { |
| 5062 | const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 5070 | const dst_addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 5063 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); | 5071 | const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| 5064 | errdefer self.register_manager.unlockReg(dst_addr_lock); | 5072 | errdefer self.register_manager.unlockReg(dst_addr_lock); |
| 5065 | | 5073 | |
| 5066 | switch (dst_mcv) { | 5074 | switch (dst_mcv) { |
| 5067 | .memory => |addr| try self.genSetReg(Type.usize, dst_addr_reg, .{ .immediate = addr }), | 5075 | .memory => |addr| try self.genSetReg(Type.usize, dst_addr_reg, .{ .immediate = addr }), |
| | 5076 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, dst_addr_reg, .{ .lea_tlv = sym_index }), |
| 5068 | .linker_load => |load_struct| { | 5077 | .linker_load => |load_struct| { |
| 5069 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 5078 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 5070 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 5079 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -5099,7 +5108,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5099,7 +5108,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5099 | addr_lock: RegisterLock, | 5108 | addr_lock: RegisterLock, |
| 5100 | } = switch (src_mcv) { | 5109 | } = switch (src_mcv) { |
| 5101 | else => null, | 5110 | else => null, |
| 5102 | .memory, .linker_load => src: { | 5111 | .memory, .load_tlv, .linker_load => src: { |
| 5103 | const src_limb_reg = try self.register_manager.allocReg(null, gp); | 5112 | const src_limb_reg = try self.register_manager.allocReg(null, gp); |
| 5104 | const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); | 5113 | const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg); |
| 5105 | errdefer self.register_manager.unlockReg(src_limb_lock); | 5114 | errdefer self.register_manager.unlockReg(src_limb_lock); |
| ... | @@ -5110,6 +5119,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5110,6 +5119,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5110 | | 5119 | |
| 5111 | switch (src_mcv) { | 5120 | switch (src_mcv) { |
| 5112 | .memory => |addr| try self.genSetReg(Type.usize, src_addr_reg, .{ .immediate = addr }), | 5121 | .memory => |addr| try self.genSetReg(Type.usize, src_addr_reg, .{ .immediate = addr }), |
| | 5122 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, src_addr_reg, .{ .lea_tlv = sym_index }), |
| 5113 | .linker_load => |load_struct| { | 5123 | .linker_load => |load_struct| { |
| 5114 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 5124 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 5115 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 5125 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -5233,7 +5243,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5233,7 +5243,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5233 | else => unreachable, | 5243 | else => unreachable, |
| 5234 | } | 5244 | } |
| 5235 | }, | 5245 | }, |
| 5236 | .memory, .linker_load, .tlv_reloc => { | 5246 | .memory, .linker_load, .lea_tlv, .load_tlv => { |
| 5237 | try self.asmRegisterMemory( | 5247 | try self.asmRegisterMemory( |
| 5238 | .mov, | 5248 | .mov, |
| 5239 | registerAlias(src.?.limb_reg, limb_abi_size), | 5249 | registerAlias(src.?.limb_reg, limb_abi_size), |
| ... | @@ -5272,7 +5282,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5272,7 +5282,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5272 | } | 5282 | } |
| 5273 | }, | 5283 | }, |
| 5274 | .ptr_stack_offset => unreachable, | 5284 | .ptr_stack_offset => unreachable, |
| 5275 | .tlv_reloc => unreachable, | 5285 | .lea_tlv => unreachable, |
| 5276 | } | 5286 | } |
| 5277 | } | 5287 | } |
| 5278 | | 5288 | |
| ... | @@ -5286,7 +5296,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5286,7 +5296,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5286 | .dead, .unreach, .immediate => unreachable, | 5296 | .dead, .unreach, .immediate => unreachable, |
| 5287 | .eflags => unreachable, | 5297 | .eflags => unreachable, |
| 5288 | .ptr_stack_offset => unreachable, | 5298 | .ptr_stack_offset => unreachable, |
| 5289 | .tlv_reloc => unreachable, | 5299 | .lea_tlv => unreachable, |
| 5290 | .register_overflow => unreachable, | 5300 | .register_overflow => unreachable, |
| 5291 | .register => |dst_reg| { | 5301 | .register => |dst_reg| { |
| 5292 | const dst_alias = registerAlias(dst_reg, abi_size); | 5302 | const dst_alias = registerAlias(dst_reg, abi_size); |
| ... | @@ -5298,7 +5308,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5298,7 +5308,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5298 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), | 5308 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), |
| 5299 | .dead, .unreach => unreachable, | 5309 | .dead, .unreach => unreachable, |
| 5300 | .ptr_stack_offset => unreachable, | 5310 | .ptr_stack_offset => unreachable, |
| 5301 | .tlv_reloc => unreachable, | 5311 | .lea_tlv => unreachable, |
| 5302 | .register_overflow => unreachable, | 5312 | .register_overflow => unreachable, |
| 5303 | .register => |src_reg| try self.asmRegisterRegister( | 5313 | .register => |src_reg| try self.asmRegisterRegister( |
| 5304 | .imul, | 5314 | .imul, |
| ... | @@ -5325,7 +5335,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5325,7 +5335,7 @@ 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 }), | 5335 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), |
| 5326 | ); | 5336 | ); |
| 5327 | }, | 5337 | }, |
| 5328 | .memory => { | 5338 | .memory, .load_tlv => { |
| 5329 | return self.fail("TODO implement x86 multiply source memory", .{}); | 5339 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 5330 | }, | 5340 | }, |
| 5331 | .linker_load => { | 5341 | .linker_load => { |
| ... | @@ -5342,7 +5352,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5342,7 +5352,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5342 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), | 5352 | .undef => return self.genSetStack(dst_ty, off, .undef, .{}), |
| 5343 | .dead, .unreach => unreachable, | 5353 | .dead, .unreach => unreachable, |
| 5344 | .ptr_stack_offset => unreachable, | 5354 | .ptr_stack_offset => unreachable, |
| 5345 | .tlv_reloc => unreachable, | 5355 | .lea_tlv => unreachable, |
| 5346 | .register_overflow => unreachable, | 5356 | .register_overflow => unreachable, |
| 5347 | .register => |src_reg| { | 5357 | .register => |src_reg| { |
| 5348 | // copy dst to a register | 5358 | // copy dst to a register |
| ... | @@ -5365,7 +5375,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5365,7 +5375,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5365 | | 5375 | |
| 5366 | return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{}); | 5376 | return self.genSetStack(dst_ty, off, .{ .register = dst_reg }, .{}); |
| 5367 | }, | 5377 | }, |
| 5368 | .memory, .stack_offset => { | 5378 | .memory, .load_tlv, .stack_offset => { |
| 5369 | return self.fail("TODO implement x86 multiply source memory", .{}); | 5379 | return self.fail("TODO implement x86 multiply source memory", .{}); |
| 5370 | }, | 5380 | }, |
| 5371 | .linker_load => { | 5381 | .linker_load => { |
| ... | @@ -5376,7 +5386,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5376,7 +5386,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5376 | }, | 5386 | }, |
| 5377 | } | 5387 | } |
| 5378 | }, | 5388 | }, |
| 5379 | .memory => { | 5389 | .memory, .load_tlv => { |
| 5380 | return self.fail("TODO implement x86 multiply destination memory", .{}); | 5390 | return self.fail("TODO implement x86 multiply destination memory", .{}); |
| 5381 | }, | 5391 | }, |
| 5382 | .linker_load => { | 5392 | .linker_load => { |
| ... | @@ -5565,7 +5575,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5565,7 +5575,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5565 | .linker_load => unreachable, | 5575 | .linker_load => unreachable, |
| 5566 | .eflags => unreachable, | 5576 | .eflags => unreachable, |
| 5567 | .register_overflow => unreachable, | 5577 | .register_overflow => unreachable, |
| 5568 | .tlv_reloc => unreachable, | 5578 | .lea_tlv => unreachable, |
| | 5579 | .load_tlv => unreachable, |
| 5569 | } | 5580 | } |
| 5570 | } | 5581 | } |
| 5571 | | 5582 | |
| ... | @@ -5604,7 +5615,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -5604,7 +5615,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 5604 | .linker_load => unreachable, | 5615 | .linker_load => unreachable, |
| 5605 | .eflags => unreachable, | 5616 | .eflags => unreachable, |
| 5606 | .register_overflow => unreachable, | 5617 | .register_overflow => unreachable, |
| 5607 | .tlv_reloc => unreachable, | 5618 | .lea_tlv => unreachable, |
| | 5619 | .load_tlv => unreachable, |
| 5608 | } | 5620 | } |
| 5609 | } | 5621 | } |
| 5610 | | 5622 | |
| ... | @@ -6126,7 +6138,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -6126,7 +6138,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6126 | .register_overflow, | 6138 | .register_overflow, |
| 6127 | .ptr_stack_offset, | 6139 | .ptr_stack_offset, |
| 6128 | .eflags, | 6140 | .eflags, |
| 6129 | .tlv_reloc, | 6141 | .lea_tlv, |
| 6130 | => unreachable, | 6142 | => unreachable, |
| 6131 | | 6143 | |
| 6132 | .register => |opt_reg| { | 6144 | .register => |opt_reg| { |
| ... | @@ -6147,13 +6159,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -6147,13 +6159,14 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6147 | return .{ .eflags = .nc }; | 6159 | return .{ .eflags = .nc }; |
| 6148 | }, | 6160 | }, |
| 6149 | | 6161 | |
| 6150 | .memory, .linker_load => { | 6162 | .memory, .load_tlv, .linker_load => { |
| 6151 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 6163 | const addr_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 6152 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 6164 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 6153 | defer self.register_manager.unlockReg(addr_reg_lock); | 6165 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 6154 | | 6166 | |
| 6155 | switch (opt_mcv) { | 6167 | switch (opt_mcv) { |
| 6156 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 6168 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), |
| | 6169 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), |
| 6157 | .linker_load => |load_struct| { | 6170 | .linker_load => |load_struct| { |
| 6158 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 6171 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 6159 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 6172 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -7099,7 +7112,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -7099,7 +7112,7 @@ 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}), | 7112 | else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}), |
| 7100 | } | 7113 | } |
| 7101 | }, | 7114 | }, |
| 7102 | .memory, .linker_load => { | 7115 | .memory, .load_tlv, .linker_load => { |
| 7103 | if (abi_size <= 8) { | 7116 | if (abi_size <= 8) { |
| 7104 | const reg = try self.copyToTmpRegister(ty, mcv); | 7117 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7105 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 7118 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| ... | @@ -7111,6 +7124,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -7111,6 +7124,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7111 | | 7124 | |
| 7112 | switch (mcv) { | 7125 | switch (mcv) { |
| 7113 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 7126 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), |
| | 7127 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), |
| 7114 | .linker_load => |load_struct| { | 7128 | .linker_load => |load_struct| { |
| 7115 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7129 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 7116 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7130 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -7170,7 +7184,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -7170,7 +7184,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7170 | }, | 7184 | }, |
| 7171 | } | 7185 | } |
| 7172 | }, | 7186 | }, |
| 7173 | .ptr_stack_offset, .tlv_reloc => { | 7187 | .ptr_stack_offset, .lea_tlv => { |
| 7174 | const reg = try self.copyToTmpRegister(ty, mcv); | 7188 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7175 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); | 7189 | return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); |
| 7176 | }, | 7190 | }, |
| ... | @@ -7328,7 +7342,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7328,7 +7342,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7328 | }, | 7342 | }, |
| 7329 | } | 7343 | } |
| 7330 | }, | 7344 | }, |
| 7331 | .memory, .linker_load => if (abi_size <= 8) { | 7345 | .memory, .load_tlv, .linker_load => if (abi_size <= 8) { |
| 7332 | const reg = try self.copyToTmpRegister(ty, mcv); | 7346 | const reg = try self.copyToTmpRegister(ty, mcv); |
| 7333 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); | 7347 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); |
| 7334 | } else { | 7348 | } else { |
| ... | @@ -7338,6 +7352,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7338,6 +7352,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7338 | | 7352 | |
| 7339 | switch (mcv) { | 7353 | switch (mcv) { |
| 7340 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), | 7354 | .memory => |addr| try self.genSetReg(Type.usize, addr_reg, .{ .immediate = addr }), |
| | 7355 | .load_tlv => |sym_index| try self.genSetReg(Type.usize, addr_reg, .{ .lea_tlv = sym_index }), |
| 7341 | .linker_load => |load_struct| { | 7356 | .linker_load => |load_struct| { |
| 7342 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7357 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 7343 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7358 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -7375,7 +7390,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7375,7 +7390,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7375 | .{ .immediate = abi_size }, | 7390 | .{ .immediate = abi_size }, |
| 7376 | .{}, | 7391 | .{}, |
| 7377 | ), | 7392 | ), |
| 7378 | .ptr_stack_offset, .tlv_reloc => { | 7393 | .ptr_stack_offset, .lea_tlv => { |
| 7379 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); | 7394 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); |
| 7380 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); | 7395 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7381 | defer self.register_manager.unlockReg(tmp_lock); | 7396 | defer self.register_manager.unlockReg(tmp_lock); |
| ... | @@ -7484,7 +7499,10 @@ fn genInlineMemcpy( | ... | @@ -7484,7 +7499,10 @@ fn genInlineMemcpy( |
| 7484 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), | 7499 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), |
| 7485 | } | 7500 | } |
| 7486 | }, | 7501 | }, |
| 7487 | .tlv_reloc => try self.genSetReg(Type.usize, .rdi, dst_ptr), | 7502 | .lea_tlv, .load_tlv => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) { |
| | 7503 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 7504 | else => dst_ptr, |
| | 7505 | }), |
| 7488 | .stack_offset, .ptr_stack_offset => |off| { | 7506 | .stack_offset, .ptr_stack_offset => |off| { |
| 7489 | try self.asmRegisterMemory(switch (dst_ptr) { | 7507 | try self.asmRegisterMemory(switch (dst_ptr) { |
| 7490 | .stack_offset => .mov, | 7508 | .stack_offset => .mov, |
| ... | @@ -7527,7 +7545,10 @@ fn genInlineMemcpy( | ... | @@ -7527,7 +7545,10 @@ fn genInlineMemcpy( |
| 7527 | .got, .direct => try self.asmMovLinker(.rsi, atom_index, load_struct), | 7545 | .got, .direct => try self.asmMovLinker(.rsi, atom_index, load_struct), |
| 7528 | } | 7546 | } |
| 7529 | }, | 7547 | }, |
| 7530 | .tlv_reloc => try self.genSetReg(Type.usize, .rsi, src_ptr), | 7548 | .lea_tlv, .load_tlv => try self.genSetReg(Type.usize, .rsi, switch (src_ptr) { |
| | 7549 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 7550 | else => src_ptr, |
| | 7551 | }), |
| 7531 | .stack_offset, .ptr_stack_offset => |off| { | 7552 | .stack_offset, .ptr_stack_offset => |off| { |
| 7532 | try self.asmRegisterMemory(switch (src_ptr) { | 7553 | try self.asmRegisterMemory(switch (src_ptr) { |
| 7533 | .stack_offset => .mov, | 7554 | .stack_offset => .mov, |
| ... | @@ -7593,7 +7614,10 @@ fn genInlineMemset( | ... | @@ -7593,7 +7614,10 @@ fn genInlineMemset( |
| 7593 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), | 7614 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), |
| 7594 | } | 7615 | } |
| 7595 | }, | 7616 | }, |
| 7596 | .tlv_reloc => try self.genSetReg(Type.usize, .rdi, dst_ptr), | 7617 | .lea_tlv, .load_tlv => try self.genSetReg(Type.usize, .rdi, switch (dst_ptr) { |
| | 7618 | .load_tlv => |sym_index| .{ .lea_tlv = sym_index }, |
| | 7619 | else => dst_ptr, |
| | 7620 | }), |
| 7597 | .stack_offset, .ptr_stack_offset => |off| { | 7621 | .stack_offset, .ptr_stack_offset => |off| { |
| 7598 | try self.asmRegisterMemory(switch (dst_ptr) { | 7622 | try self.asmRegisterMemory(switch (dst_ptr) { |
| 7599 | .stack_offset => .mov, | 7623 | .stack_offset => .mov, |
| ... | @@ -7769,7 +7793,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -7769,7 +7793,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 7769 | } | 7793 | } |
| 7770 | }, | 7794 | }, |
| 7771 | }, | 7795 | }, |
| 7772 | .tlv_reloc => |sym_index| { | 7796 | .lea_tlv => |sym_index| { |
| 7773 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7797 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { |
| 7774 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); | 7798 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| 7775 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; | 7799 | break :blk macho_file.getAtom(atom).getSymbolIndex().?; |
| ... | @@ -7793,6 +7817,33 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -7793,6 +7817,33 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 7793 | try self.genSetReg(Type.usize, reg, .{ .register = .rax }); | 7817 | 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)}); | 7818 | } else return self.fail("TODO emit ptr to TLV sequence on {s}", .{@tagName(self.bin_file.tag)}); |
| 7795 | }, | 7819 | }, |
| | 7820 | .load_tlv => |sym_index| { |
| | 7821 | const base_reg = switch (ty.zigTypeTag()) { |
| | 7822 | .Float => (try self.register_manager.allocReg(null, gp)).to64(), |
| | 7823 | else => reg.to64(), |
| | 7824 | }; |
| | 7825 | try self.genSetReg(Type.usize, base_reg, .{ .lea_tlv = sym_index }); |
| | 7826 | switch (ty.zigTypeTag()) { |
| | 7827 | .Float => if (intrinsicsAllowed(self.target.*, ty)) { |
| | 7828 | return self.asmRegisterMemory( |
| | 7829 | switch (ty.tag()) { |
| | 7830 | .f32 => .movss, |
| | 7831 | .f64 => .movsd, |
| | 7832 | else => return self.fail("TODO genSetReg from memory for {}", .{ |
| | 7833 | ty.fmt(self.bin_file.options.module.?), |
| | 7834 | }), |
| | 7835 | }, |
| | 7836 | reg.to128(), |
| | 7837 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg }), |
| | 7838 | ); |
| | 7839 | } else return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}), |
| | 7840 | else => try self.asmRegisterMemory( |
| | 7841 | .mov, |
| | 7842 | registerAlias(reg, abi_size), |
| | 7843 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg }), |
| | 7844 | ), |
| | 7845 | } |
| | 7846 | }, |
| 7796 | .linker_load => |load_struct| { | 7847 | .linker_load => |load_struct| { |
| 7797 | const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { | 7848 | 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); | 7849 | const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); |
| ... | @@ -8586,7 +8637,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8586,7 +8637,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); | 8637 | const elem_byte_off = @intCast(i32, elem_off / elem_abi_bits * elem_abi_size); |
| 8587 | const elem_bit_off = elem_off % elem_abi_bits; | 8638 | const elem_bit_off = elem_off % elem_abi_bits; |
| 8588 | const elem_mcv = try self.resolveInst(elem); | 8639 | const elem_mcv = try self.resolveInst(elem); |
| 8589 | const elem_lock = switch (elem_mcv) { | 8640 | const mat_elem_mcv = switch (elem_mcv) { |
| | 8641 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| | 8642 | else => elem_mcv, |
| | 8643 | }; |
| | 8644 | const elem_lock = switch (mat_elem_mcv) { |
| 8590 | .register => |reg| self.register_manager.lockReg(reg), | 8645 | .register => |reg| self.register_manager.lockReg(reg), |
| 8591 | .immediate => |imm| lock: { | 8646 | .immediate => |imm| lock: { |
| 8592 | if (imm == 0) continue; | 8647 | if (imm == 0) continue; |
| ... | @@ -8596,7 +8651,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8596,7 +8651,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8596 | }; | 8651 | }; |
| 8597 | defer if (elem_lock) |lock| self.register_manager.unlockReg(lock); | 8652 | defer if (elem_lock) |lock| self.register_manager.unlockReg(lock); |
| 8598 | const elem_reg = registerAlias( | 8653 | const elem_reg = registerAlias( |
| 8599 | try self.copyToTmpRegister(elem_ty, elem_mcv), | 8654 | try self.copyToTmpRegister(elem_ty, mat_elem_mcv), |
| 8600 | elem_abi_size, | 8655 | elem_abi_size, |
| 8601 | ); | 8656 | ); |
| 8602 | const elem_extra_bits = self.regExtraBits(elem_ty); | 8657 | const elem_extra_bits = self.regExtraBits(elem_ty); |
| ... | @@ -8616,7 +8671,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8616,7 +8671,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8616 | .{ .register = elem_reg }, | 8671 | .{ .register = elem_reg }, |
| 8617 | ); | 8672 | ); |
| 8618 | if (elem_bit_off > elem_extra_bits) { | 8673 | if (elem_bit_off > elem_extra_bits) { |
| 8619 | const reg = try self.copyToTmpRegister(elem_ty, elem_mcv); | 8674 | const reg = try self.copyToTmpRegister(elem_ty, mat_elem_mcv); |
| 8620 | if (elem_extra_bits > 0) { | 8675 | if (elem_extra_bits > 0) { |
| 8621 | try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size)); | 8676 | try self.truncateRegister(elem_ty, registerAlias(reg, elem_abi_size)); |
| 8622 | } | 8677 | } |
| ... | @@ -8641,7 +8696,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8641,7 +8696,11 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8641 | const elem_ty = result_ty.structFieldType(elem_i); | 8696 | const elem_ty = result_ty.structFieldType(elem_i); |
| 8642 | const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*)); | 8697 | const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, self.target.*)); |
| 8643 | const elem_mcv = try self.resolveInst(elem); | 8698 | const elem_mcv = try self.resolveInst(elem); |
| 8644 | try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{}); | 8699 | const mat_elem_mcv = switch (elem_mcv) { |
| | 8700 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| | 8701 | else => elem_mcv, |
| | 8702 | }; |
| | 8703 | try self.genSetStack(elem_ty, stack_offset - elem_off, mat_elem_mcv, .{}); |
| 8645 | } | 8704 | } |
| 8646 | break :res .{ .stack_offset = stack_offset }; | 8705 | break :res .{ .stack_offset = stack_offset }; |
| 8647 | }, | 8706 | }, |
| ... | @@ -8652,8 +8711,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8652,8 +8711,12 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 8652 | | 8711 | |
| 8653 | for (elements, 0..) |elem, elem_i| { | 8712 | for (elements, 0..) |elem, elem_i| { |
| 8654 | const elem_mcv = try self.resolveInst(elem); | 8713 | const elem_mcv = try self.resolveInst(elem); |
| | 8714 | const mat_elem_mcv = switch (elem_mcv) { |
| | 8715 | .load_tlv => |sym_index| MCValue{ .lea_tlv = sym_index }, |
| | 8716 | else => elem_mcv, |
| | 8717 | }; |
| 8655 | const elem_off = @intCast(i32, elem_size * elem_i); | 8718 | const elem_off = @intCast(i32, elem_size * elem_i); |
| 8656 | try self.genSetStack(elem_ty, stack_offset - elem_off, elem_mcv, .{}); | 8719 | try self.genSetStack(elem_ty, stack_offset - elem_off, mat_elem_mcv, .{}); |
| 8657 | } | 8720 | } |
| 8658 | break :res MCValue{ .stack_offset = stack_offset }; | 8721 | break :res MCValue{ .stack_offset = stack_offset }; |
| 8659 | }, | 8722 | }, |
| ... | @@ -8779,7 +8842,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { | ... | @@ -8779,7 +8842,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 8779 | .linker_load => |ll| .{ .linker_load = ll }, | 8842 | .linker_load => |ll| .{ .linker_load = ll }, |
| 8780 | .immediate => |imm| .{ .immediate = imm }, | 8843 | .immediate => |imm| .{ .immediate = imm }, |
| 8781 | .memory => |addr| .{ .memory = addr }, | 8844 | .memory => |addr| .{ .memory = addr }, |
| 8782 | .tlv_reloc => |sym_index| .{ .tlv_reloc = sym_index }, | 8845 | .load_tlv => |sym_index| .{ .load_tlv = sym_index }, |
| 8783 | }, | 8846 | }, |
| 8784 | .fail => |msg| { | 8847 | .fail => |msg| { |
| 8785 | self.err_msg = msg; | 8848 | self.err_msg = msg; |