Move SH code out of nptl/ subdirectory.
[glibc.git] / sysdeps / unix / sysv / linux / sh / lowlevelrobustlock.S
blob65b8d0cdcdb9c844a5c20a5d362eaffe1f560da1
1 /* Copyright (C) 2003-2014 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, see
16    <http://www.gnu.org/licenses/>.  */
18 #include <sysdep.h>
19 #include <pthread-errnos.h>
20 #include <lowlevellock.h>
21 #include <lowlevelrobustlock.h>
22 #include <kernel-features.h>
23 #include "lowlevel-atomic.h"
25         .text
27 #define FUTEX_WAITERS           0x80000000
28 #define FUTEX_OWNER_DIED        0x40000000
30 #ifdef __ASSUME_PRIVATE_FUTEX
31 # define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
32         mov     #(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), tmp; \
33         extu.b  tmp, tmp; \
34         xor     tmp, reg
35 #else
36 # if FUTEX_WAIT == 0
37 #  define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
38         stc     gbr, tmp        ; \
39         mov.w   99f, tmp2       ; \
40         add     tmp2, tmp       ; \
41         mov.l   @tmp, tmp2      ; \
42         bra     98f             ; \
43          mov    #FUTEX_PRIVATE_FLAG, tmp ; \
44 99:     .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
45 98:     extu.b  tmp, tmp        ; \
46         xor     tmp, reg        ; \
47         and     tmp2, reg
48 # else
49 #  define LOAD_FUTEX_WAIT(reg,tmp,tmp2) \
50         stc     gbr, tmp        ; \
51         mov.w   99f, tmp2       ; \
52         add     tmp2, tmp       ; \
53         mov.l   @tmp, tmp2      ; \
54         bra     98f             ; \
55          mov    #FUTEX_PRIVATE_FLAG, tmp ; \
56 99:     .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE ; \
57 98:     extu.b  tmp, tmp        ; \
58         xor     tmp, reg        ; \
59         and     tmp2, reg       ; \
60         mov     #FUTEX_WAIT, tmp ; \
61         or      tmp, reg
62 # endif
63 #endif
65         .globl  __lll_robust_lock_wait
66         .type   __lll_robust_lock_wait,@function
67         .hidden __lll_robust_lock_wait
68         .align  5
69         cfi_startproc
70 __lll_robust_lock_wait:
71         mov.l   r8, @-r15
72         cfi_adjust_cfa_offset(4)
73         cfi_rel_offset (r8, 0)
74         mov     r5, r8
75         mov     #0, r7          /* No timeout.  */
76         mov     r6, r5
77         LOAD_FUTEX_WAIT (r5, r0, r1)
80         mov     r4, r6
81         mov.l   .L_FUTEX_WAITERS, r0
82         or      r0, r6
83         shlr    r0              /* r0 = FUTEX_OWNER_DIED */
84         tst     r0, r4
85         bf/s    3f
86          cmp/eq r4, r6
87         bt      1f
89         CMPXCHG (r4, @r8, r6, r2)
90         bf      2f
93         mov     r8, r4
94         mov     #SYS_futex, r3
95         extu.b  r3, r3
96         trapa   #0x14
97         SYSCALL_INST_PAD
99         mov.l   @r8, r2
102         tst     r2, r2
103         bf/s    4b
104          mov    r2, r4
106         stc     gbr, r1
107         mov.w   .Ltidoff, r2
108         add     r2, r1
109         mov.l   @r1, r6
110         mov     #0, r3
111         CMPXCHG (r3, @r8, r6, r4)
112         bf      4b
113         mov     #0, r4
116         mov.l   @r15+, r8
117         cfi_adjust_cfa_offset (-4)
118         cfi_restore (r8)
119         ret
120          mov    r4, r0
121         cfi_endproc
122         .align  2
123 .L_FUTEX_WAITERS:
124         .long   FUTEX_WAITERS
125 .Ltidoff:
126         .word   TID - TLS_PRE_TCB_SIZE
127         .size   __lll_robust_lock_wait,.-__lll_robust_lock_wait
130         .globl  __lll_robust_timedlock_wait
131         .type   __lll_robust_timedlock_wait,@function
132         .hidden __lll_robust_timedlock_wait
133         .align  5
134         cfi_startproc
135 __lll_robust_timedlock_wait:
136         /* Check for a valid timeout value.  */
137         mov.l   @(4,r6), r1
138         mov.l   .L1g, r0
139         cmp/hs  r0, r1
140         bt      3f
142         cfi_remember_state
144         mov.l   r11, @-r15
145         cfi_adjust_cfa_offset(4)
146         cfi_rel_offset (r11, 0)
147         mov.l   r10, @-r15
148         cfi_adjust_cfa_offset(4)
149         cfi_rel_offset (r10, 0)
150         mov.l   r9, @-r15
151         cfi_adjust_cfa_offset(4)
152         cfi_rel_offset (r9, 0)
153         mov.l   r8, @-r15
154         cfi_adjust_cfa_offset(4)
155         cfi_rel_offset (r8, 0)
156         mov     r7, r11
157         mov     r4, r10
158         mov     r6, r9
159         mov     r5, r8
161         /* Stack frame for the timespec and timeval structs.  */
162         add     #-8, r15
163         cfi_adjust_cfa_offset(8)
166         /* Get current time.  */
167         mov     r15, r4
168         mov     #0, r5
169         mov     #__NR_gettimeofday, r3
170         trapa   #0x12
171         SYSCALL_INST_PAD
173         /* Compute relative timeout.  */
174         mov.l   @(4,r15), r0
175         mov.w   .L1k, r1
176         dmulu.l r0, r1          /* Micro seconds to nano seconds.  */
177         mov.l   @r9, r2
178         mov.l   @(4,r9), r3
179         mov.l   @r15, r0
180         sts     macl, r1
181         sub     r0, r2
182         clrt
183         subc    r1, r3
184         bf      4f
185         mov.l   .L1g, r1
186         add     r1, r3
187         add     #-1, r2
189         cmp/pz  r2
190         bf      8f              /* Time is already up.  */
192         mov.l   r2, @r15        /* Store relative timeout.  */
193         mov.l   r3, @(4,r15)
195         mov     r10, r6
196         mov.l   .L_FUTEX_WAITERS2, r0
197         or      r0, r6
198         shlr    r0              /* r0 = FUTEX_OWNER_DIED */
199         tst     r0, r4
200         bf/s    6f
201          cmp/eq r4, r6
202         bt      2f
204         CMPXCHG (r4, @r8, r6, r2)
205         bf/s    5f
206          mov    #0, r5
209         mov     r8, r4
210         mov     r11, r5
211         LOAD_FUTEX_WAIT (r5, r0, r1)
212         mov     r10, r6
213         mov     r15, r7
214         mov     #SYS_futex, r3
215         extu.b  r3, r3
216         trapa   #0x14
217         SYSCALL_INST_PAD
218         mov     r0, r5
220         mov.l   @r8, r2
223         tst     r2, r2
224         bf/s    7f
225          mov    r2, r10
227         stc     gbr, r1
228         mov.w   .Ltidoff2, r2
229         add     r2, r1
230         mov.l   @r1, r4
231         mov     #0, r3
232         CMPXCHG (r3, @r8, r4, r10)
233         bf      7f
234         mov     #0, r0
237         cfi_remember_state
238         add     #8, r15
239         cfi_adjust_cfa_offset (-8)
240         mov.l   @r15+, r8
241         cfi_adjust_cfa_offset (-4)
242         cfi_restore (r8)
243         mov.l   @r15+, r9
244         cfi_adjust_cfa_offset (-4)
245         cfi_restore (r9)
246         mov.l   @r15+, r10
247         cfi_adjust_cfa_offset (-4)
248         cfi_restore (r10)
249         rts
250          mov.l  @r15+, r11
251         /* Omit CFI for restore in delay slot.  */
252         cfi_restore_state
255         /* Check whether the time expired.  */
256         mov     #-ETIMEDOUT, r1
257         cmp/eq  r5, r1
258         bf      1b
261         bra     6b
262          mov    #ETIMEDOUT, r0
264         cfi_restore_state
266         rts
267          mov    #EINVAL, r0
268         cfi_endproc
269         .align  2
270 .L_FUTEX_WAITERS2:
271         .long   FUTEX_WAITERS
272 .L1g:
273         .long   1000000000
274 .Ltidoff2:
275         .word   TID - TLS_PRE_TCB_SIZE
276 .L1k:
277         .word   1000
278         .size   __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait