microblaze: sync sysdep-cancel.h/sydep.h with GNU libc
[uclibc-ng.git] / libpthread / nptl / sysdeps / unix / sysv / linux / microblaze / sysdep-cancel.h
bloba03e42a40382ebae6bf24b42dcbfd566c8d13b7a
1 /* Copyright (C) 2014-2016 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library. If not, see
16 <http://www.gnu.org/licenses/>. */
18 #include <sysdep.h>
19 #include <tls.h>
20 #ifndef __ASSEMBLER__
21 # include <pthreadP.h>
22 #endif
24 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
26 # if !defined IS_IN_librt || !defined(PIC)
27 # define AC_STACK_SIZE 16 /* space for r15, async_cancel arg and 2 temp words */
28 # define AC_SET_GOT /* empty */
29 # define AC_RESTORE_GOT /* empty */
30 # else
31 # define AC_STACK_SIZE 20 /* extra 4 bytes for r20 */
32 # define AC_SET_GOT \
33 swi r20, r1, AC_STACK_SIZE-4; \
34 mfs r20, rpc; \
35 addik r20, r20, _GLOBAL_OFFSET_TABLE_+8;
36 # define AC_RESTORE_GOT \
37 lwi r20, r1, AC_STACK_SIZE-4;
38 # endif
40 # undef PSEUDO
41 # define PSEUDO(name, syscall_name, args) \
42 .text; \
43 ENTRY (name) \
44 SINGLE_THREAD_P(r12); \
45 bnei r12, L(pseudo_cancel); \
46 .globl __##syscall_name##_nocancel; \
47 .type __##syscall_name##_nocancel,@function; \
48 __##syscall_name##_nocancel: \
49 DO_CALL (syscall_name, args); \
50 addik r4, r0, -4095; \
51 cmpu r4, r4, r3; \
52 bgei r4, SYSCALL_ERROR_LABEL; \
53 rtsd r15, 8; \
54 nop; \
55 .size __##syscall_name##_nocancel, .-__##syscall_name##_nocancel; \
56 L(pseudo_cancel): \
57 addik r1, r1, -AC_STACK_SIZE; \
58 swi r15, r1, 0; \
59 AC_SET_GOT \
60 DOCARGS_##args \
61 CENABLE; \
62 swi r3, r1, 8; \
63 UNDOCARGS_##args \
64 DO_CALL (syscall_name, args); \
65 swi r3, r1, 12; \
66 lwi r5, r1, 8; \
67 CDISABLE; \
68 lwi r3, r1, 12; \
69 lwi r15, r1, 0; \
70 AC_RESTORE_GOT \
71 addik r1, r1, AC_STACK_SIZE; \
72 addik r4, r0, -4095; \
73 cmpu r4, r4, r3; \
74 bgei r4, SYSCALL_ERROR_LABEL; \
75 rtsd r15, 8; \
76 nop;
79 * Macros to save/restore syscall arguments across CENABLE
80 * The arguments are saved into the caller's stack (original r1 + 4)
83 # define DOCARGS_0
84 # define DOCARGS_1 swi r5, r1, AC_STACK_SIZE + 4;
85 # define DOCARGS_2 swi r6, r1, AC_STACK_SIZE + 8; DOCARGS_1
86 # define DOCARGS_3 swi r7, r1, AC_STACK_SIZE + 12; DOCARGS_2
87 # define DOCARGS_4 swi r8, r1, AC_STACK_SIZE + 16; DOCARGS_3
88 # define DOCARGS_5 swi r9, r1, AC_STACK_SIZE + 20; DOCARGS_4
89 # define DOCARGS_6 swi r10, r1, AC_STACK_SIZE + 24; DOCARGS_5
91 # define UNDOCARGS_0
92 # define UNDOCARGS_1 lwi r5, r1, AC_STACK_SIZE + 4;
93 # define UNDOCARGS_2 UNDOCARGS_1 lwi r6, r1, AC_STACK_SIZE + 8;
94 # define UNDOCARGS_3 UNDOCARGS_2 lwi r7, r1, AC_STACK_SIZE + 12;
95 # define UNDOCARGS_4 UNDOCARGS_3 lwi r8, r1, AC_STACK_SIZE + 16;
96 # define UNDOCARGS_5 UNDOCARGS_4 lwi r9, r1, AC_STACK_SIZE + 20;
97 # define UNDOCARGS_6 UNDOCARGS_5 lwi r10, r1, AC_STACK_SIZE + 24;
99 # ifdef PIC
100 # define PSEUDO_JMP(sym) brlid r15, sym##@PLTPC; addk r0, r0, r0
101 # else
102 # define PSEUDO_JMP(sym) brlid r15, sym; addk r0, r0, r0
103 # endif
105 # if defined IS_IN_libpthread
106 # define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
107 # define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel)
108 # define __local_multiple_threads __pthread_multiple_threads
109 # elif !defined NOT_IN_libc
110 # define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
111 # define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel)
112 # define __local_multiple_threads __libc_multiple_threads
113 # elif defined IS_IN_librt
114 # define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
115 # define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel)
116 # else
117 # error Unsupported library
118 # endif
120 #if !defined NOT_IN_libc || defined IS_IN_libpthread
121 # ifndef __ASSEMBLER__
122 extern int __local_multiple_threads attribute_hidden;
123 # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
124 # else
125 # if !defined PIC
126 # define SINGLE_THREAD_P(reg) lwi reg, r0, __local_multiple_threads;
127 # else
128 # define SINGLE_THREAD_P(reg) \
129 mfs reg, rpc; \
130 addik reg, reg, _GLOBAL_OFFSET_TABLE_+8; \
131 lwi reg, reg, __local_multiple_threads@GOT; \
132 lwi reg, reg, 0;
133 # endif
134 # endif
135 # else
136 # ifndef __ASSEMBLER__
137 # define SINGLE_THREAD_P \
138 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
139 header.multiple_threads) == 0, 1)
140 # else
141 # define SINGLE_THREAD_P(reg) \
142 lwi reg, r0, MULTIPLE_THREADS_OFFSET(reg)
143 # endif
144 # endif
146 #elif !defined __ASSEMBLER__
148 # define SINGLE_THREAD_P (1)
149 # define NO_CANCELLATION (1)
151 #endif