Warning: That file was not part of the compilation database. It may have many parsing errors.

1/* Assembly macros for C-SKY.
2 Copyright (C) 2018-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_CSKY_SYSDEP_H
20#define _LINUX_CSKY_SYSDEP_H 1
21
22/* There is some commonality. */
23#include <sysdeps/unix/sysv/linux/generic/sysdep.h>
24#include <sysdeps/unix/sysv/linux/sysdep.h>
25#include <sysdeps/csky/sysdep.h>
26
27/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */
28#include <dl-sysdep.h>
29
30#include <tls.h>
31
32/* In order to get __set_errno() definition in INLINE_SYSCALL. */
33#ifndef __ASSEMBLER__
34# include <errno.h>
35#endif
36
37#undef SYS_ify
38#define SYS_ify(syscall_name) (__NR_##syscall_name)
39
40#ifdef __ASSEMBLER__
41/* Linux uses a negative return value to indicate syscall errors,
42 unlike most Unices, which use the condition codes' carry flag.
43
44 Since version 2.1 the return value of a system call might be
45 negative even if the call succeeded. E.g., the `lseek' system call
46 might return a large offset. Therefore we must not anymore test
47 for < 0, but test for a real error by making sure the value in R0
48 is a real error number. Linus said he will make sure the no syscall
49 returns a value in -1 .. -4095 as a valid result so we can safely
50 test with -4095. */
51
52# undef PSEUDO
53# define PSEUDO(name, syscall_name, args) \
54 .text; \
55 ENTRY (name); \
56 DO_CALL (syscall_name, args);
57
58# define GETGB \
59 grs t0, .Lgetpc; \
60.Lgetpc: \
61 lrw gb, .Lgetpc@GOTPC; \
62 addu gb, t0;
63
64# if IS_IN (libc)
65# ifdef __PIC__
66# define PSEUDO_RET \
67 btsti a0, 31; \
68 bf 1f; \
69 subi sp, 8; \
70 st.w lr, (sp); \
71 st.w gb, (sp, 4); \
72 GETGB; \
73 lrw a2, SYSCALL_ERROR@PLT; \
74 add a2, gb; \
75 ld.w a2, (a2); \
76 jsr a2; \
77 ld.w lr, (sp); \
78 ld.w gb, (sp, 4); \
79 addi sp, 8; \
801: \
81 rts
82# else
83# define PSEUDO_RET \
84 btsti a0, 31; \
85 bf 1f; \
86 jmpi SYSCALL_ERROR; \
871: \
88 rts
89# endif
90# else
91# ifdef __PIC__
92# define PSEUDO_RET \
93 btsti a0, 31; \
94 bf 1f; \
95 subi sp, 8; \
96 st.w lr, (sp); \
97 st.w gb, (sp, 4); \
98 GETGB; \
99 bsr SYSCALL_ERROR; \
100 ld.w lr, (sp); \
101 ld.w gb, (sp, 4); \
102 addi sp, 8; \
1031: \
104 rts
105# else
106# define PSEUDO_RET \
107 btsti a0, 31; \
108 bt SYSCALL_ERROR; \
109 rts
110# endif
111# endif
112
113# undef ret
114# define ret PSEUDO_RET
115
116# undef PSEUDO_END
117# define PSEUDO_END(name) \
118 .align 4; \
119 SYSCALL_ERROR_HANDLER; \
120 END (name)
121
122# undef PSEUDO_NOERRNO
123# define PSEUDO_NOERRNO(name, syscall_name, args) \
124 .text; \
125 ENTRY (name); \
126 DO_CALL (syscall_name, args)
127
128# define PSEUDO_RET_NOERRNO rts
129
130# undef ret_NOERRNO
131# define ret_NOERRNO PSEUDO_RET_NOERRNO
132
133# undef PSEUDO_END_NOERRNO
134# define PSEUDO_END_NOERRNO(name) END (name)
135
136/* The function has to return the error code. */
137# undef PSEUDO_ERRVAL
138# define PSEUDO_ERRVAL(name, syscall_name, args) \
139 .text; \
140 ENTRY (name) \
141 DO_CALL (syscall_name, args); \
142 not a0; \
143 addi a0, 1
144
145# undef PSEUDO_END_ERRVAL
146# define PSEUDO_END_ERRVAL(name) END (name)
147
148# define ret_ERRVAL rts
149
150# if !IS_IN (libc)
151# define SYSCALL_ERROR __local_syscall_error
152# if RTLD_PRIVATE_ERRNO
153# ifdef __PIC__
154# define SYSCALL_ERROR_HANDLER \
155__local_syscall_error: \
156 lrw a1, rtld_errno@PLT; \
157 addu a1, gb; \
158 ldw a1, (a1); \
159 rsubi a0, 0; \
160 stw a0, (a1); \
161 bmaski a0, 0; \
162 rts
163# else /* __PIC__ */
164# define SYSCALL_ERROR_HANDLER \
165__local_syscall_error: \
166 lrw a1, rtld_errno; \
167 rsubi a0, 0; \
168 stw a0, (a1); \
169 bmaski a0, 0; \
170 rts
171# endif /* __PIC__ */
172# else /* !RTLD_PRIVATE_ERRNO */
173# ifdef __PIC__
174# define SYSCALL_ERROR_HANDLER \
175__local_syscall_error: \
176 subi sp, 8; \
177 stw a0, (sp, 0); \
178 stw r15, (sp, 4); \
179 lrw a1, __errno_location@PLT; \
180 add a1, gb; \
181 ldw a1, (a1); \
182 jsr a1; \
183 ldw a1, (sp, 0); /* load errno*/ \
184 ldw r15, (sp, 4); \
185 addi sp, 8; \
186 movi a2, 0; \
187 rsub a1, a1, a2; \
188 stw a1, (a0); \
189 bmaski a0, 0; \
190 rts
191# else
192# define SYSCALL_ERROR_HANDLER \
193__local_syscall_error: \
194 subi sp, 8; \
195 stw a0, (sp, 0); \
196 stw r15, (sp, 4); \
197 lrw a1, __errno_location; \
198 jsr a1; \
199 ldw a1, (sp, 0); /* load errno */ \
200 ldw r15, (sp, 4); \
201 addi sp, 8; \
202 movi a2, 0; \
203 rsub a1, a1, a2; \
204 stw a1, (a0); \
205 bmaski a0, 0; \
206 rts
207# endif /* __PIC__ */
208# endif/* RTLD_PRIVATE_ERROR */
209# else
210# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
211# define SYSCALL_ERROR __syscall_error
212# endif/* IS_IN (libc) */
213
214/* define DO_CALL */
215# undef DO_CALL
216# define DO_CALL(syscall_name, args) \
217 DOARGS_##args; \
218 lrw r7, SYS_ify(syscall_name); \
219 trap 0; \
220 UNDOARGS_##args
221
222# undef DOARGS_0
223# define DOARGS_0 \
224 subi sp, 8; \
225 cfi_adjust_cfa_offset (8); \
226 stw r7, (sp, 0); \
227 cfi_rel_offset (r7, 0);
228
229# undef DOARGS_1
230# define DOARGS_1 DOARGS_0
231# undef DOARGS_2
232# define DOARGS_2 DOARGS_0
233# undef DOARGS_3
234# define DOARGS_3 DOARGS_0
235# undef DOARGS_4
236# define DOARGS_4 DOARGS_0
237# undef DOARGS_5
238# define DOARGS_5 \
239 subi sp, 8; \
240 cfi_adjust_cfa_offset (8); \
241 stw r7, (sp, 0); \
242 cfi_rel_offset (7, 0); \
243 stw r4, (sp, 4); \
244 cfi_rel_offset (4, 4); \
245 ldw r4, (sp, 8)
246# undef DOARGS_6
247# define DOARGS_6 \
248 subi sp, 16; \
249 cfi_adjust_cfa_offset (16); \
250 stw r7, (sp, 0); \
251 cfi_rel_offset (7, 0); \
252 stw r4, (sp, 4); \
253 cfi_rel_offset (4, 4); \
254 stw r5, (sp, 8); \
255 cfi_rel_offset (5, 8); \
256 ldw r4, (sp, 16); \
257 ldw r5, (sp, 20)
258
259# undef UNDOARGS_0
260# define UNDOARGS_0 \
261 ldw r7, (sp, 0); \
262 cfi_restore (r7); \
263 addi sp, 8; \
264 cfi_adjust_cfa_offset (-8);
265
266# undef UNDOARGS_1
267# define UNDOARGS_1 UNDOARGS_0
268# undef UNDOARGS_2
269# define UNDOARGS_2 UNDOARGS_0
270# undef UNDOARGS_3
271# define UNDOARGS_3 UNDOARGS_0
272# undef UNDOARGS_4
273# define UNDOARGS_4 UNDOARGS_0
274# undef UNDOARGS_5
275# define UNDOARGS_5 \
276 ldw r7, (sp, 0); \
277 cfi_restore (r4); \
278 ldw r4, (sp, 4); \
279 cfi_restore (r4); \
280 addi sp, 8; \
281 cfi_adjust_cfa_offset (-8);
282
283# undef UNDOARGS_6
284# define UNDOARGS_6 \
285 ldw r7, (sp, 0); \
286 cfi_restore (r7); \
287 ldw r4, (sp, 4); \
288 cfi_restore (r4); \
289 ldw r5, (sp, 8); \
290 cfi_restore (r5); \
291 addi sp, 16; \
292 cfi_adjust_cfa_offset (-16);
293
294#else /* not __ASSEMBLER__ */
295
296# undef INTERNAL_SYSCALL_RAW
297# define INTERNAL_SYSCALL_RAW0(name, dummy...) \
298 ({unsigned int __sys_result; \
299 { \
300 register int _a1 __asm__ ("a0"), _nr __asm__ ("r7"); \
301 _nr = name; \
302 __asm__ __volatile__ ("trap 0 \n\t" \
303 : "=r" (_a1) \
304 : "r" (_nr) \
305 : "memory"); \
306 __sys_result = _a1; \
307 } \
308 (int) __sys_result; })
309
310# define INTERNAL_SYSCALL_RAW1(name, arg1) \
311 ({unsigned int __sys_result; \
312 register int _tmp_arg1 = (int)(arg1); \
313 { \
314 register int _a1 __asm__ ("a0"), _nr __asm__ ("r7"); \
315 _a1 = _tmp_arg1; \
316 _nr = name; \
317 __asm__ __volatile__ ("trap 0 \n\t" \
318 : "=r" (_a1) \
319 : "r" (_nr), "r" (_a1) \
320 : "memory"); \
321 __sys_result = _a1; \
322 } \
323 (int) __sys_result; })
324
325# define INTERNAL_SYSCALL_RAW2(name, arg1, arg2) \
326 ({unsigned int __sys_result; \
327 register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
328 { \
329 register int _nr __asm__ ("r7"); \
330 register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
331 _a1 = _tmp_arg1, _a2 = _tmp_arg2; \
332 _nr = name; \
333 __asm__ __volatile__ ("trap 0 \n\t" \
334 : "=r" (_a1) \
335 : "r" (_nr), "r" (_a1), "r" (_a2) \
336 : "memory"); \
337 __sys_result = _a1; \
338 } \
339 (int) __sys_result; })
340
341# define INTERNAL_SYSCALL_RAW3(name, arg1, arg2, arg3) \
342 ({unsigned int __sys_result; \
343 register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
344 register int _tmp_arg3 = (int)(arg3); \
345 { \
346 register int _nr __asm__ ("r7"); \
347 register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
348 register int _a3 __asm__ ("a2"); \
349 _a1 = _tmp_arg1; \
350 _a2 = _tmp_arg2; \
351 _a3 = _tmp_arg3; \
352 _nr = name; \
353 __asm__ __volatile__ ("trap 0 \n\t" \
354 : "=r" (_a1) \
355 : "r" (_nr), "r" (_a1), "r" (_a2), \
356 "r" (_a3) \
357 : "memory"); \
358 __sys_result = _a1; \
359 } \
360 (int) __sys_result; })
361
362# define INTERNAL_SYSCALL_RAW4(name, arg1, arg2, arg3, arg4) \
363 ({unsigned int __sys_result; \
364 register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
365 register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
366 { \
367 register int _nr __asm__ ("r7"); \
368 register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
369 register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
370 _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
371 _a4 = _tmp_arg4; \
372 _nr = name; \
373 __asm__ __volatile__ ("trap 0 \n\t" \
374 : "=r" (_a1) \
375 : "r" (_nr), "r" (_a1), "r" (_a2), \
376 "r" (_a3), "r" (_a4) \
377 : "memory"); \
378 __sys_result = _a1; \
379 } \
380 (int) __sys_result; })
381
382# define INTERNAL_SYSCALL_RAW5(name, arg1, arg2, arg3, arg4, \
383 arg5) \
384 ({unsigned int __sys_result; \
385 register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
386 register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
387 register int _tmp_arg5 = (int)(arg5); \
388 { \
389 register int _nr __asm__ ("r7"); \
390 register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
391 register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
392 register int _a5 __asm__ ("r4"); \
393 _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
394 _a4 = _tmp_arg4, _a5 = _tmp_arg5; \
395 _nr = name; \
396 __asm__ __volatile__ ("trap 0 \n\t" \
397 : "=r" (_a1) \
398 : "r" (_nr), "r" (_a1), "r" (_a2), \
399 "r" (_a3), "r" (_a4), "r" (_a5) \
400 : "memory"); \
401 __sys_result = _a1; \
402 } \
403 (int) __sys_result; })
404
405# define INTERNAL_SYSCALL_RAW6(name, arg1, arg2, arg3, arg4, \
406 arg5, arg6) \
407 ({unsigned int __sys_result; \
408 register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
409 register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
410 register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6); \
411 { \
412 register int _nr __asm__ ("r7"); \
413 register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
414 register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
415 register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5"); \
416 _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
417 _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6; \
418 _nr = name; \
419 __asm__ __volatile__ ("trap 0 \n\t" \
420 : "=r" (_a1) \
421 : "r" (_nr), "r" (_a1), "r" (_a2), \
422 "r" (_a3), "r" (_a4), "r" (_a5), \
423 "r" (_a6) \
424 : "memory"); \
425 __sys_result = _a1; \
426 } \
427 (int) __sys_result; })
428
429# define INTERNAL_SYSCALL_RAW7(name, arg1, arg2, arg3, arg4, \
430 arg5, arg6, arg7) \
431 ({unsigned int __sys_result; \
432 register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2); \
433 register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4); \
434 register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6); \
435 register int _tmp_arg7 = (int)(arg7); \
436 { \
437 register int _nr __asm__ ("r7"); \
438 register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1"); \
439 register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3"); \
440 register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5"); \
441 register int _a7 __asm__ ("r6"); \
442 _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3; \
443 _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6; \
444 _a7 = _tmp_arg7; \
445 _nr = name; \
446 __asm__ __volatile__ ("trap 0 \n\t" \
447 : "=r" (_a1) \
448 : "r" (_nr), "r" (_a1), "r" (_a2), \
449 "r" (_a3), "r" (_a4), "r" (_a5), \
450 "r" (_a6), "r" (_a7) \
451 : "memory"); \
452 __sys_result = _a1; \
453 } \
454 (int) __sys_result; })
455
456# undef INTERNAL_SYSCALL
457# define INTERNAL_SYSCALL(name, nr, args...) \
458 INTERNAL_SYSCALL_RAW##nr(SYS_ify(name), args)
459
460# undef INTERNAL_SYSCALL_NCS
461# define INTERNAL_SYSCALL_NCS(number, nr, args...) \
462 INTERNAL_SYSCALL_RAW##nr (number, args)
463
464#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
465#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
466
467#endif /* __ASSEMBLER__ */
468
469/* Pointer mangling support. */
470#if (IS_IN (rtld) \
471 || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread))))
472# ifdef __ASSEMBLER__
473# define PTR_MANGLE(dst, src, guard) \
474 grs t0, 1f; \
4751: \
476 lrw guard, 1b@GOTPC; \
477 addu t0, guard; \
478 lrw guard, __pointer_chk_guard_local@GOT; \
479 ldr.w guard, (t0, guard << 0); \
480 ldw guard, (guard, 0); \
481 xor dst, src, guard;
482# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard)
483# define PTR_MANGLE2(dst, src, guard) \
484 xor dst, src, guard
485# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard)
486# else
487extern uintptr_t __pointer_chk_guard_local;
488# define PTR_MANGLE(var) \
489 (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
490# define PTR_DEMANGLE(var) PTR_MANGLE (var)
491# endif
492#else
493# ifdef __ASSEMBLER__
494# define PTR_MANGLE(dst, src, guard) \
495 grs t0, 1f; \
4961: \
497 lrw guard, 1b@GOTPC; \
498 addu t0, guard; \
499 lrw guard, __pointer_chk_guard@GOT; \
500 ldr.w guard, (t0, guard << 0); \
501 ldw guard, (guard, 0); \
502 xor dst, src, guard;
503# define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard)
504# define PTR_MANGLE2(dst, src, guard) \
505 xor dst, src, guard
506# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard)
507# else
508extern uintptr_t __pointer_chk_guard;
509# define PTR_MANGLE(var) \
510 (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
511# define PTR_DEMANGLE(var) PTR_MANGLE (var)
512# endif
513#endif
514
515#endif /* linux/csky/sysdep.h */
516

Warning: That file was not part of the compilation database. It may have many parsing errors.

source code of glibc/sysdeps/unix/sysv/linux/csky/sysdep.h