chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / nptl / sysdeps / unix / sysv / linux / ia64 / sysdep-cancel.h
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.
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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <sysdep.h>
21 #include <tls.h>
22 #ifndef __ASSEMBLER__
23 # include <nptl/pthreadP.h>
24 #endif
25
26 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
27
28 # undef PSEUDO
29
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
78
79 # ifndef USE_DL_SYSINFO
80
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)
124
125 # else /* USE_DL_SYSINFO */
126
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)
181
182 # endif /* USE_DL_SYSINFO */
183
184 # undef PSEUDO_END
185 # define PSEUDO_END(name) .endp
186
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
199
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;
208
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
216
217 #elif !defined __ASSEMBLER__
218
219 # define SINGLE_THREAD_P (1)
220 # define NO_CANCELLATION 1
221
222 #endif
223
224 #ifndef __ASSEMBLER__
225 # define RTLD_SINGLE_THREAD_P \
226   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
227                                    header.multiple_threads) == 0, 1)
228 #endif