| ... | @@ -736,6 +736,7 @@ fn asmMovLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege | ... | @@ -736,6 +736,7 @@ fn asmMovLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege |
| 736 | .got => .got_reloc, | 736 | .got => .got_reloc, |
| 737 | .direct => .direct_reloc, | 737 | .direct => .direct_reloc, |
| 738 | .import => .import_reloc, | 738 | .import => .import_reloc, |
| | 739 | .tlv => .tlv_reloc, |
| 739 | }; | 740 | }; |
| 740 | _ = try self.addInst(.{ | 741 | _ = try self.addInst(.{ |
| 741 | .tag = .mov_linker, | 742 | .tag = .mov_linker, |
| ... | @@ -753,6 +754,7 @@ fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege | ... | @@ -753,6 +754,7 @@ fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege |
| 753 | .got => .got_reloc, | 754 | .got => .got_reloc, |
| 754 | .direct => .direct_reloc, | 755 | .direct => .direct_reloc, |
| 755 | .import => .import_reloc, | 756 | .import => .import_reloc, |
| | 757 | .tlv => .tlv_reloc, |
| 756 | }; | 758 | }; |
| 757 | _ = try self.addInst(.{ | 759 | _ = try self.addInst(.{ |
| 758 | .tag = .lea_linker, | 760 | .tag = .lea_linker, |
| ... | @@ -765,6 +767,15 @@ fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege | ... | @@ -765,6 +767,15 @@ fn asmLeaLinker(self: *Self, reg: Register, atom_index: u32, linker_load: codege |
| 765 | }); | 767 | }); |
| 766 | } | 768 | } |
| 767 | | 769 | |
| | 770 | fn genTlvPtr(self: *Self, reg: Register, atom_index: u32, linker_load: codegen.LinkerLoad) !void { |
| | 771 | assert(linker_load.type == .tlv); |
| | 772 | if (self.bin_file.cast(link.File.MachO)) |_| { |
| | 773 | try self.asmMovLinker(.rdi, atom_index, linker_load); |
| | 774 | try self.asmMemory(.call, Memory.sib(.qword, .{ .base = .rdi })); |
| | 775 | try self.genSetReg(Type.usize, reg, .{ .register = .rax }); |
| | 776 | } else return self.fail("TODO emit ptr-to-TLV sequence on {s}", .{@tagName(self.bin_file.tag)}); |
| | 777 | } |
| | 778 | |
| 768 | fn gen(self: *Self) InnerError!void { | 779 | fn gen(self: *Self) InnerError!void { |
| 769 | const cc = self.fn_type.fnCallingConvention(); | 780 | const cc = self.fn_type.fnCallingConvention(); |
| 770 | if (cc != .Naked) { | 781 | if (cc != .Naked) { |
| ... | @@ -2931,6 +2942,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2931,6 +2942,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2931 | .import => unreachable, | 2942 | .import => unreachable, |
| 2932 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | 2943 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), |
| 2933 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | 2944 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), |
| | 2945 | .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct), |
| 2934 | } | 2946 | } |
| 2935 | }, | 2947 | }, |
| 2936 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), | 2948 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), |
| ... | @@ -3805,6 +3817,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3805,6 +3817,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3805 | .import => unreachable, | 3817 | .import => unreachable, |
| 3806 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | 3818 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), |
| 3807 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | 3819 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), |
| | 3820 | .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct), |
| 3808 | } | 3821 | } |
| 3809 | }, | 3822 | }, |
| 3810 | else => unreachable, | 3823 | else => unreachable, |
| ... | @@ -3866,6 +3879,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3866,6 +3879,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3866 | switch (load_struct.type) { | 3879 | switch (load_struct.type) { |
| 3867 | .import => unreachable, | 3880 | .import => unreachable, |
| 3868 | .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct), | 3881 | .got, .direct => try self.asmMovLinker(addr_reg, atom_index, load_struct), |
| | 3882 | .tlv => { |
| | 3883 | try self.genTlvPtr(addr_reg, atom_index, load_struct); |
| | 3884 | // Load the pointer, which is stored in memory |
| | 3885 | try self.asmRegisterMemory(.mov, addr_reg, Memory.sib(.qword, .{ .base = addr_reg })); |
| | 3886 | }, |
| 3869 | } | 3887 | } |
| 3870 | }, | 3888 | }, |
| 3871 | else => unreachable, | 3889 | else => unreachable, |
| ... | @@ -4221,6 +4239,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue | ... | @@ -4221,6 +4239,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue |
| 4221 | .import => unreachable, | 4239 | .import => unreachable, |
| 4222 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | 4240 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), |
| 4223 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | 4241 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), |
| | 4242 | .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct), |
| 4224 | } | 4243 | } |
| 4225 | }, | 4244 | }, |
| 4226 | else => unreachable, | 4245 | else => unreachable, |
| ... | @@ -4896,6 +4915,7 @@ fn genBinOp( | ... | @@ -4896,6 +4915,7 @@ fn genBinOp( |
| 4896 | .import => unreachable, | 4915 | .import => unreachable, |
| 4897 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | 4916 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), |
| 4898 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | 4917 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), |
| | 4918 | .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct), |
| 4899 | } | 4919 | } |
| 4900 | }, | 4920 | }, |
| 4901 | else => unreachable, | 4921 | else => unreachable, |
| ... | @@ -5042,6 +5062,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5042,6 +5062,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5042 | .import => unreachable, | 5062 | .import => unreachable, |
| 5043 | .got => try self.asmMovLinker(dst_addr_reg, atom_index, load_struct), | 5063 | .got => try self.asmMovLinker(dst_addr_reg, atom_index, load_struct), |
| 5044 | .direct => try self.asmLeaLinker(dst_addr_reg, atom_index, load_struct), | 5064 | .direct => try self.asmLeaLinker(dst_addr_reg, atom_index, load_struct), |
| | 5065 | .tlv => try self.genTlvPtr(dst_addr_reg, atom_index, load_struct), |
| 5045 | } | 5066 | } |
| 5046 | }, | 5067 | }, |
| 5047 | else => unreachable, | 5068 | else => unreachable, |
| ... | @@ -5087,6 +5108,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s | ... | @@ -5087,6 +5108,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s |
| 5087 | .import => unreachable, | 5108 | .import => unreachable, |
| 5088 | .got => try self.asmMovLinker(src_addr_reg, atom_index, load_struct), | 5109 | .got => try self.asmMovLinker(src_addr_reg, atom_index, load_struct), |
| 5089 | .direct => try self.asmLeaLinker(src_addr_reg, atom_index, load_struct), | 5110 | .direct => try self.asmLeaLinker(src_addr_reg, atom_index, load_struct), |
| | 5111 | .tlv => try self.genTlvPtr(src_addr_reg, atom_index, load_struct), |
| 5090 | } | 5112 | } |
| 5091 | }, | 5113 | }, |
| 5092 | else => unreachable, | 5114 | else => unreachable, |
| ... | @@ -6124,6 +6146,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -6124,6 +6146,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 6124 | .import => unreachable, | 6146 | .import => unreachable, |
| 6125 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | 6147 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), |
| 6126 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | 6148 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), |
| | 6149 | .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct), |
| 6127 | } | 6150 | } |
| 6128 | }, | 6151 | }, |
| 6129 | else => unreachable, | 6152 | else => unreachable, |
| ... | @@ -7081,6 +7104,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE | ... | @@ -7081,6 +7104,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 7081 | .import => unreachable, | 7104 | .import => unreachable, |
| 7082 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | 7105 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), |
| 7083 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | 7106 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), |
| | 7107 | .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct), |
| 7084 | } | 7108 | } |
| 7085 | }, | 7109 | }, |
| 7086 | else => unreachable, | 7110 | else => unreachable, |
| ... | @@ -7308,6 +7332,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl | ... | @@ -7308,6 +7332,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 7308 | .import => unreachable, | 7332 | .import => unreachable, |
| 7309 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), | 7333 | .got => try self.asmMovLinker(addr_reg, atom_index, load_struct), |
| 7310 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), | 7334 | .direct => try self.asmLeaLinker(addr_reg, atom_index, load_struct), |
| | 7335 | .tlv => try self.genTlvPtr(addr_reg, atom_index, load_struct), |
| 7311 | } | 7336 | } |
| 7312 | }, | 7337 | }, |
| 7313 | else => unreachable, | 7338 | else => unreachable, |
| ... | @@ -7439,6 +7464,11 @@ fn genInlineMemcpy( | ... | @@ -7439,6 +7464,11 @@ fn genInlineMemcpy( |
| 7439 | switch (load_struct.type) { | 7464 | switch (load_struct.type) { |
| 7440 | .import => unreachable, | 7465 | .import => unreachable, |
| 7441 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), | 7466 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), |
| | 7467 | .tlv => { |
| | 7468 | try self.genTlvPtr(.rdi, atom_index, load_struct); |
| | 7469 | // Load the pointer, which is stored in memory |
| | 7470 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| | 7471 | }, |
| 7442 | } | 7472 | } |
| 7443 | }, | 7473 | }, |
| 7444 | .stack_offset, .ptr_stack_offset => |off| { | 7474 | .stack_offset, .ptr_stack_offset => |off| { |
| ... | @@ -7481,6 +7511,11 @@ fn genInlineMemcpy( | ... | @@ -7481,6 +7511,11 @@ fn genInlineMemcpy( |
| 7481 | switch (load_struct.type) { | 7511 | switch (load_struct.type) { |
| 7482 | .import => unreachable, | 7512 | .import => unreachable, |
| 7483 | .got, .direct => try self.asmMovLinker(.rsi, atom_index, load_struct), | 7513 | .got, .direct => try self.asmMovLinker(.rsi, atom_index, load_struct), |
| | 7514 | .tlv => { |
| | 7515 | try self.genTlvPtr(.rsi, atom_index, load_struct); |
| | 7516 | // Load the pointer, which is stored in memory |
| | 7517 | try self.asmRegisterMemory(.mov, .rsi, Memory.sib(.qword, .{ .base = .rsi })); |
| | 7518 | }, |
| 7484 | } | 7519 | } |
| 7485 | }, | 7520 | }, |
| 7486 | .stack_offset, .ptr_stack_offset => |off| { | 7521 | .stack_offset, .ptr_stack_offset => |off| { |
| ... | @@ -7546,6 +7581,11 @@ fn genInlineMemset( | ... | @@ -7546,6 +7581,11 @@ fn genInlineMemset( |
| 7546 | switch (load_struct.type) { | 7581 | switch (load_struct.type) { |
| 7547 | .import => unreachable, | 7582 | .import => unreachable, |
| 7548 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), | 7583 | .got, .direct => try self.asmMovLinker(.rdi, atom_index, load_struct), |
| | 7584 | .tlv => { |
| | 7585 | try self.genTlvPtr(.rdi, atom_index, load_struct); |
| | 7586 | // Load the pointer, which is stored in memory |
| | 7587 | try self.asmRegisterMemory(.mov, .rdi, Memory.sib(.qword, .{ .base = .rdi })); |
| | 7588 | }, |
| 7549 | } | 7589 | } |
| 7550 | }, | 7590 | }, |
| 7551 | .stack_offset, .ptr_stack_offset => |off| { | 7591 | .stack_offset, .ptr_stack_offset => |off| { |
| ... | @@ -7735,7 +7775,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -7735,7 +7775,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 7735 | switch (ty.zigTypeTag()) { | 7775 | switch (ty.zigTypeTag()) { |
| 7736 | .Float => { | 7776 | .Float => { |
| 7737 | const base_reg = (try self.register_manager.allocReg(null, gp)).to64(); | 7777 | const base_reg = (try self.register_manager.allocReg(null, gp)).to64(); |
| 7738 | try self.asmLeaLinker(base_reg, atom_index, load_struct); | 7778 | switch (load_struct.type) { |
| | 7779 | .tlv => try self.genTlvPtr(base_reg, atom_index, load_struct), |
| | 7780 | else => try self.asmLeaLinker(base_reg, atom_index, load_struct), |
| | 7781 | } |
| 7739 | | 7782 | |
| 7740 | if (intrinsicsAllowed(self.target.*, ty)) { | 7783 | if (intrinsicsAllowed(self.target.*, ty)) { |
| 7741 | return self.asmRegisterMemory( | 7784 | return self.asmRegisterMemory( |
| ... | @@ -7753,7 +7796,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -7753,7 +7796,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 7753 | | 7796 | |
| 7754 | return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); | 7797 | return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); |
| 7755 | }, | 7798 | }, |
| 7756 | else => try self.asmMovLinker(registerAlias(reg, abi_size), atom_index, load_struct), | 7799 | else => switch (load_struct.type) { |
| | 7800 | .tlv => { |
| | 7801 | try self.genTlvPtr(reg.to64(), atom_index, load_struct); |
| | 7802 | try self.asmRegisterMemory( |
| | 7803 | .mov, |
| | 7804 | registerAlias(reg, abi_size), |
| | 7805 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }), |
| | 7806 | ); |
| | 7807 | }, |
| | 7808 | else => try self.asmMovLinker(registerAlias(reg, abi_size), atom_index, load_struct), |
| | 7809 | }, |
| 7757 | } | 7810 | } |
| 7758 | }, | 7811 | }, |
| 7759 | .stack_offset => |off| { | 7812 | .stack_offset => |off| { |