authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-14 09:32:12+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-15 13:59:17+02:00
log12b1d57df1e0efed6e5a3eb3933de7f08d42d6d5
tree454b6849878243b3f49465417e0d1ff237670899
parent3d3aff0da9ef2af703a81097b9ca73de9b89adae
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.debug.cpu_context: add Sparc context


1 files changed, 88 insertions(+), 0 deletions(-)

lib/std/debug/cpu_context.zig+88
...@@ -10,6 +10,7 @@ else switch (native_arch) {...@@ -10,6 +10,7 @@ else switch (native_arch) {
10 .loongarch32, .loongarch64 => LoongArch,10 .loongarch32, .loongarch64 => LoongArch,
11 .mips, .mipsel, .mips64, .mips64el => Mips,11 .mips, .mipsel, .mips64, .mips64el => Mips,
12 .powerpc, .powerpcle, .powerpc64, .powerpc64le => Powerpc,12 .powerpc, .powerpcle, .powerpc64, .powerpc64le => Powerpc,
13 .sparc, .sparc64 => Sparc,
13 .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv,14 .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv,
14 .s390x => S390x,15 .s390x => S390x,
15 .x86 => X86,16 .x86 => X86,
...@@ -858,6 +859,93 @@ const Powerpc = extern struct {...@@ -858,6 +859,93 @@ const Powerpc = extern struct {
858 }859 }
859};860};
860861
862/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
863const Sparc = extern struct {
864 g: [8]Gpr,
865 o: [8]Gpr,
866 l: [8]Gpr,
867 i: [8]Gpr,
868 pc: Gpr,
869
870 pub const Gpr = if (native_arch == .sparc64) u64 else u32;
871
872 pub inline fn current() Sparc {
873 var ctx: Sparc = undefined;
874 asm volatile (if (Gpr == u64)
875 \\ stx %g0, [%l0 + 0]
876 \\ stx %g1, [%l0 + 8]
877 \\ stx %g2, [%l0 + 16]
878 \\ stx %g3, [%l0 + 24]
879 \\ stx %g4, [%l0 + 32]
880 \\ stx %g5, [%l0 + 40]
881 \\ stx %g6, [%l0 + 48]
882 \\ stx %g7, [%l0 + 56]
883 \\ stx %o0, [%l0 + 64]
884 \\ stx %o1, [%l0 + 72]
885 \\ stx %o2, [%l0 + 80]
886 \\ stx %o3, [%l0 + 88]
887 \\ stx %o4, [%l0 + 96]
888 \\ stx %o5, [%l0 + 104]
889 \\ stx %o6, [%l0 + 112]
890 \\ stx %o7, [%l0 + 120]
891 \\ stx %l0, [%l0 + 128]
892 \\ stx %l1, [%l0 + 136]
893 \\ stx %l2, [%l0 + 144]
894 \\ stx %l3, [%l0 + 152]
895 \\ stx %l4, [%l0 + 160]
896 \\ stx %l5, [%l0 + 168]
897 \\ stx %l6, [%l0 + 176]
898 \\ stx %l7, [%l0 + 184]
899 \\ stx %i0, [%l0 + 192]
900 \\ stx %i1, [%l0 + 200]
901 \\ stx %i2, [%l0 + 208]
902 \\ stx %i3, [%l0 + 216]
903 \\ stx %i4, [%l0 + 224]
904 \\ stx %i5, [%l0 + 232]
905 \\ stx %i6, [%l0 + 240]
906 \\ stx %i7, [%l0 + 248]
907 \\ call 1f
908 \\ stx %o7, [%l0 + 256]
909 \\1:
910 else
911 \\ std %g0, [%l0 + 0]
912 \\ std %g2, [%l0 + 8]
913 \\ std %g4, [%l0 + 16]
914 \\ std %g6, [%l0 + 24]
915 \\ std %o0, [%l0 + 32]
916 \\ std %o2, [%l0 + 40]
917 \\ std %o4, [%l0 + 48]
918 \\ std %o6, [%l0 + 56]
919 \\ std %l0, [%l0 + 64]
920 \\ std %l2, [%l0 + 72]
921 \\ std %l4, [%l0 + 80]
922 \\ std %l6, [%l0 + 88]
923 \\ std %i0, [%l0 + 96]
924 \\ std %i2, [%l0 + 104]
925 \\ std %i4, [%l0 + 112]
926 \\ std %i6, [%l0 + 120]
927 \\ call 1f
928 \\ st %o7, [%l0 + 128]
929 \\1:
930 :
931 : [gprs] "{l0}" (&ctx),
932 : .{ .o7 = true, .memory = true });
933 return ctx;
934 }
935
936 pub fn dwarfRegisterBytes(ctx: *Sparc, register_num: u16) DwarfRegisterError![]u8 {
937 switch (register_num) {
938 0...7 => return @ptrCast(&ctx.g[register_num]),
939 8...15 => return @ptrCast(&ctx.o[register_num - 8]),
940 16...23 => return @ptrCast(&ctx.l[register_num - 16]),
941 24...31 => return @ptrCast(&ctx.i[register_num - 24]),
942 32 => return @ptrCast(&ctx.pc),
943
944 else => return error.InvalidRegister,
945 }
946 }
947};
948
861/// This is an `extern struct` so that inline assembly in `current` can use field offsets.949/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
862const Riscv = extern struct {950const Riscv = extern struct {
863 /// The numbered general-purpose registers r0 - r31. r0 must be zero.951 /// The numbered general-purpose registers r0 - r31. r0 must be zero.