| ... | @@ -139,21 +139,10 @@ const MCValue = union(enum) { | ... | @@ -139,21 +139,10 @@ const MCValue = union(enum) { |
| 139 | /// If the type is a pointer, it means the pointer address is at | 139 | /// If the type is a pointer, it means the pointer address is at |
| 140 | /// this memory location. | 140 | /// this memory location. |
| 141 | memory: u64, | 141 | memory: u64, |
| 142 | /// The value is in memory referenced indirectly via a GOT entry | 142 | /// The value is in memory but requires a linker relocation fixup: |
| 143 | /// index. | 143 | /// * got - the value is referenced indirectly via GOT entry index (the linker emits a got-type reloc) |
| 144 | /// | 144 | /// * direct - the value is referenced directly via symbol index index (the linker emits a displacement reloc) |
| 145 | /// If the type is a pointer, it means the pointer is referenced | 145 | linker_load: struct { @"type": enum { got, direct }, sym_index: u32 }, |
| 146 | /// indirectly via GOT. When lowered, linker will emit | | |
| 147 | /// relocations of type ARM64_RELOC_GOT_LOAD_PAGE21 and | | |
| 148 | /// ARM64_RELOC_GOT_LOAD_PAGEOFF12. | | |
| 149 | got_load: u32, | | |
| 150 | /// The value is in memory referenced directly via symbol index. | | |
| 151 | /// | | |
| 152 | /// If the type is a pointer, it means the pointer is referenced | | |
| 153 | /// directly via symbol index. When lowered, linker will emit a | | |
| 154 | /// relocation of type ARM64_RELOC_PAGE21 and | | |
| 155 | /// ARM64_RELOC_PAGEOFF12. | | |
| 156 | direct_load: u32, | | |
| 157 | /// The value is one of the stack variables. | 146 | /// The value is one of the stack variables. |
| 158 | /// | 147 | /// |
| 159 | /// If the type is a pointer, it means the pointer address is in | 148 | /// If the type is a pointer, it means the pointer address is in |
| ... | @@ -2959,8 +2948,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -2959,8 +2948,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2959 | .memory, | 2948 | .memory, |
| 2960 | .stack_offset, | 2949 | .stack_offset, |
| 2961 | .stack_argument_offset, | 2950 | .stack_argument_offset, |
| 2962 | .got_load, | 2951 | .linker_load, |
| 2963 | .direct_load, | | |
| 2964 | => { | 2952 | => { |
| 2965 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); | 2953 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 2966 | try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty); | 2954 | try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty); |
| ... | @@ -3197,8 +3185,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -3197,8 +3185,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3197 | .memory, | 3185 | .memory, |
| 3198 | .stack_offset, | 3186 | .stack_offset, |
| 3199 | .stack_argument_offset, | 3187 | .stack_argument_offset, |
| 3200 | .got_load, | 3188 | .linker_load, |
| 3201 | .direct_load, | | |
| 3202 | => { | 3189 | => { |
| 3203 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); | 3190 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3204 | try self.store(.{ .register = addr_reg }, value, ptr_ty, value_ty); | 3191 | try self.store(.{ .register = addr_reg }, value, ptr_ty, value_ty); |
| ... | @@ -3493,7 +3480,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3493,7 +3480,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3493 | const func = func_payload.data; | 3480 | const func = func_payload.data; |
| 3494 | const fn_owner_decl = mod.declPtr(func.owner_decl); | 3481 | const fn_owner_decl = mod.declPtr(func.owner_decl); |
| 3495 | try self.genSetReg(Type.initTag(.u64), .x30, .{ | 3482 | try self.genSetReg(Type.initTag(.u64), .x30, .{ |
| 3496 | .got_load = fn_owner_decl.link.macho.sym_index, | 3483 | .linker_load = .{ |
| | 3484 | .@"type" = .got, |
| | 3485 | .sym_index = fn_owner_decl.link.macho.sym_index, |
| | 3486 | }, |
| 3497 | }); | 3487 | }); |
| 3498 | // blr x30 | 3488 | // blr x30 |
| 3499 | _ = try self.addInst(.{ | 3489 | _ = try self.addInst(.{ |
| ... | @@ -4427,8 +4417,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -4427,8 +4417,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 4427 | .register = cond_reg, | 4417 | .register = cond_reg, |
| 4428 | }); | 4418 | }); |
| 4429 | }, | 4419 | }, |
| 4430 | .got_load, | 4420 | .linker_load, |
| 4431 | .direct_load, | | |
| 4432 | .memory, | 4421 | .memory, |
| 4433 | .stack_argument_offset, | 4422 | .stack_argument_offset, |
| 4434 | .stack_offset, | 4423 | .stack_offset, |
| ... | @@ -4479,13 +4468,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -4479,13 +4468,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 4479 | }); | 4468 | }); |
| 4480 | }, | 4469 | }, |
| 4481 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = addr }), | 4470 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = addr }), |
| 4482 | .got_load, | 4471 | .linker_load => |load_struct| { |
| 4483 | .direct_load, | 4472 | const tag: Mir.Inst.Tag = switch (load_struct.@"type") { |
| 4484 | => |sym_index| { | 4473 | .got => .load_memory_ptr_got, |
| 4485 | const tag: Mir.Inst.Tag = switch (mcv) { | 4474 | .direct => .load_memory_ptr_direct, |
| 4486 | .got_load => .load_memory_ptr_got, | | |
| 4487 | .direct_load => .load_memory_ptr_direct, | | |
| 4488 | else => unreachable, | | |
| 4489 | }; | 4475 | }; |
| 4490 | const mod = self.bin_file.options.module.?; | 4476 | const mod = self.bin_file.options.module.?; |
| 4491 | _ = try self.addInst(.{ | 4477 | _ = try self.addInst(.{ |
| ... | @@ -4494,7 +4480,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro | ... | @@ -4494,7 +4480,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 4494 | .payload = try self.addExtra(Mir.LoadMemoryPie{ | 4480 | .payload = try self.addExtra(Mir.LoadMemoryPie{ |
| 4495 | .register = @enumToInt(src_reg), | 4481 | .register = @enumToInt(src_reg), |
| 4496 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, | 4482 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| 4497 | .sym_index = sym_index, | 4483 | .sym_index = load_struct.sym_index, |
| 4498 | }), | 4484 | }), |
| 4499 | }, | 4485 | }, |
| 4500 | }); | 4486 | }); |
| ... | @@ -4594,13 +4580,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -4594,13 +4580,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 4594 | }); | 4580 | }); |
| 4595 | }, | 4581 | }, |
| 4596 | .register_with_overflow => unreachable, // doesn't fit into a register | 4582 | .register_with_overflow => unreachable, // doesn't fit into a register |
| 4597 | .got_load, | 4583 | .linker_load => |load_struct| { |
| 4598 | .direct_load, | 4584 | const tag: Mir.Inst.Tag = switch (load_struct.@"type") { |
| 4599 | => |sym_index| { | 4585 | .got => .load_memory_got, |
| 4600 | const tag: Mir.Inst.Tag = switch (mcv) { | 4586 | .direct => .load_memory_direct, |
| 4601 | .got_load => .load_memory_got, | | |
| 4602 | .direct_load => .load_memory_direct, | | |
| 4603 | else => unreachable, | | |
| 4604 | }; | 4587 | }; |
| 4605 | const mod = self.bin_file.options.module.?; | 4588 | const mod = self.bin_file.options.module.?; |
| 4606 | _ = try self.addInst(.{ | 4589 | _ = try self.addInst(.{ |
| ... | @@ -4609,7 +4592,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -4609,7 +4592,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 4609 | .payload = try self.addExtra(Mir.LoadMemoryPie{ | 4592 | .payload = try self.addExtra(Mir.LoadMemoryPie{ |
| 4610 | .register = @enumToInt(reg), | 4593 | .register = @enumToInt(reg), |
| 4611 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, | 4594 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| 4612 | .sym_index = sym_index, | 4595 | .sym_index = load_struct.sym_index, |
| 4613 | }), | 4596 | }), |
| 4614 | }, | 4597 | }, |
| 4615 | }); | 4598 | }); |
| ... | @@ -4741,8 +4724,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -4741,8 +4724,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4741 | .register_with_overflow => { | 4724 | .register_with_overflow => { |
| 4742 | return self.fail("TODO implement genSetStackArgument {}", .{mcv}); | 4725 | return self.fail("TODO implement genSetStackArgument {}", .{mcv}); |
| 4743 | }, | 4726 | }, |
| 4744 | .got_load, | 4727 | .linker_load, |
| 4745 | .direct_load, | | |
| 4746 | .memory, | 4728 | .memory, |
| 4747 | .stack_argument_offset, | 4729 | .stack_argument_offset, |
| 4748 | .stack_offset, | 4730 | .stack_offset, |
| ... | @@ -4785,13 +4767,10 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -4785,13 +4767,10 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4785 | }); | 4767 | }); |
| 4786 | }, | 4768 | }, |
| 4787 | .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }), | 4769 | .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }), |
| 4788 | .got_load, | 4770 | .linker_load => |load_struct| { |
| 4789 | .direct_load, | 4771 | const tag: Mir.Inst.Tag = switch (load_struct.@"type") { |
| 4790 | => |sym_index| { | 4772 | .got => .load_memory_ptr_got, |
| 4791 | const tag: Mir.Inst.Tag = switch (mcv) { | 4773 | .direct => .load_memory_ptr_direct, |
| 4792 | .got_load => .load_memory_ptr_got, | | |
| 4793 | .direct_load => .load_memory_ptr_direct, | | |
| 4794 | else => unreachable, | | |
| 4795 | }; | 4774 | }; |
| 4796 | const mod = self.bin_file.options.module.?; | 4775 | const mod = self.bin_file.options.module.?; |
| 4797 | _ = try self.addInst(.{ | 4776 | _ = try self.addInst(.{ |
| ... | @@ -4800,7 +4779,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I | ... | @@ -4800,7 +4779,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4800 | .payload = try self.addExtra(Mir.LoadMemoryPie{ | 4779 | .payload = try self.addExtra(Mir.LoadMemoryPie{ |
| 4801 | .register = @enumToInt(src_reg), | 4780 | .register = @enumToInt(src_reg), |
| 4802 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, | 4781 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| 4803 | .sym_index = sym_index, | 4782 | .sym_index = load_struct.sym_index, |
| 4804 | }), | 4783 | }), |
| 4805 | }, | 4784 | }, |
| 4806 | }); | 4785 | }); |
| ... | @@ -5107,7 +5086,10 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne | ... | @@ -5107,7 +5086,10 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne |
| 5107 | // Because MachO is PIE-always-on, we defer memory address resolution until | 5086 | // Because MachO is PIE-always-on, we defer memory address resolution until |
| 5108 | // the linker has enough info to perform relocations. | 5087 | // the linker has enough info to perform relocations. |
| 5109 | assert(decl.link.macho.sym_index != 0); | 5088 | assert(decl.link.macho.sym_index != 0); |
| 5110 | return MCValue{ .got_load = decl.link.macho.sym_index }; | 5089 | return MCValue{ .linker_load = .{ |
| | 5090 | .@"type" = .got, |
| | 5091 | .sym_index = decl.link.macho.sym_index, |
| | 5092 | } }; |
| 5111 | } else if (self.bin_file.cast(link.File.Coff)) |_| { | 5093 | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| 5112 | return self.fail("TODO codegen COFF const Decl pointer", .{}); | 5094 | return self.fail("TODO codegen COFF const Decl pointer", .{}); |
| 5113 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 5095 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| ... | @@ -5129,7 +5111,10 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { | ... | @@ -5129,7 +5111,10 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { |
| 5129 | const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; | 5111 | const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; |
| 5130 | return MCValue{ .memory = vaddr }; | 5112 | return MCValue{ .memory = vaddr }; |
| 5131 | } else if (self.bin_file.cast(link.File.MachO)) |_| { | 5113 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 5132 | return MCValue{ .direct_load = local_sym_index }; | 5114 | return MCValue{ .linker_load = .{ |
| | 5115 | .@"type" = .direct, |
| | 5116 | .sym_index = local_sym_index, |
| | 5117 | } }; |
| 5133 | } else if (self.bin_file.cast(link.File.Coff)) |_| { | 5118 | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| 5134 | return self.fail("TODO lower unnamed const in COFF", .{}); | 5119 | return self.fail("TODO lower unnamed const in COFF", .{}); |
| 5135 | } else if (self.bin_file.cast(link.File.Plan9)) |_| { | 5120 | } else if (self.bin_file.cast(link.File.Plan9)) |_| { |