This is an extern struct so that inline assembly in current can use field offsets.
const Aarch64 = extern struct
const Aarch64 = extern struct {
/// The numbered general-purpose registers X0 - X30.
x: [31]Gpr,
sp: Gpr,
pc: Gpr,
pub const Gpr = u64;
pub inline fn current() Aarch64 {
var ctx: Aarch64 = undefined;
asm volatile (
\\ stp x0, x1, [x0, #0x000]
\\ stp x2, x3, [x0, #0x010]
\\ stp x4, x5, [x0, #0x020]
\\ stp x6, x7, [x0, #0x030]
\\ stp x8, x9, [x0, #0x040]
\\ stp x10, x11, [x0, #0x050]
\\ stp x12, x13, [x0, #0x060]
\\ stp x14, x15, [x0, #0x070]
\\ stp x16, x17, [x0, #0x080]
\\ stp x18, x19, [x0, #0x090]
\\ stp x20, x21, [x0, #0x0a0]
\\ stp x22, x23, [x0, #0x0b0]
\\ stp x24, x25, [x0, #0x0c0]
\\ stp x26, x27, [x0, #0x0d0]
\\ stp x28, x29, [x0, #0x0e0]
\\ str x30, [x0, #0x0f0]
\\ mov x1, sp
\\ str x1, [x0, #0x0f8]
\\ adr x1, .
\\ str x1, [x0, #0x100]
:
: [ctx] "{x0}" (&ctx),
: .{ .x1 = true, .memory = true });
return ctx;
}
pub fn getFp(ctx: *const Aarch64) usize {
return ctx.x[29];
}
pub fn getPc(ctx: *const Aarch64) usize {
return ctx.pc;
}
pub fn dwarfRegisterBytes(ctx: *Aarch64, register_num: u16) DwarfRegisterError![]u8 {
// DWARF for the Arm(r) 64-bit Architecture (AArch64) ยง 4.1 "DWARF register names"
switch (register_num) {
0...30 => return @ptrCast(&ctx.x[register_num]),
31 => return @ptrCast(&ctx.sp),
32 => return @ptrCast(&ctx.pc),
33 => return error.UnsupportedRegister, // ELR_mode
34 => return error.UnsupportedRegister, // RA_SIGN_STATE
35 => return error.UnsupportedRegister, // TPIDRRO_ELO
36 => return error.UnsupportedRegister, // TPIDR_ELO
37 => return error.UnsupportedRegister, // TPIDR_EL1
38 => return error.UnsupportedRegister, // TPIDR_EL2
39 => return error.UnsupportedRegister, // TPIDR_EL3
40...45 => return error.UnsupportedRegister, // Reserved
46 => return error.UnsupportedRegister, // VG
47 => return error.UnsupportedRegister, // FFR
48...63 => return error.UnsupportedRegister, // P0 - P15
64...95 => return error.UnsupportedRegister, // V0 - V31
96...127 => return error.UnsupportedRegister, // Z0 - Z31
else => return error.InvalidRegister,
}
}
}