lib/util: Add clz32() and clz64().
[sliver-openvswitch.git] / lib / util.c
index 53c3849..76f4cd6 100644 (file)
@@ -848,50 +848,11 @@ english_list_delimiter(size_t index, size_t total)
             : " and ");
 }
 
-/* Given a 32 bit word 'n', calculates floor(log_2('n')).  This is equivalent
- * to finding the bit position of the most significant one bit in 'n'.  It is
- * an error to call this function with 'n' == 0. */
-int
-log_2_floor(uint32_t n)
-{
-    ovs_assert(n);
-
-#if !defined(UINT_MAX) || !defined(UINT32_MAX)
-#error "Someone screwed up the #includes."
-#elif __GNUC__ >= 4 && UINT_MAX == UINT32_MAX
-    return 31 - __builtin_clz(n);
-#else
-    {
-        int log = 0;
-
-#define BIN_SEARCH_STEP(BITS)                   \
-        if (n >= (1 << BITS)) {                 \
-            log += BITS;                        \
-            n >>= BITS;                         \
-        }
-        BIN_SEARCH_STEP(16);
-        BIN_SEARCH_STEP(8);
-        BIN_SEARCH_STEP(4);
-        BIN_SEARCH_STEP(2);
-        BIN_SEARCH_STEP(1);
-#undef BIN_SEARCH_STEP
-        return log;
-    }
-#endif
-}
-
-/* Given a 32 bit word 'n', calculates ceil(log_2('n')).  It is an error to
- * call this function with 'n' == 0. */
-int
-log_2_ceil(uint32_t n)
-{
-    return log_2_floor(n) + !is_pow2(n);
-}
-
 /* Returns the number of trailing 0-bits in 'n'.  Undefined if 'n' == 0. */
 #if __GNUC__ >= 4
 /* Defined inline in util.h. */
 #else
+/* Returns the number of trailing 0-bits in 'n'.  Undefined if 'n' == 0. */
 int
 raw_ctz(uint64_t n)
 {
@@ -914,6 +875,30 @@ raw_ctz(uint64_t n)
 
     return count;
 }
+
+/* Returns the number of leading 0-bits in 'n'.  Undefined if 'n' == 0. */
+int
+raw_clz64(uint64_t n)
+{
+    uint64_t k;
+    int count = 63;
+
+#define CLZ_STEP(X)                             \
+    k = n >> (X);                               \
+    if (k) {                                    \
+        count -= X;                             \
+        n = k;                                  \
+    }
+    CLZ_STEP(32);
+    CLZ_STEP(16);
+    CLZ_STEP(8);
+    CLZ_STEP(4);
+    CLZ_STEP(2);
+    CLZ_STEP(1);
+#undef CLZ_STEP
+
+    return count;
+}
 #endif
 
 /* Returns the number of 1-bits in 'x', between 0 and 32 inclusive. */