summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/h8300/clone.S
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-07-15 07:34:00 +0000
committerEric Andersen <andersen@codepoet.org>2004-07-15 07:34:00 +0000
commit71150804d1ac8ed2f7b9c6d3025fd415c58b129e (patch)
treeaab8c892a813847614070f73e711178cd3c9ec74 /libc/sysdeps/linux/h8300/clone.S
parent255fbb6abcef56c5f8c36383d49a902686f258f5 (diff)
h8300 updates from Yoshinori Sato
Diffstat (limited to 'libc/sysdeps/linux/h8300/clone.S')
-rw-r--r--libc/sysdeps/linux/h8300/clone.S78
1 files changed, 78 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/h8300/clone.S b/libc/sysdeps/linux/h8300/clone.S
new file mode 100644
index 000000000..7d100b6c4
--- /dev/null
+++ b/libc/sysdeps/linux/h8300/clone.S
@@ -0,0 +1,78 @@
+/* Adapted from glibc */
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. */
+
+/* clone is even more special than fork as it mucks with stacks
+ and invokes a function in the right context after its all over. */
+
+#define _ERRNO_H
+#include <bits/errno.h>
+#include <sys/syscall.h>
+
+/* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
+
+#ifdef __H8300H__
+ .h8300h
+#endif
+#ifdef __H8300S__
+ .h8300s
+#endif
+
+.text
+.globl _clone
+.globl ___clone
+_clone:
+___clone:
+ /* Sanity check arguments. */
+ mov.l #-EINVAL,er3
+ mov.l er0,er0 /* no NULL function pointers */
+ beq __syscall_error
+ mov.l er1,er1 /* no NULL stack pointers */
+ beq __syscall_error
+
+ /* Allocate space and copy the argument onto the new stack. */
+ mov.l @(4:16,sp),er3
+ mov.l er3,@-er1
+
+ /* Do the system call */
+ mov.l er0,er3 /* er3 = child entry */
+ mov.l er1,er0
+ mov.l er2,er1 /* er1 = flags */
+ mov.l er0,er2 /* er2 = child sp */
+ mov.l #__NR_clone,r0
+ trapa #0
+ mov.l er0,er0
+ bmi __syscall_error
+ beq thread_start
+
+ rts
+
+__syscall_error:
+ neg.l er0
+ mov.l er0,@-sp
+#if !defined(__PIC__)
+ jsr @__errno_location
+#else
+ mov.l @(__errno_location@GOTOFF,er5),er1
+ jsr @er1
+#endif
+ mov.l @sp,er1
+ mov.l er1,@er0
+ sub.l er0,er0
+ dec.l #1,er0
+
+ rts
+
+thread_start:
+ mov.l @sp+,er0 /* restore args */
+ jsr @er3
+ mov.l er0,er1
+ mov.l #__NR_exit,er0
+ trapa #0
+
+#if defined(__HAVE_ELF__)
+ .weak clone
+ clone = __clone
+#else
+ .set clone,__clone
+#endif
+