This is an extern struct so that inline assembly in current can use field offsets.
const Hexagon = extern struct
const Hexagon = extern struct {
/// The numbered general-purpose registers r0 - r31.
r: [32]Gpr,
pc: Gpr,
pub const Gpr = u32;
pub inline fn current() Hexagon {
var ctx: Hexagon = undefined;
asm volatile (
\\ memw(r0 + #0) = r0
\\ memw(r0 + #4) = r1
\\ memw(r0 + #8) = r2
\\ memw(r0 + #12) = r3
\\ memw(r0 + #16) = r4
\\ memw(r0 + #20) = r5
\\ memw(r0 + #24) = r6
\\ memw(r0 + #28) = r7
\\ memw(r0 + #32) = r8
\\ memw(r0 + #36) = r9
\\ memw(r0 + #40) = r10
\\ memw(r0 + #44) = r11
\\ memw(r0 + #48) = r12
\\ memw(r0 + #52) = r13
\\ memw(r0 + #56) = r14
\\ memw(r0 + #60) = r15
\\ memw(r0 + #64) = r16
\\ memw(r0 + #68) = r17
\\ memw(r0 + #72) = r18
\\ memw(r0 + #76) = r19
\\ memw(r0 + #80) = r20
\\ memw(r0 + #84) = r21
\\ memw(r0 + #88) = r22
\\ memw(r0 + #92) = r23
\\ memw(r0 + #96) = r24
\\ memw(r0 + #100) = r25
\\ memw(r0 + #104) = r26
\\ memw(r0 + #108) = r27
\\ memw(r0 + #112) = r28
\\ memw(r0 + #116) = r29
\\ memw(r0 + #120) = r30
\\ memw(r0 + #124) = r31
\\ r1 = pc
\\ memw(r0 + #128) = r1
:
: [ctx] "{r0}" (&ctx),
: .{ .r1 = true, .memory = true });
return ctx;
}
pub fn getFp(ctx: *const Hexagon) usize {
return ctx.r[30];
}
pub fn getPc(ctx: *const Hexagon) usize {
return ctx.pc;
}
pub fn dwarfRegisterBytes(ctx: *Hexagon, register_num: u16) DwarfRegisterError![]u8 {
// Sourced from LLVM's HexagonRegisterInfo.td, which disagrees with LLDB...
switch (register_num) {
0...31 => return @ptrCast(&ctx.r[register_num]),
76 => return @ptrCast(&ctx.pc),
// This is probably covering some numbers that aren't actually mapped, but seriously,
// look at that file. I really can't be bothered to make it more precise.
32...75 => return error.UnsupportedRegister,
77...259 => return error.UnsupportedRegister,
// 999999...1000030 => return error.UnsupportedRegister,
// 9999999...10000030 => return error.UnsupportedRegister,
else => return error.InvalidRegister,
}
}
}