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