]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/linuxthreads/sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / linuxthreads / sysdeps / unix / sysv / linux / hppa / sysdep-cancel.h
1 /* cancellable system calls for Linux/HPPA.
2    Copyright (C) 2003 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Carlos O'Donell <carlos@baldric.uwo.ca>, 2003.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <sysdep.h>
21 #ifndef __ASSEMBLER__
22 # include <linuxthreads/internals.h>
23 #endif
24
25 #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
26
27 # ifndef NO_ERROR
28 #  define NO_ERROR -0x1000
29 # endif
30
31 # undef PSEUDO
32 # define PSEUDO(name, syscall_name, args)                               \
33   ENTRY (name)                                                          \
34     SINGLE_THREAD_P                                     ASM_LINE_SEP    \
35     cmpib,<> 0,%ret0,Lpseudo_cancel                     ASM_LINE_SEP    \
36     nop                                                 ASM_LINE_SEP    \
37     DO_CALL(syscall_name, args)                         ASM_LINE_SEP    \
38     /* DONE! */                                         ASM_LINE_SEP    \
39     bv 0(2)                                             ASM_LINE_SEP    \
40     nop                                                 ASM_LINE_SEP    \
41   Lpseudo_cancel:                                       ASM_LINE_SEP    \
42     /* store return ptr */                              ASM_LINE_SEP    \
43     stw %rp, -20(%sr0,%sp)                              ASM_LINE_SEP    \
44     /* save syscall args */                             ASM_LINE_SEP    \
45     PUSHARGS_##args /* MACRO */                         ASM_LINE_SEP    \
46     STW_PIC                                             ASM_LINE_SEP    \
47     CENABLE /* FUNC CALL */                             ASM_LINE_SEP    \
48     ldo 64(%sp), %sp                                    ASM_LINE_SEP    \
49     ldo -64(%sp), %sp                                   ASM_LINE_SEP    \
50     LDW_PIC                                             ASM_LINE_SEP    \
51     /* restore syscall args */                          ASM_LINE_SEP    \
52     POPARGS_##args                                      ASM_LINE_SEP    \
53     /* save r4 in arg0 stack slot */                    ASM_LINE_SEP    \
54     stw %r4, -36(%sr0,%sp)                              ASM_LINE_SEP    \
55     /* save mask from cenable */                        ASM_LINE_SEP    \
56     copy %ret0, %r4                                     ASM_LINE_SEP    \
57     ble 0x100(%sr2,%r0)                                 ASM_LINE_SEP    \
58     ldi SYS_ify (syscall_name), %r20                    ASM_LINE_SEP    \
59     LDW_PIC                                             ASM_LINE_SEP    \
60     /* pass mask as arg0 to cdisable */                 ASM_LINE_SEP    \
61     copy %r4, %r26                                      ASM_LINE_SEP    \
62     copy %ret0, %r4                                     ASM_LINE_SEP    \
63     CDISABLE                                            ASM_LINE_SEP    \
64     ldo 64(%sp), %sp                                    ASM_LINE_SEP    \
65     ldo -64(%sp), %sp                                   ASM_LINE_SEP    \
66     LDW_PIC                                             ASM_LINE_SEP    \
67     /* compare error */                                 ASM_LINE_SEP    \
68     ldi NO_ERROR,%r1                                    ASM_LINE_SEP    \
69     /* branch if no error */                            ASM_LINE_SEP    \
70     cmpb,>>=,n %r1,%r4,Lpre_end                         ASM_LINE_SEP    \
71     nop                                                 ASM_LINE_SEP    \
72     SYSCALL_ERROR_HANDLER                               ASM_LINE_SEP    \
73     ldo 64(%sp), %sp                                    ASM_LINE_SEP    \
74     ldo -64(%sp), %sp                                   ASM_LINE_SEP    \
75     /* No need to LDW_PIC */                            ASM_LINE_SEP    \
76     /* make syscall res value positive */               ASM_LINE_SEP    \
77     sub %r0, %r4, %r4                                   ASM_LINE_SEP    \
78     /* store into errno location */                     ASM_LINE_SEP    \
79     stw %r4, 0(%sr0,%ret0)                              ASM_LINE_SEP    \
80     /* return -1 */                                     ASM_LINE_SEP    \
81     ldo -1(%r0), %ret0                                  ASM_LINE_SEP    \
82   Lpre_end:                                             ASM_LINE_SEP    \
83     ldw -20(%sr0,%sp), %rp                              ASM_LINE_SEP    \
84     /* No need to LDW_PIC */                            ASM_LINE_SEP    \
85     ldw -36(%sr0,%sp), %r4                              ASM_LINE_SEP
86
87 /* Save arguments into our frame */
88 # define PUSHARGS_0     /* nothing to do */
89 # define PUSHARGS_1     PUSHARGS_0 stw %r26, -36(%sr0,%sp)      ASM_LINE_SEP
90 # define PUSHARGS_2     PUSHARGS_1 stw %r25, -40(%sr0,%sp)      ASM_LINE_SEP
91 # define PUSHARGS_3     PUSHARGS_2 stw %r24, -44(%sr0,%sp)      ASM_LINE_SEP
92 # define PUSHARGS_4     PUSHARGS_3 stw %r23, -48(%sr0,%sp)      ASM_LINE_SEP
93 # define PUSHARGS_5     PUSHARGS_4 /* Args are on the stack... */
94 # define PUSHARGS_6     PUSHARGS_5
95
96 /* Bring them back from the stack */
97 # define POPARGS_0      /* nothing to do */
98 # define POPARGS_1      POPARGS_0 ldw -36(%sr0,%sp), %r26       ASM_LINE_SEP
99 # define POPARGS_2      POPARGS_1 ldw -40(%sr0,%sp), %r25       ASM_LINE_SEP
100 # define POPARGS_3      POPARGS_2 ldw -44(%sr0,%sp), %r24       ASM_LINE_SEP
101 # define POPARGS_4      POPARGS_3 ldw -48(%sr0,%sp), %r23       ASM_LINE_SEP
102 # define POPARGS_5      POPARGS_4 ldw -52(%sr0,%sp), %r22       ASM_LINE_SEP
103 # define POPARGS_6      POPARGS_5 ldw -54(%sr0,%sp), %r21       ASM_LINE_SEP
104
105 # ifdef IS_IN_libpthread
106 #  ifdef __PIC__
107 #   define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \
108                         bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP
109 #   define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \
110                         bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP
111 #  else
112 #   define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \
113                         bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP
114 #   define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \
115                         bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP
116 #  endif
117 # elif !defined NOT_IN_libc
118 #  ifdef __PIC__
119 #   define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \
120                         bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP
121 #   define CDISABLE     .import __libc_disable_asynccancel,code ASM_LINE_SEP \
122                         bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP
123 #  else
124 #   define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \
125                         bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP
126 #   define CDISABLE     .import __libc_disable_asynccancel,code ASM_LINE_SEP \
127                         bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP
128 #  endif
129 # else
130 #  ifdef __PIC__
131 #   define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \
132                         bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP
133 #   define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \
134                         bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP
135 #  else
136 #   define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \
137                         bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP
138 #   define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \
139                         bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP
140 #  endif
141 # endif
142
143 /* p_header.multiple_threads is +12 from the pthread_descr struct start,
144    We could have called __get_cr27() but we really want less overhead */
145 # define MULTIPLE_THREADS_OFFSET 0xC
146
147 /* cr27 has been initialized to 0x0 by kernel */
148 # define NO_THREAD_CR27 0x0
149
150 # ifdef IS_IN_libpthread
151 #  define __local_multiple_threads __pthread_multiple_threads
152 # elif !defined NOT_IN_libc
153 #  define __local_multiple_threads __libc_multiple_threads
154 # else
155 #  define __local_multiple_threads __librt_multiple_threads
156 # endif
157
158 # ifndef __ASSEMBLER__
159  extern int __local_multiple_threads attribute_hidden;
160 #  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
161 # else
162 /* This ALT version requires newer kernel support */
163 #  define SINGLE_THREAD_P_MFCTL                                         \
164         mfctl %cr27, %ret0                                      ASM_LINE_SEP    \
165         cmpib,= NO_THREAD_CR27,%ret0,Lstp                       ASM_LINE_SEP    \
166         nop                                                     ASM_LINE_SEP    \
167         ldw MULTIPLE_THREADS_OFFSET(%sr0,%ret0),%ret0           ASM_LINE_SEP    \
168  Lstp:                                                          ASM_LINE_SEP
169 #  ifdef __PIC__
170 /* Slower version uses GOT to get value of __local_multiple_threads */
171 #   define SINGLE_THREAD_P                                                      \
172         addil LT%__local_multiple_threads, %r19                 ASM_LINE_SEP    \
173         ldw RT%__local_multiple_threads(%sr0,%r1), %ret0        ASM_LINE_SEP    \
174         ldw 0(%sr0,%ret0), %ret0                                ASM_LINE_SEP
175 #  else
176   /* Slow non-pic version using DP */
177 #   define SINGLE_THREAD_P                                                              \
178         addil LR%__local_multiple_threads-$global$,%r27                 ASM_LINE_SEP    \
179         ldw RR%__local_multiple_threads-$global$(%sr0,%r1),%ret0        ASM_LINE_SEP
180 #  endif
181 # endif
182 #elif !defined __ASSEMBLER__
183
184 /* This code should never be used but we define it anyhow.  */
185 # define SINGLE_THREAD_P (1)
186
187 #endif
188 /* !defined NOT_IN_libc || defined IS_IN_libpthread */