aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-mips/atomic.h
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-09-27 20:45:21 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-02-13 17:40:50 -0500
commitf65e4fa8e0c6022ad58dc88d1b11b12589ed7f9f (patch)
tree2405e012e079693e0fcfde9ff981c549d6c68a21 /include/asm-mips/atomic.h
parent509cb37e173d4e39cec47238397e91b718730794 (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/atomic.h')
-rw-r--r--include/asm-mips/atomic.h50
1 files changed, 40 insertions, 10 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)