ia64: define nocancel entry points in PSEUDO
[glibc.git] / sysdeps / unix / sysv / linux / ia64 / sysdep-cancel.h
blobc44c48460c5bdb2647fefe43abcce9546392b6c1
1 /* Copyright (C) 2002-2014 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
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.
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.
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 <http://www.gnu.org/licenses/>. */
19 #include <sysdep.h>
20 #include <tls.h>
21 #ifndef __ASSEMBLER__
22 # include <nptl/pthreadP.h>
23 #endif
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
27 # undef PSEUDO
29 # ifndef NOT_IN_libc
30 # define SYSDEP_CANCEL_ERRNO __libc_errno
31 # else
32 # define SYSDEP_CANCEL_ERRNO errno
33 # endif
34 # define SYSDEP_CANCEL_ERROR(args) \
35 .section .gnu.linkonce.t.__syscall_error_##args, "ax"; \
36 .align 32; \
37 .proc __syscall_error_##args; \
38 .global __syscall_error_##args; \
39 .hidden __syscall_error_##args; \
40 .size __syscall_error_##args, 64; \
41 __syscall_error_##args: \
42 .prologue; \
43 .regstk args, 5, args, 0; \
44 .save ar.pfs, loc0; \
45 .save rp, loc1; \
46 .body; \
47 addl loc4 = @ltoff(@tprel(SYSDEP_CANCEL_ERRNO)), gp;; \
48 ld8 loc4 = [loc4]; \
49 mov rp = loc1;; \
50 mov r8 = -1; \
51 add loc4 = loc4, r13;; \
52 st4 [loc4] = loc3; \
53 mov ar.pfs = loc0
55 # ifndef USE_DL_SYSINFO
57 # define PSEUDO(name, syscall_name, args) \
58 .text; \
59 ENTRY (name) \
60 adds r14 = MULTIPLE_THREADS_OFFSET, r13;; \
61 ld4 r14 = [r14]; \
62 mov r15 = SYS_ify(syscall_name);; \
63 cmp4.ne p6, p7 = 0, r14; \
64 (p6) br.cond.spnt .Lpseudo_cancel;; \
65 break __BREAK_SYSCALL;; \
66 cmp.eq p6,p0=-1,r10; \
67 (p6) br.cond.spnt.few __syscall_error; \
68 ret;; \
69 .endp name; \
70 .proc __GC_##name; \
71 .globl __GC_##name; \
72 .hidden __GC_##name; \
73 __GC_##name: \
74 .Lpseudo_cancel: \
75 .prologue; \
76 .regstk args, 5, args, 0; \
77 .save ar.pfs, loc0; \
78 alloc loc0 = ar.pfs, args, 5, args, 0; \
79 .save rp, loc1; \
80 mov loc1 = rp;; \
81 .body; \
82 CENABLE;; \
83 mov loc2 = r8; \
84 COPY_ARGS_##args \
85 mov r15 = SYS_ify(syscall_name); \
86 break __BREAK_SYSCALL;; \
87 mov loc3 = r8; \
88 mov loc4 = r10; \
89 mov out0 = loc2; \
90 CDISABLE;; \
91 cmp.eq p6,p0=-1,loc4; \
92 (p6) br.cond.spnt.few __syscall_error_##args; \
93 mov r8 = loc3; \
94 mov rp = loc1; \
95 mov ar.pfs = loc0; \
96 .Lpseudo_end: \
97 ret; \
98 .endp __GC_##name; \
99 SYSDEP_CANCEL_ERROR(args)
101 # else /* USE_DL_SYSINFO */
103 # define PSEUDO(name, syscall_name, args) \
104 .text; \
105 ENTRY (name) \
106 .prologue; \
107 adds r2 = SYSINFO_OFFSET, r13; \
108 adds r14 = MULTIPLE_THREADS_OFFSET, r13; \
109 .save ar.pfs, r11; \
110 mov r11 = ar.pfs;; \
111 .body; \
112 ld4 r14 = [r14]; \
113 ld8 r2 = [r2]; \
114 mov r15 = SYS_ify(syscall_name);; \
115 cmp4.ne p6, p7 = 0, r14; \
116 mov b7 = r2; \
117 (p6) br.cond.spnt .Lpseudo_cancel; \
118 br.call.sptk.many b6 = b7;; \
119 mov ar.pfs = r11; \
120 cmp.eq p6,p0 = -1, r10; \
121 (p6) br.cond.spnt.few __syscall_error; \
122 ret;; \
123 .endp name; \
125 .proc __##syscall_name##_nocancel; \
126 .globl __##syscall_name##_nocancel; \
127 __##syscall_name##_nocancel: \
128 .prologue; \
129 adds r2 = SYSINFO_OFFSET, r13; \
130 .save ar.pfs, r11; \
131 mov r11 = ar.pfs;; \
132 .body; \
133 ld8 r2 = [r2]; \
134 mov r15 = SYS_ify(syscall_name);; \
135 mov b7 = r2; \
136 br.call.sptk.many b6 = b7;; \
137 mov ar.pfs = r11; \
138 cmp.eq p6,p0 = -1, r10; \
139 (p6) br.cond.spnt.few __syscall_error; \
140 ret;; \
141 .endp __##syscall_name##_nocancel; \
143 .proc __GC_##name; \
144 .globl __GC_##name; \
145 .hidden __GC_##name; \
146 __GC_##name: \
147 .Lpseudo_cancel: \
148 .prologue; \
149 .regstk args, 5, args, 0; \
150 .save ar.pfs, loc0; \
151 alloc loc0 = ar.pfs, args, 5, args, 0; \
152 adds loc4 = SYSINFO_OFFSET, r13; \
153 .save rp, loc1; \
154 mov loc1 = rp;; \
155 .body; \
156 ld8 loc4 = [loc4]; \
157 CENABLE;; \
158 mov loc2 = r8; \
159 mov b7 = loc4; \
160 COPY_ARGS_##args \
161 mov r15 = SYS_ify(syscall_name); \
162 br.call.sptk.many b6 = b7;; \
163 mov loc3 = r8; \
164 mov loc4 = r10; \
165 mov out0 = loc2; \
166 CDISABLE;; \
167 cmp.eq p6,p0=-1,loc4; \
168 (p6) br.cond.spnt.few __syscall_error_##args; \
169 mov r8 = loc3; \
170 mov rp = loc1; \
171 mov ar.pfs = loc0; \
172 .Lpseudo_end: \
173 ret; \
174 .endp __GC_##name; \
175 SYSDEP_CANCEL_ERROR(args)
177 # endif /* USE_DL_SYSINFO */
179 # undef PSEUDO_END
180 # define PSEUDO_END(name) .endp
182 # ifdef IS_IN_libpthread
183 # define CENABLE br.call.sptk.many b0 = __pthread_enable_asynccancel
184 # define CDISABLE br.call.sptk.many b0 = __pthread_disable_asynccancel
185 # elif !defined NOT_IN_libc
186 # define CENABLE br.call.sptk.many b0 = __libc_enable_asynccancel
187 # define CDISABLE br.call.sptk.many b0 = __libc_disable_asynccancel
188 # elif defined IS_IN_librt
189 # define CENABLE br.call.sptk.many b0 = __librt_enable_asynccancel
190 # define CDISABLE br.call.sptk.many b0 = __librt_disable_asynccancel
191 # else
192 # error Unsupported library
193 # endif
195 # define COPY_ARGS_0 /* Nothing */
196 # define COPY_ARGS_1 COPY_ARGS_0 mov out0 = in0;
197 # define COPY_ARGS_2 COPY_ARGS_1 mov out1 = in1;
198 # define COPY_ARGS_3 COPY_ARGS_2 mov out2 = in2;
199 # define COPY_ARGS_4 COPY_ARGS_3 mov out3 = in3;
200 # define COPY_ARGS_5 COPY_ARGS_4 mov out4 = in4;
201 # define COPY_ARGS_6 COPY_ARGS_5 mov out5 = in5;
202 # define COPY_ARGS_7 COPY_ARGS_6 mov out6 = in6;
204 # ifndef __ASSEMBLER__
205 # define SINGLE_THREAD_P \
206 __builtin_expect (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0, 1)
207 # else
208 # define SINGLE_THREAD_P \
209 adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14
210 # endif
212 #elif !defined __ASSEMBLER__
214 # define SINGLE_THREAD_P (1)
215 # define NO_CANCELLATION 1
217 #endif
219 #ifndef __ASSEMBLER__
220 # define RTLD_SINGLE_THREAD_P \
221 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
222 header.multiple_threads) == 0, 1)
223 #endif