iconv: prevent compiler warning during initialization with jis0208
[uclibc-ng.git] / libc / sysdeps / linux / nds32 / clone.S
blobb28619bf1729925d3de6d83fcf8232c27fb483ec
1 /*
2  * Copyright (C) 2016-2017 Andes Technology, Inc.
3  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4  */
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
22    02111-1307 USA.  */
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.  */
27 #include <sysdep.h>
28 #define _ERRNO_H        1
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)  */
34 ENTRY(__clone)
35 #ifdef __NDS32_ABI_2FP_PLUS__
36         lwi     $r4, [$sp]
37         lwi     $r5, [$sp+4]
38 #endif
39 #ifdef PIC
40         /* set GP register to parent only, cause child's $SP will be $r1. */
41         pushm   $fp, $gp
42         cfi_adjust_cfa_offset(8)
43         cfi_rel_offset(fp, 0)
44         cfi_rel_offset(gp, 4)
45         mfusr   $r15, $pc
46         sethi   $gp, hi20(_GLOBAL_OFFSET_TABLE_+4)
47         ori     $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8)
48         add     $gp, $gp, $r15
49 #endif /* PIC  */
51         /* sanity check arguments.  */
52         beqz    $r0, 1f
53         bnez    $r1, 2f
56         movi    $r0, -EINVAL
59 #ifdef PIC
60         /* restore GP register, only in parent's stack  */
61         la      $r15, C_SYMBOL_NAME(__syscall_error@PLT)
62         push    $lp
63         cfi_adjust_cfa_offset(4)
64         cfi_rel_offset(lp, 0)
65         addi    $sp, $sp, -4
66         cfi_adjust_cfa_offset(4)
67         jral    $r15
68         addi    $sp, $sp, 4
69         cfi_adjust_cfa_offset(-4)
70         pop     $lp
71         cfi_adjust_cfa_offset(-4)
72         cfi_restore(lp)
73         popm    $fp, $gp
74         cfi_adjust_cfa_offset(-8)
75         cfi_restore(fp)
76         cfi_restore(gp)
77         ret
78 #else /* ! PIC  */
79         la      $r15, C_SYMBOL_NAME(__syscall_error)
80         jr      $r15
81 #endif /* ! PIC  */
84         /* Child's $sp will be $r1, make $sp 8-byte alignment */
85         bitci   $r1, $r1, 7
86         /* push to child's stack only.  */
87         addi    $r1, $r1, -4
88         swi.p   $r3, [$r1], -4                  ! arg
89         swi     $r0, [$r1]                      ! fn
91         /* do the system call  */
92         or      $r0, $r2, $r2                   ! move $r0, $r2
94         move    $r3, $r5
95         move    $r5, $r2                        ! Use $r5 to backup $r2
96                                                 ! The pt_regs is placed in $r5 in kerenl (sys_clone_wrapper)
97         move    $r2, $r4
99 #ifdef __NDS32_ABI_2FP_PLUS__
100 # ifdef PIC
101        lwi     $r4, [$sp+#0x10]
102 # else
103        lwi     $r4, [$sp+#0x8]
104 # endif
105 #else
106 # ifdef PIC
107        lwi     $r4, [$sp+#0x8]
108 # else
109        lwi     $r4, [$sp]
110 # endif
111 #endif
113         __do_syscall(clone)
114         beqz    $r0, 4f
115         bltz    $r0, 5b
119 #ifdef PIC
120         /* restore GP register, only in parent's stack  */
121         popm    $fp, $gp
122         cfi_adjust_cfa_offset(-8)
123         cfi_restore(gp)
124         cfi_restore(fp)
125 #endif /* PIC  */
126         ret
128         /* Only in child's stack.  */
129         pop     $r1                             ! fn
130         pop     $r0                             ! arg
133 #if !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)
134         addi    $sp, $sp, -24
135 #endif /* !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)  */
137         ! use $r15 in case _exit is PIC
138         bral    $r1
140 #if !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)
141         addi    $sp, $sp, 24
142 #endif /* !defined(__NDS32_ABI_2__) && !defined(__NDS32_ABI_2FP_PLUS__)  */
144         ! use $r15 in case _exit is PIC
145 #ifdef PIC
146         la      $r15, C_SYMBOL_NAME(_exit@PLT)
147 #else /* ! PIC  */
148         la      $r15, C_SYMBOL_NAME(_exit)
149 #endif /* ! PIC  */
150         jr      $r15
153 PSEUDO_END (__clone)
154 weak_alias (__clone, clone)