initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / sparc64 / lib / rwsem.c
blobe19968dbc2d1551c31d08a5a4276ac8c71bf35b2
1 /* rwsem.c: Don't inline expand these suckers all over the place.
3 * Written by David S. Miller (davem@redhat.com), 2001.
4 * Derived from asm-i386/rwsem.h
5 */
7 #include <linux/kernel.h>
8 #include <linux/rwsem.h>
9 #include <linux/init.h>
10 #include <linux/module.h>
12 extern struct rw_semaphore *FASTCALL(rwsem_down_read_failed(struct rw_semaphore *sem));
13 extern struct rw_semaphore *FASTCALL(rwsem_down_write_failed(struct rw_semaphore *sem));
14 extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *));
15 extern struct rw_semaphore *FASTCALL(rwsem_downgrade_wake(struct rw_semaphore *));
17 void __sched __down_read(struct rw_semaphore *sem)
19 __asm__ __volatile__(
20 "! beginning __down_read\n"
21 "1:\tlduw [%0], %%g5\n\t"
22 "add %%g5, 1, %%g7\n\t"
23 "cas [%0], %%g5, %%g7\n\t"
24 "cmp %%g5, %%g7\n\t"
25 "bne,pn %%icc, 1b\n\t"
26 " add %%g7, 1, %%g7\n\t"
27 "cmp %%g7, 0\n\t"
28 "bl,pn %%icc, 3f\n\t"
29 " membar #StoreLoad | #StoreStore\n"
30 "2:\n\t"
31 ".subsection 2\n"
32 "3:\tmov %0, %%g5\n\t"
33 "save %%sp, -160, %%sp\n\t"
34 "mov %%g1, %%l1\n\t"
35 "mov %%g2, %%l2\n\t"
36 "mov %%g3, %%l3\n\t"
37 "call %1\n\t"
38 " mov %%g5, %%o0\n\t"
39 "mov %%l1, %%g1\n\t"
40 "mov %%l2, %%g2\n\t"
41 "ba,pt %%xcc, 2b\n\t"
42 " restore %%l3, %%g0, %%g3\n\t"
43 ".previous\n\t"
44 "! ending __down_read"
45 : : "r" (sem), "i" (rwsem_down_read_failed)
46 : "g5", "g7", "memory", "cc");
48 EXPORT_SYMBOL(__down_read);
50 int __down_read_trylock(struct rw_semaphore *sem)
52 int result;
54 __asm__ __volatile__(
55 "! beginning __down_read_trylock\n"
56 "1:\tlduw [%1], %%g5\n\t"
57 "add %%g5, 1, %%g7\n\t"
58 "cmp %%g7, 0\n\t"
59 "bl,pn %%icc, 2f\n\t"
60 " mov 0, %0\n\t"
61 "cas [%1], %%g5, %%g7\n\t"
62 "cmp %%g5, %%g7\n\t"
63 "bne,pn %%icc, 1b\n\t"
64 " mov 1, %0\n\t"
65 "membar #StoreLoad | #StoreStore\n"
66 "2:\n\t"
67 "! ending __down_read_trylock"
68 : "=&r" (result)
69 : "r" (sem)
70 : "g5", "g7", "memory", "cc");
72 return result;
74 EXPORT_SYMBOL(__down_read_trylock);
76 void __sched __down_write(struct rw_semaphore *sem)
78 __asm__ __volatile__(
79 "! beginning __down_write\n\t"
80 "sethi %%hi(%2), %%g1\n\t"
81 "or %%g1, %%lo(%2), %%g1\n"
82 "1:\tlduw [%0], %%g5\n\t"
83 "add %%g5, %%g1, %%g7\n\t"
84 "cas [%0], %%g5, %%g7\n\t"
85 "cmp %%g5, %%g7\n\t"
86 "bne,pn %%icc, 1b\n\t"
87 " cmp %%g7, 0\n\t"
88 "bne,pn %%icc, 3f\n\t"
89 " membar #StoreLoad | #StoreStore\n"
90 "2:\n\t"
91 ".subsection 2\n"
92 "3:\tmov %0, %%g5\n\t"
93 "save %%sp, -160, %%sp\n\t"
94 "mov %%g2, %%l2\n\t"
95 "mov %%g3, %%l3\n\t"
96 "call %1\n\t"
97 " mov %%g5, %%o0\n\t"
98 "mov %%l2, %%g2\n\t"
99 "ba,pt %%xcc, 2b\n\t"
100 " restore %%l3, %%g0, %%g3\n\t"
101 ".previous\n\t"
102 "! ending __down_write"
103 : : "r" (sem), "i" (rwsem_down_write_failed),
104 "i" (RWSEM_ACTIVE_WRITE_BIAS)
105 : "g1", "g5", "g7", "memory", "cc");
107 EXPORT_SYMBOL(__down_write);
109 int __down_write_trylock(struct rw_semaphore *sem)
111 int result;
113 __asm__ __volatile__(
114 "! beginning __down_write_trylock\n\t"
115 "sethi %%hi(%2), %%g1\n\t"
116 "or %%g1, %%lo(%2), %%g1\n"
117 "1:\tlduw [%1], %%g5\n\t"
118 "cmp %%g5, 0\n\t"
119 "bne,pn %%icc, 2f\n\t"
120 " mov 0, %0\n\t"
121 "add %%g5, %%g1, %%g7\n\t"
122 "cas [%1], %%g5, %%g7\n\t"
123 "cmp %%g5, %%g7\n\t"
124 "bne,pn %%icc, 1b\n\t"
125 " mov 1, %0\n\t"
126 "membar #StoreLoad | #StoreStore\n"
127 "2:\n\t"
128 "! ending __down_write_trylock"
129 : "=&r" (result)
130 : "r" (sem), "i" (RWSEM_ACTIVE_WRITE_BIAS)
131 : "g1", "g5", "g7", "memory", "cc");
133 return result;
135 EXPORT_SYMBOL(__down_write_trylock);
137 void __up_read(struct rw_semaphore *sem)
139 __asm__ __volatile__(
140 "! beginning __up_read\n\t"
141 "1:\tlduw [%0], %%g5\n\t"
142 "sub %%g5, 1, %%g7\n\t"
143 "cas [%0], %%g5, %%g7\n\t"
144 "cmp %%g5, %%g7\n\t"
145 "bne,pn %%icc, 1b\n\t"
146 " cmp %%g7, 0\n\t"
147 "bl,pn %%icc, 3f\n\t"
148 " membar #StoreLoad | #StoreStore\n"
149 "2:\n\t"
150 ".subsection 2\n"
151 "3:\tsethi %%hi(%2), %%g1\n\t"
152 "sub %%g7, 1, %%g7\n\t"
153 "or %%g1, %%lo(%2), %%g1\n\t"
154 "andcc %%g7, %%g1, %%g0\n\t"
155 "bne,pn %%icc, 2b\n\t"
156 " mov %0, %%g5\n\t"
157 "save %%sp, -160, %%sp\n\t"
158 "mov %%g2, %%l2\n\t"
159 "mov %%g3, %%l3\n\t"
160 "call %1\n\t"
161 " mov %%g5, %%o0\n\t"
162 "mov %%l2, %%g2\n\t"
163 "ba,pt %%xcc, 2b\n\t"
164 " restore %%l3, %%g0, %%g3\n\t"
165 ".previous\n\t"
166 "! ending __up_read"
167 : : "r" (sem), "i" (rwsem_wake),
168 "i" (RWSEM_ACTIVE_MASK)
169 : "g1", "g5", "g7", "memory", "cc");
171 EXPORT_SYMBOL(__up_read);
173 void __up_write(struct rw_semaphore *sem)
175 __asm__ __volatile__(
176 "! beginning __up_write\n\t"
177 "sethi %%hi(%2), %%g1\n\t"
178 "or %%g1, %%lo(%2), %%g1\n"
179 "1:\tlduw [%0], %%g5\n\t"
180 "sub %%g5, %%g1, %%g7\n\t"
181 "cas [%0], %%g5, %%g7\n\t"
182 "cmp %%g5, %%g7\n\t"
183 "bne,pn %%icc, 1b\n\t"
184 " sub %%g7, %%g1, %%g7\n\t"
185 "cmp %%g7, 0\n\t"
186 "bl,pn %%icc, 3f\n\t"
187 " membar #StoreLoad | #StoreStore\n"
188 "2:\n\t"
189 ".subsection 2\n"
190 "3:\tmov %0, %%g5\n\t"
191 "save %%sp, -160, %%sp\n\t"
192 "mov %%g2, %%l2\n\t"
193 "mov %%g3, %%l3\n\t"
194 "call %1\n\t"
195 " mov %%g5, %%o0\n\t"
196 "mov %%l2, %%g2\n\t"
197 "ba,pt %%xcc, 2b\n\t"
198 " restore %%l3, %%g0, %%g3\n\t"
199 ".previous\n\t"
200 "! ending __up_write"
201 : : "r" (sem), "i" (rwsem_wake),
202 "i" (RWSEM_ACTIVE_WRITE_BIAS)
203 : "g1", "g5", "g7", "memory", "cc");
205 EXPORT_SYMBOL(__up_write);
207 void __downgrade_write(struct rw_semaphore *sem)
209 __asm__ __volatile__(
210 "! beginning __downgrade_write\n\t"
211 "sethi %%hi(%2), %%g1\n\t"
212 "or %%g1, %%lo(%2), %%g1\n"
213 "1:\tlduw [%0], %%g5\n\t"
214 "sub %%g5, %%g1, %%g7\n\t"
215 "cas [%0], %%g5, %%g7\n\t"
216 "cmp %%g5, %%g7\n\t"
217 "bne,pn %%icc, 1b\n\t"
218 " sub %%g7, %%g1, %%g7\n\t"
219 "cmp %%g7, 0\n\t"
220 "bl,pn %%icc, 3f\n\t"
221 " membar #StoreLoad | #StoreStore\n"
222 "2:\n\t"
223 ".subsection 2\n"
224 "3:\tmov %0, %%g5\n\t"
225 "save %%sp, -160, %%sp\n\t"
226 "mov %%g2, %%l2\n\t"
227 "mov %%g3, %%l3\n\t"
228 "call %1\n\t"
229 " mov %%g5, %%o0\n\t"
230 "mov %%l2, %%g2\n\t"
231 "ba,pt %%xcc, 2b\n\t"
232 " restore %%l3, %%g0, %%g3\n\t"
233 ".previous\n\t"
234 "! ending __up_write"
235 : : "r" (sem), "i" (rwsem_downgrade_wake),
236 "i" (RWSEM_WAITING_BIAS)
237 : "g1", "g5", "g7", "memory", "cc");
239 EXPORT_SYMBOL(__downgrade_write);