authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-05-23 11:00:41+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-05-23 11:02:56+02:00
log79e87e575391f63eb921de94dbf1020fa24c8e89
treea5e6e3cbd16b85f421ea1cce7abbaae360787cb6
parentffb7d76e1145832a535d3c8f20b7d1f3297a6091
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.debug: add m88k-openbsd support

closes https://codeberg.org/ziglang/zig/issues/31817

3 files changed, 93 insertions(+), 0 deletions(-)

lib/std/debug/Dwarf.zig+3
......@@ -1445,6 +1445,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
14451445 .lanai => 2,
14461446 .loongarch32, .loongarch64 => 64,
14471447 .m68k => 26,
1448 .m88k => 64,
14481449 .mips, .mipsel, .mips64, .mips64el => 66,
14491450 .or1k => 35,
14501451 .powerpc, .powerpcle, .powerpc64, .powerpc64le => 67,
......@@ -1470,6 +1471,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
14701471 .lanai => 5,
14711472 .loongarch32, .loongarch64 => 22,
14721473 .m68k => 14,
1474 .m88k => 30,
14731475 .mips, .mipsel, .mips64, .mips64el => 30,
14741476 .or1k => 2,
14751477 .powerpc, .powerpcle, .powerpc64, .powerpc64le => 1,
......@@ -1495,6 +1497,7 @@ pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
14951497 .lanai => 4,
14961498 .loongarch32, .loongarch64 => 3,
14971499 .m68k => 15,
1500 .m88k => 31,
14981501 .mips, .mipsel, .mips64, .mips64el => 29,
14991502 .or1k => 1,
15001503 .powerpc, .powerpcle, .powerpc64, .powerpc64le => 1,
lib/std/debug/SelfInfo/Elf.zig+1
......@@ -161,6 +161,7 @@ pub const can_unwind: bool = s: {
161161 // Not supported yet: arm
162162 .openbsd => &.{
163163 .aarch64,
164 .m88k,
164165 .mips64,
165166 .mips64el,
166167 .riscv64,
lib/std/debug/cpu_context.zig+89
......@@ -14,6 +14,7 @@ else switch (native_arch) {
1414 .lanai => Lanai,
1515 .loongarch32, .loongarch64 => LoongArch,
1616 .m68k => M68k,
17 .m88k => M88k,
1718 .mips, .mipsel, .mips64, .mips64el => Mips,
1819 .or1k => Or1k,
1920 .powerpc, .powerpcle, .powerpc64, .powerpc64le => Powerpc,
......@@ -62,6 +63,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
6263 },
6364 .pc = @truncate(uc.mcontext.pc),
6465 };
66 } else if (native_arch == .m88k and native_os == .openbsd) {
67 // OpenBSD makes no effort to clear the V and E bits of the SXIP register when presenting it
68 // to user space, so we need to do that here.
69 return .{
70 .r = uc.mcontext.r,
71 .xip = uc.mcontext.xip & ~@as(u32, 0b11),
72 };
6573 } else if (native_arch.isMIPS32() and native_os == .linux) {
6674 // The O32 kABI uses 64-bit fields for some reason.
6775 return .{
......@@ -894,6 +902,75 @@ const M68k = extern struct {
894902 }
895903};
896904
905/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
906const M88k = extern struct {
907 /// The numbered general-purpose registers r0 - r31.
908 r: [32]u32,
909 xip: u32,
910
911 pub inline fn current() M88k {
912 var ctx: M88k = undefined;
913 asm volatile (
914 \\ st %%r0, %%r2, 0
915 \\ st %%r1, %%r2, 4
916 \\ st %%r2, %%r2, 8
917 \\ st %%r3, %%r2, 12
918 \\ st %%r4, %%r2, 16
919 \\ st %%r5, %%r2, 20
920 \\ st %%r6, %%r2, 24
921 \\ st %%r7, %%r2, 28
922 \\ st %%r8, %%r2, 32
923 \\ st %%r9, %%r2, 36
924 \\ st %%r10, %%r2, 40
925 \\ st %%r11, %%r2, 44
926 \\ st %%r12, %%r2, 48
927 \\ st %%r13, %%r2, 52
928 \\ st %%r14, %%r2, 56
929 \\ st %%r15, %%r2, 60
930 \\ st %%r16, %%r2, 64
931 \\ st %%r17, %%r2, 68
932 \\ st %%r18, %%r2, 72
933 \\ st %%r19, %%r2, 76
934 \\ st %%r20, %%r2, 80
935 \\ st %%r21, %%r2, 84
936 \\ st %%r22, %%r2, 88
937 \\ st %%r23, %%r2, 92
938 \\ st %%r24, %%r2, 96
939 \\ st %%r25, %%r2, 100
940 \\ st %%r26, %%r2, 104
941 \\ st %%r27, %%r2, 108
942 \\ st %%r28, %%r2, 112
943 \\ st %%r29, %%r2, 116
944 \\ st %%r30, %%r2, 120
945 \\ st %%r31, %%r2, 124
946 \\ bsr.n 1f
947 \\1:
948 \\ st %%r1, %%r2, 128
949 :
950 : [ctx] "{r2}" (&ctx),
951 : .{ .r1 = true, .memory = true });
952 return ctx;
953 }
954
955 pub fn getFp(ctx: *const M88k) u32 {
956 return ctx.r[30];
957 }
958 pub fn getPc(ctx: *const M88k) u32 {
959 return ctx.xip;
960 }
961
962 pub fn dwarfRegisterBytes(ctx: *M88k, register_num: u16) DwarfRegisterError![]u8 {
963 switch (register_num) {
964 0...31 => return @ptrCast(&ctx.r[register_num]),
965 64 => return @ptrCast(&ctx.xip),
966
967 32...63 => return error.UnsupportedRegister, // x0 - x31
968
969 else => return error.InvalidRegister,
970 }
971 }
972};
973
897974/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
898975const Mips = extern struct {
899976 /// The numbered general-purpose registers r0 - r31. r0 must be zero.
......@@ -2363,6 +2440,18 @@ const signal_ucontext_t = switch (native_os) {
23632440 r23_29: [7]u32,
23642441 r31: u32,
23652442 },
2443 // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/m88k/include/signal.h
2444 .m88k => extern struct {
2445 _cookie: i32,
2446 _mask: i32,
2447 mcontext: extern struct {
2448 r: [32]u32,
2449 _epsr: u32,
2450 _fpsr: u32,
2451 _fpcr: u32,
2452 xip: u32,
2453 },
2454 },
23662455 // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/mips64/include/signal.h
23672456 .mips64, .mips64el => extern struct {
23682457 _cookie: i64,