OSDN Git Service

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