[SPARC64]: Avoid membar instructions in delay slots.
[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         membar          #StoreLoad | #StoreStore
21         bl,pn           %icc, 3f
22          nop
23 2:
24         retl
25          nop
26 3:
27         save            %sp, -192, %sp
28         call            rwsem_down_read_failed
29          mov            %i0, %o0
30         ret
31          restore
32         .size           __down_read, .-__down_read
33
34         .globl          __down_read_trylock
35 __down_read_trylock:
36 1:      lduw            [%o0], %g1
37         add             %g1, 1, %g7
38         cmp             %g7, 0
39         bl,pn           %icc, 2f
40          mov            0, %o1
41         cas             [%o0], %g1, %g7
42         cmp             %g1, %g7
43         bne,pn          %icc, 1b
44          mov            1, %o1
45         membar          #StoreLoad | #StoreStore
46 2:      retl
47          mov            %o1, %o0
48         .size           __down_read_trylock, .-__down_read_trylock
49
50         .globl          __down_write
51 __down_write:
52         sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
53         or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
54 1:
55         lduw            [%o0], %g3
56         add             %g3, %g1, %g7
57         cas             [%o0], %g3, %g7
58         cmp             %g3, %g7
59         bne,pn          %icc, 1b
60          cmp            %g7, 0
61         membar          #StoreLoad | #StoreStore
62         bne,pn          %icc, 3f
63          nop
64 2:      retl
65          nop
66 3:
67         save            %sp, -192, %sp
68         call            rwsem_down_write_failed
69          mov            %i0, %o0
70         ret
71          restore
72         .size           __down_write, .-__down_write
73
74         .globl          __down_write_trylock
75 __down_write_trylock:
76         sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
77         or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
78 1:
79         lduw            [%o0], %g3
80         cmp             %g3, 0
81         bne,pn          %icc, 2f
82          mov            0, %o1
83         add             %g3, %g1, %g7
84         cas             [%o0], %g3, %g7
85         cmp             %g3, %g7
86         bne,pn          %icc, 1b
87          mov            1, %o1
88         membar          #StoreLoad | #StoreStore
89 2:      retl
90          mov            %o1, %o0
91         .size           __down_write_trylock, .-__down_write_trylock
92
93         .globl          __up_read
94 __up_read:
95 1:
96         lduw            [%o0], %g1
97         sub             %g1, 1, %g7
98         cas             [%o0], %g1, %g7
99         cmp             %g1, %g7
100         bne,pn          %icc, 1b
101          cmp            %g7, 0
102         membar          #StoreLoad | #StoreStore
103         bl,pn           %icc, 3f
104          nop
105 2:      retl
106          nop
107 3:      sethi           %hi(RWSEM_ACTIVE_MASK), %g1
108         sub             %g7, 1, %g7
109         or              %g1, %lo(RWSEM_ACTIVE_MASK), %g1
110         andcc           %g7, %g1, %g0
111         bne,pn          %icc, 2b
112          nop
113         save            %sp, -192, %sp
114         call            rwsem_wake
115          mov            %i0, %o0
116         ret
117          restore
118         .size           __up_read, .-__up_read
119
120         .globl          __up_write
121 __up_write:
122         sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
123         or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
124 1:
125         lduw            [%o0], %g3
126         sub             %g3, %g1, %g7
127         cas             [%o0], %g3, %g7
128         cmp             %g3, %g7
129         bne,pn          %icc, 1b
130          sub            %g7, %g1, %g7
131         cmp             %g7, 0
132         membar          #StoreLoad | #StoreStore
133         bl,pn           %icc, 3f
134          nop
135 2:
136         retl
137          nop
138 3:
139         save            %sp, -192, %sp
140         call            rwsem_wake
141          mov            %i0, %o0
142         ret
143          restore
144         .size           __up_write, .-__up_write
145
146         .globl          __downgrade_write
147 __downgrade_write:
148         sethi           %hi(RWSEM_WAITING_BIAS), %g1
149         or              %g1, %lo(RWSEM_WAITING_BIAS), %g1
150 1:
151         lduw            [%o0], %g3
152         sub             %g3, %g1, %g7
153         cas             [%o0], %g3, %g7
154         cmp             %g3, %g7
155         bne,pn          %icc, 1b
156          sub            %g7, %g1, %g7
157         cmp             %g7, 0
158         membar          #StoreLoad | #StoreStore
159         bl,pn           %icc, 3f
160          nop
161 2:
162         retl
163          nop
164 3:
165         save            %sp, -192, %sp
166         call            rwsem_downgrade_wake
167          mov            %i0, %o0
168         ret
169          restore
170         .size           __downgrade_write, .-__downgrade_write