summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Pettit <jpettit@ovn.org>2019-10-03 09:39:31 -0700
committerJustin Pettit <jpettit@ovn.org>2019-10-03 09:41:03 -0700
commit0ea07c1df3b982cd0517c44668e89bf1872679da (patch)
tree8074a78a70d1c0881ad1fcf485c27a74c451969f
parentaf1883400e0865f7464b679a93c860a38bcff091 (diff)
downloadopenvswitch-ovn-ddlog-patches.tar.gz
Export 'count_1bits' function needed by ddlog.ovn-ddlog-patches
-rw-r--r--lib/util.c50
-rw-r--r--lib/util.h52
2 files changed, 50 insertions, 52 deletions
diff --git a/lib/util.c b/lib/util.c
index 830e14516..7dd681cca 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -1344,7 +1344,38 @@ raw_clz64(uint64_t n)
}
#endif
-#if NEED_COUNT_1BITS_8
+/* unsigned int count_1bits(uint64_t x):
+ *
+ * Returns the number of 1-bits in 'x', between 0 and 64 inclusive. */
+#if UINTPTR_MAX == UINT64_MAX
+unsigned int
+count_1bits(uint64_t x)
+{
+#if (__GNUC__ >= 4 && __POPCNT__) || (defined(__aarch64__) && __GNUC__ >= 7)
+ return __builtin_popcountll(x);
+#elif defined(__aarch64__) && __GNUC__ >= 6
+ return vaddv_u8(vcnt_u8(vcreate_u8(x)));
+#else
+ /* This portable implementation is the fastest one we know of for 64
+ * bits, and about 3x faster than GCC 4.7 __builtin_popcountll(). */
+ const uint64_t h55 = UINT64_C(0x5555555555555555);
+ const uint64_t h33 = UINT64_C(0x3333333333333333);
+ const uint64_t h0F = UINT64_C(0x0F0F0F0F0F0F0F0F);
+ const uint64_t h01 = UINT64_C(0x0101010101010101);
+ x -= (x >> 1) & h55; /* Count of each 2 bits in-place. */
+ x = (x & h33) + ((x >> 2) & h33); /* Count of each 4 bits in-place. */
+ x = (x + (x >> 4)) & h0F; /* Count of each 8 bits in-place. */
+ return (x * h01) >> 56; /* Sum of all bytes. */
+#endif
+}
+#else /* Not 64-bit. */
+#if __GNUC__ >= 4 && __POPCNT__
+unsigned int
+count_1bits_32__(uint32_t x)
+{
+ return __builtin_popcount(x);
+}
+#else
#define INIT1(X) \
((((X) & (1 << 0)) != 0) + \
(((X) & (1 << 1)) != 0) + \
@@ -1364,6 +1395,23 @@ raw_clz64(uint64_t n)
const uint8_t count_1bits_8[256] = {
INIT64(0), INIT64(64), INIT64(128), INIT64(192)
};
+
+static inline unsigned int
+count_1bits_32__(uint32_t x)
+{
+ /* This portable implementation is the fastest one we know of for 32 bits,
+ * and faster than GCC __builtin_popcount(). */
+ return (count_1bits_8[x & 0xff] +
+ count_1bits_8[(x >> 8) & 0xff] +
+ count_1bits_8[(x >> 16) & 0xff] +
+ count_1bits_8[x >> 24]);
+}
+#endif
+static inline unsigned int
+count_1bits(uint64_t x)
+{
+ return count_1bits_32__(x) + count_1bits_32__(x >> 32);
+}
#endif
/* Returns true if the 'n' bytes starting at 'p' are 'byte'. */
diff --git a/lib/util.h b/lib/util.h
index 7ad8758fe..2734d26c5 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -357,57 +357,7 @@ log_2_ceil(uint64_t n)
return log_2_floor(n) + !is_pow2(n);
}
-/* unsigned int count_1bits(uint64_t x):
- *
- * Returns the number of 1-bits in 'x', between 0 and 64 inclusive. */
-#if UINTPTR_MAX == UINT64_MAX
-static inline unsigned int
-count_1bits(uint64_t x)
-{
-#if (__GNUC__ >= 4 && __POPCNT__) || (defined(__aarch64__) && __GNUC__ >= 7)
- return __builtin_popcountll(x);
-#elif defined(__aarch64__) && __GNUC__ >= 6
- return vaddv_u8(vcnt_u8(vcreate_u8(x)));
-#else
- /* This portable implementation is the fastest one we know of for 64
- * bits, and about 3x faster than GCC 4.7 __builtin_popcountll(). */
- const uint64_t h55 = UINT64_C(0x5555555555555555);
- const uint64_t h33 = UINT64_C(0x3333333333333333);
- const uint64_t h0F = UINT64_C(0x0F0F0F0F0F0F0F0F);
- const uint64_t h01 = UINT64_C(0x0101010101010101);
- x -= (x >> 1) & h55; /* Count of each 2 bits in-place. */
- x = (x & h33) + ((x >> 2) & h33); /* Count of each 4 bits in-place. */
- x = (x + (x >> 4)) & h0F; /* Count of each 8 bits in-place. */
- return (x * h01) >> 56; /* Sum of all bytes. */
-#endif
-}
-#else /* Not 64-bit. */
-#if __GNUC__ >= 4 && __POPCNT__
-static inline unsigned int
-count_1bits_32__(uint32_t x)
-{
- return __builtin_popcount(x);
-}
-#else
-#define NEED_COUNT_1BITS_8 1
-extern const uint8_t count_1bits_8[256];
-static inline unsigned int
-count_1bits_32__(uint32_t x)
-{
- /* This portable implementation is the fastest one we know of for 32 bits,
- * and faster than GCC __builtin_popcount(). */
- return (count_1bits_8[x & 0xff] +
- count_1bits_8[(x >> 8) & 0xff] +
- count_1bits_8[(x >> 16) & 0xff] +
- count_1bits_8[x >> 24]);
-}
-#endif
-static inline unsigned int
-count_1bits(uint64_t x)
-{
- return count_1bits_32__(x) + count_1bits_32__(x >> 32);
-}
-#endif
+unsigned int count_1bits(uint64_t x);
/* Returns the rightmost 1-bit in 'x' (e.g. 01011000 => 00001000), or 0 if 'x'
* is 0. */