Update copyright dates with scripts/update-copyrights
[glibc.git] / sysdeps / unix / sysv / linux / or1k / or1k_clone.S
blob31d5956b7c7f90aadf1695277d918aa37b24ab6d
1 /* clone helper __or1k_clone for OpenRISC.
2    Copyright (C) 2022-2023 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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 #include <sysdep.h>
21 #include <tls.h>
22 #define __ASSEMBLY__
23 #include <linux/sched.h>
25         .text
26 ENTRY (__or1k_clone)
28         /* To handle GCC varargs we need to use our __clone wrapper to pop
29            everything from the stack for us.
30            Now everything is placed in the registers which saves us a lot
31            of trouble.
33            The userland implementation is:
35              int clone (int (*fn)(void *), void *child_stack,
36                         int flags, void *arg, pid_t *ptid,
37                         struct user_desc *tls, pid_t *ctid);
38            The kernel entry is:
40              int clone (long flags, void *child_stack, int *parent_tid,
41                         int *child_tid, struct void *tls)
43              NB: tls isn't really an argument, it is read from r7 directly.  */
45         /* First, align the stack to 4 bytes.  */
46         l.xori  r11, r0, -4
47         l.and   r4, r4, r11
49         /* Put 'fn', 'arg' and 'flags' on the child stack.  */
50         l.addi  r4, r4, -12
51         l.sw    8(r4), r3
52         l.sw    4(r4), r6
53         l.sw    0(r4), r5
55         l.ori   r3, r5, 0
56         /* The child_stack is already in r4.  */
57         l.ori   r5, r7, 0
58         l.lwz   r6, 0(r1)
59         l.ori   r7, r8, 0
61         DO_CALL (clone)
63         l.sfgeui r11, 0xf001
64         l.bf    L(error)
65          l.nop
67         /* If we are not the child, return the pid.  */
68         l.sfeqi r11, 0
69         l.bf    L(thread_start)
70          l.nop
72         l.jr    r9
73          l.nop
75 L(thread_start):
76         /* Load function from stack.  */
77         l.lwz   r11, 8(r1)
78         l.jalr  r11
79          l.lwz  r3, 4(r1)
81         /* Exit the child thread.  */
82         l.ori   r3, r11, 0
83         DO_CALL (exit)
85 L(error):
86         l.j     SYSCALL_ERROR_NAME
87          l.ori  r3, r11, 0
89 END (__or1k_clone)