This is an extern struct so that inline assembly in current can use field offsets.
const S390x = extern struct
const S390x = extern struct {
/// The numbered general-purpose registers r0 - r15.
r: [16]Gpr,
/// The program counter.
psw: extern struct {
mask: Gpr,
addr: Gpr,
},
pub const Gpr = u64;
pub inline fn current() S390x {
var ctx: S390x = undefined;
asm volatile (
\\ stmg %%r0, %%r15, 0(%%r2)
\\ epsw %%r0, %%r1
\\ stm %%r0, %%r1, 128(%%r2)
\\ larl %%r0, .
\\ stg %%r0, 136(%%r2)
:
: [ctx] "{r2}" (&ctx),
: .{ .r0 = true, .r1 = true, .memory = true });
return ctx;
}
pub fn getFp(ctx: *const S390x) usize {
return ctx.r[11];
}
pub fn getPc(ctx: *const S390x) usize {
return ctx.psw.addr;
}
pub fn dwarfRegisterBytes(ctx: *S390x, register_num: u16) DwarfRegisterError![]u8 {
switch (register_num) {
0...15 => return @ptrCast(&ctx.r[register_num]),
64 => return @ptrCast(&ctx.psw.mask),
65 => return @ptrCast(&ctx.psw.addr),
16...31 => return error.UnsupportedRegister, // f0 - f15
32...47 => return error.UnsupportedRegister, // cr0 - cr15
48...63 => return error.UnsupportedRegister, // a0 - a15
66...67 => return error.UnsupportedRegister, // z/OS stuff???
68...83 => return error.UnsupportedRegister, // v16 - v31
else => return error.InvalidRegister,
}
}
}