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 |