This is an extern struct so that inline assembly in current can use field offsets.
const Powerpc = extern struct
const Powerpc = extern struct {
/// The numbered general-purpose registers r0 - r31.
r: [32]Gpr,
pc: Gpr,
lr: Gpr,
pub const Gpr = if (native_arch.isPowerPC64()) u64 else u32;
pub inline fn current() Powerpc {
var ctx: Powerpc = undefined;
asm volatile (if (Gpr == u64)
\\ std 0, 0(10)
\\ std 1, 8(10)
\\ std 2, 16(10)
\\ std 3, 24(10)
\\ std 4, 32(10)
\\ std 5, 40(10)
\\ std 6, 48(10)
\\ std 7, 56(10)
\\ std 8, 64(10)
\\ std 9, 72(10)
\\ std 10, 80(10)
\\ std 11, 88(10)
\\ std 12, 96(10)
\\ std 13, 104(10)
\\ std 14, 112(10)
\\ std 15, 120(10)
\\ std 16, 128(10)
\\ std 17, 136(10)
\\ std 18, 144(10)
\\ std 19, 152(10)
\\ std 20, 160(10)
\\ std 21, 168(10)
\\ std 22, 176(10)
\\ std 23, 184(10)
\\ std 24, 192(10)
\\ std 25, 200(10)
\\ std 26, 208(10)
\\ std 27, 216(10)
\\ std 28, 224(10)
\\ std 29, 232(10)
\\ std 30, 240(10)
\\ std 31, 248(10)
\\ mflr 8
\\ std 8, 264(10)
\\ bl 1f
\\1:
\\ mflr 8
\\ std 8, 256(10)
else
\\ stw 0, 0(10)
\\ stw 1, 4(10)
\\ stw 2, 8(10)
\\ stw 3, 12(10)
\\ stw 4, 16(10)
\\ stw 5, 20(10)
\\ stw 6, 24(10)
\\ stw 7, 28(10)
\\ stw 8, 32(10)
\\ stw 9, 36(10)
\\ stw 10, 40(10)
\\ stw 11, 44(10)
\\ stw 12, 48(10)
\\ stw 13, 52(10)
\\ stw 14, 56(10)
\\ stw 15, 60(10)
\\ stw 16, 64(10)
\\ stw 17, 68(10)
\\ stw 18, 72(10)
\\ stw 19, 76(10)
\\ stw 20, 80(10)
\\ stw 21, 84(10)
\\ stw 22, 88(10)
\\ stw 23, 92(10)
\\ stw 24, 96(10)
\\ stw 25, 100(10)
\\ stw 26, 104(10)
\\ stw 27, 108(10)
\\ stw 28, 112(10)
\\ stw 29, 116(10)
\\ stw 30, 120(10)
\\ stw 31, 124(10)
\\ mflr 8
\\ stw 8, 132(10)
\\ bl 1f
\\1:
\\ mflr 8
\\ stw 8, 128(10)
:
: [ctx] "{r10}" (&ctx),
: .{ .r8 = true, .lr = true, .memory = true });
return ctx;
}
pub fn getFp(ctx: *const Powerpc) usize {
return ctx.r[1];
}
pub fn getPc(ctx: *const Powerpc) usize {
return ctx.pc;
}
pub fn dwarfRegisterBytes(ctx: *Powerpc, register_num: u16) DwarfRegisterError![]u8 {
// References:
//
// * System V Application Binary Interface - PowerPC Processor Supplement §3-46
// * Power Architecture 32-bit Application Binary Interface Supplement 1.0 - Linux & Embedded §3.4
// * 64-bit ELF V2 ABI Specification - Power Architecture Revision 1.5 §2.4
//
// Are we having fun yet?
if (Gpr == u64) switch (register_num) {
65 => return @ptrCast(&ctx.lr), // lr
66 => return error.UnsupportedRegister, // ctr
68...75 => return error.UnsupportedRegister, // cr0 - cr7
76 => return error.UnsupportedRegister, // xer
77...108 => return error.UnsupportedRegister, // vr0 - vr31
109 => return error.UnsupportedRegister, // vrsave (LLVM)
110 => return error.UnsupportedRegister, // vscr
114 => return error.UnsupportedRegister, // tfhar
115 => return error.UnsupportedRegister, // tfiar
116 => return error.UnsupportedRegister, // texasr
else => {},
} else switch (register_num) {
65 => return @ptrCast(&ctx.lr), // fpscr (SVR4 / EABI), or lr if you ask LLVM
108 => return @ptrCast(&ctx.lr),
64 => return error.UnsupportedRegister, // cr
66 => return error.UnsupportedRegister, // msr (SVR4 / EABI), or ctr if you ask LLVM
68...75 => return error.UnsupportedRegister, // cr0 - cr7 if you ask LLVM
76 => return error.UnsupportedRegister, // xer if you ask LLVM
99 => return error.UnsupportedRegister, // acc
100 => return error.UnsupportedRegister, // mq
101 => return error.UnsupportedRegister, // xer
102...107 => return error.UnsupportedRegister, // SPRs
109 => return error.UnsupportedRegister, // ctr
110...111 => return error.UnsupportedRegister, // SPRs
112 => return error.UnsupportedRegister, // spefscr
113...1123 => return error.UnsupportedRegister, // SPRs
1124...1155 => return error.UnsupportedRegister, // SPE v0 - v31
1200...1231 => return error.UnsupportedRegister, // SPE upper r0 - r31
3072...4095 => return error.UnsupportedRegister, // DCRs
4096...5120 => return error.UnsupportedRegister, // PMRs
else => {},
}
switch (register_num) {
0...31 => return @ptrCast(&ctx.r[register_num]),
67 => return @ptrCast(&ctx.pc),
32...63 => return error.UnsupportedRegister, // f0 - f31
else => return error.InvalidRegister,
}
}
}