Use GCC builtins for bit scanning. The minor benefit is that it is
authorScott Wood <scott@buserror.net>
Tue, 26 Dec 2006 00:58:40 +0000 (18:58 -0600)
committerScott Wood <scott@buserror.net>
Tue, 26 Dec 2006 00:58:40 +0000 (18:58 -0600)
non-arch-specific; the major benefit is that it can be done at
compile-time when the argument is a constant.

include/c/lowlevel/arch-x64/bitops.h
include/c/lowlevel/arch-x86-common/bitops.h [new file with mode: 0644]
include/c/lowlevel/arch-x86/bitops.h
include/c/lowlevel/bitops.h

index e165c6df450c8d7f0afbd7198db85177e964814b..c92b2cd5e78b8f99567c05389bb97aad2089a598 100644 (file)
@@ -1,50 +1,6 @@
-// Bit manipulation functions.  These functions are not privileged.
-
 #ifndef _LL_ARCH_BITOPS_H
 #define _LL_ARCH_BITOPS_H
 
-// Find First (least-significant) Set, counting from 0,
-// undefined if no bits set
-
-static inline int ll_ffs(unsigned long val)
-{
-       unsigned long ret;
-       asm("bsfq %1, %0" : "=r" (ret) : "r" (val));
-       return ret;
-}
-
-// Find Last (most-significant) Set, counting from 0, 
-// undefined if no bits set
-
-static inline int ll_fls(unsigned long val)
-{
-       unsigned long ret;
-       asm("bsrq %1, %0" : "=r" (ret) : "r" (val));
-       return ret;
-}
-
-// As above, but on 64-bit values, regardless of sizeof(long)
-static inline int ll_ffs64(uint64_t val)
-{
-       return ll_ffs(val);
-}
-
-static inline int ll_fls64(uint64_t val)
-{
-       return ll_fls(val);
-}
-
-// Set/Clear the nth bit in a multiword bitmap.  These functions
-// are endian and word-size dependent.
-
-static inline void ll_multiword_set_bit(unsigned long *bitmap, int bit)
-{
-       asm("bts %1, %0" : "=m" (bitmap[0]) : "r" (bit) : "memory");
-}
-
-static inline void ll_multiword_clear_bit(unsigned long *bitmap, int bit)
-{
-       asm("btr %1, %0" : "=m" (bitmap[0]) : "r" (bit) : "memory");
-}
+#include <lowlevel/arch-x86-common/bitops.h>
 
 #endif
diff --git a/include/c/lowlevel/arch-x86-common/bitops.h b/include/c/lowlevel/arch-x86-common/bitops.h
new file mode 100644 (file)
index 0000000..beca262
--- /dev/null
@@ -0,0 +1,19 @@
+// Bit manipulation functions.  These functions are not privileged.
+
+#ifndef _LL_ARCH_X86C_BITOPS_H
+#define _LL_ARCH_X86C_BITOPS_H
+
+// Set/Clear the nth bit in a multiword bitmap.  These functions
+// are endian and word-size dependent.
+
+static inline void ll_multiword_set_bit(unsigned long *bitmap, int bit)
+{
+       asm("bts %1, %0" : "=m" (bitmap[0]) : "r" (bit) : "memory");
+}
+
+static inline void ll_multiword_clear_bit(unsigned long *bitmap, int bit)
+{
+       asm("btr %1, %0" : "=m" (bitmap[0]) : "r" (bit) : "memory");
+}
+
+#endif
index aa608417ffc368b21e42c465d945c6629b8bd909..c92b2cd5e78b8f99567c05389bb97aad2089a598 100644 (file)
@@ -1,52 +1,6 @@
-// Bit manipulation functions.  These functions are not privileged.
-
 #ifndef _LL_ARCH_BITOPS_H
 #define _LL_ARCH_BITOPS_H
 
-// Find First Set, counting from 0, undefined if no bits set
-static inline int ll_ffs(unsigned long val)
-{
-       unsigned long ret;
-       asm("bsfl %1, %0" : "=r" (ret) : "r" (val));
-       return ret;
-}
-
-// Find Last Set, counting from 0, undefined if no bits set
-static inline int ll_fls(unsigned long val)
-{
-       unsigned long ret;
-       asm("bsrl %1, %0" : "=r" (ret) : "r" (val));
-       return ret;
-}
-
-// As above, but on 64-bit values, regardless of sizeof(long)
-static inline int ll_ffs64(uint64_t val)
-{
-       if ((uint32_t)val)
-               return ll_ffs((uint32_t)val);
-       else
-               return ll_ffs((uint32_t)(val >> 32));
-}
-
-static inline int ll_fls64(uint64_t val)
-{
-       if ((uint32_t)(val >> 32))
-               return ll_ffs((uint32_t)(val >> 32));
-       else
-               return ll_ffs((uint32_t)val);
-}
-
-// Set/Clear the nth bit in a multiword bitmap.  These functions
-// are endian and word-size dependent.
-
-static inline void ll_multiword_set_bit(unsigned long *bitmap, int bit)
-{
-       asm("bts %1, %0" : "=m" (bitmap[0]) : "r" (bit) : "memory");
-}
-
-static inline void ll_multiword_clear_bit(unsigned long *bitmap, int bit)
-{
-       asm("btr %1, %0" : "=m" (bitmap[0]) : "r" (bit) : "memory");
-}
+#include <lowlevel/arch-x86-common/bitops.h>
 
 #endif
index 9c3ce7e17f6d07b5af44063915281173e6995803..6aa90292b3bdcc3fb1d8e9542da8d6b830f70d4b 100644 (file)
@@ -7,9 +7,39 @@
 #include <lowlevel/types.h>
 #include _LL_INC(bitops.h)
 
+// Find First (least-significant) Set, counting from 0,
+// undefined if no bits set
+
+static inline int ll_ffs(unsigned long val)
+{
+       return __builtin_ctzl(val);
+}
+
+// Find Last (most-significant) Set, counting from 0, 
+// undefined if no bits set
+
+static inline int ll_fls(unsigned long val)
+{
+       return (sizeof(unsigned long)*8 - 1) ^ __builtin_clzl(val);
+}
+
+// As above, except on 64-bit values regardless of sizeof(long).
+static inline int ll_ffs64(uint64_t val)
+{
+       return __builtin_ctzll(val);
+}
+
+// Find Last (most-significant) Set, counting from 0, 
+// undefined if no bits set
+
+static inline int ll_fls64(unsigned long val)
+{
+       return (sizeof(unsigned long long)*8 - 1) ^ __builtin_clzll(val);
+}
+
 static inline int ll_get_order_round_up(unsigned long val)
 {
-       return val != 1 ? ll_fls(val - 1) + 1 : 0;
+       return val > 1 ? ll_fls(val - 1) + 1 : 0;
 }
 
 static inline int ll_get_order_round_down(unsigned long val)