Fix nptl build for mips
[uclibc-ng.git] / libpthread / nptl / sysdeps / unix / sysv / linux / arm / sysdep-cancel.h
blob11b99e3b658b7ad5e5ae26526378d90926feb70c
1 /* Copyright (C) 2003, 2004, 2005 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, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
19 #include <sysdep.h>
20 #ifndef __ASSEMBLER__
21 # include <pthreadP.h>
22 #endif
24 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
26 # undef PSEUDO
27 # define PSEUDO(name, syscall_name, args) \
28 .section ".text"; \
29 PSEUDO_PROLOGUE; \
30 .type __##syscall_name##_nocancel,%function; \
31 .globl __##syscall_name##_nocancel; \
32 __##syscall_name##_nocancel: \
33 DO_CALL (syscall_name, args); \
34 PSEUDO_RET; \
35 .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
36 ENTRY (name); \
37 SINGLE_THREAD_P; \
38 DOARGS_##args; \
39 bne .Lpseudo_cancel; \
40 DO_CALL (syscall_name, 0); \
41 UNDOARGS_##args; \
42 cmn r0, $4096; \
43 PSEUDO_RET; \
44 .Lpseudo_cancel: \
45 DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \
46 CENABLE; \
47 mov ip, r0; /* put mask in safe place. */ \
48 UNDOCARGS_##args; /* restore syscall args. */ \
49 swi SYS_ify (syscall_name); /* do the call. */ \
50 str r0, [sp, $-4]!; /* save syscall return value. */ \
51 mov r0, ip; /* get mask back. */ \
52 CDISABLE; \
53 ldmfd sp!, {r0, lr}; /* retrieve return value and address. */ \
54 UNDOARGS_##args; \
55 cmn r0, $4096;
57 # define DOCARGS_0 str lr, [sp, #-4]!;
58 # define UNDOCARGS_0
60 # define DOCARGS_1 stmfd sp!, {r0, lr};
61 # define UNDOCARGS_1 ldr r0, [sp], #4;
63 # define DOCARGS_2 stmfd sp!, {r0, r1, lr};
64 # define UNDOCARGS_2 ldmfd sp!, {r0, r1};
66 # define DOCARGS_3 stmfd sp!, {r0, r1, r2, lr};
67 # define UNDOCARGS_3 ldmfd sp!, {r0, r1, r2};
69 # define DOCARGS_4 stmfd sp!, {r0, r1, r2, r3, lr};
70 # define UNDOCARGS_4 ldmfd sp!, {r0, r1, r2, r3};
72 # define DOCARGS_5 DOCARGS_4
73 # define UNDOCARGS_5 UNDOCARGS_4
75 # define DOCARGS_6 DOCARGS_5
76 # define UNDOCARGS_6 UNDOCARGS_5
78 # ifdef IS_IN_libpthread
79 # define CENABLE bl PLTJMP(__pthread_enable_asynccancel)
80 # define CDISABLE bl PLTJMP(__pthread_disable_asynccancel)
81 # define __local_multiple_threads __pthread_multiple_threads
82 # elif !defined NOT_IN_libc
83 # define CENABLE bl PLTJMP(__libc_enable_asynccancel)
84 # define CDISABLE bl PLTJMP(__libc_disable_asynccancel)
85 # define __local_multiple_threads __libc_multiple_threads
86 # elif defined IS_IN_librt
87 # define CENABLE bl PLTJMP(__librt_enable_asynccancel)
88 # define CDISABLE bl PLTJMP(__librt_disable_asynccancel)
89 # else
90 # error Unsupported library
91 # endif
93 # if defined IS_IN_libpthread || !defined NOT_IN_libc
94 # ifndef __ASSEMBLER__
95 extern int __local_multiple_threads attribute_hidden;
96 # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
97 # else
98 # define SINGLE_THREAD_P \
99 ldr ip, 1b; \
100 2: \
101 ldr ip, [pc, ip]; \
102 teq ip, #0;
103 # define PSEUDO_PROLOGUE \
104 1: .word __local_multiple_threads - 2f - 8;
105 # endif
106 # else
107 /* There is no __local_multiple_threads for librt, so use the TCB. */
108 # ifndef __ASSEMBLER__
109 # define SINGLE_THREAD_P \
110 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
111 header.multiple_threads) == 0, 1)
112 # else
113 # define PSEUDO_PROLOGUE
114 # define SINGLE_THREAD_P \
115 stmfd sp!, {r0, lr}; \
116 bl __aeabi_read_tp; \
117 ldr ip, [r0, #MULTIPLE_THREADS_OFFSET]; \
118 ldmfd sp!, {r0, lr}; \
119 teq ip, #0
120 # define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
121 # endif
122 # endif
124 #elif !defined __ASSEMBLER__
126 /* For rtld, et cetera. */
127 # define SINGLE_THREAD_P 1
128 # define NO_CANCELLATION 1
130 #endif
132 #ifndef __ASSEMBLER__
133 # define RTLD_SINGLE_THREAD_P \
134 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
135 header.multiple_threads) == 0, 1)
136 #endif