]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/frv/clone.S
Inital import
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / frv / clone.S
diff --git a/l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/frv/clone.S b/l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/frv/clone.S
new file mode 100644 (file)
index 0000000..1456157
--- /dev/null
@@ -0,0 +1,83 @@
+/* Copyright (C) 2003, 2004 Free Software Foudnation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Alexandre Oliva <aoliva@redhat.com>, 2003.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* clone() is even more special than fork() as it mucks with stacks
+   and invokes a function in the right context after its all over.  */
+
+#include <features.h>
+#include <asm/unistd.h>
+#define _ERRNO_H       1
+#include <bits/errno.h>
+
+       .text
+       .globl  clone
+       .type clone,@function
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
+clone:
+       /* Sanity check arguments.  */
+       cmp.p   gr8, gr0, icc0
+       cmp     gr9, gr0, icc1
+       mov.p   gr8, gr4
+       beq     icc0, #0, .Lerror
+       mov.p   gr11, gr5
+       beq     icc1, #0, .Lerror
+
+       mov.p   gr10, gr8
+       setlos  #__NR_clone, gr7
+       tra     gr0,gr0
+
+       cmp.p   gr8, gr0, icc0
+       setlos #-4096, gr6
+       cmp.p   gr8, gr6, icc1
+       beq     icc0, #0, .Lthread_start
+       blslr   icc1, #2
+
+.Lsys_error:
+       sethi.p #gotofffuncdeschi(__syscall_error), gr14
+       setlo   #gotofffuncdesclo(__syscall_error), gr14
+       ldd     @(gr14, gr15), gr14
+       jmpl    @(gr14, gr0)
+
+.Lerror:
+       setlos.p #-EINVAL, gr8
+       bra     .Lsys_error
+
+###############################################################################
+#
+# come here as the new thread [GR4 is fn, GR5 is arg]
+#
+###############################################################################
+.Lthread_start:
+       /* Save the PIC register.  */
+       mov     gr15, gr17
+
+       /* Call the user's function.  */
+       ldd.p   @(gr4, gr0), gr14
+       mov     gr5, gr8
+       calll   @(gr14, gr0)
+
+       /* Call _exit, rather simply inlining the syscall, such that
+          breakpoints work.*/
+
+       mov.p   gr17, gr15
+       call    HIDDEN_JUMPTARGET(_exit)
+
+       /* Should never get here.  */
+       jmpl    @(gr0, gr0)
+       .size   clone,.-clone