174ff7b9164c5493f2062967fdd6ecc165746051
[linux-3.10.git] / arch / sparc64 / lib / rwsem.S
1 /* rwsem.S: RW semaphore assembler.
2  *
3  * Written by David S. Miller (davem@redhat.com), 2001.
4  * Derived from asm-i386/rwsem.h
5  */
6
7 #include <asm/rwsem-const.h>
8
9         .section        .sched.text
10
11         .globl          __down_read
12 __down_read:
13 1:      lduw            [%o0], %g1
14         add             %g1, 1, %g7
15         cas             [%o0], %g1, %g7
16         cmp             %g1, %g7
17         bne,pn          %icc, 1b
18          add            %g7, 1, %g7
19         cmp             %g7, 0
20         bl,pn           %icc, 3f
21          membar         #StoreLoad | #StoreStore
22 2:
23         retl
24          nop
25 3:
26         save            %sp, -192, %sp
27         call            rwsem_down_read_failed
28          mov            %i0, %o0
29         ret
30          restore
31         .size           __down_read, .-__down_read
32
33         .globl          __down_read_trylock
34 __down_read_trylock:
35 1:      lduw            [%o0], %g1
36         add             %g1, 1, %g7
37         cmp             %g7, 0
38         bl,pn           %icc, 2f
39          mov            0, %o1
40         cas             [%o0], %g1, %g7
41         cmp             %g1, %g7
42         bne,pn          %icc, 1b
43          mov            1, %o1
44         membar          #StoreLoad | #StoreStore
45 2:      retl
46          mov            %o1, %o0
47         .size           __down_read_trylock, .-__down_read_trylock
48
49         .globl          __down_write
50 __down_write:
51         sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
52         or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
53 1:
54         lduw            [%o0], %g3
55         add             %g3, %g1, %g7
56         cas             [%o0], %g3, %g7
57         cmp             %g3, %g7
58         bne,pn          %icc, 1b
59          cmp            %g7, 0
60         bne,pn          %icc, 3f
61          membar         #StoreLoad | #StoreStore
62 2:      retl
63          nop
64 3:
65         save            %sp, -192, %sp
66         call            rwsem_down_write_failed
67          mov            %i0, %o0
68         ret
69          restore
70         .size           __down_write, .-__down_write
71
72         .globl          __down_write_trylock
73 __down_write_trylock:
74         sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
75         or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
76 1:
77         lduw            [%o0], %g3
78         cmp             %g3, 0
79         bne,pn          %icc, 2f
80          mov            0, %o1
81         add             %g3, %g1, %g7
82         cas             [%o0], %g3, %g7
83         cmp             %g3, %g7
84         bne,pn          %icc, 1b
85          mov            1, %o1
86         membar          #StoreLoad | #StoreStore
87 2:      retl
88          mov            %o1, %o0
89         .size           __down_write_trylock, .-__down_write_trylock
90
91         .globl          __up_read
92 __up_read:
93 1:
94         lduw            [%o0], %g1
95         sub             %g1, 1, %g7
96         cas             [%o0], %g1, %g7
97         cmp             %g1, %g7
98         bne,pn          %icc, 1b
99          cmp            %g7, 0
100         bl,pn           %icc, 3f
101          membar         #StoreLoad | #StoreStore
102 2:      retl
103          nop
104 3:      sethi           %hi(RWSEM_ACTIVE_MASK), %g1
105         sub             %g7, 1, %g7
106         or              %g1, %lo(RWSEM_ACTIVE_MASK), %g1
107         andcc           %g7, %g1, %g0
108         bne,pn          %icc, 2b
109          nop
110         save            %sp, -192, %sp
111         call            rwsem_wake
112          mov            %i0, %o0
113         ret
114          restore
115         .size           __up_read, .-__up_read
116
117         .globl          __up_write
118 __up_write:
119         sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
120         or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
121 1:
122         lduw            [%o0], %g3
123         sub             %g3, %g1, %g7
124         cas             [%o0], %g3, %g7
125         cmp             %g3, %g7
126         bne,pn          %icc, 1b
127          sub            %g7, %g1, %g7
128         cmp             %g7, 0
129         bl,pn           %icc, 3f
130          membar         #StoreLoad | #StoreStore
131 2:
132         retl
133          nop
134 3:
135         save            %sp, -192, %sp
136         call            rwsem_wake
137          mov            %i0, %o0
138         ret
139          restore
140         .size           __up_write, .-__up_write
141
142         .globl          __downgrade_write
143 __downgrade_write:
144         sethi           %hi(RWSEM_WAITING_BIAS), %g1
145         or              %g1, %lo(RWSEM_WAITING_BIAS), %g1
146 1:
147         lduw            [%o0], %g3
148         sub             %g3, %g1, %g7
149         cas             [%o0], %g3, %g7
150         cmp             %g3, %g7
151         bne,pn          %icc, 1b
152          sub            %g7, %g1, %g7
153         cmp             %g7, 0
154         bl,pn           %icc, 3f
155          membar         #StoreLoad | #StoreStore
156 2:
157         retl
158          nop
159 3:
160         save            %sp, -192, %sp
161         call            rwsem_downgrade_wake
162          mov            %i0, %o0
163         ret
164          restore
165         .size           __downgrade_write, .-__downgrade_write