| #ifndef _ASMX86_BITOPS_H_ |
| #define _ASMX86_BITOPS_H_ |
| |
| #ifndef _BITOPS_H_ |
| #error only <bitops.h> can be included directly |
| #endif |
| |
| #ifdef __x86_64__ |
| #define BITS_PER_LONG 64 |
| #else |
| #define BITS_PER_LONG 32 |
| #endif |
| |
| #define HAVE_BUILTIN_FLS 1 |
| |
| /* |
| * Macros to generate condition code outputs from inline assembly, |
| * The output operand must be type "bool". |
| */ |
| #ifdef __GCC_ASM_FLAG_OUTPUTS__ |
| # define CC_SET(c) "\n\t/* output condition code " #c "*/\n" |
| # define CC_OUT(c) "=@cc" #c |
| #else |
| # define CC_SET(c) "\n\tset" #c " %[_cc_" #c "]\n" |
| # define CC_OUT(c) [_cc_ ## c] "=qm" |
| #endif |
| |
| static inline void __clear_bit(int bit, void *__addr) |
| { |
| unsigned long *addr = __addr; |
| |
| __asm__ __volatile__("btr %1, %0" |
| : "+m" (*addr) : "Ir" (bit) : "cc", "memory"); |
| } |
| |
| static inline void __set_bit(int bit, void *__addr) |
| { |
| unsigned long *addr = __addr; |
| |
| __asm__ __volatile__("bts %1, %0" |
| : "+m" (*addr) : "Ir" (bit) : "cc", "memory"); |
| } |
| |
| static inline bool __test_and_clear_bit(int bit, void *__addr) |
| { |
| unsigned long *addr = __addr; |
| bool v; |
| |
| __asm__ __volatile__("btr %2, %1" CC_SET(c) |
| : CC_OUT(c) (v), "+m" (*addr) : "Ir" (bit)); |
| return v; |
| } |
| |
| static inline bool __test_and_set_bit(int bit, void *__addr) |
| { |
| unsigned long *addr = __addr; |
| bool v; |
| |
| __asm__ __volatile__("bts %2, %1" CC_SET(c) |
| : CC_OUT(c) (v), "+m" (*addr) : "Ir" (bit)); |
| return v; |
| } |
| |
| static inline void clear_bit(int bit, void *__addr) |
| { |
| unsigned long *addr = __addr; |
| |
| __asm__ __volatile__("lock; btr %1, %0" |
| : "+m" (*addr) : "Ir" (bit) : "cc", "memory"); |
| } |
| |
| static inline void set_bit(int bit, void *__addr) |
| { |
| unsigned long *addr = __addr; |
| |
| __asm__ __volatile__("lock; bts %1, %0" |
| : "+m" (*addr) : "Ir" (bit) : "cc", "memory"); |
| } |
| |
| static inline bool test_and_clear_bit(int bit, void *__addr) |
| { |
| unsigned long *addr = __addr; |
| bool v; |
| |
| __asm__ __volatile__("lock; btr %2, %1" CC_SET(c) |
| : CC_OUT(c) (v), "+m" (*addr) : "Ir" (bit)); |
| return v; |
| } |
| |
| static inline bool test_and_set_bit(int bit, void *__addr) |
| { |
| unsigned long *addr = __addr; |
| bool v; |
| |
| __asm__ __volatile__("lock; bts %2, %1" CC_SET(c) |
| : CC_OUT(c) (v), "+m" (*addr) : "Ir" (bit)); |
| return v; |
| } |
| |
| #endif |