Updated to fedora-glibc-20070731T1624
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / sem_timedwait.S
blobe5e064b3a5203c14ee94135b8e8f75f10ed8fef1
1 /* Copyright (C) 2003, 2004, 2007 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.h>
20 #include <shlib-compat.h>
21 #include <pthread-errnos.h>
22 #include <tcb-offsets.h>
23 #include <structsem.h>
24 #include "lowlevel-atomic.h"
27 #define SYS_gettimeofday        __NR_gettimeofday
28 #define SYS_futex               240
29 #define FUTEX_WAIT              0
31 #if VALUE != 0
32 # error "code needs to be rewritten for VALUE != 0"
33 #endif
35         .text
37         .globl  sem_timedwait
38         .type   sem_timedwait,@function
39         .align  5
40 sem_timedwait:
41 .LSTARTCODE:
42         mov.l   @r4, r0
44         tst     r0, r0
45         bt      1f
46         mov     r0, r3
47         mov     r0, r6
48         add     #-1, r3
49         CMPXCHG (r6, @r4, r3, r2)
50         bf/s    2b
51          mov    r2, r0
52         rts
53          mov    #0, r0
56         /* Check whether the timeout value is valid.  */
57         mov.l   r8, @-r15
58 .Lpush_r8:
59         mov.l   r9, @-r15
60 .Lpush_r9:
61         mov.l   r10, @-r15
62 .Lpush_r10:
63         mov.l   r12, @-r15
64 .Lpush_r12:
65         sts.l   pr, @-r15
66 .Lpush_pr:
67         add     #-8, r15
68 .Lalloc:
69         mov     r4, r8
70         mov     r5, r9
72         /* Check for invalid nanosecond field.  */
73         mov.l   @(4,r9), r0
74         mov.l   .L1g, r1
75         cmp/hs  r1, r0
76         bt/s    6f
77          mov    #EINVAL, r0
78         INC (@(NWAITERS,r8),r2)
81         /* Compute relative timeout.  */
82         mov     r15, r4
83         mov     #0, r5
84         mov     #SYS_gettimeofday, r3
85         trapa   #0x12
86         SYSCALL_INST_PAD
88         mov.l   @(4,r15), r0
89         mov.w   .L1k, r1
90         dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
91         mov.l   @r9, r2
92         mov.l   @(4,r9), r3
93         mov.l   @r15, r0
94         sts     macl, r1
95         sub     r0, r2
96         clrt
97         subc    r1, r3
98         bf      5f
99         mov.l   .L1g, r1
100         add     r1, r3
101         add     #-1, r2
103         cmp/pz  r2
104         bf/s    6f              /* Time is already up.  */
105          mov    #ETIMEDOUT, r0
107         /* Store relative timeout.  */
108         mov.l   r2, @r15
109         mov.l   r3, @(4,r15)
111 .LcleanupSTART:
112         mov.l   .Lenable0, r1
113         bsrf    r1
114          nop
115 .Lenable0b:
116         mov     r0, r10
118         mov     r8, r4
119 #if FUTEX_WAIT == 0
120         mov.l   @(PRIVATE,r8), r5
121 #else
122         mov.l   @(PRIVATE,r8), r5
123         mov     #FUTEX_WAIT, r0
124         or      r0, r5
125 #endif
126         mov     #0, r6
127         mov     r15, r7
128         mov     #SYS_futex, r3
129         extu.b  r3, r3
130         trapa   #0x14
131         SYSCALL_INST_PAD
133         mov.l   .Ldisable0, r1
134         mov     r10, r4
135         bsrf    r1
136          mov    r0, r10
137 .Ldisable0b:    
138         mov     r10, r0
139 .LcleanupEND:
141         tst     r0, r0
142         bt      9f
143         cmp/eq  #-EWOULDBLOCK, r0
144         bf      3f
146         mov.l   @r8, r0
148         tst     r0, r0
149         bt      7b
151         mov     r0, r3
152         mov     r0, r4
153         add     #-1, r3
154         CMPXCHG (r4, @r8, r3, r2)
155         bf/s    8b
156          mov    r2, r0
158         DEC (@(NWAITERS,r8), r2)
159         mov     #0, r0
162         add     #8, r15
163         lds.l   @r15+, pr
164         mov.l   @r15+, r12
165         mov.l   @r15+, r10
166         mov.l   @r15+, r9
167         mov.l   @r15+, r8
168         rts
169          nop
172         neg     r0, r0
174         mov     r0, r10
175         mova    .Lgot2, r0
176         mov.l   .Lgot2, r12
177         add     r0, r12
179 #if USE___THREAD
180         mov.l   .Lerrno2, r0
181         stc     gbr, r1
182         mov.l   @(r0, r12), r0
183         add     r1, r0
184         mov.l   r10, @r0
185 #else
186         mov.l   .Lerrloc2, r1
187         bsrf    r1
188          nop
189 .Lerrloc2b:
190         mov.l   r10, @r0
191 #endif
192         DEC (@(NWAITERS,r8), r2)
193         bra     10b
194          mov    #-1, r0
196 .L1k:
197         .word   1000
198         .align  2
199 .L1g:
200         .long   1000000000
201 .Lgot2:
202         .long   _GLOBAL_OFFSET_TABLE_
203 #if USE___THREAD
204 .Lerrno2:
205         .long   errno@GOTTPOFF
206 #else
207 .Lerrloc2:
208         .long   __errno_location@PLT-(.Lerrloc2b-.)
209 #endif
210 .Lenable0:
211         .long   __pthread_enable_asynccancel-.Lenable0b
212 .Ldisable0:
213         .long   __pthread_disable_asynccancel-.Ldisable0b
214         .size   sem_timedwait,.-sem_timedwait
216         .type   sem_wait_cleanup,@function
217 sem_wait_cleanup:
218         DEC (@(NWAITERS,r8), r2)
219 .LcallUR:
220         mov.l   .Lresume, r1
221 #ifdef PIC
222         add     r12, r1
223 #endif
224         jsr     @r1
225          nop
226         sleep
228         .align  2
229 .Lresume:
230 #ifdef PIC
231         .long   _Unwind_Resume@GOTOFF
232 #else
233         .long   _Unwind_Resume
234 #endif
235 .LENDCODE:
236         .size   sem_wait_cleanup,.-sem_wait_cleanup
239         .section .gcc_except_table,"a",@progbits
240 .LexceptSTART:
241         .byte   0xff                            ! @LPStart format (omit)
242         .byte   0xff                            ! @TType format (omit)
243         .byte   0x01                            ! call-site format
244                                                 ! DW_EH_PE_uleb128
245         .uleb128 .Lcstend-.Lcstbegin
246 .Lcstbegin:
247         .uleb128 .LcleanupSTART-.LSTARTCODE
248         .uleb128 .LcleanupEND-.LcleanupSTART
249         .uleb128 sem_wait_cleanup-.LSTARTCODE
250         .uleb128  0
251         .uleb128 .LcallUR-.LSTARTCODE
252         .uleb128 .LENDCODE-.LcallUR
253         .uleb128 0
254         .uleb128  0
255 .Lcstend:
258         .section .eh_frame,"a",@progbits
259 .LSTARTFRAME:
260         .ualong .LENDCIE-.LSTARTCIE             ! Length of the CIE.
261 .LSTARTCIE:
262         .ualong 0                               ! CIE ID.
263         .byte   1                               ! Version number.
264 #ifdef SHARED
265         .string "zPLR"                          ! NUL-terminated augmentation
266                                                 ! string.
267 #else
268         .string "zPL"                           ! NUL-terminated augmentation
269                                                 ! string.
270 #endif
271         .uleb128 1                              ! Code alignment factor.
272         .sleb128 -4                             ! Data alignment factor.
273         .byte   0x11                            ! Return address register
274                                                 ! column.
275 #ifdef SHARED
276         .uleb128 7                              ! Augmentation value length.
277         .byte   0x9b                            ! Personality: DW_EH_PE_pcrel
278                                                 ! + DW_EH_PE_sdata4
279                                                 ! + DW_EH_PE_indirect
280         .ualong DW.ref.__gcc_personality_v0-.
281         .byte   0x1b                            ! LSDA Encoding: DW_EH_PE_pcrel
282                                                 ! + DW_EH_PE_sdata4.
283         .byte   0x1b                            ! FDE Encoding: DW_EH_PE_pcrel
284                                                 ! + DW_EH_PE_sdata4.
285 #else
286         .uleb128 6                              ! Augmentation value length.
287         .byte   0x0                             ! Personality: absolute
288         .ualong __gcc_personality_v0
289         .byte   0x0                             ! LSDA Encoding: absolute
290 #endif
291         .byte 0x0c                              ! DW_CFA_def_cfa
292         .uleb128 0xf
293         .uleb128 0
294         .align 4
295 .LENDCIE:
297         .ualong .LENDFDE-.LSTARTFDE             ! Length of the FDE.
298 .LSTARTFDE:
299         .ualong .LSTARTFDE-.LSTARTFRAME         ! CIE pointer.
300 #ifdef SHARED
301         .ualong .LSTARTCODE-.                   ! PC-relative start address
302                                                 ! of the code.
303 #else
304         .ualong .LSTARTCODE                     ! Start address of the code.
305 #endif
306         .ualong .LENDCODE-.LSTARTCODE           ! Length of the code.
307         .uleb128 4                              ! Augmentation size
308 #ifdef SHARED
309         .ualong .LexceptSTART-.
310 #else
311         .ualong .LexceptSTART
312 #endif
314         .byte   4                               ! DW_CFA_advance_loc4
315         .ualong .Lpush_r8-.LSTARTCODE
316         .byte   14                              ! DW_CFA_def_cfa_offset
317         .uleb128 4
318         .byte   0x88                            ! DW_CFA_offset r8
319         .uleb128 1
320         .byte   4                               ! DW_CFA_advance_loc4
321         .ualong .Lpush_r9-.Lpush_r8
322         .byte   14                              ! DW_CFA_def_cfa_offset
323         .uleb128 8
324         .byte   0x89                            ! DW_CFA_offset r9
325         .uleb128 2
326         .byte   4                               ! DW_CFA_advance_loc4
327         .ualong .Lpush_r10-.Lpush_r9
328         .byte   14                              ! DW_CFA_def_cfa_offset
329         .uleb128 12
330         .byte   0x8a                            ! DW_CFA_offset r10
331         .uleb128 3
332         .byte   4                               ! DW_CFA_advance_loc4
333         .ualong .Lpush_r12-.Lpush_r10
334         .byte   14                              ! DW_CFA_def_cfa_offset
335         .uleb128 16
336         .byte   0x8c                            ! DW_CFA_offset r12
337         .uleb128 4
338         .byte   4                               ! DW_CFA_advance_loc4
339         .ualong .Lpush_pr-.Lpush_r12
340         .byte   14                              ! DW_CFA_def_cfa_offset
341         .uleb128 20
342         .byte   0x91                            ! DW_CFA_offset pr
343         .uleb128 5
344         .byte   4                               ! DW_CFA_advance_loc4
345         .ualong .Lalloc-.Lpush_pr
346         .byte   14                              ! DW_CFA_def_cfa_offset
347         .uleb128 28
348         .align  4
349 .LENDFDE:
352 #ifdef SHARED
353         .hidden DW.ref.__gcc_personality_v0
354         .weak   DW.ref.__gcc_personality_v0
355         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
356         .align  4
357         .type   DW.ref.__gcc_personality_v0, @object
358         .size   DW.ref.__gcc_personality_v0, 4
359 DW.ref.__gcc_personality_v0:
360         .long   __gcc_personality_v0
361 #endif