@@ -8,6 +8,7 @@ else switch (native_arch) {
88 .arm , .armeb , .thumb , .thumbeb = > Arm ,
99 .loongarch32 , .loongarch64 = > LoongArch ,
1010 .riscv32 , .riscv32be , .riscv64 , .riscv64be = > Riscv ,
11+ .s390x = > S390x ,
1112 .x86 = > X86 ,
1213 .x86_64 = > X86_64 ,
1314 else = > noreturn ,
@@ -189,6 +190,17 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
189190 },
190191 else = > null ,
191192 },
193+ .s390x = > switch (builtin .os .tag ) {
194+ .linux = > .{
195+ .r = uc .mcontext .gregs ,
196+ .f = uc .mcontext .fregs ,
197+ .psw = .{
198+ .mask = uc .mcontext .psw .mask ,
199+ .addr = uc .mcontext .psw .addr ,
200+ },
201+ },
202+ else = > null ,
203+ },
192204 else = > null ,
193205 };
194206}
@@ -677,6 +689,81 @@ pub const Riscv = extern struct {
677689 }
678690};
679691
692+ /// This is an `extern struct` so that inline assembly in `current` can use field offsets.
693+ pub const S390x = extern struct {
694+ /// The numbered general-purpose registers r0 - r15.
695+ r : [16 ]u64 ,
696+ /// The numbered floating-point registers f0 - f15. Yes, really - they can be used in DWARF CFI.
697+ f : [16 ]f64 ,
698+ /// The program counter.
699+ psw : extern struct {
700+ mask : u64 ,
701+ addr : u64 ,
702+ },
703+
704+ pub inline fn current () S390x {
705+ var ctx : S390x = undefined ;
706+ asm volatile (
707+ \\ stmg %%r0, %%r15, 0(%%r2)
708+ \\ std %%f0, 128(%%r2)
709+ \\ std %%f1, 136(%%r2)
710+ \\ std %%f2, 144(%%r2)
711+ \\ std %%f3, 152(%%r2)
712+ \\ std %%f4, 160(%%r2)
713+ \\ std %%f5, 168(%%r2)
714+ \\ std %%f6, 176(%%r2)
715+ \\ std %%f7, 184(%%r2)
716+ \\ std %%f8, 192(%%r2)
717+ \\ std %%f9, 200(%%r2)
718+ \\ std %%f10, 208(%%r2)
719+ \\ std %%f11, 216(%%r2)
720+ \\ std %%f12, 224(%%r2)
721+ \\ std %%f13, 232(%%r2)
722+ \\ std %%f14, 240(%%r2)
723+ \\ std %%f15, 248(%%r2)
724+ \\ epsw %%r0, %%r1
725+ \\ stm %%r0, %%r1, 256(%%r2)
726+ \\ larl %%r0, .
727+ \\ stg %%r0, 264(%%r2)
728+ \\ lg %%r0, 0(%%r2)
729+ \\ lg %%r1, 8(%%r2)
730+ :
731+ : [gprs ] "{r2}" (& ctx ),
732+ : .{ .memory = true });
733+ return ctx ;
734+ }
735+
736+ pub fn dwarfRegisterBytes (ctx : * S390x , register_num : u16 ) DwarfRegisterError ! []u8 {
737+ switch (register_num ) {
738+ 0... 15 = > return @ptrCast (& ctx .r [register_num ]),
739+ // Why???
740+ 16 = > return @ptrCast (& ctx .f [0 ]),
741+ 17 = > return @ptrCast (& ctx .f [2 ]),
742+ 18 = > return @ptrCast (& ctx .f [4 ]),
743+ 19 = > return @ptrCast (& ctx .f [6 ]),
744+ 20 = > return @ptrCast (& ctx .f [1 ]),
745+ 21 = > return @ptrCast (& ctx .f [3 ]),
746+ 22 = > return @ptrCast (& ctx .f [5 ]),
747+ 23 = > return @ptrCast (& ctx .f [7 ]),
748+ 24 = > return @ptrCast (& ctx .f [8 ]),
749+ 25 = > return @ptrCast (& ctx .f [10 ]),
750+ 26 = > return @ptrCast (& ctx .f [12 ]),
751+ 27 = > return @ptrCast (& ctx .f [14 ]),
752+ 28 = > return @ptrCast (& ctx .f [9 ]),
753+ 29 = > return @ptrCast (& ctx .f [11 ]),
754+ 30 = > return @ptrCast (& ctx .f [13 ]),
755+ 31 = > return @ptrCast (& ctx .f [15 ]),
756+ 64 = > return @ptrCast (& ctx .psw .mask ),
757+ 65 = > return @ptrCast (& ctx .psw .addr ),
758+
759+ 48... 63 = > return error .UnsupportedRegister , // a0 - a15
760+ 68... 83 = > return error .UnsupportedRegister , // v16 - v31
761+
762+ else = > return error .InvalidRegister ,
763+ }
764+ }
765+ };
766+
680767const signal_ucontext_t = switch (native_os ) {
681768 .linux = > std .os .linux .ucontext_t ,
682769 .emscripten = > std .os .emscripten .ucontext_t ,
0 commit comments