diff options
Diffstat (limited to 'include/asm-x86/bitops.h')
-rw-r--r-- | include/asm-x86/bitops.h | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h index ab7635a4acd9..6c5054819719 100644 --- a/include/asm-x86/bitops.h +++ b/include/asm-x86/bitops.h | |||
@@ -28,16 +28,15 @@ | |||
28 | #define BITOP_ADDR(x) "+m" (*(volatile long *) (x)) | 28 | #define BITOP_ADDR(x) "+m" (*(volatile long *) (x)) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #define ADDR BITOP_ADDR(addr) | 31 | #define ADDR BITOP_ADDR(addr) |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * We do the locked ops that don't return the old value as | 34 | * We do the locked ops that don't return the old value as |
35 | * a mask operation on a byte. | 35 | * a mask operation on a byte. |
36 | */ | 36 | */ |
37 | #define IS_IMMEDIATE(nr) \ | 37 | #define IS_IMMEDIATE(nr) (__builtin_constant_p(nr)) |
38 | (__builtin_constant_p(nr)) | 38 | #define CONST_MASK_ADDR(nr, addr) BITOP_ADDR((void *)(addr) + ((nr)>>3)) |
39 | #define CONST_MASK_ADDR BITOP_ADDR(addr + (nr>>3)) | 39 | #define CONST_MASK(nr) (1 << ((nr) & 7)) |
40 | #define CONST_MASK (1 << (nr & 7)) | ||
41 | 40 | ||
42 | /** | 41 | /** |
43 | * set_bit - Atomically set a bit in memory | 42 | * set_bit - Atomically set a bit in memory |
@@ -56,13 +55,17 @@ | |||
56 | */ | 55 | */ |
57 | static inline void set_bit(unsigned int nr, volatile unsigned long *addr) | 56 | static inline void set_bit(unsigned int nr, volatile unsigned long *addr) |
58 | { | 57 | { |
59 | if (IS_IMMEDIATE(nr)) | 58 | if (IS_IMMEDIATE(nr)) { |
60 | asm volatile(LOCK_PREFIX "orb %1,%0" : CONST_MASK_ADDR : "i" (CONST_MASK) : "memory"); | 59 | asm volatile(LOCK_PREFIX "orb %1,%0" |
61 | else | 60 | : CONST_MASK_ADDR(nr, addr) |
62 | asm volatile(LOCK_PREFIX "bts %1,%0" : ADDR : "Ir" (nr) : "memory"); | 61 | : "i" (CONST_MASK(nr)) |
62 | : "memory"); | ||
63 | } else { | ||
64 | asm volatile(LOCK_PREFIX "bts %1,%0" | ||
65 | : BITOP_ADDR(addr) : "Ir" (nr) : "memory"); | ||
66 | } | ||
63 | } | 67 | } |
64 | 68 | ||
65 | |||
66 | /** | 69 | /** |
67 | * __set_bit - Set a bit in memory | 70 | * __set_bit - Set a bit in memory |
68 | * @nr: the bit to set | 71 | * @nr: the bit to set |
@@ -89,10 +92,15 @@ static inline void __set_bit(int nr, volatile unsigned long *addr) | |||
89 | */ | 92 | */ |
90 | static inline void clear_bit(int nr, volatile unsigned long *addr) | 93 | static inline void clear_bit(int nr, volatile unsigned long *addr) |
91 | { | 94 | { |
92 | if (IS_IMMEDIATE(nr)) | 95 | if (IS_IMMEDIATE(nr)) { |
93 | asm volatile(LOCK_PREFIX "andb %1,%0" : CONST_MASK_ADDR : "i" (~CONST_MASK)); | 96 | asm volatile(LOCK_PREFIX "andb %1,%0" |
94 | else | 97 | : CONST_MASK_ADDR(nr, addr) |
95 | asm volatile(LOCK_PREFIX "btr %1,%0" : ADDR : "Ir" (nr)); | 98 | : "i" (~CONST_MASK(nr))); |
99 | } else { | ||
100 | asm volatile(LOCK_PREFIX "btr %1,%0" | ||
101 | : BITOP_ADDR(addr) | ||
102 | : "Ir" (nr)); | ||
103 | } | ||
96 | } | 104 | } |
97 | 105 | ||
98 | /* | 106 | /* |