remove PID caching
[uclibc-ng.git] / libc / sysdeps / linux / xtensa / clone.S
blob913ec5a5fbbad5e3ff94b11464783799b1d83ed8
1 /* Copyright (C) 2001, 2005 Free Software Foundation, Inc.
3    The GNU C Library is free software; you can redistribute it and/or
4    modify it under the terms of the GNU Library General Public License as
5    published by the Free Software Foundation; either version 2 of the
6    License, or (at your option) any later version.
8    The GNU C Library is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11    Library General Public License for more details.
13    You should have received a copy of the GNU Library General Public
14    License along with the GNU C Library; see the file COPYING.LIB.  If not,
15    see <http://www.gnu.org/licenses/>.  */
17 /* clone is even more special than fork as it mucks with stacks
18    and invokes a function in the right context after its all over.  */
20 #include <features.h>
21 #include <sysdep.h>
22 #define _ERRNO_H        1
23 #include <bits/errno.h>
24 #define __ASSEMBLY__
25 #include <linux/sched.h>
27 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
28                     a2                    a3               a4        a5
29              pid_t *ptid, struct user_desc *tls, pid_t *ctid)
30                    a6               a7              16(sp)
33         .text
34 ENTRY (__clone)
36         /* Sanity check arguments.  */
37         beqz    a2, .Leinval    /* no NULL function pointers */
38         beqz    a3, .Leinval    /* no NULL stack pointers */
40         /* a2 and a3 are candidates for destruction by system-call return
41            parameters.  We don't need the stack pointer after the system
42            call.  We trust that the kernel will preserve a6, a7 and a9. */
44         mov     a9, a5                  /* save function argument */
45         mov     a5, a7
46         mov     a7, a2                  /* save function pointer */
47         mov     a8, a6                  /* use a8 as a temp */
48         mov     a6, a4
49         mov     a4, a8
50         l32i    a8, a1, FRAMESIZE       /* child_tid */
51         movi    a2, SYS_ify(clone)
53         /* syscall(NR_clone,clone_flags, usp, parent_tid, child_tls, child_tid)
54                      a2         a6        a3        a4        a5         a8
55          */
57         syscall
58         bltz    a2, SYSCALL_ERROR_LABEL
59         beqz    a2, .Lthread_start
61         /* fall through for parent */
63 .Lpseudo_end:
64         abi_ret
66 .Leinval:
67         movi    a2, -EINVAL
68         j       SYSCALL_ERROR_LABEL
70 .Lthread_start:
72 #if CLONE_THREAD != 0x00010000 || CLONE_VM != 0x00000100
73 # error invalid values for CLONE_THREAD or CLONE_VM
74 #endif
76         /* start child thread */
77         movi    a0, 0                   /* terminate the stack frame */
79 #if defined(__XTENSA_WINDOWED_ABI__)
80         mov     a6, a9                  /* load up the 'arg' parameter */
81         callx4  a7                      /* call the user's function */
83         /* Call _exit.  Note that any return parameter from the user's
84            function in a6 is seen as inputs to _exit. */
85         movi    a2, JUMPTARGET(_exit)
86         callx4  a2
87 #elif defined(__XTENSA_CALL0_ABI__)
88         mov     a2, a9                  /* load up the 'arg' parameter */
89         callx0  a7                      /* call the user's function */
91         /* Call _exit.  Note that any return parameter from the user's
92            function in a2 is seen as inputs to _exit.  */
93         movi    a0, JUMPTARGET(_exit)
94         callx0  a0
95 #else
96 #error Unsupported Xtensa ABI
97 #endif
99 PSEUDO_END (__clone)
100 weak_alias (__clone, clone)