authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-10 00:57:54+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-10 00:57:54+02:00
log485d8819b33e3fca1eb63b0d109019d0c3fc15fc
treeccd53cb90b53be7bdc1b5e24e543b3907178d47f
parentfc5a6e0e327c1b671aa782d24059e27e5aa55c84

aarch64: update codegen to using a global index rather than local index


2 files changed, 37 insertions(+), 54 deletions(-)

src/arch/aarch64/CodeGen.zig+35-50
...@@ -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 at139 /// 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 entry142 /// 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 referenced145 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 in148 /// 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 x303488 // 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 register4582 .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 until5086 // 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)) |_| {
src/arch/aarch64/Emit.zig+2-4
...@@ -681,12 +681,10 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -681,12 +681,10 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
681 };681 };
682 // Add relocation to the decl.682 // Add relocation to the decl.
683 const atom = macho_file.atom_by_index_table.get(relocation.atom_index).?;683 const atom = macho_file.atom_by_index_table.get(relocation.atom_index).?;
684 const target = macho_file.getGlobalByIndex(relocation.sym_index);
684 try atom.relocs.append(emit.bin_file.allocator, .{685 try atom.relocs.append(emit.bin_file.allocator, .{
685 .offset = offset,686 .offset = offset,
686 .target = .{687 .target = target,
687 .sym_index = relocation.sym_index,
688 .file = null,
689 },
690 .addend = 0,688 .addend = 0,
691 .subtractor = null,689 .subtractor = null,
692 .pcrel = true,690 .pcrel = true,