authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-11-11 22:34:24+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-11-12 22:23:29+01:00
log8ab90a0b32834d28e08210d271522e58c2a931d7
tree983faf0f451e9ee3768538c40e4d21324bf314af
parent71388b980bfc4c7eb267ed7c168c2395098f6db2
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: split Instruction.ldr into ldr and ldrLiteral


3 files changed, 64 insertions(+), 85 deletions(-)

src/arch/aarch64/Emit.zig+14-13
......@@ -587,12 +587,11 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {
587587 try emit.writeInstruction(Instruction.adrp(reg, 0));
588588
589589 // ldr reg, reg, offset
590 try emit.writeInstruction(Instruction.ldr(reg, .{
591 .register = .{
592 .rn = reg,
593 .offset = Instruction.LoadStoreOffset.imm(0),
594 },
595 }));
590 try emit.writeInstruction(Instruction.ldr(
591 reg,
592 reg,
593 Instruction.LoadStoreOffset.imm(0),
594 ));
596595
597596 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
598597 // TODO I think the reloc might be in the wrong place.
......@@ -626,7 +625,8 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {
626625 try emit.moveImmediate(reg, addr);
627626 try emit.writeInstruction(Instruction.ldr(
628627 reg,
629 .{ .register = .{ .rn = reg, .offset = Instruction.LoadStoreOffset.none } },
628 reg,
629 Instruction.LoadStoreOffset.none,
630630 ));
631631 }
632632}
......@@ -659,32 +659,33 @@ fn mirLoadStoreRegister(emit: *Emit, inst: Mir.Inst.Index) !void {
659659 switch (tag) {
660660 .ldr => try emit.writeInstruction(Instruction.ldr(
661661 load_store_register.rt,
662 .{ .register = .{ .rn = load_store_register.rn, .offset = load_store_register.offset } },
662 load_store_register.rn,
663 load_store_register.offset,
663664 )),
664665 .ldrb => try emit.writeInstruction(Instruction.ldrb(
665666 load_store_register.rt,
666667 load_store_register.rn,
667 .{ .offset = load_store_register.offset },
668 load_store_register.offset,
668669 )),
669670 .ldrh => try emit.writeInstruction(Instruction.ldrh(
670671 load_store_register.rt,
671672 load_store_register.rn,
672 .{ .offset = load_store_register.offset },
673 load_store_register.offset,
673674 )),
674675 .str => try emit.writeInstruction(Instruction.str(
675676 load_store_register.rt,
676677 load_store_register.rn,
677 .{ .offset = load_store_register.offset },
678 load_store_register.offset,
678679 )),
679680 .strb => try emit.writeInstruction(Instruction.strb(
680681 load_store_register.rt,
681682 load_store_register.rn,
682 .{ .offset = load_store_register.offset },
683 load_store_register.offset,
683684 )),
684685 .strh => try emit.writeInstruction(Instruction.strh(
685686 load_store_register.rt,
686687 load_store_register.rn,
687 .{ .offset = load_store_register.offset },
688 load_store_register.offset,
688689 )),
689690 else => unreachable,
690691 }
src/arch/aarch64/bits.zig+36-57
......@@ -742,27 +742,17 @@ pub const Instruction = union(enum) {
742742 }
743743
744744 fn loadLiteral(rt: Register, imm19: u19) Instruction {
745 switch (rt.size()) {
746 32 => {
747 return Instruction{
748 .load_literal = .{
749 .rt = rt.id(),
750 .imm19 = imm19,
751 .opc = 0b00,
752 },
753 };
754 },
755 64 => {
756 return Instruction{
757 .load_literal = .{
758 .rt = rt.id(),
759 .imm19 = imm19,
760 .opc = 0b01,
761 },
762 };
745 return Instruction{
746 .load_literal = .{
747 .rt = rt.id(),
748 .imm19 = imm19,
749 .opc = switch (rt.size()) {
750 32 => 0b00,
751 64 => 0b01,
752 else => unreachable, // unexpected register size
753 },
763754 },
764 else => unreachable, // unexpected register size
765 }
755 };
766756 }
767757
768758 fn exceptionGeneration(
......@@ -1001,43 +991,32 @@ pub const Instruction = union(enum) {
1001991
1002992 // Load or store register
1003993
1004 pub const LdrArgs = union(enum) {
1005 register: struct {
1006 rn: Register,
1007 offset: LoadStoreOffset = LoadStoreOffset.none,
1008 },
1009 literal: u19,
1010 };
1011
1012 pub fn ldr(rt: Register, args: LdrArgs) Instruction {
1013 switch (args) {
1014 .register => |info| return loadStoreRegister(rt, info.rn, info.offset, .ldr),
1015 .literal => |literal| return loadLiteral(rt, literal),
1016 }
994 pub fn ldrLiteral(rt: Register, literal: u19) Instruction {
995 return loadLiteral(rt, literal);
1017996 }
1018997
1019 pub fn ldrh(rt: Register, rn: Register, args: StrArgs) Instruction {
1020 return loadStoreRegister(rt, rn, args.offset, .ldrh);
998 pub fn ldr(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
999 return loadStoreRegister(rt, rn, offset, .ldr);
10211000 }
10221001
1023 pub fn ldrb(rt: Register, rn: Register, args: StrArgs) Instruction {
1024 return loadStoreRegister(rt, rn, args.offset, .ldrb);
1002 pub fn ldrh(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1003 return loadStoreRegister(rt, rn, offset, .ldrh);
10251004 }
10261005
1027 pub const StrArgs = struct {
1028 offset: LoadStoreOffset = LoadStoreOffset.none,
1029 };
1006 pub fn ldrb(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1007 return loadStoreRegister(rt, rn, offset, .ldrb);
1008 }
10301009
1031 pub fn str(rt: Register, rn: Register, args: StrArgs) Instruction {
1032 return loadStoreRegister(rt, rn, args.offset, .str);
1010 pub fn str(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1011 return loadStoreRegister(rt, rn, offset, .str);
10331012 }
10341013
1035 pub fn strh(rt: Register, rn: Register, args: StrArgs) Instruction {
1036 return loadStoreRegister(rt, rn, args.offset, .strh);
1014 pub fn strh(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1015 return loadStoreRegister(rt, rn, offset, .strh);
10371016 }
10381017
1039 pub fn strb(rt: Register, rn: Register, args: StrArgs) Instruction {
1040 return loadStoreRegister(rt, rn, args.offset, .strb);
1018 pub fn strb(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1019 return loadStoreRegister(rt, rn, offset, .strb);
10411020 }
10421021
10431022 // Load or store pair of registers
......@@ -1324,47 +1303,47 @@ test "serialize instructions" {
13241303 .expected = 0b1_00101_00_0000_0000_0000_0000_0000_0100,
13251304 },
13261305 .{ // ldr x2, [x1]
1327 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1 } }),
1306 .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.none),
13281307 .expected = 0b11_111_0_01_01_000000000000_00001_00010,
13291308 },
13301309 .{ // ldr x2, [x1, #1]!
1331 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_pre_index(1) } }),
1310 .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.imm_pre_index(1)),
13321311 .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010,
13331312 },
13341313 .{ // ldr x2, [x1], #-1
1335 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_post_index(-1) } }),
1314 .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.imm_post_index(-1)),
13361315 .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010,
13371316 },
13381317 .{ // ldr x2, [x1], (x3)
1339 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.reg(.x3) } }),
1318 .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.reg(.x3)),
13401319 .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010,
13411320 },
13421321 .{ // ldr x2, label
1343 .inst = Instruction.ldr(.x2, .{ .literal = 0x1 }),
1322 .inst = Instruction.ldrLiteral(.x2, 0x1),
13441323 .expected = 0b01_011_0_00_0000000000000000001_00010,
13451324 },
13461325 .{ // ldrh x7, [x4], #0xaa
1347 .inst = Instruction.ldrh(.x7, .x4, .{ .offset = Instruction.LoadStoreOffset.imm_post_index(0xaa) }),
1326 .inst = Instruction.ldrh(.x7, .x4, Instruction.LoadStoreOffset.imm_post_index(0xaa)),
13481327 .expected = 0b01_111_0_00_01_0_010101010_01_00100_00111,
13491328 },
13501329 .{ // ldrb x9, [x15, #0xff]!
1351 .inst = Instruction.ldrb(.x9, .x15, .{ .offset = Instruction.LoadStoreOffset.imm_pre_index(0xff) }),
1330 .inst = Instruction.ldrb(.x9, .x15, Instruction.LoadStoreOffset.imm_pre_index(0xff)),
13521331 .expected = 0b00_111_0_00_01_0_011111111_11_01111_01001,
13531332 },
13541333 .{ // str x2, [x1]
1355 .inst = Instruction.str(.x2, .x1, .{}),
1334 .inst = Instruction.str(.x2, .x1, Instruction.LoadStoreOffset.none),
13561335 .expected = 0b11_111_0_01_00_000000000000_00001_00010,
13571336 },
13581337 .{ // str x2, [x1], (x3)
1359 .inst = Instruction.str(.x2, .x1, .{ .offset = Instruction.LoadStoreOffset.reg(.x3) }),
1338 .inst = Instruction.str(.x2, .x1, Instruction.LoadStoreOffset.reg(.x3)),
13601339 .expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010,
13611340 },
13621341 .{ // strh w0, [x1]
1363 .inst = Instruction.strh(.w0, .x1, .{}),
1342 .inst = Instruction.strh(.w0, .x1, Instruction.LoadStoreOffset.none),
13641343 .expected = 0b01_111_0_01_00_000000000000_00001_00000,
13651344 },
13661345 .{ // strb w8, [x9]
1367 .inst = Instruction.strb(.w8, .x9, .{}),
1346 .inst = Instruction.strb(.w8, .x9, Instruction.LoadStoreOffset.none),
13681347 .expected = 0b00_111_0_01_00_000000000000_01001_01000,
13691348 },
13701349 .{ // adr x2, #0x8
src/link/MachO.zig+14-15
......@@ -2041,12 +2041,11 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {
20412041 .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21),
20422042 });
20432043 // ldr x16, [x16, 0]
2044 mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(.x16, .{
2045 .register = .{
2046 .rn = .x16,
2047 .offset = aarch64.Instruction.LoadStoreOffset.imm(0),
2048 },
2049 }).toU32());
2044 mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(
2045 .x16,
2046 .x16,
2047 aarch64.Instruction.LoadStoreOffset.imm(0),
2048 ).toU32());
20502049 atom.relocs.appendAssumeCapacity(.{
20512050 .offset = 16,
20522051 .target = .{ .global = self.undefs.items[self.dyld_stub_binder_index.?].n_strx },
......@@ -2119,9 +2118,10 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom {
21192118 break :blk try math.cast(u18, div_res);
21202119 };
21212120 // ldr w16, literal
2122 mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldr(.w16, .{
2123 .literal = literal,
2124 }).toU32());
2121 mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldrLiteral(
2122 .w16,
2123 literal,
2124 ).toU32());
21252125 // b disp
21262126 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.b(0).toU32());
21272127 atom.relocs.appendAssumeCapacity(.{
......@@ -2222,12 +2222,11 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom {
22222222 .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21),
22232223 });
22242224 // ldr x16, x16, offset
2225 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr(.x16, .{
2226 .register = .{
2227 .rn = .x16,
2228 .offset = aarch64.Instruction.LoadStoreOffset.imm(0),
2229 },
2230 }).toU32());
2225 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr(
2226 .x16,
2227 .x16,
2228 aarch64.Instruction.LoadStoreOffset.imm(0),
2229 ).toU32());
22312230 atom.relocs.appendAssumeCapacity(.{
22322231 .offset = 4,
22332232 .target = .{ .local = laptr_sym_index },