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/>. */
22 # include <nptl/pthreadP.h>
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
30 # define SYSDEP_CANCEL_ERRNO __libc_errno
32 # define SYSDEP_CANCEL_ERRNO errno
34 # define SYSDEP_CANCEL_ERROR(args) \
35 .section .gnu.linkonce.t.__syscall_error_##args, "ax"; \
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: \
43 .regstk args, 5, args, 0; \
47 addl loc4 = @ltoff(@tprel(SYSDEP_CANCEL_ERRNO)), gp;; \
51 add loc4 = loc4, r13;; \
55 # ifndef USE_DL_SYSINFO
57 # define PSEUDO(name, syscall_name, args) \
60 adds r14 = MULTIPLE_THREADS_OFFSET, r13;; \
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; \
72 .hidden __GC_##name; \
76 .regstk args, 5, args, 0; \
78 alloc loc0 = ar.pfs, args, 5, args, 0; \
85 mov r15 = SYS_ify(syscall_name); \
86 break __BREAK_SYSCALL;; \
91 cmp.eq p6,p0=-1,loc4; \
92 (p6) br.cond.spnt.few __syscall_error_##args; \
99 SYSDEP_CANCEL_ERROR(args)
101 # else /* USE_DL_SYSINFO */
103 # define PSEUDO(name, syscall_name, args) \
107 adds r2 = SYSINFO_OFFSET, r13; \
108 adds r14 = MULTIPLE_THREADS_OFFSET, r13; \
114 mov r15 = SYS_ify(syscall_name);; \
115 cmp4.ne p6, p7 = 0, r14; \
117 (p6) br.cond.spnt .Lpseudo_cancel; \
118 br.call.sptk.many b6 = b7;; \
120 cmp.eq p6,p0 = -1, r10; \
121 (p6) br.cond.spnt.few __syscall_error; \
125 .proc __##syscall_name##_nocancel; \
126 .globl __##syscall_name##_nocancel; \
127 __##syscall_name##_nocancel: \
129 adds r2 = SYSINFO_OFFSET, r13; \
134 mov r15 = SYS_ify(syscall_name);; \
136 br.call.sptk.many b6 = b7;; \
138 cmp.eq p6,p0 = -1, r10; \
139 (p6) br.cond.spnt.few __syscall_error; \
141 .endp __##syscall_name##_nocancel; \
144 .globl __GC_##name; \
145 .hidden __GC_##name; \
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; \
161 mov r15 = SYS_ify(syscall_name); \
162 br.call.sptk.many b6 = b7;; \
167 cmp.eq p6,p0=-1,loc4; \
168 (p6) br.cond.spnt.few __syscall_error_##args; \
175 SYSDEP_CANCEL_ERROR(args)
177 # endif /* USE_DL_SYSINFO */
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
192 # error Unsupported library
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)
208 # define SINGLE_THREAD_P \
209 adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14
212 #elif !defined __ASSEMBLER__
214 # define SINGLE_THREAD_P (1)
215 # define NO_CANCELLATION 1
219 #ifndef __ASSEMBLER__
220 # define RTLD_SINGLE_THREAD_P \
221 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
222 header.multiple_threads) == 0, 1)