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