From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp> Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp> --- include/bitops.h | 90 ++++++------------------------------------------------ 1 file changed, 10 insertions(+), 80 deletions(-) diff --git a/include/bitops.h b/include/bitops.h index 448c1af..c2ff3e7 100644 --- a/include/bitops.h +++ b/include/bitops.h @@ -147,80 +147,6 @@ static inline void clear_bit(unsigned int nr, unsigned long *addr) } /* - * fls - find last (most-significant) bit set - * @x: the word to search - * - * This is defined the same way as ffs. - * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. - */ - -static __always_inline int fls(int x) -{ - int r = 32; - - if (!x) - return 0; - if (!(x & 0xffff0000u)) { - x <<= 16; - r -= 16; - } - if (!(x & 0xff000000u)) { - x <<= 8; - r -= 8; - } - if (!(x & 0xf0000000u)) { - x <<= 4; - r -= 4; - } - if (!(x & 0xc0000000u)) { - x <<= 2; - r -= 2; - } - if (!(x & 0x80000000u)) { - x <<= 1; - r -= 1; - } - return r; -} - -/* - * __fls - find last (most-significant) set bit in a long word - * @word: the word to search - * - * Undefined if no set bit exists, so code should check against 0 first. - */ -static __always_inline unsigned long __fls(unsigned long word) -{ - int num = BITS_PER_LONG - 1; - -#if __SIZEOF_POINTER__ == 8 - if (!(word & (~0ul << 32))) { - num -= 32; - word <<= 32; - } -#endif - if (!(word & (~0ul << (BITS_PER_LONG-16)))) { - num -= 16; - word <<= 16; - } - if (!(word & (~0ul << (BITS_PER_LONG-8)))) { - num -= 8; - word <<= 8; - } - if (!(word & (~0ul << (BITS_PER_LONG-4)))) { - num -= 4; - word <<= 4; - } - if (!(word & (~0ul << (BITS_PER_LONG-2)))) { - num -= 2; - word <<= 2; - } - if (!(word & (~0ul << (BITS_PER_LONG-1)))) - num -= 1; - return num; -} - -/* * fls64 - find last set bit in a 64-bit word * @x: the word to search * @@ -231,23 +157,27 @@ static __always_inline unsigned long __fls(unsigned long word) * set bit if value is nonzero. The last (most significant) bit is * at position 64. */ -#if __SIZEOF_POINTER__ == 4 +#if __SIZEOF_LONG__ == 4 static __always_inline int fls64(uint64_t x) { uint32_t h = x >> 32; + + if (x == 0) + return 0; + if (h) - return fls(h) + 32; - return fls(x); + return 64 - __builtin_clzl(h); + return 32 - __builtin_clzl(x); } -#elif __SIZEOF_POINTER__ == 8 +#elif __SIZEOF_LONG__ == 8 static __always_inline int fls64(uint64_t x) { if (x == 0) return 0; - return __fls(x) + 1; + return 64 - __builtin_clzl(x); } #else -#error __SIZEOF_POINTER__ not 4 or 8 +#error __SIZEOF_LONG__ not 4 or 8 #endif #endif /* __BITOPS_H__ */ -- 1.7.9.5 |