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 {...@@ -587,12 +587,11 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {
587 try emit.writeInstruction(Instruction.adrp(reg, 0));587 try emit.writeInstruction(Instruction.adrp(reg, 0));
588588
589 // ldr reg, reg, offset589 // ldr reg, reg, offset
590 try emit.writeInstruction(Instruction.ldr(reg, .{590 try emit.writeInstruction(Instruction.ldr(
591 .register = .{591 reg,
592 .rn = reg,592 reg,
593 .offset = Instruction.LoadStoreOffset.imm(0),593 Instruction.LoadStoreOffset.imm(0),
594 },594 ));
595 }));
596595
597 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {596 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
598 // TODO I think the reloc might be in the wrong place.597 // TODO I think the reloc might be in the wrong place.
...@@ -626,7 +625,8 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -626,7 +625,8 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {
626 try emit.moveImmediate(reg, addr);625 try emit.moveImmediate(reg, addr);
627 try emit.writeInstruction(Instruction.ldr(626 try emit.writeInstruction(Instruction.ldr(
628 reg,627 reg,
629 .{ .register = .{ .rn = reg, .offset = Instruction.LoadStoreOffset.none } },628 reg,
629 Instruction.LoadStoreOffset.none,
630 ));630 ));
631 }631 }
632}632}
...@@ -659,32 +659,33 @@ fn mirLoadStoreRegister(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -659,32 +659,33 @@ fn mirLoadStoreRegister(emit: *Emit, inst: Mir.Inst.Index) !void {
659 switch (tag) {659 switch (tag) {
660 .ldr => try emit.writeInstruction(Instruction.ldr(660 .ldr => try emit.writeInstruction(Instruction.ldr(
661 load_store_register.rt,661 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,
663 )),664 )),
664 .ldrb => try emit.writeInstruction(Instruction.ldrb(665 .ldrb => try emit.writeInstruction(Instruction.ldrb(
665 load_store_register.rt,666 load_store_register.rt,
666 load_store_register.rn,667 load_store_register.rn,
667 .{ .offset = load_store_register.offset },668 load_store_register.offset,
668 )),669 )),
669 .ldrh => try emit.writeInstruction(Instruction.ldrh(670 .ldrh => try emit.writeInstruction(Instruction.ldrh(
670 load_store_register.rt,671 load_store_register.rt,
671 load_store_register.rn,672 load_store_register.rn,
672 .{ .offset = load_store_register.offset },673 load_store_register.offset,
673 )),674 )),
674 .str => try emit.writeInstruction(Instruction.str(675 .str => try emit.writeInstruction(Instruction.str(
675 load_store_register.rt,676 load_store_register.rt,
676 load_store_register.rn,677 load_store_register.rn,
677 .{ .offset = load_store_register.offset },678 load_store_register.offset,
678 )),679 )),
679 .strb => try emit.writeInstruction(Instruction.strb(680 .strb => try emit.writeInstruction(Instruction.strb(
680 load_store_register.rt,681 load_store_register.rt,
681 load_store_register.rn,682 load_store_register.rn,
682 .{ .offset = load_store_register.offset },683 load_store_register.offset,
683 )),684 )),
684 .strh => try emit.writeInstruction(Instruction.strh(685 .strh => try emit.writeInstruction(Instruction.strh(
685 load_store_register.rt,686 load_store_register.rt,
686 load_store_register.rn,687 load_store_register.rn,
687 .{ .offset = load_store_register.offset },688 load_store_register.offset,
688 )),689 )),
689 else => unreachable,690 else => unreachable,
690 }691 }
src/arch/aarch64/bits.zig+36-57
...@@ -742,27 +742,17 @@ pub const Instruction = union(enum) {...@@ -742,27 +742,17 @@ pub const Instruction = union(enum) {
742 }742 }
743743
744 fn loadLiteral(rt: Register, imm19: u19) Instruction {744 fn loadLiteral(rt: Register, imm19: u19) Instruction {
745 switch (rt.size()) {745 return Instruction{
746 32 => {746 .load_literal = .{
747 return Instruction{747 .rt = rt.id(),
748 .load_literal = .{748 .imm19 = imm19,
749 .rt = rt.id(),749 .opc = switch (rt.size()) {
750 .imm19 = imm19,750 32 => 0b00,
751 .opc = 0b00,751 64 => 0b01,
752 },752 else => unreachable, // unexpected register size
753 };753 },
754 },
755 64 => {
756 return Instruction{
757 .load_literal = .{
758 .rt = rt.id(),
759 .imm19 = imm19,
760 .opc = 0b01,
761 },
762 };
763 },754 },
764 else => unreachable, // unexpected register size755 };
765 }
766 }756 }
767757
768 fn exceptionGeneration(758 fn exceptionGeneration(
...@@ -1001,43 +991,32 @@ pub const Instruction = union(enum) {...@@ -1001,43 +991,32 @@ pub const Instruction = union(enum) {
1001991
1002 // Load or store register992 // Load or store register
1003993
1004 pub const LdrArgs = union(enum) {994 pub fn ldrLiteral(rt: Register, literal: u19) Instruction {
1005 register: struct {995 return loadLiteral(rt, literal);
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 }
1017 }996 }
1018997
1019 pub fn ldrh(rt: Register, rn: Register, args: StrArgs) Instruction {998 pub fn ldr(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1020 return loadStoreRegister(rt, rn, args.offset, .ldrh);999 return loadStoreRegister(rt, rn, offset, .ldr);
1021 }1000 }
10221001
1023 pub fn ldrb(rt: Register, rn: Register, args: StrArgs) Instruction {1002 pub fn ldrh(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1024 return loadStoreRegister(rt, rn, args.offset, .ldrb);1003 return loadStoreRegister(rt, rn, offset, .ldrh);
1025 }1004 }
10261005
1027 pub const StrArgs = struct {1006 pub fn ldrb(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1028 offset: LoadStoreOffset = LoadStoreOffset.none,1007 return loadStoreRegister(rt, rn, offset, .ldrb);
1029 };1008 }
10301009
1031 pub fn str(rt: Register, rn: Register, args: StrArgs) Instruction {1010 pub fn str(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1032 return loadStoreRegister(rt, rn, args.offset, .str);1011 return loadStoreRegister(rt, rn, offset, .str);
1033 }1012 }
10341013
1035 pub fn strh(rt: Register, rn: Register, args: StrArgs) Instruction {1014 pub fn strh(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1036 return loadStoreRegister(rt, rn, args.offset, .strh);1015 return loadStoreRegister(rt, rn, offset, .strh);
1037 }1016 }
10381017
1039 pub fn strb(rt: Register, rn: Register, args: StrArgs) Instruction {1018 pub fn strb(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
1040 return loadStoreRegister(rt, rn, args.offset, .strb);1019 return loadStoreRegister(rt, rn, offset, .strb);
1041 }1020 }
10421021
1043 // Load or store pair of registers1022 // Load or store pair of registers
...@@ -1324,47 +1303,47 @@ test "serialize instructions" {...@@ -1324,47 +1303,47 @@ test "serialize instructions" {
1324 .expected = 0b1_00101_00_0000_0000_0000_0000_0000_0100,1303 .expected = 0b1_00101_00_0000_0000_0000_0000_0000_0100,
1325 },1304 },
1326 .{ // ldr x2, [x1]1305 .{ // ldr x2, [x1]
1327 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1 } }),1306 .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.none),
1328 .expected = 0b11_111_0_01_01_000000000000_00001_00010,1307 .expected = 0b11_111_0_01_01_000000000000_00001_00010,
1329 },1308 },
1330 .{ // ldr x2, [x1, #1]!1309 .{ // 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)),
1332 .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010,1311 .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010,
1333 },1312 },
1334 .{ // ldr x2, [x1], #-11313 .{ // 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)),
1336 .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010,1315 .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010,
1337 },1316 },
1338 .{ // ldr x2, [x1], (x3)1317 .{ // 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)),
1340 .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010,1319 .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010,
1341 },1320 },
1342 .{ // ldr x2, label1321 .{ // ldr x2, label
1343 .inst = Instruction.ldr(.x2, .{ .literal = 0x1 }),1322 .inst = Instruction.ldrLiteral(.x2, 0x1),
1344 .expected = 0b01_011_0_00_0000000000000000001_00010,1323 .expected = 0b01_011_0_00_0000000000000000001_00010,
1345 },1324 },
1346 .{ // ldrh x7, [x4], #0xaa1325 .{ // 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)),
1348 .expected = 0b01_111_0_00_01_0_010101010_01_00100_00111,1327 .expected = 0b01_111_0_00_01_0_010101010_01_00100_00111,
1349 },1328 },
1350 .{ // ldrb x9, [x15, #0xff]!1329 .{ // 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)),
1352 .expected = 0b00_111_0_00_01_0_011111111_11_01111_01001,1331 .expected = 0b00_111_0_00_01_0_011111111_11_01111_01001,
1353 },1332 },
1354 .{ // str x2, [x1]1333 .{ // str x2, [x1]
1355 .inst = Instruction.str(.x2, .x1, .{}),1334 .inst = Instruction.str(.x2, .x1, Instruction.LoadStoreOffset.none),
1356 .expected = 0b11_111_0_01_00_000000000000_00001_00010,1335 .expected = 0b11_111_0_01_00_000000000000_00001_00010,
1357 },1336 },
1358 .{ // str x2, [x1], (x3)1337 .{ // 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)),
1360 .expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010,1339 .expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010,
1361 },1340 },
1362 .{ // strh w0, [x1]1341 .{ // strh w0, [x1]
1363 .inst = Instruction.strh(.w0, .x1, .{}),1342 .inst = Instruction.strh(.w0, .x1, Instruction.LoadStoreOffset.none),
1364 .expected = 0b01_111_0_01_00_000000000000_00001_00000,1343 .expected = 0b01_111_0_01_00_000000000000_00001_00000,
1365 },1344 },
1366 .{ // strb w8, [x9]1345 .{ // strb w8, [x9]
1367 .inst = Instruction.strb(.w8, .x9, .{}),1346 .inst = Instruction.strb(.w8, .x9, Instruction.LoadStoreOffset.none),
1368 .expected = 0b00_111_0_01_00_000000000000_01001_01000,1347 .expected = 0b00_111_0_01_00_000000000000_01001_01000,
1369 },1348 },
1370 .{ // adr x2, #0x81349 .{ // adr x2, #0x8
src/link/MachO.zig+14-15
...@@ -2041,12 +2041,11 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {...@@ -2041,12 +2041,11 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {
2041 .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21),2041 .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21),
2042 });2042 });
2043 // ldr x16, [x16, 0]2043 // ldr x16, [x16, 0]
2044 mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(.x16, .{2044 mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(
2045 .register = .{2045 .x16,
2046 .rn = .x16,2046 .x16,
2047 .offset = aarch64.Instruction.LoadStoreOffset.imm(0),2047 aarch64.Instruction.LoadStoreOffset.imm(0),
2048 },2048 ).toU32());
2049 }).toU32());
2050 atom.relocs.appendAssumeCapacity(.{2049 atom.relocs.appendAssumeCapacity(.{
2051 .offset = 16,2050 .offset = 16,
2052 .target = .{ .global = self.undefs.items[self.dyld_stub_binder_index.?].n_strx },2051 .target = .{ .global = self.undefs.items[self.dyld_stub_binder_index.?].n_strx },
...@@ -2119,9 +2118,10 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom {...@@ -2119,9 +2118,10 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom {
2119 break :blk try math.cast(u18, div_res);2118 break :blk try math.cast(u18, div_res);
2120 };2119 };
2121 // ldr w16, literal2120 // ldr w16, literal
2122 mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldr(.w16, .{2121 mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldrLiteral(
2123 .literal = literal,2122 .w16,
2124 }).toU32());2123 literal,
2124 ).toU32());
2125 // b disp2125 // b disp
2126 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.b(0).toU32());2126 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.b(0).toU32());
2127 atom.relocs.appendAssumeCapacity(.{2127 atom.relocs.appendAssumeCapacity(.{
...@@ -2222,12 +2222,11 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom {...@@ -2222,12 +2222,11 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom {
2222 .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21),2222 .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21),
2223 });2223 });
2224 // ldr x16, x16, offset2224 // ldr x16, x16, offset
2225 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr(.x16, .{2225 mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr(
2226 .register = .{2226 .x16,
2227 .rn = .x16,2227 .x16,
2228 .offset = aarch64.Instruction.LoadStoreOffset.imm(0),2228 aarch64.Instruction.LoadStoreOffset.imm(0),
2229 },2229 ).toU32());
2230 }).toU32());
2231 atom.relocs.appendAssumeCapacity(.{2230 atom.relocs.appendAssumeCapacity(.{
2232 .offset = 4,2231 .offset = 4,
2233 .target = .{ .local = laptr_sym_index },2232 .target = .{ .local = laptr_sym_index },