2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / s390 / s390-64 / sysdep-cancel.h
blob70d5a864296d3129e873d7433f19af4f57e7bd79
1 /* Copyright (C) 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>, 2003.
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
29 # define PSEUDO(name, syscall_name, args) \
30 .text; \
31 L(pseudo_cancel): \
32 cfi_startproc; \
33 STM_##args \
34 stmg %r13,%r15,104(%r15); \
35 cfi_offset (%r15,-40); \
36 cfi_offset (%r14,-48); \
37 cfi_offset (%r13,-56); \
38 lgr %r14,%r15; \
39 aghi %r15,-160; \
40 cfi_adjust_cfa_offset (160); \
41 stg %r14,0(%r15); \
42 brasl %r14,CENABLE; \
43 lgr %r0,%r2; \
44 LM_##args \
45 .if SYS_ify (syscall_name) < 256; \
46 svc SYS_ify (syscall_name); \
47 .else; \
48 lghi %r1,SYS_ify (syscall_name); \
49 svc 0; \
50 .endif; \
51 LR7_##args \
52 lgr %r13,%r2; \
53 lgr %r2,%r0; \
54 brasl %r14,CDISABLE; \
55 lgr %r2,%r13; \
56 lmg %r13,%r15,104+160(%r15); \
57 cfi_endproc; \
58 j L(pseudo_check); \
59 ENTRY(name) \
60 SINGLE_THREAD_P \
61 jne L(pseudo_cancel); \
62 .type __##syscall_name##_nocancel,@function; \
63 .globl __##syscall_name##_nocancel; \
64 __##syscall_name##_nocancel: \
65 DO_CALL(syscall_name, args); \
66 L(pseudo_check): \
67 lghi %r4,-4095; \
68 clgr %r2,%r4; \
69 jgnl SYSCALL_ERROR_LABEL; \
70 .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
71 L(pseudo_end):
73 # ifdef IS_IN_libpthread
74 # define CENABLE __pthread_enable_asynccancel
75 # define CDISABLE __pthread_disable_asynccancel
76 # define __local_multiple_threads __pthread_multiple_threads
77 # elif !defined NOT_IN_libc
78 # define CENABLE __libc_enable_asynccancel
79 # define CDISABLE __libc_disable_asynccancel
80 # define __local_multiple_threads __libc_multiple_threads
81 # elif defined IS_IN_librt
82 # define CENABLE __librt_enable_asynccancel
83 # define CDISABLE __librt_disable_asynccancel
84 # else
85 # error Unsupported library
86 # endif
88 #define STM_0 /* Nothing */
89 #define STM_1 stg %r2,16(%r15);
90 #define STM_2 stmg %r2,%r3,16(%r15);
91 #define STM_3 stmg %r2,%r4,16(%r15);
92 #define STM_4 stmg %r2,%r5,16(%r15);
93 #define STM_5 stmg %r2,%r5,16(%r15);
94 #define STM_6 stmg %r2,%r7,16(%r15);
96 #define LM_0 /* Nothing */
97 #define LM_1 lg %r2,16+160(%r15);
98 #define LM_2 lmg %r2,%r3,16+160(%r15);
99 #define LM_3 lmg %r2,%r4,16+160(%r15);
100 #define LM_4 lmg %r2,%r5,16+160(%r15);
101 #define LM_5 lmg %r2,%r5,16+160(%r15);
102 #define LM_6 lmg %r2,%r5,16+160(%r15); \
103 cfi_offset (%r7, -104); \
104 lg %r7,160+160(%r15);
106 #define LR7_0 /* Nothing */
107 #define LR7_1 /* Nothing */
108 #define LR7_2 /* Nothing */
109 #define LR7_3 /* Nothing */
110 #define LR7_4 /* Nothing */
111 #define LR7_5 /* Nothing */
112 #define LR7_6 lg %r7,56+160(%r15); \
113 cfi_restore (%r7);
115 # if defined IS_IN_libpthread || !defined NOT_IN_libc
116 # ifndef __ASSEMBLER__
117 extern int __local_multiple_threads attribute_hidden;
118 # define SINGLE_THREAD_P \
119 __builtin_expect (__local_multiple_threads == 0, 1)
120 # else
121 # define SINGLE_THREAD_P \
122 larl %r1,__local_multiple_threads; \
123 icm %r0,15,0(%r1);
124 # endif
126 # else
128 # ifndef __ASSEMBLER__
129 # define SINGLE_THREAD_P \
130 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
131 header.multiple_threads) == 0, 1)
132 # else
133 # define SINGLE_THREAD_P \
134 ear %r1,%a0; \
135 sllg %r1,%r1,32; \
136 ear %r1,%a1; \
137 icm %r1,15,MULTIPLE_THREADS_OFFSET(%r1);
138 # endif
140 # endif
142 #elif !defined __ASSEMBLER__
144 # define SINGLE_THREAD_P (1)
145 # define NO_CANCELLATION 1
147 #endif
149 #ifndef __ASSEMBLER__
150 # define RTLD_SINGLE_THREAD_P \
151 __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
152 header.multiple_threads) == 0, 1)
153 #endif