eal: introduce rte version of fls

The function returns the last (most-significant) bit set.
Added unit testcase to verify rte_fls_u32().

Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
This commit is contained in:
Jerin Jacob 2018-11-07 06:59:03 +00:00 committed by Thomas Monjalon
parent fac66b1295
commit 3a6f2c50b9
2 changed files with 51 additions and 0 deletions

View File

@ -473,6 +473,25 @@ rte_log2_u32(uint32_t v)
return rte_bsf32(v);
}
/**
* 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_u32(uint32_t x)
{
return (x == 0) ? 0 : 32 - __builtin_clz(x);
}
#ifndef offsetof
/** Return the offset of a field in a structure. */
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)

View File

@ -188,6 +188,37 @@ test_log2(void)
return 0;
}
static int
test_fls(void)
{
struct fls_test_vector {
uint32_t arg;
int rc;
};
int expected, rc;
uint32_t i, arg;
const struct fls_test_vector test[] = {
{0x0, 0},
{0x1, 1},
{0x4000, 15},
{0x80000000, 32},
};
for (i = 0; i < RTE_DIM(test); i++) {
arg = test[i].arg;
rc = rte_fls_u32(arg);
expected = test[i].rc;
if (rc != expected) {
printf("Wrong rte_fls_u32(0x%x) rc=%d, expected=%d\n",
arg, rc, expected);
return TEST_FAILED;
}
}
return 0;
}
static int
test_common(void)
{
@ -196,6 +227,7 @@ test_common(void)
ret |= test_macros(0);
ret |= test_misc();
ret |= test_log2();
ret |= test_fls();
return ret;
}