From 0ee140fb69ec924fe5280c1ceaa82c7a3d8f4223 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 21 Aug 2012 10:47:22 -0700 Subject: [PATCH] util: New function raw_ctz(). This will acquire a user in an upcoming commit. Signed-off-by: Ben Pfaff --- lib/util.c | 42 +++++++++++++++++++----------------------- lib/util.h | 25 ++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/lib/util.c b/lib/util.c index 256421a6d..c90d556c3 100644 --- a/lib/util.c +++ b/lib/util.c @@ -790,38 +790,34 @@ log_2_ceil(uint32_t n) return log_2_floor(n) + !IS_POW2(n); } -/* Returns the number of trailing 0-bits in 'n', or 32 if 'n' is 0. */ -int -ctz(uint32_t n) -{ - if (!n) { - return 32; - } else { +/* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */ #if !defined(UINT_MAX) || !defined(UINT32_MAX) #error "Someone screwed up the #includes." #elif __GNUC__ >= 4 && UINT_MAX == UINT32_MAX - return __builtin_ctz(n); +/* Defined inline in util.h. */ #else - unsigned int k; - int count = 31; +static int +raw_ctz(uint32_t n) +{ + unsigned int k; + int count = 31; #define CTZ_STEP(X) \ - k = n << (X); \ - if (k) { \ - count -= X; \ - n = k; \ - } - CTZ_STEP(16); - CTZ_STEP(8); - CTZ_STEP(4); - CTZ_STEP(2); - CTZ_STEP(1); + k = n << (X); \ + if (k) { \ + count -= X; \ + n = k; \ + } + CTZ_STEP(16); + CTZ_STEP(8); + CTZ_STEP(4); + CTZ_STEP(2); + CTZ_STEP(1); #undef CTZ_STEP - return count; -#endif - } + return count; } +#endif /* Returns the number of 1-bits in 'x', between 0 and 32 inclusive. */ int diff --git a/lib/util.h b/lib/util.h index a8d866573..a1f4bd740 100644 --- a/lib/util.h +++ b/lib/util.h @@ -242,9 +242,32 @@ char *xreadlink(const char *filename); char *follow_symlinks(const char *filename); void ignore(bool x OVS_UNUSED); + +/* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. + * + * This compiles to a single machine instruction ("bsf") with GCC on x86. */ +#if !defined(UINT_MAX) || !defined(UINT32_MAX) +#error "Someone screwed up the #includes." +#elif __GNUC__ >= 4 && UINT_MAX == UINT32_MAX +static inline int +raw_ctz(uint32_t n) +{ + return __builtin_ctz(n); +} +#else +/* Defined in util.c. */ +int raw_ctz(uint32_t n); +#endif + +/* Returns the number of trailing 0-bits in 'n', or 32 if 'n' is 0. */ +static inline int +ctz(uint32_t n) +{ + return n ? raw_ctz(n) : 32; +} + int log_2_floor(uint32_t); int log_2_ceil(uint32_t); -int ctz(uint32_t); int popcount(uint32_t); bool is_all_zeros(const uint8_t *, size_t); -- 2.43.0