Commit 341eec71fd

Koakuma <koachan@protonmail.com>
2020-08-29 06:50:07
Add clone(2) implementation
This implementation kindly provided by @LemonBoy at GitHub https://github.com/ziglang/zig/pull/6187#issuecomment-682635168
1 parent 300cfbf
Changed files (1)
lib
std
special
lib/std/special/c.zig
@@ -479,7 +479,6 @@ fn clone() callconv(.Naked) void {
                 \\  syscall
             );
         },
-
         .powerpc64, .powerpc64le => {
             asm volatile (
                 \\  # store non-volatile regs r30, r31 on stack in order to put our
@@ -528,7 +527,51 @@ fn clone() callconv(.Naked) void {
                 \\  blr
             );
         },
+        .sparcv9 => {
+            // Implementation by @LemonBoy (https://github.com/LemonBoy)
+            // __clone(func, stack, flags, arg, ptid, tls, ctid)
+            //           i0,    i1,    i2,  i3,   i4,  i5,   sp
 
+            // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+            //                g1     o0,    o1,   o2,  o3,   o4
+            asm volatile (
+                \\ save %%sp, -192, %%sp
+                \\ # Save the func pointer and the arg pointer
+                \\ mov %%i0, %%g2
+                \\ mov %%i3, %%g3
+                \\ # Shuffle the arguments
+                \\ mov 217, %%g1
+                \\ mov %%i2, %%o0
+                \\ sub %%i1, 2047, %%o1
+                \\ mov %%i4, %%o2
+                \\ mov %%i5, %%o3
+                \\ ldx [%%fp + 192 - 2*8 + 2047], %%o4
+                \\ t 0x6d
+                \\ bcs,pn %%xcc, 2f
+                \\ nop
+                \\ # sparc64 returns the child pid in o0 and a flag telling
+                \\ # whether the process is the child in o1
+                \\ brnz %%o1, 1f
+                \\ nop
+                \\ # This is the parent process, return the child pid
+                \\ mov %%o0, %%i0
+                \\ ret
+                \\ restore
+                \\1:
+                \\ # This is the child process
+                \\ mov %%g0, %%fp
+                \\ call %%g2
+                \\ mov %%g3, %%o0
+                \\ # Exit
+                \\ mov 1, %%g1
+                \\ t 0x6d
+                \\2:
+                \\ # The syscall failed
+                \\ sub %%g0, %%o0, %%i0
+                \\ ret
+                \\ restore
+            );
+        },
         else => @compileError("Implement clone() for this arch."),
     }
 }