diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-09-27 20:45:21 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-02-13 17:40:50 -0500 |
commit | f65e4fa8e0c6022ad58dc88d1b11b12589ed7f9f (patch) | |
tree | 2405e012e079693e0fcfde9ff981c549d6c68a21 /include/asm-mips | |
parent | 509cb37e173d4e39cec47238397e91b718730794 (diff) |
[MIPS] Improve branch prediction in ll/sc atomic operations.
Now that finally all supported versions of binutils have functioning
support for .subsection use .subsection to tweak the branch prediction
I did not modify the R10000 errata variants because it seems unclear if
this will invalidate the workaround which actually relies on the cheesy
prediction of branch likely to cause a misspredict if the sc was
successful.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'include/asm-mips')
-rw-r--r-- | include/asm-mips/atomic.h | 50 | ||||
-rw-r--r-- | include/asm-mips/bitops.h | 33 | ||||
-rw-r--r-- | include/asm-mips/spinlock.h | 56 | ||||
-rw-r--r-- | include/asm-mips/system.h | 20 |
4 files changed, 127 insertions, 32 deletions
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index c1a2409bb52a..8578869a8bcf 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h | |||
@@ -69,7 +69,10 @@ static __inline__ void atomic_add(int i, atomic_t * v) | |||
69 | "1: ll %0, %1 # atomic_add \n" | 69 | "1: ll %0, %1 # atomic_add \n" |
70 | " addu %0, %2 \n" | 70 | " addu %0, %2 \n" |
71 | " sc %0, %1 \n" | 71 | " sc %0, %1 \n" |
72 | " beqz %0, 1b \n" | 72 | " beqz %0, 2f \n" |
73 | " .subsection 2 \n" | ||
74 | "2: b 1b \n" | ||
75 | " .previous \n" | ||
73 | " .set mips0 \n" | 76 | " .set mips0 \n" |
74 | : "=&r" (temp), "=m" (v->counter) | 77 | : "=&r" (temp), "=m" (v->counter) |
75 | : "Ir" (i), "m" (v->counter)); | 78 | : "Ir" (i), "m" (v->counter)); |
@@ -111,7 +114,10 @@ static __inline__ void atomic_sub(int i, atomic_t * v) | |||
111 | "1: ll %0, %1 # atomic_sub \n" | 114 | "1: ll %0, %1 # atomic_sub \n" |
112 | " subu %0, %2 \n" | 115 | " subu %0, %2 \n" |
113 | " sc %0, %1 \n" | 116 | " sc %0, %1 \n" |
114 | " beqz %0, 1b \n" | 117 | " beqz %0, 2f \n" |
118 | " .subsection 2 \n" | ||
119 | "2: b 1b \n" | ||
120 | " .previous \n" | ||
115 | " .set mips0 \n" | 121 | " .set mips0 \n" |
116 | : "=&r" (temp), "=m" (v->counter) | 122 | : "=&r" (temp), "=m" (v->counter) |
117 | : "Ir" (i), "m" (v->counter)); | 123 | : "Ir" (i), "m" (v->counter)); |
@@ -155,8 +161,11 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) | |||
155 | "1: ll %1, %2 # atomic_add_return \n" | 161 | "1: ll %1, %2 # atomic_add_return \n" |
156 | " addu %0, %1, %3 \n" | 162 | " addu %0, %1, %3 \n" |
157 | " sc %0, %2 \n" | 163 | " sc %0, %2 \n" |
158 | " beqz %0, 1b \n" | 164 | " beqz %0, 2f \n" |
159 | " addu %0, %1, %3 \n" | 165 | " addu %0, %1, %3 \n" |
166 | " .subsection 2 \n" | ||
167 | "2: b 1b \n" | ||
168 | " .previous \n" | ||
160 | " .set mips0 \n" | 169 | " .set mips0 \n" |
161 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 170 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
162 | : "Ir" (i), "m" (v->counter) | 171 | : "Ir" (i), "m" (v->counter) |
@@ -204,8 +213,11 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) | |||
204 | "1: ll %1, %2 # atomic_sub_return \n" | 213 | "1: ll %1, %2 # atomic_sub_return \n" |
205 | " subu %0, %1, %3 \n" | 214 | " subu %0, %1, %3 \n" |
206 | " sc %0, %2 \n" | 215 | " sc %0, %2 \n" |
207 | " beqz %0, 1b \n" | 216 | " beqz %0, 2f \n" |
208 | " subu %0, %1, %3 \n" | 217 | " subu %0, %1, %3 \n" |
218 | " .subsection 2 \n" | ||
219 | "2: b 1b \n" | ||
220 | " .previous \n" | ||
209 | " .set mips0 \n" | 221 | " .set mips0 \n" |
210 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 222 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
211 | : "Ir" (i), "m" (v->counter) | 223 | : "Ir" (i), "m" (v->counter) |
@@ -267,10 +279,13 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
267 | " bltz %0, 1f \n" | 279 | " bltz %0, 1f \n" |
268 | " sc %0, %2 \n" | 280 | " sc %0, %2 \n" |
269 | " .set noreorder \n" | 281 | " .set noreorder \n" |
270 | " beqz %0, 1b \n" | 282 | " beqz %0, 2f \n" |
271 | " subu %0, %1, %3 \n" | 283 | " subu %0, %1, %3 \n" |
272 | " .set reorder \n" | 284 | " .set reorder \n" |
273 | "1: \n" | 285 | "1: \n" |
286 | " .subsection 2 \n" | ||
287 | "2: b 1b \n" | ||
288 | " .previous \n" | ||
274 | " .set mips0 \n" | 289 | " .set mips0 \n" |
275 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 290 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
276 | : "Ir" (i), "m" (v->counter) | 291 | : "Ir" (i), "m" (v->counter) |
@@ -429,7 +444,10 @@ static __inline__ void atomic64_add(long i, atomic64_t * v) | |||
429 | "1: lld %0, %1 # atomic64_add \n" | 444 | "1: lld %0, %1 # atomic64_add \n" |
430 | " addu %0, %2 \n" | 445 | " addu %0, %2 \n" |
431 | " scd %0, %1 \n" | 446 | " scd %0, %1 \n" |
432 | " beqz %0, 1b \n" | 447 | " beqz %0, 2f \n" |
448 | " .subsection 2 \n" | ||
449 | "2: b 1b \n" | ||
450 | " .previous \n" | ||
433 | " .set mips0 \n" | 451 | " .set mips0 \n" |
434 | : "=&r" (temp), "=m" (v->counter) | 452 | : "=&r" (temp), "=m" (v->counter) |
435 | : "Ir" (i), "m" (v->counter)); | 453 | : "Ir" (i), "m" (v->counter)); |
@@ -471,7 +489,10 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v) | |||
471 | "1: lld %0, %1 # atomic64_sub \n" | 489 | "1: lld %0, %1 # atomic64_sub \n" |
472 | " subu %0, %2 \n" | 490 | " subu %0, %2 \n" |
473 | " scd %0, %1 \n" | 491 | " scd %0, %1 \n" |
474 | " beqz %0, 1b \n" | 492 | " beqz %0, 2f \n" |
493 | " .subsection 2 \n" | ||
494 | "2: b 1b \n" | ||
495 | " .previous \n" | ||
475 | " .set mips0 \n" | 496 | " .set mips0 \n" |
476 | : "=&r" (temp), "=m" (v->counter) | 497 | : "=&r" (temp), "=m" (v->counter) |
477 | : "Ir" (i), "m" (v->counter)); | 498 | : "Ir" (i), "m" (v->counter)); |
@@ -515,8 +536,11 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v) | |||
515 | "1: lld %1, %2 # atomic64_add_return \n" | 536 | "1: lld %1, %2 # atomic64_add_return \n" |
516 | " addu %0, %1, %3 \n" | 537 | " addu %0, %1, %3 \n" |
517 | " scd %0, %2 \n" | 538 | " scd %0, %2 \n" |
518 | " beqz %0, 1b \n" | 539 | " beqz %0, 2f \n" |
519 | " addu %0, %1, %3 \n" | 540 | " addu %0, %1, %3 \n" |
541 | " .subsection 2 \n" | ||
542 | "2: b 1b \n" | ||
543 | " .previous \n" | ||
520 | " .set mips0 \n" | 544 | " .set mips0 \n" |
521 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 545 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
522 | : "Ir" (i), "m" (v->counter) | 546 | : "Ir" (i), "m" (v->counter) |
@@ -564,8 +588,11 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) | |||
564 | "1: lld %1, %2 # atomic64_sub_return \n" | 588 | "1: lld %1, %2 # atomic64_sub_return \n" |
565 | " subu %0, %1, %3 \n" | 589 | " subu %0, %1, %3 \n" |
566 | " scd %0, %2 \n" | 590 | " scd %0, %2 \n" |
567 | " beqz %0, 1b \n" | 591 | " beqz %0, 2f \n" |
568 | " subu %0, %1, %3 \n" | 592 | " subu %0, %1, %3 \n" |
593 | " .subsection 2 \n" | ||
594 | "2: b 1b \n" | ||
595 | " .previous \n" | ||
569 | " .set mips0 \n" | 596 | " .set mips0 \n" |
570 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 597 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
571 | : "Ir" (i), "m" (v->counter) | 598 | : "Ir" (i), "m" (v->counter) |
@@ -627,10 +654,13 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
627 | " bltz %0, 1f \n" | 654 | " bltz %0, 1f \n" |
628 | " scd %0, %2 \n" | 655 | " scd %0, %2 \n" |
629 | " .set noreorder \n" | 656 | " .set noreorder \n" |
630 | " beqz %0, 1b \n" | 657 | " beqz %0, 2f \n" |
631 | " dsubu %0, %1, %3 \n" | 658 | " dsubu %0, %1, %3 \n" |
632 | " .set reorder \n" | 659 | " .set reorder \n" |
633 | "1: \n" | 660 | "1: \n" |
661 | " .subsection 2 \n" | ||
662 | "2: b 1b \n" | ||
663 | " .previous \n" | ||
634 | " .set mips0 \n" | 664 | " .set mips0 \n" |
635 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 665 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) |
636 | : "Ir" (i), "m" (v->counter) | 666 | : "Ir" (i), "m" (v->counter) |
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 06445de1324b..06c08228a525 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h | |||
@@ -68,7 +68,10 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
68 | "1: " __LL "%0, %1 # set_bit \n" | 68 | "1: " __LL "%0, %1 # set_bit \n" |
69 | " or %0, %2 \n" | 69 | " or %0, %2 \n" |
70 | " " __SC "%0, %1 \n" | 70 | " " __SC "%0, %1 \n" |
71 | " beqz %0, 1b \n" | 71 | " beqz %0, 2f \n" |
72 | " .subsection 2 \n" | ||
73 | "2: b 1b \n" | ||
74 | " .previous \n" | ||
72 | " .set mips0 \n" | 75 | " .set mips0 \n" |
73 | : "=&r" (temp), "=m" (*m) | 76 | : "=&r" (temp), "=m" (*m) |
74 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 77 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
@@ -116,7 +119,10 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
116 | "1: " __LL "%0, %1 # clear_bit \n" | 119 | "1: " __LL "%0, %1 # clear_bit \n" |
117 | " and %0, %2 \n" | 120 | " and %0, %2 \n" |
118 | " " __SC "%0, %1 \n" | 121 | " " __SC "%0, %1 \n" |
119 | " beqz %0, 1b \n" | 122 | " beqz %0, 2f \n" |
123 | " .subsection 2 \n" | ||
124 | "2: b 1b \n" | ||
125 | " .previous \n" | ||
120 | " .set mips0 \n" | 126 | " .set mips0 \n" |
121 | : "=&r" (temp), "=m" (*m) | 127 | : "=&r" (temp), "=m" (*m) |
122 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); | 128 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); |
@@ -166,7 +172,10 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
166 | "1: " __LL "%0, %1 # change_bit \n" | 172 | "1: " __LL "%0, %1 # change_bit \n" |
167 | " xor %0, %2 \n" | 173 | " xor %0, %2 \n" |
168 | " " __SC "%0, %1 \n" | 174 | " " __SC "%0, %1 \n" |
169 | " beqz %0, 1b \n" | 175 | " beqz %0, 2f \n" |
176 | " .subsection 2 \n" | ||
177 | "2: b 1b \n" | ||
178 | " .previous \n" | ||
170 | " .set mips0 \n" | 179 | " .set mips0 \n" |
171 | : "=&r" (temp), "=m" (*m) | 180 | : "=&r" (temp), "=m" (*m) |
172 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 181 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
@@ -222,8 +231,12 @@ static inline int test_and_set_bit(unsigned long nr, | |||
222 | "1: " __LL "%0, %1 # test_and_set_bit \n" | 231 | "1: " __LL "%0, %1 # test_and_set_bit \n" |
223 | " or %2, %0, %3 \n" | 232 | " or %2, %0, %3 \n" |
224 | " " __SC "%2, %1 \n" | 233 | " " __SC "%2, %1 \n" |
225 | " beqz %2, 1b \n" | 234 | " beqz %2, 2f \n" |
226 | " and %2, %0, %3 \n" | 235 | " and %2, %0, %3 \n" |
236 | " .subsection 2 \n" | ||
237 | "2: b 1b \n" | ||
238 | " nop \n" | ||
239 | " .previous \n" | ||
227 | " .set pop \n" | 240 | " .set pop \n" |
228 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 241 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
229 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 242 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
@@ -290,8 +303,12 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
290 | " or %2, %0, %3 \n" | 303 | " or %2, %0, %3 \n" |
291 | " xor %2, %3 \n" | 304 | " xor %2, %3 \n" |
292 | " " __SC "%2, %1 \n" | 305 | " " __SC "%2, %1 \n" |
293 | " beqz %2, 1b \n" | 306 | " beqz %2, 2f \n" |
294 | " and %2, %0, %3 \n" | 307 | " and %2, %0, %3 \n" |
308 | " .subsection 2 \n" | ||
309 | "2: b 1b \n" | ||
310 | " nop \n" | ||
311 | " .previous \n" | ||
295 | " .set pop \n" | 312 | " .set pop \n" |
296 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 313 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
297 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 314 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
@@ -356,8 +373,12 @@ static inline int test_and_change_bit(unsigned long nr, | |||
356 | "1: " __LL "%0, %1 # test_and_change_bit \n" | 373 | "1: " __LL "%0, %1 # test_and_change_bit \n" |
357 | " xor %2, %0, %3 \n" | 374 | " xor %2, %0, %3 \n" |
358 | " " __SC "\t%2, %1 \n" | 375 | " " __SC "\t%2, %1 \n" |
359 | " beqz %2, 1b \n" | 376 | " beqz %2, 2f \n" |
360 | " and %2, %0, %3 \n" | 377 | " and %2, %0, %3 \n" |
378 | " .subsection 2 \n" | ||
379 | "2: b 1b \n" | ||
380 | " nop \n" | ||
381 | " .previous \n" | ||
361 | " .set pop \n" | 382 | " .set pop \n" |
362 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 383 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
363 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 384 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h index fc3217fc1118..f1755d28a36a 100644 --- a/include/asm-mips/spinlock.h +++ b/include/asm-mips/spinlock.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (C) 1999, 2000, 06 by Ralf Baechle | 6 | * Copyright (C) 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org) |
7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
8 | */ | 8 | */ |
9 | #ifndef _ASM_SPINLOCK_H | 9 | #ifndef _ASM_SPINLOCK_H |
@@ -49,11 +49,18 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) | |||
49 | __asm__ __volatile__( | 49 | __asm__ __volatile__( |
50 | " .set noreorder # __raw_spin_lock \n" | 50 | " .set noreorder # __raw_spin_lock \n" |
51 | "1: ll %1, %2 \n" | 51 | "1: ll %1, %2 \n" |
52 | " bnez %1, 1b \n" | 52 | " bnez %1, 2f \n" |
53 | " li %1, 1 \n" | 53 | " li %1, 1 \n" |
54 | " sc %1, %0 \n" | 54 | " sc %1, %0 \n" |
55 | " beqz %1, 1b \n" | 55 | " beqz %1, 2f \n" |
56 | " nop \n" | 56 | " nop \n" |
57 | " .subsection 2 \n" | ||
58 | "2: ll %1, %2 \n" | ||
59 | " bnez %1, 2b \n" | ||
60 | " li %1, 1 \n" | ||
61 | " b 1b \n" | ||
62 | " nop \n" | ||
63 | " .previous \n" | ||
57 | " .set reorder \n" | 64 | " .set reorder \n" |
58 | : "=m" (lock->lock), "=&r" (tmp) | 65 | : "=m" (lock->lock), "=&r" (tmp) |
59 | : "m" (lock->lock) | 66 | : "m" (lock->lock) |
@@ -99,8 +106,12 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock) | |||
99 | "1: ll %0, %3 \n" | 106 | "1: ll %0, %3 \n" |
100 | " ori %2, %0, 1 \n" | 107 | " ori %2, %0, 1 \n" |
101 | " sc %2, %1 \n" | 108 | " sc %2, %1 \n" |
102 | " beqz %2, 1b \n" | 109 | " beqz %2, 2f \n" |
103 | " andi %2, %0, 1 \n" | 110 | " andi %2, %0, 1 \n" |
111 | " .subsection 2 \n" | ||
112 | "2: b 1b \n" | ||
113 | " nop \n" | ||
114 | " .previous \n" | ||
104 | " .set reorder" | 115 | " .set reorder" |
105 | : "=&r" (temp), "=m" (lock->lock), "=&r" (res) | 116 | : "=&r" (temp), "=m" (lock->lock), "=&r" (res) |
106 | : "m" (lock->lock) | 117 | : "m" (lock->lock) |
@@ -154,11 +165,18 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) | |||
154 | __asm__ __volatile__( | 165 | __asm__ __volatile__( |
155 | " .set noreorder # __raw_read_lock \n" | 166 | " .set noreorder # __raw_read_lock \n" |
156 | "1: ll %1, %2 \n" | 167 | "1: ll %1, %2 \n" |
157 | " bltz %1, 1b \n" | 168 | " bltz %1, 2f \n" |
158 | " addu %1, 1 \n" | 169 | " addu %1, 1 \n" |
159 | " sc %1, %0 \n" | 170 | " sc %1, %0 \n" |
160 | " beqz %1, 1b \n" | 171 | " beqz %1, 1b \n" |
161 | " nop \n" | 172 | " nop \n" |
173 | " .subsection 2 \n" | ||
174 | "2: ll %1, %2 \n" | ||
175 | " bltz %1, 2b \n" | ||
176 | " addu %1, 1 \n" | ||
177 | " b 1b \n" | ||
178 | " nop \n" | ||
179 | " .previous \n" | ||
162 | " .set reorder \n" | 180 | " .set reorder \n" |
163 | : "=m" (rw->lock), "=&r" (tmp) | 181 | : "=m" (rw->lock), "=&r" (tmp) |
164 | : "m" (rw->lock) | 182 | : "m" (rw->lock) |
@@ -192,8 +210,12 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw) | |||
192 | "1: ll %1, %2 \n" | 210 | "1: ll %1, %2 \n" |
193 | " sub %1, 1 \n" | 211 | " sub %1, 1 \n" |
194 | " sc %1, %0 \n" | 212 | " sc %1, %0 \n" |
195 | " beqz %1, 1b \n" | 213 | " beqz %1, 2f \n" |
214 | " nop \n" | ||
215 | " .subsection 2 \n" | ||
216 | "2: b 1b \n" | ||
196 | " nop \n" | 217 | " nop \n" |
218 | " .previous \n" | ||
197 | " .set reorder \n" | 219 | " .set reorder \n" |
198 | : "=m" (rw->lock), "=&r" (tmp) | 220 | : "=m" (rw->lock), "=&r" (tmp) |
199 | : "m" (rw->lock) | 221 | : "m" (rw->lock) |
@@ -222,11 +244,18 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) | |||
222 | __asm__ __volatile__( | 244 | __asm__ __volatile__( |
223 | " .set noreorder # __raw_write_lock \n" | 245 | " .set noreorder # __raw_write_lock \n" |
224 | "1: ll %1, %2 \n" | 246 | "1: ll %1, %2 \n" |
225 | " bnez %1, 1b \n" | 247 | " bnez %1, 2f \n" |
226 | " lui %1, 0x8000 \n" | 248 | " lui %1, 0x8000 \n" |
227 | " sc %1, %0 \n" | 249 | " sc %1, %0 \n" |
228 | " beqz %1, 1b \n" | 250 | " beqz %1, 2f \n" |
251 | " nop \n" | ||
252 | " .subsection 2 \n" | ||
253 | "2: ll %1, %2 \n" | ||
254 | " bnez %1, 2b \n" | ||
255 | " lui %1, 0x8000 \n" | ||
256 | " b 1b \n" | ||
229 | " nop \n" | 257 | " nop \n" |
258 | " .previous \n" | ||
230 | " .set reorder \n" | 259 | " .set reorder \n" |
231 | : "=m" (rw->lock), "=&r" (tmp) | 260 | : "=m" (rw->lock), "=&r" (tmp) |
232 | : "m" (rw->lock) | 261 | : "m" (rw->lock) |
@@ -322,12 +351,15 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) | |||
322 | " bnez %1, 2f \n" | 351 | " bnez %1, 2f \n" |
323 | " lui %1, 0x8000 \n" | 352 | " lui %1, 0x8000 \n" |
324 | " sc %1, %0 \n" | 353 | " sc %1, %0 \n" |
325 | " beqz %1, 1b \n" | 354 | " beqz %1, 3f \n" |
326 | " nop \n" | 355 | " li %2, 1 \n" |
356 | "2: \n" | ||
327 | __WEAK_ORDERING_MB | 357 | __WEAK_ORDERING_MB |
328 | " li %2, 1 \n" | 358 | " .subsection 2 \n" |
359 | "3: b 1b \n" | ||
360 | " li %2, 0 \n" | ||
361 | " .previous \n" | ||
329 | " .set reorder \n" | 362 | " .set reorder \n" |
330 | "2: \n" | ||
331 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 363 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) |
332 | : "m" (rw->lock) | 364 | : "m" (rw->lock) |
333 | : "memory"); | 365 | : "memory"); |
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 5e1289c85ed9..597a3743f6a1 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h | |||
@@ -110,7 +110,10 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | |||
110 | " move %2, %z4 \n" | 110 | " move %2, %z4 \n" |
111 | " .set mips3 \n" | 111 | " .set mips3 \n" |
112 | " sc %2, %1 \n" | 112 | " sc %2, %1 \n" |
113 | " beqz %2, 1b \n" | 113 | " beqz %2, 2f \n" |
114 | " .subsection 2 \n" | ||
115 | "2: b 1b \n" | ||
116 | " .previous \n" | ||
114 | " .set mips0 \n" | 117 | " .set mips0 \n" |
115 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 118 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) |
116 | : "R" (*m), "Jr" (val) | 119 | : "R" (*m), "Jr" (val) |
@@ -155,7 +158,10 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) | |||
155 | "1: lld %0, %3 # xchg_u64 \n" | 158 | "1: lld %0, %3 # xchg_u64 \n" |
156 | " move %2, %z4 \n" | 159 | " move %2, %z4 \n" |
157 | " scd %2, %1 \n" | 160 | " scd %2, %1 \n" |
158 | " beqz %2, 1b \n" | 161 | " beqz %2, 2f \n" |
162 | " .subsection 2 \n" | ||
163 | "2: b 1b \n" | ||
164 | " .previous \n" | ||
159 | " .set mips0 \n" | 165 | " .set mips0 \n" |
160 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 166 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) |
161 | : "R" (*m), "Jr" (val) | 167 | : "R" (*m), "Jr" (val) |
@@ -232,8 +238,11 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old, | |||
232 | " move $1, %z4 \n" | 238 | " move $1, %z4 \n" |
233 | " .set mips3 \n" | 239 | " .set mips3 \n" |
234 | " sc $1, %1 \n" | 240 | " sc $1, %1 \n" |
235 | " beqz $1, 1b \n" | 241 | " beqz $1, 3f \n" |
236 | "2: \n" | 242 | "2: \n" |
243 | " .subsection 2 \n" | ||
244 | "3: b 1b \n" | ||
245 | " .previous \n" | ||
237 | " .set pop \n" | 246 | " .set pop \n" |
238 | : "=&r" (retval), "=R" (*m) | 247 | : "=&r" (retval), "=R" (*m) |
239 | : "R" (*m), "Jr" (old), "Jr" (new) | 248 | : "R" (*m), "Jr" (old), "Jr" (new) |
@@ -283,8 +292,11 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old, | |||
283 | " bne %0, %z3, 2f \n" | 292 | " bne %0, %z3, 2f \n" |
284 | " move $1, %z4 \n" | 293 | " move $1, %z4 \n" |
285 | " scd $1, %1 \n" | 294 | " scd $1, %1 \n" |
286 | " beqz $1, 1b \n" | 295 | " beqz $1, 3f \n" |
287 | "2: \n" | 296 | "2: \n" |
297 | " .subsection 2 \n" | ||
298 | "3: b 1b \n" | ||
299 | " .previous \n" | ||
288 | " .set pop \n" | 300 | " .set pop \n" |
289 | : "=&r" (retval), "=R" (*m) | 301 | : "=&r" (retval), "=R" (*m) |
290 | : "R" (*m), "Jr" (old), "Jr" (new) | 302 | : "R" (*m), "Jr" (old), "Jr" (new) |