Updated to fedora-glibc-20041217T0906
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc32 / clone.S
1 /* Copyright (C) 1996, 1997, 1998, 2000, 2003, 2004
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Richard Henderson (rth@tamu.edu).
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* clone() is even more special than fork() as it mucks with stacks
22    and invokes a function in the right context after its all over.  */
23
24 #include <asm/errno.h>
25 #include <asm/unistd.h>
26 #include <tcb-offsets.h>
27
28 #define CLONE_VM        0x00000100
29 #define CLONE_THREAD    0x00010000
30
31 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
32              pid_t *ptid, void *tls, pid_t *ctid); */
33
34         .text
35         .align  4
36         .globl  __clone
37         .type   __clone,@function
38
39 __clone:
40         save    %sp,-96,%sp
41
42         /* sanity check arguments */
43         tst     %i0
44         be      .Lerror
45          orcc   %i1,%g0,%o1
46         be      .Lerror
47          mov    %i2,%o0
48         /* ptid */
49         mov     %i4,%o2
50         /* tls */
51         mov     %i5,%o3
52         /* ctid */
53         ld      [%fp+92],%o4
54
55         /* Do the system call */
56         set     __NR_clone,%g1
57         ta      0x10
58         bcs     .Lerror
59          tst    %o1
60         bne     __thread_start
61          nop
62         ret
63          restore %o0,%g0,%o0
64
65 .Lerror:
66         call    __errno_location
67          or     %g0,EINVAL,%i0
68         st      %i0,[%o0]
69         ret
70          restore %g0,-1,%o0
71
72         .size   __clone, .-__clone
73
74         .type   __thread_start,@function
75
76 __thread_start:
77 #ifdef RESET_PID
78         sethi   %hi(CLONE_THREAD), %l0
79         andcc   %i2, %l0, %g0
80         bne     1f
81          andcc  %i2, CLONE_VM, %g0
82         bne,a   2f
83          mov    -1,%o0
84         set     __NR_getpid,%g1
85         ta      0x10
86 2:      st      %o0,[%g7 + PID]
87         st      %o0,[%g7 + TID]
88 1:
89 #endif
90         call    %i0
91          mov    %i3,%o0
92         call    _exit,0
93          nop
94
95         .size   __thread_start, .-__thread_start
96
97 weak_alias(__clone, clone)