diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig index e0583f430..c50aa940d 100644 --- a/lib/std/special/c.zig +++ b/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."), } }