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/atomic.h | |
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/atomic.h')
-rw-r--r-- | include/asm-mips/atomic.h | 50 |
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) |