commit 17a55fdd3a55db65c4b761da4eb918b72cf9f302 (tree)
parent 55186f1224cfea0cde09e48b12b07a753bfddc6a
Author: Alex Rønne Petersen <alex@alexrp.com>
Date: Thu, 4 Jun 2026 14:55:15 +0200
std.os.linux: add sh arch bits
closes https://codeberg.org/ziglang/zig/issues/30946
Diffstat:
2 files changed, 251 insertions(+), 1 deletion(-)
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
@@ -52,6 +52,7 @@ const arch_bits = switch (native_arch) {
.riscv32 => @import("linux/riscv32.zig"),
.riscv64 => @import("linux/riscv64.zig"),
.s390x => @import("linux/s390x.zig"),
+ .sh, .sheb => @import("linux/sh.zig"),
.sparc => @import("linux/sparc.zig"),
.sparc64 => @import("linux/sparc64.zig"),
.x86 => @import("linux/x86.zig"),
@@ -302,6 +303,8 @@ pub const MAP = switch (native_arch) {
.microblazeel,
.or1k,
.s390x,
+ .sh,
+ .sheb,
=> packed struct(u32) {
TYPE: MAP_TYPE,
FIXED: bool = false,
@@ -534,6 +537,8 @@ pub const O = switch (native_arch) {
.microblazeel,
.or1k,
.s390x,
+ .sh,
+ .sheb,
.xtensa,
.xtensaeb,
=> packed struct(u32) {
@@ -6995,6 +7000,8 @@ pub const MINSIGSTKSZ = switch (native_arch) {
.riscv32,
.riscv64,
.s390x,
+ .sh,
+ .sheb,
.thumb,
.thumbeb,
.x86,
@@ -7035,6 +7042,8 @@ pub const SIGSTKSZ = switch (native_arch) {
.riscv32,
.riscv64,
.s390x,
+ .sh,
+ .sheb,
.thumb,
.thumbeb,
.x86,
@@ -10749,9 +10758,11 @@ pub const AUDIT = struct {
.powerpc64le => .PPC64LE,
.riscv32 => .RISCV32,
.riscv64 => .RISCV64,
+ .s390x => .S390X,
+ .sh => .SHEL,
+ .sheb => .SH,
.sparc => .SPARC,
.sparc64 => .SPARC64,
- .s390x => .S390X,
.x86 => .I386,
.x86_64 => .X86_64,
.xtensa => .XTENSA,
diff --git a/lib/std/os/linux/sh.zig b/lib/std/os/linux/sh.zig
@@ -0,0 +1,239 @@
+const builtin = @import("builtin");
+const std = @import("../../std.zig");
+const SYS = std.os.linux.SYS;
+
+pub const syscall_arg_t = u32;
+
+pub fn syscall0(
+ number: SYS,
+) u32 {
+ return asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ : [ret] "={r0}" (-> u32),
+ : [number] "{r3}" (@intFromEnum(number)),
+ : .{ .memory = true });
+}
+
+pub fn syscall1(
+ number: SYS,
+ arg1: syscall_arg_t,
+) u32 {
+ return asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ : [ret] "={r0}" (-> u32),
+ : [number] "{r3}" (@intFromEnum(number)),
+ [arg1] "{r4}" (arg1),
+ : .{ .memory = true });
+}
+
+pub fn syscall2(
+ number: SYS,
+ arg1: syscall_arg_t,
+ arg2: syscall_arg_t,
+) u32 {
+ return asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ : [ret] "={r0}" (-> u32),
+ : [number] "{r3}" (@intFromEnum(number)),
+ [arg1] "{r4}" (arg1),
+ [arg2] "{r5}" (arg2),
+ : .{ .memory = true });
+}
+
+pub fn syscall3(
+ number: SYS,
+ arg1: syscall_arg_t,
+ arg2: syscall_arg_t,
+ arg3: syscall_arg_t,
+) u32 {
+ return asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ : [ret] "={r0}" (-> u32),
+ : [number] "{r3}" (@intFromEnum(number)),
+ [arg1] "{r4}" (arg1),
+ [arg2] "{r5}" (arg2),
+ [arg3] "{r6}" (arg3),
+ : .{ .memory = true });
+}
+
+pub fn syscall4(
+ number: SYS,
+ arg1: syscall_arg_t,
+ arg2: syscall_arg_t,
+ arg3: syscall_arg_t,
+ arg4: syscall_arg_t,
+) u32 {
+ return asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ : [ret] "={r0}" (-> u32),
+ : [number] "{r3}" (@intFromEnum(number)),
+ [arg1] "{r4}" (arg1),
+ [arg2] "{r5}" (arg2),
+ [arg3] "{r6}" (arg3),
+ [arg4] "{r7}" (arg4),
+ : .{ .memory = true });
+}
+
+pub fn syscall5(
+ number: SYS,
+ arg1: syscall_arg_t,
+ arg2: syscall_arg_t,
+ arg3: syscall_arg_t,
+ arg4: syscall_arg_t,
+ arg5: syscall_arg_t,
+) u32 {
+ return asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ : [ret] "={r0}" (-> u32),
+ : [number] "{r3}" (@intFromEnum(number)),
+ [arg1] "{r4}" (arg1),
+ [arg2] "{r5}" (arg2),
+ [arg3] "{r6}" (arg3),
+ [arg4] "{r7}" (arg4),
+ [arg5] "{r0}" (arg5),
+ : .{ .memory = true });
+}
+
+pub fn syscall6(
+ number: SYS,
+ arg1: syscall_arg_t,
+ arg2: syscall_arg_t,
+ arg3: syscall_arg_t,
+ arg4: syscall_arg_t,
+ arg5: syscall_arg_t,
+ arg6: syscall_arg_t,
+) u32 {
+ return asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ : [ret] "={r0}" (-> u32),
+ : [number] "{r3}" (@intFromEnum(number)),
+ [arg1] "{r4}" (arg1),
+ [arg2] "{r5}" (arg2),
+ [arg3] "{r6}" (arg3),
+ [arg4] "{r7}" (arg4),
+ [arg5] "{r0}" (arg5),
+ [arg6] "{r1}" (arg6),
+ : .{ .memory = true });
+}
+
+pub fn clone() callconv(.naked) u32 {
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
+ // r4, r5, r6, r7, +0, +4, +8
+ //
+ // syscall(SYS_clone, flags, stack, ptid, ctid, tls)
+ // r3 r4, r5, r6, r7, r0
+ asm volatile (
+ \\ mov #-4, r0
+ \\ and r0, r5
+ \\
+ \\ mov r4, r1
+ \\ mov r7, r2
+ \\
+ \\ mov #120, r3 ! SYS_clone
+ \\ mov r6, r4
+ \\ mov.l @r15, r6
+ \\ mov.l @(r15, 8), r7
+ \\ mov.l @(r15, 4), r0
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\
+ \\ cmp/eq #0, r0
+ \\ bt 1f
+ \\
+ \\ // parent
+ \\ rts
+ \\ nop
+ \\
+ \\ // child
+ \\1:
+ );
+ if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
+ \\ .cfi_undefined pr
+ );
+ asm volatile (
+ \\ mov #0, r0
+ \\ lds r0, pr
+ \\ mov r0, r14
+ \\
+ \\ mov r2, r4
+ \\ jsr @r1
+ \\ nop
+ \\
+ \\ mov #1, r3 ! SYS_exit
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ );
+}
+
+pub fn restore() callconv(.naked) noreturn {
+ asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ :
+ : [number] "{r3}" (@intFromEnum(SYS.sigreturn)),
+ );
+}
+
+pub fn restore_rt() callconv(.naked) noreturn {
+ asm volatile (
+ \\ trapa #31
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ \\ or r0, r0
+ :
+ : [number] "{r3}" (@intFromEnum(SYS.rt_sigreturn)),
+ );
+}
+
+pub const time_t = i32;
+
+pub const VDSO = void;