Commit 8ab90a0b32

joachimschmidt557 <joachim.schmidt557@outlook.com>
2021-11-11 22:34:24
stage2 AArch64: split Instruction.ldr into ldr and ldrLiteral
1 parent 71388b9
Changed files (3)
src
arch
link
src/arch/aarch64/bits.zig
@@ -742,27 +742,17 @@ pub const Instruction = union(enum) {
     }
 
     fn loadLiteral(rt: Register, imm19: u19) Instruction {
-        switch (rt.size()) {
-            32 => {
-                return Instruction{
-                    .load_literal = .{
-                        .rt = rt.id(),
-                        .imm19 = imm19,
-                        .opc = 0b00,
-                    },
-                };
-            },
-            64 => {
-                return Instruction{
-                    .load_literal = .{
-                        .rt = rt.id(),
-                        .imm19 = imm19,
-                        .opc = 0b01,
-                    },
-                };
+        return Instruction{
+            .load_literal = .{
+                .rt = rt.id(),
+                .imm19 = imm19,
+                .opc = switch (rt.size()) {
+                    32 => 0b00,
+                    64 => 0b01,
+                    else => unreachable, // unexpected register size
+                },
             },
-            else => unreachable, // unexpected register size
-        }
+        };
     }
 
     fn exceptionGeneration(
@@ -1001,43 +991,32 @@ pub const Instruction = union(enum) {
 
     // Load or store register
 
-    pub const LdrArgs = union(enum) {
-        register: struct {
-            rn: Register,
-            offset: LoadStoreOffset = LoadStoreOffset.none,
-        },
-        literal: u19,
-    };
-
-    pub fn ldr(rt: Register, args: LdrArgs) Instruction {
-        switch (args) {
-            .register => |info| return loadStoreRegister(rt, info.rn, info.offset, .ldr),
-            .literal => |literal| return loadLiteral(rt, literal),
-        }
+    pub fn ldrLiteral(rt: Register, literal: u19) Instruction {
+        return loadLiteral(rt, literal);
     }
 
-    pub fn ldrh(rt: Register, rn: Register, args: StrArgs) Instruction {
-        return loadStoreRegister(rt, rn, args.offset, .ldrh);
+    pub fn ldr(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
+        return loadStoreRegister(rt, rn, offset, .ldr);
     }
 
-    pub fn ldrb(rt: Register, rn: Register, args: StrArgs) Instruction {
-        return loadStoreRegister(rt, rn, args.offset, .ldrb);
+    pub fn ldrh(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
+        return loadStoreRegister(rt, rn, offset, .ldrh);
     }
 
-    pub const StrArgs = struct {
-        offset: LoadStoreOffset = LoadStoreOffset.none,
-    };
+    pub fn ldrb(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
+        return loadStoreRegister(rt, rn, offset, .ldrb);
+    }
 
-    pub fn str(rt: Register, rn: Register, args: StrArgs) Instruction {
-        return loadStoreRegister(rt, rn, args.offset, .str);
+    pub fn str(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
+        return loadStoreRegister(rt, rn, offset, .str);
     }
 
-    pub fn strh(rt: Register, rn: Register, args: StrArgs) Instruction {
-        return loadStoreRegister(rt, rn, args.offset, .strh);
+    pub fn strh(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
+        return loadStoreRegister(rt, rn, offset, .strh);
     }
 
-    pub fn strb(rt: Register, rn: Register, args: StrArgs) Instruction {
-        return loadStoreRegister(rt, rn, args.offset, .strb);
+    pub fn strb(rt: Register, rn: Register, offset: LoadStoreOffset) Instruction {
+        return loadStoreRegister(rt, rn, offset, .strb);
     }
 
     // Load or store pair of registers
@@ -1324,47 +1303,47 @@ test "serialize instructions" {
             .expected = 0b1_00101_00_0000_0000_0000_0000_0000_0100,
         },
         .{ // ldr x2, [x1]
-            .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1 } }),
+            .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.none),
             .expected = 0b11_111_0_01_01_000000000000_00001_00010,
         },
         .{ // ldr x2, [x1, #1]!
-            .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_pre_index(1) } }),
+            .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.imm_pre_index(1)),
             .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010,
         },
         .{ // ldr x2, [x1], #-1
-            .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_post_index(-1) } }),
+            .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.imm_post_index(-1)),
             .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010,
         },
         .{ // ldr x2, [x1], (x3)
-            .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.reg(.x3) } }),
+            .inst = Instruction.ldr(.x2, .x1, Instruction.LoadStoreOffset.reg(.x3)),
             .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010,
         },
         .{ // ldr x2, label
-            .inst = Instruction.ldr(.x2, .{ .literal = 0x1 }),
+            .inst = Instruction.ldrLiteral(.x2, 0x1),
             .expected = 0b01_011_0_00_0000000000000000001_00010,
         },
         .{ // ldrh x7, [x4], #0xaa
-            .inst = Instruction.ldrh(.x7, .x4, .{ .offset = Instruction.LoadStoreOffset.imm_post_index(0xaa) }),
+            .inst = Instruction.ldrh(.x7, .x4, Instruction.LoadStoreOffset.imm_post_index(0xaa)),
             .expected = 0b01_111_0_00_01_0_010101010_01_00100_00111,
         },
         .{ // ldrb x9, [x15, #0xff]!
-            .inst = Instruction.ldrb(.x9, .x15, .{ .offset = Instruction.LoadStoreOffset.imm_pre_index(0xff) }),
+            .inst = Instruction.ldrb(.x9, .x15, Instruction.LoadStoreOffset.imm_pre_index(0xff)),
             .expected = 0b00_111_0_00_01_0_011111111_11_01111_01001,
         },
         .{ // str x2, [x1]
-            .inst = Instruction.str(.x2, .x1, .{}),
+            .inst = Instruction.str(.x2, .x1, Instruction.LoadStoreOffset.none),
             .expected = 0b11_111_0_01_00_000000000000_00001_00010,
         },
         .{ // str x2, [x1], (x3)
-            .inst = Instruction.str(.x2, .x1, .{ .offset = Instruction.LoadStoreOffset.reg(.x3) }),
+            .inst = Instruction.str(.x2, .x1, Instruction.LoadStoreOffset.reg(.x3)),
             .expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010,
         },
         .{ // strh w0, [x1]
-            .inst = Instruction.strh(.w0, .x1, .{}),
+            .inst = Instruction.strh(.w0, .x1, Instruction.LoadStoreOffset.none),
             .expected = 0b01_111_0_01_00_000000000000_00001_00000,
         },
         .{ // strb w8, [x9]
-            .inst = Instruction.strb(.w8, .x9, .{}),
+            .inst = Instruction.strb(.w8, .x9, Instruction.LoadStoreOffset.none),
             .expected = 0b00_111_0_01_00_000000000000_01001_01000,
         },
         .{ // adr x2, #0x8
src/arch/aarch64/Emit.zig
@@ -587,12 +587,11 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {
         try emit.writeInstruction(Instruction.adrp(reg, 0));
 
         // ldr reg, reg, offset
-        try emit.writeInstruction(Instruction.ldr(reg, .{
-            .register = .{
-                .rn = reg,
-                .offset = Instruction.LoadStoreOffset.imm(0),
-            },
-        }));
+        try emit.writeInstruction(Instruction.ldr(
+            reg,
+            reg,
+            Instruction.LoadStoreOffset.imm(0),
+        ));
 
         if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
             // TODO I think the reloc might be in the wrong place.
@@ -626,7 +625,8 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {
         try emit.moveImmediate(reg, addr);
         try emit.writeInstruction(Instruction.ldr(
             reg,
-            .{ .register = .{ .rn = reg, .offset = Instruction.LoadStoreOffset.none } },
+            reg,
+            Instruction.LoadStoreOffset.none,
         ));
     }
 }
@@ -659,32 +659,33 @@ fn mirLoadStoreRegister(emit: *Emit, inst: Mir.Inst.Index) !void {
     switch (tag) {
         .ldr => try emit.writeInstruction(Instruction.ldr(
             load_store_register.rt,
-            .{ .register = .{ .rn = load_store_register.rn, .offset = load_store_register.offset } },
+            load_store_register.rn,
+            load_store_register.offset,
         )),
         .ldrb => try emit.writeInstruction(Instruction.ldrb(
             load_store_register.rt,
             load_store_register.rn,
-            .{ .offset = load_store_register.offset },
+            load_store_register.offset,
         )),
         .ldrh => try emit.writeInstruction(Instruction.ldrh(
             load_store_register.rt,
             load_store_register.rn,
-            .{ .offset = load_store_register.offset },
+            load_store_register.offset,
         )),
         .str => try emit.writeInstruction(Instruction.str(
             load_store_register.rt,
             load_store_register.rn,
-            .{ .offset = load_store_register.offset },
+            load_store_register.offset,
         )),
         .strb => try emit.writeInstruction(Instruction.strb(
             load_store_register.rt,
             load_store_register.rn,
-            .{ .offset = load_store_register.offset },
+            load_store_register.offset,
         )),
         .strh => try emit.writeInstruction(Instruction.strh(
             load_store_register.rt,
             load_store_register.rn,
-            .{ .offset = load_store_register.offset },
+            load_store_register.offset,
         )),
         else => unreachable,
     }
src/link/MachO.zig
@@ -2041,12 +2041,11 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {
                 .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21),
             });
             // ldr x16, [x16, 0]
