Add clone(2) implementation

This implementation kindly provided by @LemonBoy at GitHub
https://github.com/ziglang/zig/pull/6187#issuecomment-682635168
master
Koakuma 2020-08-29 11:50:07 +07:00
parent 300cfbf252
commit 341eec71fd
1 changed files with 44 additions and 1 deletions

View File

@ -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."),
}
}