diff options
Diffstat (limited to 'arch/arm/include/asm/bitops.h')
| -rw-r--r-- | arch/arm/include/asm/bitops.h | 58 | 
1 files changed, 45 insertions, 13 deletions
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index e691ec91e4d..56380995f4c 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -25,9 +25,7 @@  #include <linux/compiler.h>  #include <linux/irqflags.h> - -#define smp_mb__before_clear_bit()	smp_mb() -#define smp_mb__after_clear_bit()	smp_mb() +#include <asm/barrier.h>  /*   * These functions are the basis of our bit ops. @@ -254,25 +252,59 @@ static inline int constant_fls(int x)  }  /* - * On ARMv5 and above those functions can be implemented around - * the clz instruction for much better code efficiency. + * On ARMv5 and above those functions can be implemented around the + * clz instruction for much better code efficiency.  __clz returns + * the number of leading zeros, zero input will return 32, and + * 0x80000000 will return 0.   */ +static inline unsigned int __clz(unsigned int x) +{ +	unsigned int ret; + +	asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); + +	return ret; +} +/* + * fls() returns zero if the input is zero, otherwise returns the bit + * position of the last set bit, where the LSB is 1 and MSB is 32. + */  static inline int fls(int x)  { -	int ret; -  	if (__builtin_constant_p(x))  	       return constant_fls(x); -	asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); -       	ret = 32 - ret; -	return ret; +	return 32 - __clz(x); +} + +/* + * __fls() returns the bit position of the last bit set, where the + * LSB is 0 and MSB is 31.  Zero input is undefined. + */ +static inline unsigned long __fls(unsigned long x) +{ +	return fls(x) - 1; +} + +/* + * ffs() returns zero if the input was zero, otherwise returns the bit + * position of the first set bit, where the LSB is 1 and MSB is 32. + */ +static inline int ffs(int x) +{ +	return fls(x & -x); +} + +/* + * __ffs() returns the bit position of the first bit set, where the + * LSB is 0 and MSB is 31.  Zero input is undefined. + */ +static inline unsigned long __ffs(unsigned long x) +{ +	return ffs(x) - 1;  } -#define __fls(x) (fls(x) - 1) -#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) -#define __ffs(x) (ffs(x) - 1)  #define ffz(x) __ffs( ~(x) )  #endif  | 
