authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-23 21:32:25+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-23 21:58:13+01:00
logf91fe9afb92dda2b7b1ae37147ce7af40101d5ea
tree3e9743e17dab31808acbd39def65afa3aba85b51
parent4683f94463cf7165bcaf88c8de73dd7ed5279c60
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: more support for MCValue.got_load and direct_load


9 files changed, 73 insertions(+), 41 deletions(-)

src/arch/aarch64/CodeGen.zig+26-23
......@@ -1717,6 +1717,8 @@ fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_ind
17171717
17181718fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
17191719 const elem_ty = ptr_ty.elemType();
1720 const elem_size = elem_ty.abiSize(self.target.*);
1721
17201722 switch (ptr) {
17211723 .none => unreachable,
17221724 .undef => unreachable,
......@@ -1736,17 +1738,16 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
17361738 self.register_manager.freezeRegs(&.{addr_reg});
17371739 defer self.register_manager.unfreezeRegs(&.{addr_reg});
17381740
1739 const abi_size = elem_ty.abiSize(self.target.*);
17401741 switch (dst_mcv) {
17411742 .dead => unreachable,
17421743 .undef => unreachable,
17431744 .compare_flags_signed, .compare_flags_unsigned => unreachable,
17441745 .embedded_in_code => unreachable,
17451746 .register => |dst_reg| {
1746 try self.genLdrRegister(dst_reg, addr_reg, abi_size);
1747 try self.genLdrRegister(dst_reg, addr_reg, elem_size);
17471748 },
17481749 .stack_offset => |off| {
1749 if (abi_size <= 8) {
1750 if (elem_size <= 8) {
17501751 const tmp_reg = try self.register_manager.allocReg(null);
17511752 self.register_manager.freezeRegs(&.{tmp_reg});
17521753 defer self.register_manager.unfreezeRegs(&.{tmp_reg});
......@@ -1766,17 +1767,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
17661767 const tmp_reg = regs[3];
17671768
17681769 // sub dst_reg, fp, #off
1769 const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
1770 const adj_off = off + elem_size;
1771 const offset = math.cast(u12, adj_off) catch return self.fail("TODO load: larger stack offsets", .{});
1772 _ = try self.addInst(.{
1773 .tag = .sub_immediate,
1774 .data = .{ .rr_imm12_sh = .{
1775 .rd = dst_reg,
1776 .rn = .x29,
1777 .imm12 = offset,
1778 } },
1779 });
1770 try self.genSetReg(ptr_ty, dst_reg, .{ .ptr_stack_offset = off });
17801771
17811772 // mov len, #elem_size
17821773 try self.genSetReg(Type.usize, len_reg, .{ .immediate = elem_size });
......@@ -2046,14 +2037,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
20462037 },
20472038 .memory,
20482039 .stack_offset,
2049 => {
2050 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr);
2051 try self.store(.{ .register = addr_reg }, value, ptr_ty, value_ty);
2052 },
20532040 .got_load,
20542041 .direct_load,
20552042 => {
2056 return self.fail("TODO implement storing to {}", .{ptr});
2043 const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr);
2044 try self.store(.{ .register = addr_reg }, value, ptr_ty, value_ty);
20572045 },
20582046 }
20592047}
......@@ -3142,10 +3130,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
31423130 },
31433131 .got_load,
31443132 .direct_load,
3145 => |sym_index| {
3146 _ = sym_index;
3147 return self.fail("TODO implement set stack variable from {}", .{mcv});
3148 },
31493133 .memory,
31503134 .stack_offset,
31513135 => {
......@@ -3187,6 +3171,25 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
31873171 });
31883172 },
31893173 .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = addr }),
3174 .got_load,
3175 .direct_load,
3176 => |sym_index| {
3177 const tag: Mir.Inst.Tag = switch (mcv) {
3178 .got_load => .load_memory_ptr_got,
3179 .direct_load => .load_memory_ptr_direct,
3180 else => unreachable,
3181 };
3182 _ = try self.addInst(.{
3183 .tag = tag,
3184 .data = .{
3185 .payload = try self.addExtra(Mir.LoadMemoryPie{
3186 .register = @enumToInt(src_reg),
3187 .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index,
3188 .sym_index = sym_index,
3189 }),
3190 },
3191 });
3192 },
31903193 else => unreachable,
31913194 }
31923195
src/arch/aarch64/Emit.zig+35-10
......@@ -110,6 +110,8 @@ pub fn emitMir(
110110
111111 .load_memory_got => try emit.mirLoadMemoryPie(inst),
112112 .load_memory_direct => try emit.mirLoadMemoryPie(inst),
113 .load_memory_ptr_got => try emit.mirLoadMemoryPie(inst),
114 .load_memory_ptr_direct => try emit.mirLoadMemoryPie(inst),
113115
114116 .ldp => try emit.mirLoadStoreRegisterPair(inst),
115117 .stp => try emit.mirLoadStoreRegisterPair(inst),
......@@ -208,6 +210,8 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize {
208210 switch (tag) {
209211 .load_memory_got,
210212 .load_memory_direct,
213 .load_memory_ptr_got,
214 .load_memory_ptr_direct,
211215 => return 2 * 4,
212216 .pop_regs, .push_regs => {
213217 const reg_list = emit.mir.instructions.items(.data)[inst].reg_list;
......@@ -655,12 +659,25 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
655659 const offset = @intCast(u32, emit.code.items.len);
656660 try emit.writeInstruction(Instruction.adrp(reg, 0));
657661
658 // ldr reg, reg, offset
659 try emit.writeInstruction(Instruction.ldr(
660 reg,
661 reg,
662 Instruction.LoadStoreOffset.imm(0),
663 ));
662 switch (tag) {
663 .load_memory_got,
664 .load_memory_direct,
665 => {
666 // ldr reg, reg, offset
667 try emit.writeInstruction(Instruction.ldr(
668 reg,
669 reg,
670 Instruction.LoadStoreOffset.imm(0),
671 ));
672 },
673 .load_memory_ptr_got,
674 .load_memory_ptr_direct,
675 => {
676 // add reg, reg, offset
677 try emit.writeInstruction(Instruction.add(reg, reg, 0, false));
678 },
679 else => unreachable,
680 }
664681
665682 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
666683 const atom = macho_file.atom_by_index_table.get(data.atom_index).?;
......@@ -673,8 +690,12 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
673690 .pcrel = true,
674691 .length = 2,
675692 .@"type" = switch (tag) {
676 .load_memory_got => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21),
677 .load_memory_direct => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_PAGE21),
693 .load_memory_got,
694 .load_memory_ptr_got,
695 => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21),
696 .load_memory_direct,
697 .load_memory_ptr_direct,
698 => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_PAGE21),
678699 else => unreachable,
679700 },
680701 });
......@@ -687,8 +708,12 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
687708 .pcrel = false,
688709 .length = 2,
689710 .@"type" = switch (tag) {
690 .load_memory_got => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12),
691 .load_memory_direct => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_PAGEOFF12),
711 .load_memory_got,
712 .load_memory_ptr_got,
713 => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12),
714 .load_memory_direct,
715 .load_memory_ptr_direct,
716 => @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_PAGEOFF12),
692717 else => unreachable,
693718 },
694719 });
src/arch/aarch64/Mir.zig+12
......@@ -56,10 +56,22 @@ pub const Inst = struct {
5656 dbg_line,
5757 /// Bitwise Exclusive OR (shifted register)
5858 eor_shifted_register,
59 /// Loads the contents into a register
60 ///
5961 /// Payload is `LoadMemoryPie`
6062 load_memory_got,
63 /// Loads the contents into a register
64 ///
6165 /// Payload is `LoadMemoryPie`
6266 load_memory_direct,
67 /// Loads the address into a register
68 ///
69 /// Payload is `LoadMemoryPie`
70 load_memory_ptr_got,
71 /// Loads the address into a register
72 ///
73 /// Payload is `LoadMemoryPie`
74 load_memory_ptr_direct,
6375 /// Load Pair of Registers
6476 ldp,
6577 /// Pseudo-instruction: Load from stack
test/behavior/align.zig-1
......@@ -305,7 +305,6 @@ fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) !void {
305305}
306306
307307test "alignment of function with c calling convention" {
308 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
309308 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
310309
311310 var runtime_nothing = &nothing;
test/behavior/basic.zig-3
......@@ -48,7 +48,6 @@ const g1: i32 = 1233 + 1;
4848var g2: i32 = 0;
4949
5050test "global variables" {
51 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
5251 try expect(g2 == 0);
5352 g2 = g1;
5453 try expect(g2 == 1234);
......@@ -604,7 +603,6 @@ test "comptime cast fn to ptr" {
604603}
605604
606605test "equality compare fn ptrs" {
607 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
608606 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
609607
610608 var a = &emptyFn;
......@@ -612,7 +610,6 @@ test "equality compare fn ptrs" {
612610}
613611
614612test "self reference through fn ptr field" {
615 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
616613 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
617614 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
618615
test/behavior/bugs/2006.zig-1
......@@ -6,7 +6,6 @@ const S = struct {
66 p: *S,
77};
88test "bug 2006" {
9 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
109 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1110 var a: S = undefined;
1211 a = S{ .p = undefined };
test/behavior/cast.zig-1
......@@ -1013,7 +1013,6 @@ test "cast from array reference to fn: comptime fn ptr" {
10131013 try expect(@ptrToInt(f) == @ptrToInt(&global_array));
10141014}
10151015test "cast from array reference to fn: runtime fn ptr" {
1016 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
10171016 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
10181017 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10191018 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
test/behavior/slice.zig-1
......@@ -81,7 +81,6 @@ fn assertLenIsZero(msg: []const u8) !void {
8181}
8282
8383test "access len index of sentinel-terminated slice" {
84 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
8584 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
8685
8786 const S = struct {
test/behavior/struct.zig-1
......@@ -66,7 +66,6 @@ const SmallStruct = struct {
6666};
6767
6868test "lower unnamed constants" {
69 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
7069 var foo = SmallStruct{ .a = 1, .b = 255 };
7170 try expect(foo.first() == 1);
7271 try expect(foo.second() == 255);