]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / alpha / sysdep-cancel.h
1 /* Copyright (C) 2003, 2006 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
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.
8
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.
13
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.  */
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 # ifdef PROF
28 #  define PSEUDO_PROF                           \
29         .set noat;                              \
30         lda     AT, _mcount;                    \
31         jsr     AT, (AT), _mcount;              \
32         .set at
33 # else
34 #  define PSEUDO_PROF
35 # endif
36
37 /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END
38    besides "ret".  */
39
40 # undef PSEUDO
41 # define PSEUDO(name, syscall_name, args)                       \
42         .globl name;                                            \
43         .align 4;                                               \
44         .type name, @function;                                  \
45         .usepv name, std;                                       \
46         cfi_startproc;                                          \
47 __LABEL(name)                                                   \
48         ldgp    gp, 0(pv);                                      \
49         PSEUDO_PROF;                                            \
50         PSEUDO_PREPARE_ARGS                                     \
51         SINGLE_THREAD_P(t0);                                    \
52         bne     t0, $pseudo_cancel;                             \
53         lda     v0, SYS_ify(syscall_name);                      \
54         call_pal PAL_callsys;                                   \
55         bne     a3, SYSCALL_ERROR_LABEL;                        \
56 __LABEL($pseudo_ret)                                            \
57         .subsection 2;                                          \
58         cfi_startproc;                                          \
59 __LABEL($pseudo_cancel)                                         \
60         subq    sp, 64, sp;                                     \
61         cfi_def_cfa_offset(64);                                 \
62         stq     ra, 0(sp);                                      \
63         cfi_offset(ra, -64);                                    \
64         SAVE_ARGS_##args;                                       \
65         CENABLE;                                                \
66         LOAD_ARGS_##args;                                       \
67         /* Save the CENABLE return value in RA.  That register  \
68            is preserved across syscall and the real return      \
69            address is saved on the stack.  */                   \
70         mov     v0, ra;                                         \
71         lda     v0, SYS_ify(syscall_name);                      \
72         call_pal PAL_callsys;                                   \
73         stq     v0, 8(sp);                                      \
74         mov     ra, a0;                                         \
75         bne     a3, $multi_error;                               \
76         CDISABLE;                                               \
77         ldq     ra, 0(sp);                                      \
78         ldq     v0, 8(sp);                                      \
79         addq    sp, 64, sp;                                     \
80         cfi_remember_state;                                     \
81         cfi_restore(ra);                                        \
82         cfi_def_cfa_offset(0);                                  \
83         ret;                                                    \
84         cfi_restore_state;                                      \
85 __LABEL($multi_error)                                           \
86         CDISABLE;                                               \
87         ldq     ra, 0(sp);                                      \
88         ldq     v0, 8(sp);                                      \
89         addq    sp, 64, sp;                                     \
90         cfi_restore(ra);                                        \
91         cfi_def_cfa_offset(0);                                  \
92 __LABEL($syscall_error)                                         \
93         SYSCALL_ERROR_HANDLER;                                  \
94         cfi_endproc;                                            \
95         .previous
96
97 # undef PSEUDO_END
98 # define PSEUDO_END(sym)                                        \
99         cfi_endproc;                                            \
100         .subsection 2;                                          \
101         .size sym, .-sym
102
103 # define SAVE_ARGS_0    /* Nothing.  */
104 # define SAVE_ARGS_1    SAVE_ARGS_0; stq a0, 8(sp)
105 # define SAVE_ARGS_2    SAVE_ARGS_1; stq a1, 16(sp)
106 # define SAVE_ARGS_3    SAVE_ARGS_2; stq a2, 24(sp)
107 # define SAVE_ARGS_4    SAVE_ARGS_3; stq a3, 32(sp)
108 # define SAVE_ARGS_5    SAVE_ARGS_4; stq a4, 40(sp)
109 # define SAVE_ARGS_6    SAVE_ARGS_5; stq a5, 48(sp)
110
111 # define LOAD_ARGS_0    /* Nothing.  */
112 # define LOAD_ARGS_1    LOAD_ARGS_0; ldq a0, 8(sp)
113 # define LOAD_ARGS_2    LOAD_ARGS_1; ldq a1, 16(sp)
114 # define LOAD_ARGS_3    LOAD_ARGS_2; ldq a2, 24(sp)
115 # define LOAD_ARGS_4    LOAD_ARGS_3; ldq a3, 32(sp)
116 # define LOAD_ARGS_5    LOAD_ARGS_4; ldq a4, 40(sp)
117 # define LOAD_ARGS_6    LOAD_ARGS_5; ldq a5, 48(sp)
118
119 # ifdef IS_IN_libpthread
120 #  define __local_enable_asynccancel    __pthread_enable_asynccancel
121 #  define __local_disable_asynccancel   __pthread_disable_asynccancel
122 #  define __local_multiple_threads      __pthread_multiple_threads
123 # elif !defined NOT_IN_libc
124 #  define __local_enable_asynccancel    __libc_enable_asynccancel
125 #  define __local_disable_asynccancel   __libc_disable_asynccancel
126 #  define __local_multiple_threads      __libc_multiple_threads
127 # elif defined IS_IN_librt
128 #  define __local_enable_asynccancel    __librt_enable_asynccancel
129 #  define __local_disable_asynccancel   __librt_disable_asynccancel
130 # else
131 #  error Unsupported library
132 # endif
133
134 # ifdef __PIC__
135 #  define CENABLE       bsr ra, __local_enable_asynccancel !samegp
136 #  define CDISABLE      bsr ra, __local_disable_asynccancel !samegp
137 # else
138 #  define CENABLE       jsr ra, __local_enable_asynccancel; ldgp ra, 0(gp)
139 #  define CDISABLE      jsr ra, __local_disable_asynccancel; ldgp ra, 0(gp)
140 # endif
141
142 # if defined IS_IN_libpthread || !defined NOT_IN_libc
143 #  ifndef __ASSEMBLER__
144 extern int __local_multiple_threads attribute_hidden;
145 #   define SINGLE_THREAD_P \
146         __builtin_expect (__local_multiple_threads == 0, 1)
147 #  elif defined(__PIC__)
148 #   define SINGLE_THREAD_P(reg)  ldl reg, __local_multiple_threads(gp) !gprel
149 #  else
150 #   define SINGLE_THREAD_P(reg)                                 \
151         ldah    reg, __local_multiple_threads(gp) !gprelhigh;   \
152         ldl     reg, __local_multiple_threads(reg) !gprellow
153 #  endif
154 # else
155 #  ifndef __ASSEMBLER__
156 #   define SINGLE_THREAD_P \
157         __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
158                                    header.multiple_threads) == 0, 1)
159 #  else
160 #   define SINGLE_THREAD_P(reg)                                 \
161         call_pal PAL_rduniq;                                    \
162         ldl reg, MULTIPLE_THREADS_OFFSET($0)
163 #  endif
164 # endif
165
166 #else
167
168 # define SINGLE_THREAD_P (1)
169 # define NO_CANCELLATION 1
170
171 #endif
172
173 #ifndef __ASSEMBLER__
174 # define RTLD_SINGLE_THREAD_P \
175   __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
176                                    header.multiple_threads) == 0, 1)
177 #endif