(pthread_barrier_wait): Don't save, load, and restore %esi for last thread.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / sem_timedwait.S
1 /* Copyright (C) 2003 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, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <sysdep.h>
20 #include <shlib-compat.h>
21 #include "lowlevel-atomic.h"
22
23
24 #define SYS_gettimeofday        __NR_gettimeofday
25 #define SYS_futex               240
26 #define FUTEX_WAIT              0
27 #define FUTEX_WAKE              1
28
29 #define EINTR                   4
30 #define EAGAIN                  11
31 #define EWOULDBLOCK             EAGAIN
32 #define EINVAL                  22
33 #define ETIMEDOUT               110
34
35         .text
36
37         .globl  sem_timedwait
38         .type   sem_timedwait,@function
39         .align  5
40 sem_timedwait:
41         mov.l   @r4, r0
42 2:
43         tst     r0, r0
44         bt      1f
45         mov     r0, r3
46         mov     r0, r6
47         add     #-1, r3
48         CMPXCHG (r6, @r4, r3, r2)
49         bf/s    2b
50          mov    r2, r0
51         rts
52          mov    #0, r0
53
54 1:
55         /* Check whether the timeout value is valid.  */
56         mov.l   r12, @-r15
57         mov.l   r9, @-r15
58         mov.l   r8, @-r15
59         sts.l   pr, @-r15
60         add     #-8, r15
61         mov     r4, r8
62         mov     r5, r9
63
64         /* Check for invalid nanosecond field.  */
65         mov.l   @(4,r9), r0
66         mov.l   .L1g, r1
67         cmp/hs  r1, r0
68         bt/s    6f
69          mov    #EINVAL, r0
70 7:
71         /* Compute relative timeout.  */
72         mov     r15, r4
73         mov     #0, r5
74         mov     #SYS_gettimeofday, r3
75         trapa   #0x12
76         SYSCALL_INST_PAD
77
78         mov.l   @(4,r15), r0
79         mov.w   .L1k, r1
80         dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
81         mov.l   @r9, r2
82         mov.l   @(4,r9), r3
83         mov.l   @r15, r0
84         sts     macl, r1
85         sub     r0, r2
86         clrt
87         subc    r1, r3
88         bf      5f
89         mov.l   .L1g, r1
90         add     r1, r3
91         add     #-1, r2
92 5:
93         cmp/pz  r2
94         bf      6f              /* Time is already up.  */
95
96         /* Store relative timeout.  */
97         mov.l   r2, @r15
98         mov.l   r3, @(4,r15)
99
100         /* Futex call.  */
101         mov     r8, r4
102         mov     #FUTEX_WAIT, r5
103         mov     #0, r6
104         mov     r15, r7
105         mov     #SYS_futex, r3
106         extu.b  r3, r3
107         trapa   #0x14
108         SYSCALL_INST_PAD
109
110         tst     r0, r0
111         bt      9f
112         cmp/eq  #-EWOULDBLOCK, r0
113         bf      3f
114 9:
115         mov.l   @r8, r0
116 8:
117         tst     r0, r0
118         bt      7b
119
120         mov     r0, r3
121         mov     r0, r4
122         add     #-1, r3
123         CMPXCHG (r4, @r8, r3, r2)
124         bf/s    8b
125          mov    r2, r0
126
127         add     #8, r15
128         lds.l   @r15+, pr
129         mov.l   @r15+, r8
130         mov.l   @r15+, r9
131         mov.l   @r15+, r12
132         rts
133          mov    #0, r0
134
135 3:
136         neg     r0, r0
137 6:
138         mov     r0, r8
139         mova    .Lgot2, r0
140         mov.l   .Lgot2, r12
141         add     r0, r12
142
143 #if USE___THREAD
144         mov.l   .Lerrno2, r0
145         stc     gbr, r1
146         mov.l   @(r0, r12), r0
147         add     r1, r0
148         mov.l   r8, @r0
149 #else
150         mov.l   .Lerrloc2, r1
151         bsrf    r1
152          nop
153 .Lerrloc2b:
154         mov.l   r8, @r0
155 #endif
156         add     #8, r15
157         lds.l   @r15+, pr
158         mov.l   @r15+, r8
159         mov.l   @r15+, r9
160         mov.l   @r15+, r12
161         rts
162          mov    #-1, r0
163
164 .L1k:
165         .word   1000
166         .align  2
167 .L1g:
168         .long   1000000000
169 .Lgot2:
170         .long   _GLOBAL_OFFSET_TABLE_
171 #if USE___THREAD
172 .Lerrno2:
173         .long   errno@GOTTPOFF
174 #else
175 .Lerrloc2:
176         .long   __errno_location@PLT-(.Lerrloc2b+2-.)
177 #endif
178         .size   sem_timedwait,.-sem_timedwait