Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / m68k / clone.S
blobb68a3bd9360f3c83618a0e501946dbc7b17de90b
1 /* Copyright (C) 1996-2015 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Andreas Schwab (schwab@issan.informatik.uni-dortmund.de)
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, see
17    <http://www.gnu.org/licenses/>.  */
19 /* clone() is even more special than fork() as it mucks with stacks
20    and invokes a function in the right context after its all over.  */
22 #include <sysdep.h>
23 #define _ERRNO_H        1
24 #include <bits/errno.h>
25 #include <tls.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              void *parent_tidptr, void *tls, void *child_tidptr) */
33         .text
34 ENTRY (__clone)
36         /* Sanity check arguments.  */
37         movel   #-EINVAL, %d0
38         movel   4(%sp), %a0             /* no NULL function pointers */
39         tstl    %a0
40         jeq     SYSCALL_ERROR_LABEL
41         movel   8(%sp), %a1             /* no NULL stack pointers */
42         tstl    %a1
43         jeq     SYSCALL_ERROR_LABEL
45         /* Allocate space and copy the argument onto the new stack.  */
46         movel   16(%sp), -(%a1)
48         /* Do the system call */
49         movel   12+0(%sp), %d1          /* get flags */
50         movel   %d3, -(%a1)             /* save %d3 and get parent_tidptr */
51         movel   %d3, -(%sp)
52         cfi_adjust_cfa_offset (4)
53         cfi_rel_offset (%d3, 0)
54         movel   20+4(%sp), %d3
55         movel   %d4, -(%a1)             /* save %d4 and get child_tidptr */
56         movel   %d4, -(%sp)
57         cfi_adjust_cfa_offset (4)
58         cfi_rel_offset (%d4, 0)
59         movel   28+8(%sp), %d4
60         movel   %d5, -(%a1)             /* save %d5 and get tls */
61         movel   %d5, -(%sp)
62         cfi_adjust_cfa_offset (4)
63         cfi_rel_offset (%d5, 0)
64         movel   24+12(%sp), %d5
65         /* save %d2 and get stack pointer */
66 #ifdef __mcoldfire__
67         movel   %d2, -(%a1)
68         movel   %d2, -(%sp)
69         cfi_adjust_cfa_offset (4)
70         cfi_rel_offset (%d2, 0)
71         movel   %a1, %d2
72 #else
73         exg     %d2, %a1                /* save %d2 and get stack pointer */
74         cfi_register (%d2, %a1)
75 #endif
76         movel   #SYS_ify (clone), %d0
78         /* End FDE now, because in the child the unwind info will be
79            wrong.  */
80         cfi_endproc
82         trap    #0
83 #ifdef __mcoldfire__
84         movel   (%sp)+, %d2
85 #else
86         exg     %d2, %a1                /* restore %d2 */
87 #endif
88         movel   (%sp)+, %d5             /* restore %d5, %d4 and %d3 */
89         movel   (%sp)+, %d4
90         movel   (%sp)+, %d3
92         tstl    %d0
93         jmi     SYSCALL_ERROR_LABEL
94         jeq     thread_start
96         rts
98 thread_start:
99         cfi_startproc
100         cfi_undefined (pc)      /* Mark end of stack */
101         subl    %fp, %fp        /* terminate the stack frame */
102         /* Check and see if we need to reset the PID.  */
103         movel   %d1, %a1
104         andl    #CLONE_THREAD, %d1
105         jne     donepid
106         movel   %a1, %d1
107         movel   #-1, %d0
108         andl    #CLONE_VM, %d1
109         jne     gotpid
110         movel   #SYS_ify (getpid), %d0
111         trap    #0
112 gotpid:
113         movel   %a0, -(%sp)
114         movel   %d0, -(%sp)
115         bsrl    __m68k_read_tp@PLTPC
116         movel   (%sp)+, %d0
117         movel   %d0, PID_OFFSET(%a0)
118         movel   %d0, TID_OFFSET(%a0)
119         movel   (%sp)+, %a0
120 donepid:
121         jsr     (%a0)
122         movel   %d0, %d1
123         movel   #SYS_ify (exit), %d0
124         trap    #0
125         cfi_endproc
127         cfi_startproc
128 PSEUDO_END (__clone)
130 weak_alias (__clone, clone)