2 * Copyright (C) 2016-2017 Andes Technology, Inc.
3 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
6 /* Copyright (C) 2010-2014 Free Software Foundation, Inc.
7 Contributed by Pat Beirne <patb@corelcomputer.com>
9 The GNU C Library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
14 The GNU C Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with the GNU C Library; if not, write to the Free
21 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 /* clone() is even more special than fork() as it mucks with stacks
25 and invokes a function in the right context after its all over. */
29 #include <bits/errno.h>
31 /* int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);
32 _syscall2(int, clone, int, flags, void *, child_stack) */
35 #ifdef __NDS32_ABI_2FP_PLUS__
40 /* set GP register to parent only, cause child's $SP will be $r1. */
42 cfi_adjust_cfa_offset(8)
46 sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4)
47 ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8)
51 /* sanity check arguments. */
60 /* restore GP register, only in parent's stack */
61 la $r15, C_SYMBOL_NAME(__syscall_error@PLT)
63 cfi_adjust_cfa_offset(4)
66 cfi_adjust_cfa_offset(4)
69 cfi_adjust_cfa_offset(-4)
71 cfi_adjust_cfa_offset(-4)
74 cfi_adjust_cfa_offset(-8)
79 la $r15, C_SYMBOL_NAME(__syscall_error)
84 /* Child's $sp will be $r1, make $sp 8-byte alignment */
86 /* push to child's stack only. */
88 swi.p $r3, [$r1], -4 ! arg
91 /* do the system call */
92 or $r0, $r2, $r2 ! move $r0, $r2
95 move $r5, $r2 ! Use $r5 to backup $r2
96 ! The pt_regs is placed in $r5 in kerenl (sys_clone_wrapper)
99 #ifdef __NDS32_ABI_2FP_PLUS__
120 /* restore GP register, only in parent's stack */
122 cfi_adjust_cfa_offset(-8)
128 /* Only in child's stack. */
133 #if !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)
135 #endif /* !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__) */
137 ! use $r15 in case _exit is PIC
140 #if !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)
142 #endif /* !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__) */
144 ! use $r15 in case _exit is PIC
146 la $r15, C_SYMBOL_NAME(_exit@PLT)
148 la $r15, C_SYMBOL_NAME(_exit)
154 weak_alias (__clone, clone)