diff options
Diffstat (limited to 'src/vppinfra/bitops.h')
-rw-r--r-- | src/vppinfra/bitops.h | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/src/vppinfra/bitops.h b/src/vppinfra/bitops.h index 04365699f93..15454ca5036 100644 --- a/src/vppinfra/bitops.h +++ b/src/vppinfra/bitops.h @@ -38,18 +38,38 @@ #ifndef included_clib_bitops_h #define included_clib_bitops_h -#include <vppinfra/clib.h> +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__ -#if uword_bits == 64 - return __builtin_popcountll (x); -#else - return __builtin_popcount (x); -#endif + return uword_bits > 32 ? __builtin_popcountll (x) : __builtin_popcount (x); #else #if uword_bits == 64 const uword c1 = 0x5555555555555555; @@ -81,6 +101,15 @@ count_set_bits (uword x) #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 { @@ -163,45 +192,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) - -static_always_inline u64 -reset_lowest_set_bit (u64 x) -{ -#ifdef __BMI__ - return _blsr_u64 (x); -#else - return x & (x - 1); -#endif -} +#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))) -static_always_inline u64 -get_lowest_set_bit (u64 x) -{ -#ifdef __BMI__ - return _blsi_u64 (x); #else - return x & -x; -#endif -} - -static_always_inline u64 -get_lowest_set_bit_index (u64 x) -{ - return __builtin_ctzll (x); -} - +#warning "already included" #endif /* included_clib_bitops_h */ /* |