diff options
Diffstat (limited to 'include/asm-x86/bitops.h')
| -rw-r--r-- | include/asm-x86/bitops.h | 54 |
1 files changed, 24 insertions, 30 deletions
diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h index 1a23ce1a5697..1ae7b270a1ef 100644 --- a/include/asm-x86/bitops.h +++ b/include/asm-x86/bitops.h | |||
| @@ -23,10 +23,13 @@ | |||
| 23 | #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) | 23 | #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) |
| 24 | /* Technically wrong, but this avoids compilation errors on some gcc | 24 | /* Technically wrong, but this avoids compilation errors on some gcc |
| 25 | versions. */ | 25 | versions. */ |
| 26 | #define ADDR "=m" (*(volatile long *) addr) | 26 | #define ADDR "=m" (*(volatile long *)addr) |
| 27 | #define BIT_ADDR "=m" (((volatile int *)addr)[nr >> 5]) | ||
| 27 | #else | 28 | #else |
| 28 | #define ADDR "+m" (*(volatile long *) addr) | 29 | #define ADDR "+m" (*(volatile long *) addr) |
| 30 | #define BIT_ADDR "+m" (((volatile int *)addr)[nr >> 5]) | ||
| 29 | #endif | 31 | #endif |
| 32 | #define BASE_ADDR "m" (*(volatile int *)addr) | ||
| 30 | 33 | ||
| 31 | /** | 34 | /** |
| 32 | * set_bit - Atomically set a bit in memory | 35 | * set_bit - Atomically set a bit in memory |
| @@ -45,9 +48,7 @@ | |||
| 45 | */ | 48 | */ |
| 46 | static inline void set_bit(int nr, volatile void *addr) | 49 | static inline void set_bit(int nr, volatile void *addr) |
| 47 | { | 50 | { |
| 48 | asm volatile(LOCK_PREFIX "bts %1,%0" | 51 | asm volatile(LOCK_PREFIX "bts %1,%0" : ADDR : "Ir" (nr) : "memory"); |
| 49 | : ADDR | ||
| 50 | : "Ir" (nr) : "memory"); | ||
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | /** | 54 | /** |
| @@ -79,9 +80,7 @@ static inline void __set_bit(int nr, volatile void *addr) | |||
| 79 | */ | 80 | */ |
| 80 | static inline void clear_bit(int nr, volatile void *addr) | 81 | static inline void clear_bit(int nr, volatile void *addr) |
| 81 | { | 82 | { |
| 82 | asm volatile(LOCK_PREFIX "btr %1,%0" | 83 | asm volatile(LOCK_PREFIX "btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR); |
| 83 | : ADDR | ||
| 84 | : "Ir" (nr)); | ||
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | /* | 86 | /* |
| @@ -100,7 +99,7 @@ static inline void clear_bit_unlock(unsigned nr, volatile void *addr) | |||
| 100 | 99 | ||
| 101 | static inline void __clear_bit(int nr, volatile void *addr) | 100 | static inline void __clear_bit(int nr, volatile void *addr) |
| 102 | { | 101 | { |
| 103 | asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); | 102 | asm volatile("btr %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR); |
| 104 | } | 103 | } |
| 105 | 104 | ||
| 106 | /* | 105 | /* |
| @@ -135,7 +134,7 @@ static inline void __clear_bit_unlock(unsigned nr, volatile void *addr) | |||
| 135 | */ | 134 | */ |
| 136 | static inline void __change_bit(int nr, volatile void *addr) | 135 | static inline void __change_bit(int nr, volatile void *addr) |
| 137 | { | 136 | { |
| 138 | asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); | 137 | asm volatile("btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR); |
| 139 | } | 138 | } |
| 140 | 139 | ||
| 141 | /** | 140 | /** |
| @@ -149,8 +148,7 @@ static inline void __change_bit(int nr, volatile void *addr) | |||
| 149 | */ | 148 | */ |
| 150 | static inline void change_bit(int nr, volatile void *addr) | 149 | static inline void change_bit(int nr, volatile void *addr) |
| 151 | { | 150 | { |
| 152 | asm volatile(LOCK_PREFIX "btc %1,%0" | 151 | asm volatile(LOCK_PREFIX "btc %1,%2" : BIT_ADDR : "Ir" (nr), BASE_ADDR); |
| 153 | : ADDR : "Ir" (nr)); | ||
| 154 | } | 152 | } |
| 155 | 153 | ||
| 156 | /** | 154 | /** |
| @@ -166,9 +164,7 @@ static inline int test_and_set_bit(int nr, volatile void *addr) | |||
| 166 | int oldbit; | 164 | int oldbit; |
| 167 | 165 | ||
| 168 | asm volatile(LOCK_PREFIX "bts %2,%1\n\t" | 166 | asm volatile(LOCK_PREFIX "bts %2,%1\n\t" |
| 169 | "sbb %0,%0" | 167 | "sbb %0,%0" : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); |
| 170 | : "=r" (oldbit), ADDR | ||
| 171 | : "Ir" (nr) : "memory"); | ||
| 172 | 168 | ||
| 173 | return oldbit; | 169 | return oldbit; |
| 174 | } | 170 | } |
| @@ -198,10 +194,9 @@ static inline int __test_and_set_bit(int nr, volatile void *addr) | |||
| 198 | { | 194 | { |
| 199 | int oldbit; | 195 | int oldbit; |
| 200 | 196 | ||
| 201 | asm("bts %2,%1\n\t" | 197 | asm volatile("bts %2,%3\n\t" |
| 202 | "sbb %0,%0" | 198 | "sbb %0,%0" |
| 203 | : "=r" (oldbit), ADDR | 199 | : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR); |
| 204 | : "Ir" (nr)); | ||
| 205 | return oldbit; | 200 | return oldbit; |
| 206 | } | 201 | } |
| 207 | 202 | ||
| @@ -219,8 +214,7 @@ static inline int test_and_clear_bit(int nr, volatile void *addr) | |||
| 219 | 214 | ||
| 220 | asm volatile(LOCK_PREFIX "btr %2,%1\n\t" | 215 | asm volatile(LOCK_PREFIX "btr %2,%1\n\t" |
| 221 | "sbb %0,%0" | 216 | "sbb %0,%0" |
| 222 | : "=r" (oldbit), ADDR | 217 | : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); |
| 223 | : "Ir" (nr) : "memory"); | ||
| 224 | 218 | ||
| 225 | return oldbit; | 219 | return oldbit; |
| 226 | } | 220 | } |
| @@ -238,10 +232,9 @@ static inline int __test_and_clear_bit(int nr, volatile void *addr) | |||
| 238 | { | 232 | { |
| 239 | int oldbit; | 233 | int oldbit; |
| 240 | 234 | ||
| 241 | asm volatile("btr %2,%1\n\t" | 235 | asm volatile("btr %2,%3\n\t" |
| 242 | "sbb %0,%0" | 236 | "sbb %0,%0" |
| 243 | : "=r" (oldbit), ADDR | 237 | : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR); |
| 244 | : "Ir" (nr)); | ||
| 245 | return oldbit; | 238 | return oldbit; |
| 246 | } | 239 | } |
| 247 | 240 | ||
| @@ -250,10 +243,9 @@ static inline int __test_and_change_bit(int nr, volatile void *addr) | |||
| 250 | { | 243 | { |
| 251 | int oldbit; | 244 | int oldbit; |
| 252 | 245 | ||
| 253 | asm volatile("btc %2,%1\n\t" | 246 | asm volatile("btc %2,%3\n\t" |
| 254 | "sbb %0,%0" | 247 | "sbb %0,%0" |
| 255 | : "=r" (oldbit), ADDR | 248 | : "=r" (oldbit), BIT_ADDR : "Ir" (nr), BASE_ADDR); |
| 256 | : "Ir" (nr) : "memory"); | ||
| 257 | 249 | ||
| 258 | return oldbit; | 250 | return oldbit; |
| 259 | } | 251 | } |
| @@ -272,8 +264,7 @@ static inline int test_and_change_bit(int nr, volatile void *addr) | |||
| 272 | 264 | ||
| 273 | asm volatile(LOCK_PREFIX "btc %2,%1\n\t" | 265 | asm volatile(LOCK_PREFIX "btc %2,%1\n\t" |
| 274 | "sbb %0,%0" | 266 | "sbb %0,%0" |
| 275 | : "=r" (oldbit), ADDR | 267 | : "=r" (oldbit), ADDR : "Ir" (nr) : "memory"); |
| 276 | : "Ir" (nr) : "memory"); | ||
| 277 | 268 | ||
| 278 | return oldbit; | 269 | return oldbit; |
| 279 | } | 270 | } |
| @@ -288,10 +279,11 @@ static inline int variable_test_bit(int nr, volatile const void *addr) | |||
| 288 | { | 279 | { |
| 289 | int oldbit; | 280 | int oldbit; |
| 290 | 281 | ||
| 291 | asm volatile("bt %2,%1\n\t" | 282 | asm volatile("bt %2,%3\n\t" |
| 292 | "sbb %0,%0" | 283 | "sbb %0,%0" |
| 293 | : "=r" (oldbit) | 284 | : "=r" (oldbit) |
| 294 | : "m" (*(unsigned long *)addr), "Ir" (nr)); | 285 | : "m" (((volatile const int *)addr)[nr >> 5]), |
| 286 | "Ir" (nr), BASE_ADDR); | ||
| 295 | 287 | ||
| 296 | return oldbit; | 288 | return oldbit; |
| 297 | } | 289 | } |
| @@ -310,6 +302,8 @@ static int test_bit(int nr, const volatile unsigned long *addr); | |||
| 310 | constant_test_bit((nr),(addr)) : \ | 302 | constant_test_bit((nr),(addr)) : \ |
| 311 | variable_test_bit((nr),(addr))) | 303 | variable_test_bit((nr),(addr))) |
| 312 | 304 | ||
| 305 | #undef BASE_ADDR | ||
| 306 | #undef BIT_ADDR | ||
| 313 | #undef ADDR | 307 | #undef ADDR |
| 314 | 308 | ||
| 315 | #ifdef CONFIG_X86_32 | 309 | #ifdef CONFIG_X86_32 |
