commit cf13ecab29a2aa3b8616e03e4ec50f4b89f73c7b (tree)
parent a3ae499dc29747630f2801aab9bbc9661a4a0169
Author: Alex Rønne Petersen <alex@alexrp.com>
Date: Tue, 16 Jun 2026 12:09:31 +0200
std.debug.cpu_context: always declare a Gpr type on Native
Diffstat:
1 file changed, 104 insertions(+), 73 deletions(-)
diff --git a/lib/std/debug/cpu_context.zig b/lib/std/debug/cpu_context.zig
@@ -240,9 +240,11 @@ pub fn fromWindowsContext(ctx: *const std.os.windows.CONTEXT) Native {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const Aarch64 = extern struct {
/// The numbered general-purpose registers X0 - X30.
- x: [31]u64,
- sp: u64,
- pc: u64,
+ x: [31]Gpr,
+ sp: Gpr,
+ pc: Gpr,
+
+ pub const Gpr = u64;
pub inline fn current() Aarch64 {
var ctx: Aarch64 = undefined;
@@ -273,10 +275,10 @@ const Aarch64 = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Aarch64) u64 {
+ pub fn getFp(ctx: *const Aarch64) usize {
return ctx.x[29];
}
- pub fn getPc(ctx: *const Aarch64) u64 {
+ pub fn getPc(ctx: *const Aarch64) usize {
return ctx.pc;
}
@@ -308,8 +310,10 @@ const Aarch64 = extern struct {
const Alpha = extern struct {
/// The numbered general-purpose registers R0 - R31.
- r: [32]u64,
- pc: u64,
+ r: [32]Gpr,
+ pc: Gpr,
+
+ pub const Gpr = u64;
pub inline fn current() Alpha {
var ctx: Alpha = undefined;
@@ -355,10 +359,10 @@ const Alpha = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Alpha) u64 {
+ pub fn getFp(ctx: *const Alpha) usize {
return ctx.r[15];
}
- pub fn getPc(ctx: *const Alpha) u64 {
+ pub fn getPc(ctx: *const Alpha) usize {
return ctx.pc;
}
@@ -378,8 +382,10 @@ const Alpha = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const Arc = extern struct {
/// The numbered general-purpose registers r0 - r31.
- r: [32]u32,
- pcl: u32,
+ r: [32]Gpr,
+ pcl: Gpr,
+
+ pub const Gpr = u32;
pub inline fn current() Arc {
var ctx: Arc = undefined;
@@ -423,10 +429,10 @@ const Arc = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Arc) u32 {
+ pub fn getFp(ctx: *const Arc) usize {
return ctx.r[27];
}
- pub fn getPc(ctx: *const Arc) u32 {
+ pub fn getPc(ctx: *const Arc) usize {
return ctx.pcl;
}
@@ -446,7 +452,9 @@ const Arc = extern struct {
const Arm = struct {
/// The numbered general-purpose registers R0 - R15.
- r: [16]u32,
+ r: [16]Gpr,
+
+ pub const Gpr = u32;
pub inline fn current() Arm {
var ctx: Arm = undefined;
@@ -462,10 +470,10 @@ const Arm = struct {
return ctx;
}
- pub fn getFp(ctx: *const Arm) u32 {
+ pub fn getFp(ctx: *const Arm) usize {
return ctx.r[11];
}
- pub fn getPc(ctx: *const Arm) u32 {
+ pub fn getPc(ctx: *const Arm) usize {
return ctx.r[15];
}
@@ -512,8 +520,10 @@ const Arm = struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const Csky = extern struct {
/// The numbered general-purpose registers r0 - r31.
- r: [32]u32,
- pc: u32,
+ r: [32]Gpr,
+ pc: Gpr,
+
+ pub const Gpr = u32;
pub inline fn current() Csky {
var ctx: Csky = undefined;
@@ -528,10 +538,10 @@ const Csky = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Csky) u32 {
+ pub fn getFp(ctx: *const Csky) usize {
return ctx.r[14];
}
- pub fn getPc(ctx: *const Csky) u32 {
+ pub fn getPc(ctx: *const Csky) usize {
return ctx.pc;
}
@@ -550,8 +560,10 @@ const Csky = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const Hexagon = extern struct {
/// The numbered general-purpose registers r0 - r31.
- r: [32]u32,
- pc: u32,
+ r: [32]Gpr,
+ pc: Gpr,
+
+ pub const Gpr = u32;
pub inline fn current() Hexagon {
var ctx: Hexagon = undefined;
@@ -596,10 +608,10 @@ const Hexagon = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Hexagon) u32 {
+ pub fn getFp(ctx: *const Hexagon) usize {
return ctx.r[30];
}
- pub fn getPc(ctx: *const Hexagon) u32 {
+ pub fn getPc(ctx: *const Hexagon) usize {
return ctx.pc;
}
@@ -623,9 +635,11 @@ const Hexagon = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const Kvx = extern struct {
- r: [64]u64,
- ra: u64,
- pc: u64,
+ r: [64]Gpr,
+ ra: Gpr,
+ pc: Gpr,
+
+ pub const Gpr = u64;
pub inline fn current() Kvx {
var ctx: Kvx = undefined;
@@ -671,10 +685,10 @@ const Kvx = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Kvx) u64 {
+ pub fn getFp(ctx: *const Kvx) usize {
return ctx.r[14];
}
- pub fn getPc(ctx: *const Kvx) u64 {
+ pub fn getPc(ctx: *const Kvx) usize {
return ctx.pc;
}
@@ -695,7 +709,9 @@ const Kvx = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const Lanai = extern struct {
- r: [32]u32,
+ r: [32]Gpr,
+
+ pub const Gpr = u32;
pub inline fn current() Lanai {
var ctx: Lanai = undefined;
@@ -738,10 +754,10 @@ const Lanai = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Lanai) u32 {
+ pub fn getFp(ctx: *const Lanai) usize {
return ctx.r[5];
}
- pub fn getPc(ctx: *const Lanai) u32 {
+ pub fn getPc(ctx: *const Lanai) usize {
return ctx.r[2];
}
@@ -842,10 +858,10 @@ const LoongArch = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const LoongArch) Gpr {
+ pub fn getFp(ctx: *const LoongArch) usize {
return ctx.r[22];
}
- pub fn getPc(ctx: *const LoongArch) Gpr {
+ pub fn getPc(ctx: *const LoongArch) usize {
return ctx.pc;
}
@@ -864,10 +880,12 @@ const LoongArch = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const M68k = extern struct {
/// The numbered data registers d0 - d7.
- d: [8]u32,
+ d: [8]Gpr,
/// The numbered address registers a0 - a7.
- a: [8]u32,
- pc: u32,
+ a: [8]Gpr,
+ pc: Gpr,
+
+ pub const Gpr = u32;
pub inline fn current() M68k {
var ctx: M68k = undefined;
@@ -881,10 +899,10 @@ const M68k = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const M68k) u32 {
+ pub fn getFp(ctx: *const M68k) usize {
return ctx.a[6];
}
- pub fn getPc(ctx: *const M68k) u32 {
+ pub fn getPc(ctx: *const M68k) usize {
return ctx.pc;
}
@@ -905,8 +923,10 @@ const M68k = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const M88k = extern struct {
/// The numbered general-purpose registers r0 - r31.
- r: [32]u32,
- xip: u32,
+ r: [32]Gpr,
+ xip: Gpr,
+
+ pub const Gpr = u32;
pub inline fn current() M88k {
var ctx: M88k = undefined;
@@ -952,10 +972,10 @@ const M88k = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const M88k) u32 {
+ pub fn getFp(ctx: *const M88k) usize {
return ctx.r[30];
}
- pub fn getPc(ctx: *const M88k) u32 {
+ pub fn getPc(ctx: *const M88k) usize {
return ctx.xip;
}
@@ -1103,8 +1123,10 @@ const Mips = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const Or1k = extern struct {
/// The numbered general-purpose registers r0 - r31.
- r: [32]u32,
- pc: u32,
+ r: [32]Gpr,
+ pc: Gpr,
+
+ pub const Gpr = u32;
pub inline fn current() Or1k {
var ctx: Or1k = undefined;
@@ -1150,10 +1172,10 @@ const Or1k = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Or1k) u32 {
+ pub fn getFp(ctx: *const Or1k) usize {
return ctx.r[2];
}
- pub fn getPc(ctx: *const Or1k) u32 {
+ pub fn getPc(ctx: *const Or1k) usize {
return ctx.pc;
}
@@ -1262,10 +1284,10 @@ const Powerpc = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Powerpc) Gpr {
+ pub fn getFp(ctx: *const Powerpc) usize {
return ctx.r[1];
}
- pub fn getPc(ctx: *const Powerpc) Gpr {
+ pub fn getPc(ctx: *const Powerpc) usize {
return ctx.pc;
}
@@ -1415,10 +1437,10 @@ const Riscv = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Riscv) Gpr {
+ pub fn getFp(ctx: *const Riscv) usize {
return ctx.x[8];
}
- pub fn getPc(ctx: *const Riscv) Gpr {
+ pub fn getPc(ctx: *const Riscv) usize {
return ctx.pc;
}
@@ -1441,13 +1463,15 @@ const Riscv = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const S390x = extern struct {
/// The numbered general-purpose registers r0 - r15.
- r: [16]u64,
+ r: [16]Gpr,
/// The program counter.
psw: extern struct {
- mask: u64,
- addr: u64,
+ mask: Gpr,
+ addr: Gpr,
},
+ pub const Gpr = u64;
+
pub inline fn current() S390x {
var ctx: S390x = undefined;
asm volatile (
@@ -1462,10 +1486,10 @@ const S390x = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const S390x) u64 {
+ pub fn getFp(ctx: *const S390x) usize {
return ctx.r[11];
}
- pub fn getPc(ctx: *const S390x) u64 {
+ pub fn getPc(ctx: *const S390x) usize {
return ctx.psw.addr;
}
@@ -1571,10 +1595,10 @@ const Sparc = extern struct {
asm volatile ("ta 3" ::: .{ .memory = true }); // ST_FLUSH_WINDOWS
}
- pub fn getFp(ctx: *const Sparc) Gpr {
+ pub fn getFp(ctx: *const Sparc) usize {
return ctx.i[6];
}
- pub fn getPc(ctx: *const Sparc) Gpr {
+ pub fn getPc(ctx: *const Sparc) usize {
return ctx.pc;
}
@@ -1593,8 +1617,10 @@ const Sparc = extern struct {
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
const Ve = extern struct {
- s: [64]u64,
- ic: u64,
+ s: [64]Gpr,
+ ic: Gpr,
+
+ pub const Gpr = u64;
pub inline fn current() Ve {
var ctx: Ve = undefined;
@@ -1672,10 +1698,10 @@ const Ve = extern struct {
return ctx;
}
- pub fn getFp(ctx: *const Ve) u64 {
+ pub fn getFp(ctx: *const Ve) usize {
return ctx.s[9];
}
- pub fn getPc(ctx: *const Ve) u64 {
+ pub fn getPc(ctx: *const Ve) usize {
return ctx.ic;
}
@@ -1693,14 +1719,15 @@ const Ve = extern struct {
};
const X86_16 = struct {
- pub const Register = enum {
+ regs: std.enums.EnumArray(GprName, Gpr),
+
+ pub const GprName = enum {
// zig fmt: off
sp, bp, ss,
ip, cs,
// zig fmt: on
};
-
- regs: std.enums.EnumArray(Register, u16),
+ pub const Gpr = u16;
pub inline fn current() X86_16 {
var ctx: X86_16 = undefined;
@@ -1719,10 +1746,10 @@ const X86_16 = struct {
return ctx;
}
- pub fn getFp(ctx: *const X86_16) u16 {
+ pub fn getFp(ctx: *const X86_16) usize {
return ctx.regs.get(.bp);
}
- pub fn getPc(ctx: *const X86_16) u16 {
+ pub fn getPc(ctx: *const X86_16) usize {
return ctx.regs.get(.ip);
}
@@ -1740,17 +1767,19 @@ const X86_16 = struct {
};
const X86 = struct {
+ gprs: std.enums.EnumArray(GprName, Gpr),
+
/// The first 8 registers here intentionally match the order of registers in the x86 instruction
/// encoding. This order is inherited by the PUSHA instruction and the DWARF register mappings,
/// among other things.
- pub const Gpr = enum {
+ pub const GprName = enum {
// zig fmt: off
eax, ecx, edx, ebx,
esp, ebp, esi, edi,
eip,
// zig fmt: on
};
- gprs: std.enums.EnumArray(Gpr, u32),
+ pub const Gpr = u32;
pub inline fn current() X86 {
var ctx: X86 = undefined;
@@ -1772,10 +1801,10 @@ const X86 = struct {
return ctx;
}
- pub fn getFp(ctx: *const X86) u32 {
+ pub fn getFp(ctx: *const X86) usize {
return ctx.gprs.get(.ebp);
}
- pub fn getPc(ctx: *const X86) u32 {
+ pub fn getPc(ctx: *const X86) usize {
return ctx.gprs.get(.eip);
}
@@ -1806,10 +1835,12 @@ const X86 = struct {
};
const X86_64 = struct {
+ gprs: std.enums.EnumArray(GprName, Gpr),
+
/// The order here intentionally matches the order of the DWARF register mappings. It's unclear
/// where those mappings actually originated from---the ordering of the first 4 registers seems
/// quite unusual---but it is currently convenient for us to match DWARF.
- pub const Gpr = enum {
+ pub const GprName = enum {
// zig fmt: off
rax, rdx, rcx, rbx,
rsi, rdi, rbp, rsp,
@@ -1818,7 +1849,7 @@ const X86_64 = struct {
rip,
// zig fmt: on
};
- gprs: std.enums.EnumArray(Gpr, u64),
+ pub const Gpr = u64;
pub inline fn current() X86_64 {
var ctx: X86_64 = undefined;