[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