Commit 8ab90a0b32
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 },