udp: crash in format_udp_connection
[vpp.git] / src / vppinfra / bitops.h
index ab91b8a..7a4be3c 100644 (file)
 #ifndef included_clib_bitops_h
 #define included_clib_bitops_h
 
-#include <vppinfra/clib.h>
+#define SET_BIT(i)    (1 << i)
+#define GET_BIT(n, i) (n >> i) & 1U
+
+static_always_inline uword
+clear_lowest_set_bit (uword x)
+{
+#ifdef __BMI__
+  return uword_bits > 32 ? _blsr_u64 (x) : _blsr_u32 (x);
+#else
+  return x & (x - 1);
+#endif
+}
+
+static_always_inline uword
+get_lowest_set_bit (uword x)
+{
+#ifdef __BMI__
+  return uword_bits > 32 ? _blsi_u64 (x) : _blsi_u32 (x);
+#else
+  return x & -x;
+#endif
+}
+
+static_always_inline u8
+get_lowest_set_bit_index (uword x)
+{
+  return uword_bits > 32 ? __builtin_ctzll (x) : __builtin_ctz (x);
+}
 
 /* Population count from Hacker's Delight. */
 always_inline uword
 count_set_bits (uword x)
 {
+#ifdef __POPCNT__
+  return uword_bits > 32 ? __builtin_popcountll (x) : __builtin_popcount (x);
+#else
 #if uword_bits == 64
   const uword c1 = 0x5555555555555555;
   const uword c2 = 0x3333333333333333;
@@ -71,8 +101,18 @@ count_set_bits (uword x)
 #endif
 
   return x & (2 * BITS (uword) - 1);
+#endif
 }
 
+#if uword_bits == 64
+#define count_leading_zeros(x) __builtin_clzll (x)
+#else
+#define count_leading_zeros(x) __builtin_clzll (x)
+#endif
+
+#define count_trailing_zeros(x) get_lowest_set_bit_index (x)
+#define log2_first_set(x)      get_lowest_set_bit_index (x)
+
 /* Based on "Hacker's Delight" code from GLS. */
 typedef struct
 {
@@ -155,19 +195,13 @@ next_with_same_number_of_set_bits (uword x)
   return ripple | ones;
 }
 
-#define foreach_set_bit(var,mask,body)                                 \
-do {                                                                   \
-  uword _foreach_set_bit_m_##var = (mask);                             \
-  uword _foreach_set_bit_f_##var;                                      \
-  while (_foreach_set_bit_m_##var != 0)                                        \
-    {                                                                  \
-      _foreach_set_bit_f_##var = first_set (_foreach_set_bit_m_##var); \
-      _foreach_set_bit_m_##var ^= _foreach_set_bit_f_##var;            \
-      (var) = min_log2 (_foreach_set_bit_f_##var);                     \
-      do { body; } while (0);                                          \
-    }                                                                  \
-} while (0)
+#define foreach_set_bit_index(i, v)                                           \
+  for (uword _tmp = (v) + 0 * (uword) (i = get_lowest_set_bit_index (v));     \
+       _tmp;                                                                  \
+       i = get_lowest_set_bit_index (_tmp = clear_lowest_set_bit (_tmp)))
 
+#else
+#warning "already included"
 #endif /* included_clib_bitops_h */
 
 /*