-            mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(.x16, .{
-                .register = .{
-                    .rn = .x16,
-                    .offset = aarch64.Instruction.LoadStoreOffset.imm(0),
-                },
-            }).toU32());
+            mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(
+                .x16,
+                .x16,
+                aarch64.Instruction.LoadStoreOffset.imm(0),
+            ).toU32());
             atom.relocs.appendAssumeCapacity(.{
                 .offset = 16,
                 .target = .{ .global = self.undefs.items[self.dyld_stub_binder_index.?].n_strx },
@@ -2119,9 +2118,10 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom {
                 break :blk try math.cast(u18, div_res);
             };
             // ldr w16, literal
-            mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldr(.w16, .{
-                .literal = literal,
-            }).toU32());
+            mem.writeIntLittle(u32, atom.code.items[0..4], aarch64.Instruction.ldrLiteral(
+                .w16,
+                literal,
+            ).toU32());
             // b disp
             mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.b(0).toU32());
             atom.relocs.appendAssumeCapacity(.{
@@ -2222,12 +2222,11 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom {
                 .@"type" = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21),
             });
             // ldr x16, x16, offset
-            mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr(.x16, .{
-                .register = .{
-                    .rn = .x16,
-                    .offset = aarch64.Instruction.LoadStoreOffset.imm(0),
-                },
-            }).toU32());
+            mem.writeIntLittle(u32, atom.code.items[4..8], aarch64.Instruction.ldr(
+                .x16,
+                .x16,
+                aarch64.Instruction.LoadStoreOffset.imm(0),
+            ).toU32());
             atom.relocs.appendAssumeCapacity(.{
                 .offset = 4,
                 .target = .{ .local = laptr_sym_index },