2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_unlock.S
blob045b8b3b33fcee350fc7e8cee932cb92b11e405a
1 /* Copyright (C) 2003, 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 <lowlevellock.h>
21 #include <lowlevelrwlock.h>
22 #include <kernel-features.h>
23 #include "lowlevel-atomic.h"
26         .text
28         .globl  __pthread_rwlock_unlock
29         .type   __pthread_rwlock_unlock,@function
30         .align  5
31 __pthread_rwlock_unlock:
32         mov.l   r12, @-r15
33         mov.l   r8, @-r15
34         sts.l   pr, @-r15
35         mov     r4, r8
37         /* Get the lock.  */
38         mov     #0, r3
39         mov     #1, r4
40 #if MUTEX == 0
41         CMPXCHG (r3, @r8, r4, r2)
42 #else
43         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
44 #endif
45         bf      1f
47         mov.l   @(WRITER,r8), r0
48         tst     r0, r0
49         bf      5f
50         mov.l   @(NR_READERS,r8), r0
51         add     #-1, r0
52         mov.l   r0, @(NR_READERS,r8)
53         tst     r0, r0
54         bf      6f
56         mov     #0, r0
57         mov.l   r0, @(WRITER,r8)
58         mov     #1, r6
59         mov     r8, r4
60         add     #WRITERS_WAKEUP, r4
61         mov.l   @(WRITERS_QUEUED,r8), r0
62         tst     r0, r0
63         bf      0f
65         /* If also no readers waiting nothing to do.  */
66         mov.l   @(READERS_QUEUED,r8), r0
67         tst     r0, r0
68         bt      6f
70         mov     #-1, r6
71         shlr    r6              /* r6 = 0x7fffffff */
72         mov     r8, r4
73         add     #READERS_WAKEUP, r4
76         mov.l   @r4, r0
77         add     #1, r0
78         mov.l   r0, @r4
79 #if MUTEX == 0
80         DEC (@r8, r2)
81 #else
82         DEC (@(MUTEX,r8), r2)
83 #endif
84         tst     r2, r2
85         bf      7f
88 #ifdef __ASSUME_PRIVATE_FUTEX
89         mov     #PSHARED, r0
90         mov.b   @(r0,r8), r5
91         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r0
92         xor     r0, r5
93         extu.b  r5, r5
94 #else
95         mov     #PSHARED, r0
96         mov.b   @(r0,r8), r5
97         extu.b  r5, r5
98         mov     #FUTEX_WAKE, r0
99         or      r0, r5
100         stc     gbr, r1
101         mov.w   .Lpfoff, r2
102         add     r2, r1
103         mov.l   @r1, r0
104         xor     r0, r5
105 #endif
106         mov     #SYS_futex, r3
107         mov     #0, r7
108         extu.b  r3, r3
109         trapa   #0x14
110         SYSCALL_INST_PAD
112         lds.l   @r15+, pr
113         mov.l   @r15+, r8
114         mov.l   @r15+, r12
115         rts
116          mov    #0, r0
118 #if MUTEX == 0
119         DEC (@r8, r2)
120 #else
121         DEC (@(MUTEX,r8), r2)
122 #endif
123         tst     r2, r2
124         bf      3f
126         lds.l   @r15+, pr
127         mov.l   @r15+, r8
128         mov.l   @r15+, r12
129         rts
130          mov    #0, r0
133         mov     r8, r5
134 #if MUTEX != 0
135         add     #MUTEX, r5
136 #endif
137         mov     #PSHARED, r0
138         mov.b   @(r0,r8), r6
139         extu.b  r6, r6
140         mov.l   .Lwait8, r1
141         bsrf    r1
142          mov    r2, r4
143 .Lwait8b:
144         bra     2b
145          nop
147         mov     r8, r4
148 #if MUTEX != 0
149         add     #MUTEX, r4
150 #endif
151         mov     #PSHARED, r0
152         mov.b   @(r0,r8), r5
153         extu.b  r5, r5
154         mov.l   .Lwake8, r1
155         bsrf    r1
156          nop
157 .Lwake8b:
158         bra     4b
159          nop
162         mov.l   r4, @-r15
163         mov.l   r6, @-r15
164         mov     r8, r4
165 #if MUTEX != 0
166         add     #MUTEX, r4
167 #endif
168         mov     #PSHARED, r0
169         mov.b   @(r0,r8), r5
170         extu.b  r5, r5
171         mov.l   .Lwake9, r1
172         bsrf    r1
173          nop
174 .Lwake9b:
176         mov.l   @r15+, r6
177         bra     8b
178          mov.l  @r15+, r4
180 #ifndef __ASSUME_PRIVATE_FUTEX
181 .Lpfoff:
182         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
183 #endif
184         .align  2
185 .Lwait8:        
186         .long   __lll_lock_wait-.Lwait8b
187 .Lwake8:
188         .long   __lll_unlock_wake-.Lwake8b
189 .Lwake9:
190         .long   __lll_unlock_wake-.Lwake9b
191         .size   __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
193         .globl  pthread_rwlock_unlock
194 pthread_rwlock_unlock = __pthread_rwlock_unlock
196         .globl  __pthread_rwlock_unlock_internal
197 __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock