[sheepdog] [PATCH 13/14] bitops: simplify fls with gcc builtin functions
MORITA Kazutaka
morita.kazutaka at gmail.com
Sat Aug 10 17:58:54 CEST 2013
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
More information about the sheepdog
mailing list