diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 56e9d45a08..dbb9225aa2 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -112,7 +112,9 @@ pub fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*: } pub fn fork() usize { - if (@hasField(SYS, "fork")) { + if (comptime builtin.arch.isSPARC()) { + return syscall_fork(); + } else if (@hasField(SYS, "fork")) { return syscall0(.fork); } else { return syscall2(.clone, SIGCHLD, 0); diff --git a/lib/std/os/linux/sparc64.zig b/lib/std/os/linux/sparc64.zig index eefa4d60fd..20fdc275dd 100644 --- a/lib/std/os/linux/sparc64.zig +++ b/lib/std/os/linux/sparc64.zig @@ -21,6 +21,23 @@ pub fn syscall_pipe(fd: *[2]i32) usize { ); } +pub fn syscall_fork() usize { + return asm volatile ( + \\ t 0x6d + \\ bcc,pt %%xcc, 1f + \\ nop + \\ ba 2f + \\ neg %%o0 + \\ 1: + \\ dec %%o1 + \\ and %%o1, %%o0, %%o0 + \\ 2: + : [ret] "={o0}" (-> usize) + : [number] "{g1}" (@enumToInt(SYS.fork)) + : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7" + ); +} + pub fn syscall0(number: SYS) usize { return asm volatile ( \\ t 0x6d