diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-01-21 22:26:51 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-01-21 22:26:51 +0100 |
commit | 857989a7fdd2f6de42272578b8aaa413ed6e63e4 (patch) | |
tree | 21c941d63000fdaa0ea32d34087b53d41b5919f8 /arch/arm/include | |
parent | Merge branches 'amba', 'fixes', 'kees', 'misc' and 'unstable/sa11x0' into for... (diff) | |
parent | Merge branch 'for_3.14/arm-no-bootmem' of git://git.kernel.org/pub/scm/linux/... (diff) | |
download | linux-857989a7fdd2f6de42272578b8aaa413ed6e63e4.tar.xz linux-857989a7fdd2f6de42272578b8aaa413ed6e63e4.zip |
Merge branch 'devel-stable' into for-next
Diffstat (limited to 'arch/arm/include')
-rw-r--r-- | arch/arm/include/asm/bitops.h | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index e691ec91e4d3..b2e298a90d76 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -254,25 +254,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 |