summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/sparc/clone.S
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/sparc/clone.S')
-rw-r--r--mdk-stage1/dietlibc/sparc/clone.S45
1 files changed, 45 insertions, 0 deletions
diff --git a/mdk-stage1/dietlibc/sparc/clone.S b/mdk-stage1/dietlibc/sparc/clone.S
new file mode 100644
index 000000000..58b438249
--- /dev/null
+++ b/mdk-stage1/dietlibc/sparc/clone.S
@@ -0,0 +1,45 @@
+#include <asm/errno.h>
+#include <asm/unistd.h>
+
+.text
+.align 4
+.weak clone
+clone:
+.global __clone
+__clone:
+ save %sp, -96, %sp
+
+ tst %i0 /* check for function pointer */
+ be .Lerror
+ tst %i1 /* check for stack pointer */
+ be .Lerror
+ nop
+
+ mov %i1, %o1 /* child-stack */
+ mov %i2, %o0 /* clone-flags */
+ mov __NR_clone, %g1
+ ta 0x10 /* syscall: clone */
+ bcs .Lerror
+
+ tst %o1
+ bne .Lstart /* we are the child :) */
+ nop
+ mov %o0, %i0 /* return child pid */
+ ret
+ restore
+
+.Lerror:
+ call __errno_location
+ nop
+ mov EINVAL, %l0
+ st %l0, [%o0]
+ ret
+ restore %g0, -1, %o0
+
+.Lstart:
+ call %i0 /* call child-function */
+ mov %i3, %o0 /* put arg in the right place for the child */
+
+ call _exit /* child returned */
+ nop
+