mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 09:32:44 +01:00
core/bitarithm: use __builtin_clz() for bitarithm_msb()
The `clz` instruction pretty much implements getting the most significant bit in hardware, so use it instead of the software implementation. This reults in both a reduction in code size as in a speedup: master: text data bss dec hex filename 14816 136 2424 17376 43e0 tests/bitarithm_timings/bin/same54-xpro/tests_bitarithm_timings.elf + bitarithm_msb: 3529411 iterations per second this patch: text data bss dec hex filename 14768 136 2424 17328 43b0 tests/bitarithm_timings/bin/same54-xpro/tests_bitarithm_timings.elf + bitarithm_msb: 9230761 iterations per second
This commit is contained in:
parent
52bf3096cf
commit
14144030fa
@ -23,11 +23,9 @@
|
|||||||
|
|
||||||
#include "bitarithm.h"
|
#include "bitarithm.h"
|
||||||
|
|
||||||
unsigned bitarithm_msb(unsigned v)
|
unsigned bitarith_msb_32bit_no_native_clz(unsigned v)
|
||||||
{
|
{
|
||||||
register unsigned r; /* result of log2(v) will go here */
|
register unsigned r; /* result of log2(v) will go here */
|
||||||
|
|
||||||
#if ARCH_32_BIT
|
|
||||||
register unsigned shift;
|
register unsigned shift;
|
||||||
|
|
||||||
/* begin{code-style-ignore} */
|
/* begin{code-style-ignore} */
|
||||||
@ -37,13 +35,6 @@ unsigned bitarithm_msb(unsigned v)
|
|||||||
shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
|
shift = (v > 0x3 ) << 1; v >>= shift; r |= shift;
|
||||||
r |= (v >> 1);
|
r |= (v >> 1);
|
||||||
/* end{code-style-ignore} */
|
/* end{code-style-ignore} */
|
||||||
#else
|
|
||||||
r = 0;
|
|
||||||
while (v >>= 1) { /* unroll for more speed... */
|
|
||||||
r++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
|
* Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
|
||||||
*/
|
*/
|
||||||
unsigned bitarithm_msb(unsigned v);
|
static inline unsigned bitarithm_msb(unsigned v);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the number of the lowest '1' bit in a value
|
* @brief Returns the number of the lowest '1' bit in a value
|
||||||
@ -136,8 +136,33 @@ static inline uint8_t bitarithm_bits_set_u32(uint32_t v)
|
|||||||
uint8_t bitarithm_bits_set_u32(uint32_t v);
|
uint8_t bitarithm_bits_set_u32(uint32_t v);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of the highest '1' bit in a value
|
||||||
|
*
|
||||||
|
* Internal software implementation for 32 bit platforms,
|
||||||
|
* use @see bitarithm_msb in application code.
|
||||||
|
* @param[in] v Input value
|
||||||
|
* @return Bit Number
|
||||||
|
*/
|
||||||
|
unsigned bitarith_msb_32bit_no_native_clz(unsigned v);
|
||||||
|
|
||||||
/* implementations */
|
/* implementations */
|
||||||
|
|
||||||
|
static inline unsigned bitarithm_msb(unsigned v)
|
||||||
|
{
|
||||||
|
#if defined(BITARITHM_HAS_CLZ)
|
||||||
|
return 8 * sizeof(v) - __builtin_clz(v) - 1;
|
||||||
|
#elif ARCH_32_BIT
|
||||||
|
return bitarith_msb_32bit_no_native_clz(v);
|
||||||
|
#else
|
||||||
|
unsigned r = 0;
|
||||||
|
while (v >>= 1) { /* unroll for more speed... */
|
||||||
|
++r;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline unsigned bitarithm_lsb(unsigned v)
|
static inline unsigned bitarithm_lsb(unsigned v)
|
||||||
#if defined(BITARITHM_LSB_BUILTIN)
|
#if defined(BITARITHM_LSB_BUILTIN)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user