2.5-18.1
[glibc.git] / sysdeps / unix / sysv / linux / alpha / select.S
blob35a81e949f971320b510113e5b599f750afd720b
1 /* Copyright (C) 1998,2002,2003,2006 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
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.
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.
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.  */
19 #include <sysdep-cancel.h>
20 #define _ERRNO_H        1
21 #include <bits/errno.h>
22 #include <kernel-features.h>
24 .text
26 #if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
27 #define SELECT  __select_tv64
28 #else
29 #define SELECT  __select
30 #endif
32 #if defined __ASSUME_TIMEVAL64
33 PSEUDO(SELECT, select, 5)
34         ret
35 PSEUDO_END(SELECT)
36 #else
37 /* The problem here is that initially we made struct timeval compatible with
38    OSF/1, using int32.  But we defined time_t with uint64, and later found
39    that POSIX requires tv_sec to be time_t.
41    So now we have to do compatibility stuff.  */
43 /* The variable is shared between all wrappers around signal handling
44    functions which have RT equivalents.  */
45 .comm __libc_missing_axp_tv64, 4
47 LEAF(SELECT, 64)
48         ldgp    gp, 0(pv)
49         subq    sp, 64, sp
50 #ifdef PROF
51         .set noat
52         lda     AT, _mcount
53         jsr     AT, (AT), _mcount
54         .set at
55 #endif
56         stq     ra, 40(sp)
57         .mask   0x4000000, 40-64
58         .prologue 1
60 #ifdef CENABLE
61         SINGLE_THREAD_P (t1)
62 #else
63         ldl     t0, __libc_missing_axp_tv64
64 #endif
66         /* Save timeout early, since we'll need to recover this after
67            the system call.  */
68         stq     a4, 48(sp)
70 #ifdef CENABLE
71         bne     t1, $do_cancel
72 #endif
74         bne     t0, $do32
76         /* Save arguments in case we do need to fall back.  */
77         stq     a0, 8(sp)
78         stq     a1, 16(sp)
79         stq     a2, 24(sp)
80         stq     a3, 32(sp)
82         ldi     v0, SYS_ify(select)
83         callsys
84         bne     a3, $err64
86         /* Everything ok.  */
87         addq    sp, 64, sp
88         ret
90         /* If we didn't get ENOSYS, it is a real error.  */
91         .align 3
92 $err64: cmpeq   v0, ENOSYS, t0
93         beq     t0, $error
94         stl     t0, __libc_missing_axp_tv64
96         /* Recover the saved arguments.  */
97         ldq     a4, 48(sp)
98         ldq     a3, 32(sp)
99         ldq     a2, 24(sp)
100         ldq     a1, 16(sp)
101         ldq     a0, 8(sp)
103         .align 3
104 $do32:
105         /* If the timeout argument is present bounce to the smaller fmt.  */
106         beq     a4, 1f
107         ldq     t0, 0(a4)
108         ldq     t1, 8(a4)
109         stl     t0, 0(sp)
110         stl     t1, 4(sp)
111         mov     sp, a4
113 1:      ldi     v0, SYS_ify(osf_select)
114         callsys
115         bne     a3, $error
117         /* ... and bounce the remaining timeout back.  */
118         ldq     a4, 48(sp)
119         beq     a4, 2f
120         ldl     t0, 0(sp)
121         ldl     t1, 4(sp)
122         stq     t0, 0(a4)
123         stq     t1, 8(a4)
125 2:      addq    sp, 64, sp
126         ret
128 #ifdef CENABLE
129         .align  3
130 $do_cancel:
131         /* Save arguments.  */
132         stq     a0, 8(sp)
133         stq     a1, 16(sp)
134         stq     a2, 24(sp)
135         stq     a3, 32(sp)
137         CENABLE
138         mov     v0, ra
140         ldl     t0, __libc_missing_axp_tv64
141         bne     t0, $do_cancel32
143         /* Recover the saved arguments.  */
144         ldq     a4, 48(sp)
145         ldq     a3, 32(sp)
146         ldq     a2, 24(sp)
147         ldq     a1, 16(sp)
148         ldq     a0, 8(sp)
150         ldi     v0, SYS_ify(select)
151         callsys
153         mov     ra, a0
154         bne     a3, $cancel_err64
156         stq     v0, 8(sp)
157         CDISABLE
158         ldq     v0, 8(sp)
159         ldq     ra, 40(sp)
161         /* Everything ok.  */
162         addq    sp, 64, sp
163         ret
165         /* If we didn't get ENOSYS, it is a real error.  */
166         .align 3
167 $cancel_err64:
168         cmpeq   v0, ENOSYS, t0
169         beq     t0, $cancel_error
170         stl     t0, __libc_missing_axp_tv64
172         /* Recover the saved arguments.  */
173         .align 3
174 $do_cancel32:
175         ldq     a4, 48(sp)
176         ldq     a3, 32(sp)
177         ldq     a2, 24(sp)
178         ldq     a1, 16(sp)
179         ldq     a0, 8(sp)
181         /* If the timeout argument is present bounce to the smaller fmt.  */
182         beq     a4, 1f
183         ldq     t0, 0(a4)
184         ldq     t1, 8(a4)
185         stl     t0, 0(sp)
186         stl     t1, 4(sp)
187         mov     sp, a4
189 1:      ldi     v0, SYS_ify(osf_select)
190         callsys
192         mov     ra, a0
193         bne     a3, $cancel_error
195         /* ... and bounce the remaining timeout back.  */
196         ldq     a4, 48(sp)
197         beq     a4, 2f
198         ldl     t0, 0(sp)
199         ldl     t1, 4(sp)
200         stq     t0, 0(a4)
201         stq     t1, 8(a4)
203 2:      stq     v0, 8(sp)
204         CDISABLE
205         ldq     v0, 8(sp)
206         ldq     ra, 40(sp)
208         addq    sp, 64, sp
209         ret
211         .align 3
212 $cancel_error:
213         stq     v0, 8(sp)
214         CDISABLE
215         ldq     v0, 8(sp)
216         ldq     ra, 40(sp)
217 #endif
219         .align 3
220 $error:
221         addq    sp, 64, sp
222         SYSCALL_ERROR_HANDLER
224 END(SELECT)
225 #endif /* __ASSUME_TIMEVAL64 */
227 #if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
228 default_symbol_version (__select_tv64, __select, GLIBC_2.1)
230 /* It seems to me to be a misfeature of the assembler that we can only
231    have one version-alias per symbol.  So create an alias ourselves.
232    The 'p' is for 'public'.  *Shrug*  */
233 strong_alias (__select_tv64, __select_tv64p)
234 default_symbol_version (__select_tv64p, select, GLIBC_2.1)
235 libc_hidden_ver (__select_tv64, __select)
236 strong_alias (__select_tv64, __libc_select)
237 #else
238 strong_alias (__select, __libc_select)
239 weak_alias (__select, select)
240 libc_hidden_def (__select)
241 #endif