diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-mips/bitops.h | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 06c08228a525..89436b96ad66 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.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) 1994 - 1997, 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org) | 6 | * Copyright (c) 1994 - 1997, 99, 2000, 06, 07 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_BITOPS_H | 9 | #ifndef _ASM_BITOPS_H |
| @@ -24,11 +24,15 @@ | |||
| 24 | #define SZLONG_MASK 31UL | 24 | #define SZLONG_MASK 31UL |
| 25 | #define __LL "ll " | 25 | #define __LL "ll " |
| 26 | #define __SC "sc " | 26 | #define __SC "sc " |
| 27 | #define __INS "ins " | ||
| 28 | #define __EXT "ext " | ||
| 27 | #elif (_MIPS_SZLONG == 64) | 29 | #elif (_MIPS_SZLONG == 64) |
| 28 | #define SZLONG_LOG 6 | 30 | #define SZLONG_LOG 6 |
| 29 | #define SZLONG_MASK 63UL | 31 | #define SZLONG_MASK 63UL |
| 30 | #define __LL "lld " | 32 | #define __LL "lld " |
| 31 | #define __SC "scd " | 33 | #define __SC "scd " |
| 34 | #define __INS "dins " | ||
| 35 | #define __EXT "dext " | ||
| 32 | #endif | 36 | #endif |
| 33 | 37 | ||
| 34 | /* | 38 | /* |
| @@ -62,6 +66,19 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 62 | " .set mips0 \n" | 66 | " .set mips0 \n" |
| 63 | : "=&r" (temp), "=m" (*m) | 67 | : "=&r" (temp), "=m" (*m) |
| 64 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 68 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
| 69 | #ifdef CONFIG_CPU_MIPSR2 | ||
| 70 | } else if (__builtin_constant_p(nr)) { | ||
| 71 | __asm__ __volatile__( | ||
| 72 | "1: " __LL "%0, %1 # set_bit \n" | ||
| 73 | " " __INS "%0, %4, %2, 1 \n" | ||
| 74 | " " __SC "%0, %1 \n" | ||
| 75 | " beqz %0, 2f \n" | ||
| 76 | " .subsection 2 \n" | ||
| 77 | "2: b 1b \n" | ||
| 78 | " .previous \n" | ||
| 79 | : "=&r" (temp), "=m" (*m) | ||
| 80 | : "ir" (nr & SZLONG_MASK), "m" (*m), "r" (~0)); | ||
| 81 | #endif /* CONFIG_CPU_MIPSR2 */ | ||
| 65 | } else if (cpu_has_llsc) { | 82 | } else if (cpu_has_llsc) { |
| 66 | __asm__ __volatile__( | 83 | __asm__ __volatile__( |
| 67 | " .set mips3 \n" | 84 | " .set mips3 \n" |
| @@ -113,6 +130,19 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 113 | " .set mips0 \n" | 130 | " .set mips0 \n" |
| 114 | : "=&r" (temp), "=m" (*m) | 131 | : "=&r" (temp), "=m" (*m) |
| 115 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); | 132 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); |
| 133 | #ifdef CONFIG_CPU_MIPSR2 | ||
| 134 | } else if (__builtin_constant_p(nr)) { | ||
| 135 | __asm__ __volatile__( | ||
| 136 | "1: " __LL "%0, %1 # clear_bit \n" | ||
| 137 | " " __INS "%0, $0, %2, 1 \n" | ||
| 138 | " " __SC "%0, %1 \n" | ||
| 139 | " beqz %0, 2f \n" | ||
| 140 | " .subsection 2 \n" | ||
| 141 | "2: b 1b \n" | ||
| 142 | " .previous \n" | ||
| 143 | : "=&r" (temp), "=m" (*m) | ||
| 144 | : "ir" (nr & SZLONG_MASK), "m" (*m)); | ||
| 145 | #endif /* CONFIG_CPU_MIPSR2 */ | ||
| 116 | } else if (cpu_has_llsc) { | 146 | } else if (cpu_has_llsc) { |
| 117 | __asm__ __volatile__( | 147 | __asm__ __volatile__( |
| 118 | " .set mips3 \n" | 148 | " .set mips3 \n" |
| @@ -291,6 +321,26 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 291 | : "memory"); | 321 | : "memory"); |
| 292 | 322 | ||
| 293 | return res != 0; | 323 | return res != 0; |
| 324 | #ifdef CONFIG_CPU_MIPSR2 | ||
| 325 | } else if (__builtin_constant_p(nr)) { | ||
| 326 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | ||
| 327 | unsigned long temp, res; | ||
| 328 | |||
| 329 | __asm__ __volatile__( | ||
| 330 | "1: " __LL "%0, %1 # test_and_clear_bit \n" | ||
| 331 | " " __EXT "%2, %0, %3, 1 \n" | ||
| 332 | " " __INS "%0, $0, %3, 1 \n" | ||
| 333 | " " __SC "%0, %1 \n" | ||
| 334 | " beqz %0, 2f \n" | ||
| 335 | " .subsection 2 \n" | ||
| 336 | "2: b 1b \n" | ||
| 337 | " .previous \n" | ||
| 338 | : "=&r" (temp), "=m" (*m), "=&r" (res) | ||
| 339 | : "ri" (nr & SZLONG_MASK), "m" (*m) | ||
| 340 | : "memory"); | ||
| 341 | |||
| 342 | return res; | ||
| 343 | #endif | ||
| 294 | } else if (cpu_has_llsc) { | 344 | } else if (cpu_has_llsc) { |
| 295 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 345 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| 296 | unsigned long temp, res; | 346 | unsigned long temp, res; |
