const Riscv = extern struct {
/// The numbered general-purpose registers r0 - r31. r0 must be zero.
x: [32]Gpr,
pc: Gpr,
pub const Gpr = if (native_arch.isRiscv64()) u64 else u32;
pub inline fn current() Riscv {
var ctx: Riscv = undefined;
asm volatile (if (Gpr == u64)
\\ sd zero, 0(t0)
\\ sd ra, 8(t0)
\\ sd sp, 16(t0)
\\ sd gp, 24(t0)
\\ sd tp, 32(t0)
\\ sd t0, 40(t0)
\\ sd t1, 48(t0)
\\ sd t2, 56(t0)
\\ sd s0, 64(t0)
\\ sd s1, 72(t0)
\\ sd a0, 80(t0)
\\ sd a1, 88(t0)
\\ sd a2, 96(t0)
\\ sd a3, 104(t0)
\\ sd a4, 112(t0)
\\ sd a5, 120(t0)
\\ sd a6, 128(t0)
\\ sd a7, 136(t0)
\\ sd s2, 144(t0)
\\ sd s3, 152(t0)
\\ sd s4, 160(t0)
\\ sd s5, 168(t0)
\\ sd s6, 176(t0)
\\ sd s7, 184(t0)
\\ sd s8, 192(t0)
\\ sd s9, 200(t0)
\\ sd s10, 208(t0)
\\ sd s11, 216(t0)
\\ sd t3, 224(t0)
\\ sd t4, 232(t0)
\\ sd t5, 240(t0)
\\ sd t6, 248(t0)
\\ jal ra, 1f
\\1:
\\ sd ra, 256(t0)
else
\\ sw zero, 0(t0)
\\ sw ra, 4(t0)
\\ sw sp, 8(t0)
\\ sw gp, 12(t0)
\\ sw tp, 16(t0)
\\ sw t0, 20(t0)
\\ sw t1, 24(t0)
\\ sw t2, 28(t0)
\\ sw s0, 32(t0)
\\ sw s1, 36(t0)
\\ sw a0, 40(t0)
\\ sw a1, 44(t0)
\\ sw a2, 48(t0)
\\ sw a3, 52(t0)
\\ sw a4, 56(t0)
\\ sw a5, 60(t0)
\\ sw a6, 64(t0)
\\ sw a7, 68(t0)
\\ sw s2, 72(t0)
\\ sw s3, 76(t0)
\\ sw s4, 80(t0)
\\ sw s5, 84(t0)
\\ sw s6, 88(t0)
\\ sw s7, 92(t0)
\\ sw s8, 96(t0)
\\ sw s9, 100(t0)
\\ sw s10, 104(t0)
\\ sw s11, 108(t0)
\\ sw t3, 112(t0)
\\ sw t4, 116(t0)
\\ sw t5, 120(t0)
\\ sw t6, 124(t0)
\\ jal ra, 1f
\\1:
\\ sw ra, 128(t0)
:
: [ctx] "{t0}" (&ctx),
: .{ .x1 = true, .memory = true });
return ctx;
}
pub fn getFp(ctx: *const Riscv) usize {
return ctx.x[8];
}
pub fn getPc(ctx: *const Riscv) usize {
return ctx.pc;
}
pub fn dwarfRegisterBytes(ctx: *Riscv, register_num: u16) DwarfRegisterError![]u8 {
switch (register_num) {
0...31 => return @ptrCast(&ctx.x[register_num]),
65 => return @ptrCast(&ctx.pc),
32...63 => return error.UnsupportedRegister, // f0 - f31
64 => return error.UnsupportedRegister, // Alternate Frame Return Column
96...127 => return error.UnsupportedRegister, // v0 - v31
3072...4095 => return error.UnsupportedRegister, // Custom extensions
4096...8191 => return error.UnsupportedRegister, // CSRs
else => return error.InvalidRegister,
}
}
}
This is an
extern structso that inline assembly incurrentcan use field offsets.