sparc64: add basic support
[uclibc-ng.git] / libc / sysdeps / linux / sparc64 / clone.S
blob63ab38bb778ded953b4fd10053ce9f93b97448d5
1 /* Copyright (C) 1997-2017 Free Software Foundation, Inc.
2    Contributed by Richard Henderson (rth@tamu.edu).
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
18 /* clone() is even more special than fork() as it mucks with stacks
19    and invokes a function in the right context after its all over.  */
21 #include <asm/errno.h>
22 #include <asm/unistd.h>
23 #include <sysdep.h>
25 #define CLONE_VM        0x00000100
27 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
28              pid_t *ptid, void *tls, pid_t *ctid); */
30         .register       %g2,#scratch
31         .register       %g3,#scratch
33         .text
35 ENTRY (__clone)
36         save    %sp, -192, %sp
37         cfi_def_cfa_register(%fp)
38         cfi_window_save
39         cfi_register(%o7, %i7)
41         /* sanity check arguments */
42         brz,pn  %i0, 99f                /* fn non-NULL? */
43          mov    %i0, %g2
44         brz,pn  %i1, 99f                /* child_stack non-NULL? */
45          mov    %i2, %o0                /* clone flags */
47         /* The child_stack is the top of the stack, allocate one
48            whole stack frame from that as this is what the kernel
49            expects.  Also, subtract STACK_BIAS.  */
50         sub     %i1, 192 + 0x7ff, %o1
51         mov     %i3, %g3
53         mov     %i4,%o2                 /* PTID */
54         mov     %i5,%o3                 /* TLS */
55         ldx     [%fp+0x7ff+176],%o4     /* CTID */
57         /* Do the system call */
58         set     __NR_clone, %g1
59         ta      0x6d
60         bcs,pn  %xcc, 98f
61          nop
62         brnz,pn %o1, __thread_start
63          nop
64         jmpl    %i7 + 8, %g0
65          restore %o0, %g0, %o0
66 99:     mov     EINVAL, %o0
67 98:     call    __errno_location
68          mov    %o0, %i0
69         st      %i0, [%o0]
70         jmpl    %i7 + 8, %g0
71          restore %g0,-1,%o0
72 END(__clone)
74         .type __thread_start,@function
75 __thread_start:
76         mov     %g0, %fp        /* terminate backtrace */
77         call    %g2
78          mov    %g3,%o0
79         call    HIDDEN_JUMPTARGET(_exit),0
80          nop
82         .size   __thread_start, .-__thread_start
84 libc_hidden_def(__clone)
85 weak_alias(__clone, clone)