Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /* Assembler macros for Nios II. |
---|---|
2 | Copyright (C) 2000-2022 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
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. |
9 | |
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. |
14 | |
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 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #ifndef _LINUX_NIOS2_SYSDEP_H |
20 | #define _LINUX_NIOS2_SYSDEP_H 1 |
21 | |
22 | #include <sysdeps/unix/sysdep.h> |
23 | #include <sysdeps/nios2/sysdep.h> |
24 | #include <sysdeps/unix/sysv/linux/generic/sysdep.h> |
25 | |
26 | /* For RTLD_PRIVATE_ERRNO. */ |
27 | #include <dl-sysdep.h> |
28 | |
29 | #include <tls.h> |
30 | |
31 | /* For Linux we can use the system call table in the header file |
32 | /usr/include/asm/unistd.h |
33 | of the kernel. But these symbols do not follow the SYS_* syntax |
34 | so we have to redefine the `SYS_ify' macro here. */ |
35 | #undef SYS_ify |
36 | #define SYS_ify(syscall_name) __NR_##syscall_name |
37 | |
38 | #ifdef __ASSEMBLER__ |
39 | |
40 | #undef SYSCALL_ERROR_LABEL |
41 | #define SYSCALL_ERROR_LABEL __local_syscall_error |
42 | |
43 | #undef PSEUDO |
44 | #define PSEUDO(name, syscall_name, args) \ |
45 | ENTRY (name) \ |
46 | DO_CALL (syscall_name, args) \ |
47 | bne r7, zero, SYSCALL_ERROR_LABEL; \ |
48 | |
49 | #undef PSEUDO_END |
50 | #define PSEUDO_END(name) \ |
51 | SYSCALL_ERROR_HANDLER \ |
52 | END (name) |
53 | |
54 | #undef PSEUDO_NOERRNO |
55 | #define PSEUDO_NOERRNO(name, syscall_name, args) \ |
56 | ENTRY (name) \ |
57 | DO_CALL (syscall_name, args) |
58 | |
59 | #undef PSEUDO_END_NOERRNO |
60 | #define PSEUDO_END_NOERRNO(name) \ |
61 | END (name) |
62 | |
63 | #undef ret_NOERRNO |
64 | #define ret_NOERRNO ret |
65 | |
66 | #undef DO_CALL |
67 | #define DO_CALL(syscall_name, args) \ |
68 | DOARGS_##args \ |
69 | movi r2, SYS_ify(syscall_name); \ |
70 | trap; |
71 | |
72 | #if defined(__PIC__) || defined(PIC) |
73 | |
74 | # if RTLD_PRIVATE_ERRNO |
75 | |
76 | # define SYSCALL_ERROR_HANDLER \ |
77 | SYSCALL_ERROR_LABEL: \ |
78 | nextpc r3; \ |
79 | 1: \ |
80 | movhi r8, %hiadj(rtld_errno - 1b); \ |
81 | addi r8, r8, %lo(rtld_errno - 1b); \ |
82 | add r3, r3, r8; \ |
83 | stw r2, 0(r3); \ |
84 | movi r2, -1; \ |
85 | ret; |
86 | |
87 | # else |
88 | |
89 | # if IS_IN (libc) |
90 | # define SYSCALL_ERROR_ERRNO __libc_errno |
91 | # else |
92 | # define SYSCALL_ERROR_ERRNO errno |
93 | # endif |
94 | # define SYSCALL_ERROR_HANDLER \ |
95 | SYSCALL_ERROR_LABEL: \ |
96 | nextpc r3; \ |
97 | 1: \ |
98 | movhi r8, %hiadj(_gp_got - 1b); \ |
99 | addi r8, r8, %lo(_gp_got - 1b); \ |
100 | add r3, r3, r8; \ |
101 | ldw r3, %tls_ie(SYSCALL_ERROR_ERRNO)(r3); \ |
102 | add r3, r23, r3; \ |
103 | stw r2, 0(r3); \ |
104 | movi r2, -1; \ |
105 | ret; |
106 | |
107 | # endif |
108 | |
109 | #else |
110 | |
111 | /* We can use a single error handler in the static library. */ |
112 | #define SYSCALL_ERROR_HANDLER \ |
113 | SYSCALL_ERROR_LABEL: \ |
114 | jmpi __syscall_error; |
115 | |
116 | #endif |
117 | |
118 | #define DOARGS_0 /* nothing */ |
119 | #define DOARGS_1 /* nothing */ |
120 | #define DOARGS_2 /* nothing */ |
121 | #define DOARGS_3 /* nothing */ |
122 | #define DOARGS_4 /* nothing */ |
123 | #define DOARGS_5 ldw r8, 0(sp); |
124 | #define DOARGS_6 ldw r9, 4(sp); ldw r8, 0(sp); |
125 | |
126 | /* The function has to return the error code. */ |
127 | #undef PSEUDO_ERRVAL |
128 | #define PSEUDO_ERRVAL(name, syscall_name, args) \ |
129 | ENTRY (name) \ |
130 | DO_CALL (syscall_name, args) |
131 | |
132 | #undef PSEUDO_END_ERRVAL |
133 | #define PSEUDO_END_ERRVAL(name) \ |
134 | END (name) |
135 | |
136 | #define ret_ERRVAL ret |
137 | |
138 | #else /* __ASSEMBLER__ */ |
139 | |
140 | /* In order to get __set_errno() definition in INLINE_SYSCALL. */ |
141 | #include <errno.h> |
142 | |
143 | #undef INTERNAL_SYSCALL_RAW |
144 | #define INTERNAL_SYSCALL_RAW(name, nr, args...) \ |
145 | ({ unsigned int _sys_result; \ |
146 | { \ |
147 | /* Load argument values in temporary variables |
148 | to perform side effects like function calls |
149 | before the call-used registers are set. */ \ |
150 | LOAD_ARGS_##nr (args) \ |
151 | LOAD_REGS_##nr \ |
152 | register int _r2 asm ("r2") = (int)(name); \ |
153 | register int _err asm ("r7"); \ |
154 | asm volatile ("trap" \ |
155 | : "+r" (_r2), "=r" (_err) \ |
156 | : ASM_ARGS_##nr \ |
157 | : __SYSCALL_CLOBBERS); \ |
158 | _sys_result = _err != 0 ? -_r2 : _r2; \ |
159 | } \ |
160 | (int) _sys_result; }) |
161 | |
162 | #undef INTERNAL_SYSCALL |
163 | #define INTERNAL_SYSCALL(name, nr, args...) \ |
164 | INTERNAL_SYSCALL_RAW(SYS_ify(name), nr, args) |
165 | |
166 | #undef INTERNAL_SYSCALL_NCS |
167 | #define INTERNAL_SYSCALL_NCS(number, nr, args...) \ |
168 | INTERNAL_SYSCALL_RAW(number, nr, args) |
169 | |
170 | #define LOAD_ARGS_0() |
171 | #define LOAD_REGS_0 |
172 | #define ASM_ARGS_0 |
173 | #define LOAD_ARGS_1(a1) \ |
174 | LOAD_ARGS_0 () \ |
175 | int __arg1 = (int) (a1); |
176 | #define LOAD_REGS_1 \ |
177 | register int _r4 asm ("r4") = __arg1; \ |
178 | LOAD_REGS_0 |
179 | #define ASM_ARGS_1 "r" (_r4) |
180 | #define LOAD_ARGS_2(a1, a2) \ |
181 | LOAD_ARGS_1 (a1) \ |
182 | int __arg2 = (int) (a2); |
183 | #define LOAD_REGS_2 \ |
184 | register int _r5 asm ("r5") = __arg2; \ |
185 | LOAD_REGS_1 |
186 | #define ASM_ARGS_2 ASM_ARGS_1, "r" (_r5) |
187 | #define LOAD_ARGS_3(a1, a2, a3) \ |
188 | LOAD_ARGS_2 (a1, a2) \ |
189 | int __arg3 = (int) (a3); |
190 | #define LOAD_REGS_3 \ |
191 | register int _r6 asm ("r6") = __arg3; \ |
192 | LOAD_REGS_2 |
193 | #define ASM_ARGS_3 ASM_ARGS_2, "r" (_r6) |
194 | #define LOAD_ARGS_4(a1, a2, a3, a4) \ |
195 | LOAD_ARGS_3 (a1, a2, a3) \ |
196 | int __arg4 = (int) (a4); |
197 | #define LOAD_REGS_4 \ |
198 | register int _r7 asm ("r7") = __arg4; \ |
199 | LOAD_REGS_3 |
200 | #define ASM_ARGS_4 ASM_ARGS_3, "r" (_r7) |
201 | #define LOAD_ARGS_5(a1, a2, a3, a4, a5) \ |
202 | LOAD_ARGS_4 (a1, a2, a3, a4) \ |
203 | int __arg5 = (int) (a5); |
204 | #define LOAD_REGS_5 \ |
205 | register int _r8 asm ("r8") = __arg5; \ |
206 | LOAD_REGS_4 |
207 | #define ASM_ARGS_5 ASM_ARGS_4, "r" (_r8) |
208 | #define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \ |
209 | LOAD_ARGS_5 (a1, a2, a3, a4, a5) \ |
210 | int __arg6 = (int) (a6); |
211 | #define LOAD_REGS_6 \ |
212 | register int _r9 asm ("r9") = __arg6; \ |
213 | LOAD_REGS_5 |
214 | #define ASM_ARGS_6 ASM_ARGS_5, "r" (_r9) |
215 | |
216 | #define __SYSCALL_CLOBBERS "memory" |
217 | |
218 | #undef HAVE_INTERNAL_BRK_ADDR_SYMBOL |
219 | #define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 |
220 | |
221 | #endif /* __ASSEMBLER__ */ |
222 | |
223 | /* Pointer mangling support. */ |
224 | #if IS_IN (rtld) |
225 | /* We cannot use the thread descriptor because in ld.so we use setjmp |
226 | earlier than the descriptor is initialized. */ |
227 | #else |
228 | # ifdef __ASSEMBLER__ |
229 | # define PTR_MANGLE_GUARD(guard) ldw guard, POINTER_GUARD(r23) |
230 | # define PTR_MANGLE(dst, src, guard) xor dst, src, guard |
231 | # define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) |
232 | # else |
233 | # define PTR_MANGLE(var) \ |
234 | (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) |
235 | # define PTR_DEMANGLE(var) PTR_MANGLE (var) |
236 | # endif |
237 | #endif |
238 | |
239 | |
240 | #endif /* linux/nios2/sysdep.h */ |
241 |
Warning: That file was not part of the compilation database. It may have many parsing errors.