Updated to fedora-glibc-20050620T1530
[glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc64 / clone.S
blob0e1025ff6ace184aed9995af6d2bd26ef154cabb
1 /* Copyright (C) 1997, 2000 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Richard Henderson (rth@tamu.edu).
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 /* clone() is even more special than fork() as it mucks with stacks
21    and invokes a function in the right context after its all over.  */
23 #include <asm/errno.h>
24 #include <asm/unistd.h>
25 #include <tcb-offsets.h>
27 #define CLONE_VM        0x00000100
28 #define CLONE_THREAD    0x00010000
30 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
31              pid_t *ptid, void *tls, pid_t *ctid); */
33         .register       %g2,#scratch
34         .register       %g3,#scratch
36         .text
37         .align  4
38         .globl  __clone
39         .type   __clone,@function
41 __clone:
42         save    %sp, -192, %sp
44         /* sanity check arguments */
45         brz,pn  %i0, 99f                /* fn non-NULL? */
46          mov    %i0, %g2
47         brz,pn  %i1, 99f                /* child_stack non-NULL? */
48          mov    %i2, %o0                /* clone flags */
50         /* The child_stack is the top of the stack, allocate one
51            whole stack frame from that as this is what the kernel
52            expects.  Also, subtract STACK_BIAS.  */
53         sub     %i1, 192 + 0x7ff, %o1
54         mov     %i3, %g3
55         mov     %i2, %g4
57         mov     %i4,%o2                 /* PTID */
58         mov     %i5,%o3                 /* TLS */
59         ldx     [%fp+0x7ff+176],%o4     /* CTID */
61         /* Do the system call */
62         set     __NR_clone, %g1
63         ta      0x6d
64         bcs,pn  %xcc, 99f
65          nop
66         brnz,pn %o1, __thread_start
67          nop
68         ret
69          restore %o0, %g0, %o0
70 99:
71 #ifndef _LIBC_REENTRANT
72 #ifdef PIC
73         call    1f
74         sethi   %hi(_GLOBAL_OFFSET_TABLE_-(99b-.)), %l7
75 1:      or      %l7, %lo(_GLOBAL_OFFSET_TABLE_-(99b-.)), %l7
76         add     %l7, %o7, %l7
77         set     EINVAL, %i0
78         sethi   %hi(errno), %g2
79         or      %g2, %lo(errno), %g2
80         st      %i0, [%l7+%g2]
81 #else
82         sethi   %hi(errno), %g2
83         set     EINVAL, %i0
84         st      %i0, [%g2+%lo(errno)]
85 #endif
86 #else
87         call    __errno_location
88          nop
89         st      %i0, [%o0]
90 #endif
91         ret
92          restore %g0,-1,%o0
93         .size __clone, .-__clone
95         .type __thread_start,@function
96 __thread_start:
97 #ifdef RESET_PID
98         sethi   %hi(CLONE_THREAD), %l0
99         andcc   %g4, %l0, %g0
100         bne,pt  %icc, 1f
101          andcc  %g4, CLONE_VM, %g0
102         bne,a,pn %icc, 2f
103          mov    -1,%o0
104         set     __NR_getpid,%g1
105         ta      0x6d
106 2:      st      %o0,[%g7 + PID]
107         st      %o0,[%g7 + TID]
109 #endif
110         mov     %g0, %fp        /* terminate backtrace */
111         call    %g2
112          mov    %g3,%o0
113         call    _exit,0
114          nop
115         .size __thread_start, .-__thread_start
117 weak_alias (__clone, clone)