zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Mlib/std/debug/cpu_context.zig | 177++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
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;