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