Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / microblaze / sysdep-cancel.h
blob88181c1251cd7f116e88bfadc41b87a6f0177569
1 /* Copyright (C) 2014-2015 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 <nptl/pthreadP.h>
22 #endif
24 #if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
26 # if !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 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 IS_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 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
121 # if IS_IN (libpthread) || IS_IN (libc)
122 # ifndef __ASSEMBLER__
123 extern int __local_multiple_threads attribute_hidden;
124 # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
125 # else
126 # if !defined PIC
127 # define SINGLE_THREAD_P(reg) lwi reg, r0, __local_multiple_threads;
128 # else
129 # define SINGLE_THREAD_P(reg) \
130 mfs reg, rpc; \
131 addik reg, reg, _GLOBAL_OFFSET_TABLE_+8; \
132 lwi reg, reg, __local_multiple_threads@GOT; \
133 lwi reg, reg, 0;
134 # endif
135 # endif
136 # else
137 # ifndef __ASSEMBLER__
138 # define SINGLE_THREAD_P \
139 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
140 header.multiple_threads) == 0, 1)
141 # else
142 # define SINGLE_THREAD_P(reg) \
143 lwi reg, r0, MULTIPLE_THREADS_OFFSET(reg)
144 # endif
145 # endif
147 #elif !defined __ASSEMBLER__
149 # define SINGLE_THREAD_P (1)
150 # define NO_CANCELLATION (1)
152 #endif
154 #ifndef __ASSEMBLER__
155 # define RTLD_SINGLE_THREAD_P \
156 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
157 header.multiple_threads) == 0, 1)
158 #endif