Relocate AArch64 from ports to libc.
[jlayton/glibc.git] / sysdeps / unix / sysv / linux / aarch64 / nptl / sysdep-cancel.h
1 /* Copyright (C) 2003-2014 Free Software Foundation, Inc.
2
3    This file is part of the GNU C Library.
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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdep.h>
20 #include <tls.h>
21 #ifndef __ASSEMBLER__
22 # include <nptl/pthreadP.h>
23 #endif
24
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
26
27 # undef PSEUDO
28 # define PSEUDO(name, syscall_name, args)                               \
29   .section ".text";                                                     \
30   .type __##syscall_name##_nocancel,%function;                          \
31   .globl __##syscall_name##_nocancel;                                   \
32   __##syscall_name##_nocancel:                                          \
33     cfi_startproc;                                                      \
34     DO_CALL (syscall_name, args);                                       \
35     PSEUDO_RET;                                                         \
36     cfi_endproc;                                                        \
37     .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;    \
38   ENTRY (name);                                                         \
39     SINGLE_THREAD_P;                                                    \
40     DOARGS_##args;                                                      \
41     bne .Lpseudo_cancel;                                                \
42     DO_CALL (syscall_name, 0);                                          \
43     UNDOARGS_##args;                                                    \
44     cmn x0, 4095;                                                       \
45     PSEUDO_RET;                                                         \
46   .Lpseudo_cancel:                                                      \
47     DOCARGS_##args;     /* save syscall args etc. around CENABLE.  */   \
48     CENABLE;                                                            \
49     mov x16, x0;        /* put mask in safe place.  */                  \
50     UNDOCARGS_##args;   /* restore syscall args.  */                    \
51     mov x8, SYS_ify (syscall_name);     /* do the call.  */             \
52     svc 0;                                                              \
53     str x0, [sp, -16]!; /* save syscall return value.  */               \
54     cfi_adjust_cfa_offset (16);                                         \
55     mov x0, x16;         /* get mask back.  */                          \
56     CDISABLE;                                                           \
57     ldr x0, [sp], 16;                                                   \
58     cfi_adjust_cfa_offset (-16);                                        \
59     ldr x30, [sp], 16;                                                  \
60     cfi_adjust_cfa_offset (-16);                                        \
61     cfi_restore (x30);                                                  \
62     UNDOARGS_##args;                                                    \
63     cmn x0, 4095;
64
65 # define DOCARGS_0                                                      \
66         str x30, [sp, -16]!;                                            \
67         cfi_adjust_cfa_offset (16);                                     \
68         cfi_rel_offset (x30, 0)
69
70 # define UNDOCARGS_0
71
72 # define DOCARGS_1                                                      \
73         DOCARGS_0;                                                      \
74         str x0, [sp, -16]!;                                             \
75         cfi_adjust_cfa_offset (16);                                     \
76         cfi_rel_offset (x0, 0)
77
78 # define UNDOCARGS_1                                                    \
79         ldr x0, [sp], 16;                                               \
80         cfi_restore (x0);                                               \
81         cfi_adjust_cfa_offset (-16);                                    \
82
83 # define DOCARGS_2                                                      \
84         DOCARGS_1;                                                      \
85         str x1, [sp, -16]!;                                             \
86         cfi_adjust_cfa_offset (16);                                     \
87         cfi_rel_offset (x1, 0)
88
89 # define UNDOCARGS_2                                                    \
90         ldr x1, [sp], 16;                                               \
91         cfi_restore (x1);                                               \
92         cfi_adjust_cfa_offset (-16);                                    \
93         UNDOCARGS_1
94
95 # define DOCARGS_3                                                      \
96         DOCARGS_2;                                                      \
97         str x2, [sp, -16]!;                                             \
98         cfi_adjust_cfa_offset (16);                                     \
99         cfi_rel_offset (x2, 0)
100
101 # define UNDOCARGS_3                                                    \
102         ldr x2, [sp], 16;                                               \
103         cfi_restore (x2);                                               \
104         cfi_adjust_cfa_offset (-16);                                    \
105         UNDOCARGS_2
106
107 # define DOCARGS_4                                                      \
108         DOCARGS_3;                                                      \
109         str x3, [sp, -16]!;                                             \
110         cfi_adjust_cfa_offset (16);                                     \
111         cfi_rel_offset (x3, 0)
112
113 # define UNDOCARGS_4                                                    \
114         ldr x3, [sp], 16;                                               \
115         cfi_restore (x3);                                               \
116         cfi_adjust_cfa_offset (-16);                                    \
117         UNDOCARGS_3
118
119 # define DOCARGS_5                                                      \
120         DOCARGS_4;                                                      \
121         str x4, [sp, -16]!;                                             \
122         cfi_adjust_cfa_offset (16);                                     \
123         cfi_rel_offset (x4, 0)
124
125 # define UNDOCARGS_5                                                    \
126         ldr x4, [sp], 16;                                               \
127         cfi_restore (x4);                                               \
128         cfi_adjust_cfa_offset (-16);                                    \
129         UNDOCARGS_4
130
131 # define DOCARGS_6                                                      \
132         DOCARGS_5;                                                      \
133         str x5, [sp, -16]!;                                             \
134         cfi_adjust_cfa_offset (16);                                     \
135         cfi_rel_offset (x5, 0)
136
137 # define UNDOCARGS_6                                                    \
138         ldr x5, [sp], 16;                                               \
139         cfi_restore (x5);                                               \
140         cfi_adjust_cfa_offset (-16);                                    \
141         UNDOCARGS_5
142
143 # ifdef IS_IN_libpthread
144 #  define CENABLE       bl __pthread_enable_asynccancel
145 #  define CDISABLE      bl __pthread_disable_asynccancel
146 #  define __local_multiple_threads __pthread_multiple_threads
147 # elif !defined NOT_IN_libc
148 #  define CENABLE       bl __libc_enable_asynccancel
149 #  define CDISABLE      bl __libc_disable_asynccancel
150 #  define __local_multiple_threads __libc_multiple_threads
151 # elif defined IS_IN_librt
152 #  define CENABLE       bl __librt_enable_asynccancel
153 #  define CDISABLE      bl __librt_disable_asynccancel
154 # else
155 #  error Unsupported library
156 # endif
157
158 # if defined IS_IN_libpthread || !defined NOT_IN_libc
159 #  ifndef __ASSEMBLER__
160 extern int __local_multiple_threads attribute_hidden;
161 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
162 #  else
163 #   define SINGLE_THREAD_P                                              \
164   adrp  x16, __local_multiple_threads;                                  \
165   add   x16, x16, #:lo12:__local_multiple_threads;                      \
166   ldr   x16, [x16];                                                     \
167   cmp   x16, 0;
168 #  endif
169 # else
170 /*  There is no __local_multiple_threads for librt, so use the TCB.  */
171 #  ifndef __ASSEMBLER__
172 #   define SINGLE_THREAD_P                                              \
173   __builtin_expect (THREAD_GETMEM (THREAD_SELF,                         \
174                                    header.multiple_threads) == 0, 1)
175 #  else
176 #   define SINGLE_THREAD_P                                              \
177   stp   x0, x30, [sp, -16]!;                                            \
178   cfi_adjust_cfa_offset (16);                                           \
179   cfi_rel_offset (x0, 0);                                               \
180   cfi_rel_offset (x30, 8);                                              \
181   bl    __read_tp;                                                      \
182   sub   x0, x0, PTHREAD_SIZEOF;                                         \
183   ldr   x16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET];                     \
184   ldp   x0, x30, [sp], 16;                                              \
185   cfi_restore (x0);                                                     \
186   cfi_restore (x30);                                                    \
187   cfi_adjust_cfa_offset (-16);                                          \
188   cmp   x16, 0
189 #   define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
190 #  endif
191 # endif
192
193 #elif !defined __ASSEMBLER__
194
195 /* For rtld, et cetera.  */
196 # define SINGLE_THREAD_P 1
197 # define NO_CANCELLATION 1
198
199 #endif
200
201 #ifndef __ASSEMBLER__
202 # define RTLD_SINGLE_THREAD_P \
203   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
204                                    header.multiple_threads) == 0, 1)
205 #endif