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/bitops.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/bitops.h')
-rw-r--r-- | include/asm-mips/bitops.h | 33 |
1 files changed, 27 insertions, 6 deletions
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) |