]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/sh/clone.S
Update to LGPL v2.1.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / sh / clone.S
1 /* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
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.
8
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.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
18
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. */
21
22 #include <sysdep.h>
23 #define _ERRNO_H 1
24 #include <bits/errno.h>
25
26 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
27
28 .text
29 ENTRY(__clone)
30 /* sanity check arguments. */
31 tst r4, r4
32 bf/s 1f
33 tst r5, r5
34 bf/s 1f
35 mov.l .L1, r1
36 #ifdef SHARED
37 mov.l r12, @-r15
38 sts.l pr, @-r15
39 mov.l .LG, r12
40 mova .LG, r0
41 add r0, r12
42 mova .L1, r0
43 add r0, r1
44 jsr @r1
45 mov #-EINVAL, r4
46 lds.l @r15+, pr
47 rts
48 mov.l @r15+, r12
49 #else
50 jmp @r1
51 mov #-EINVAL, r4
52 #endif
53 .align 2
54 .L1:
55 .long PLTJMP(C_SYMBOL_NAME(__syscall_error))
56 1:
57 /* insert the args onto the new stack */
58 mov.l r7, @-r5
59 /* save the function pointer as the 0th element */
60 mov.l r4, @-r5
61
62 /* do the system call */
63 mov r6, r4
64 mov #+SYS_ify(clone), r3
65 trapa #0x12
66 mov r0, r1
67 mov #-12, r2
68 shad r2, r1
69 not r1, r1 // r1=0 means r0 = -1 to -4095
70 tst r1, r1 // i.e. error in linux
71 bf 2f
72 mov.l .L2, r1
73 #ifdef SHARED
74 mov r0, r4
75 mov.l r12, @-r15
76 sts.l pr, @-r15
77 mov.l .LG, r12
78 mova .LG, r0
79 add r0, r12
80 mova .L2, r0
81 add r0, r1
82 jsr @r1
83 nop
84 lds.l @r15+, pr
85 rts
86 mov.l @r15+, r12
87 #else
88 jmp @r1
89 mov r0, r4
90 #endif
91 .align 2
92 .L2:
93 .long PLTJMP(C_SYMBOL_NAME(__syscall_error))
94
95 2:
96 tst r0, r0
97 bt 3f
98 rts
99 nop
100 3:
101 /* thread starts */
102 mov.l @r15, r1
103 jsr @r1
104 mov.l @(4,r15), r4
105
106 /* we are done, passing the return value through r0 */
107 mov.l .L3, r1
108 #ifdef SHARED
109 mov.l r12, @-r15
110 sts.l pr, @-r15
111 mov r0, r4
112 mova .LG, r0
113 mov.l .LG, r12
114 add r0, r12
115 mova .L3, r0
116 add r0, r1
117 jsr @r1
118 nop
119 lds.l @r15+, pr
120 rts
121 mov.l @r15+, r12
122 #else
123 jmp @r1
124 mov r0, r4
125 #endif
126 .align 2
127 .LG:
128 .long _GLOBAL_OFFSET_TABLE_
129 .L3:
130 .long PLTJMP(C_SYMBOL_NAME(_exit))
131 PSEUDO_END (__clone)
132
133 weak_alias (__clone, clone)