Implement missing functions for 32-bit safe bsf, as well as 64-bit fls and log2.
Signed-off-by: Anatoly Burakov <anatoly.bura...@intel.com> Acked-by: Cristian Dumitrescu <cristian.dumitre...@intel.com> --- Notes: v3: - Added clarification that pos is not checked lib/librte_eal/common/include/rte_common.h | 64 +++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h index d115b175c..6883e5c3b 100644 --- a/lib/librte_eal/common/include/rte_common.h +++ b/lib/librte_eal/common/include/rte_common.h @@ -456,6 +456,30 @@ rte_bsf32(uint32_t v) return (uint32_t)__builtin_ctz(v); } +/** + * Searches the input parameter for the least significant set bit + * (starting from zero). Safe version (checks for input parameter being zero). + * + * @warning ``pos`` must be a valid pointer. It is not checked! + * + * @param v + * The input parameter. + * @param pos + * If ``v`` was not 0, this value will contain position of least significant + * bit within the input parameter. + * @return + * Returns 0 if ``v`` was 0, otherwise returns 1. + */ +static inline int +rte_bsf32_safe(uint64_t v, uint32_t *pos) +{ + if (v == 0) + return 0; + + *pos = rte_bsf32(v); + return 1; +} + /** * Return the rounded-up log2 of a integer. * @@ -473,7 +497,6 @@ rte_log2_u32(uint32_t v) return rte_bsf32(v); } - /** * Return the last (most-significant) bit set. * @@ -515,6 +538,45 @@ rte_bsf64_safe(uint64_t v, uint32_t *pos) return 1; } +/** + * Return the last (most-significant) bit set. + * + * @note The last (most significant) bit is at position 32. + * @note rte_fls_u32(0) = 0, rte_fls_u32(1) = 1, rte_fls_u32(0x80000000) = 32 + * + * @param x + * The input parameter. + * @return + * The last (most-significant) bit set, or 0 if the input is 0. + */ +static inline int +rte_fls_u64(uint64_t x) +{ + return (x == 0) ? 0 : 64 - __builtin_clzll(x); +} + +/** + * Return the rounded-up log2 of a integer. + * + * @param v + * The input parameter. + * @return + * The rounded-up log2 of the input, or 0 if the input is 0. + */ +static inline uint32_t +rte_log2_u64(uint64_t v) +{ + uint32_t pos = 0; + if (v == 0) + return 0; + v = rte_align64pow2(v); + /* TODO: replace with rte_bsf64 when that lands */ + /* we checked for v being 0 already, so pos is always valid */ + rte_bsf64_safe(v, &pos); + return pos; +} + + #ifndef offsetof /** Return the offset of a field in a structure. */ #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) -- 2.17.1