1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 10:12:45 +01:00

core/bitarithm: provide multiple implementations for bitarithm_lsb()

This commit is contained in:
Kaspar Schleiser 2017-10-06 23:45:25 +02:00
parent ef947831d1
commit 499c1812b2
2 changed files with 42 additions and 16 deletions

View File

@ -21,6 +21,8 @@
#include <stdio.h>
#include "bitarithm.h"
unsigned bitarithm_msb(unsigned v)
{
register unsigned r; // result of log2(v) will go here
@ -43,19 +45,7 @@ unsigned bitarithm_msb(unsigned v)
return r;
}
/*---------------------------------------------------------------------------*/
unsigned bitarithm_lsb(register unsigned v)
{
register unsigned r = 0;
while ((v & 0x01) == 0) {
v >>= 1;
r++;
};
return r;
}
/*---------------------------------------------------------------------------*/
unsigned bitarithm_bits_set(unsigned v)
{
unsigned c; // c accumulates the total bits set in v
@ -66,3 +56,9 @@ unsigned bitarithm_bits_set(unsigned v)
return c;
}
const uint8_t MultiplyDeBruijnBitPosition[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
* 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -20,6 +21,10 @@
#ifndef BITARITHM_H
#define BITARITHM_H
#include <stdint.h>
#include "cpu_conf.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -105,19 +110,44 @@ unsigned bitarithm_msb(unsigned v);
* function will produce an infinite loop
* @return Bit Number
*
* Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
*/
unsigned bitarithm_lsb(register unsigned v);
static inline unsigned bitarithm_lsb(unsigned v);
/**
* @brief Returns the number of bits set in a value
* @param[in] v Input value
* @return Number of set bits
*
* Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
*/
unsigned bitarithm_bits_set(unsigned v);
/* implementations */
static inline unsigned bitarithm_lsb(unsigned v)
#if defined(BITARITHM_LSB_BUILTIN)
{
return __builtin_ffs(v) - 1;
}
#elif defined(BITARITHM_LSB_LOOKUP)
{
/* Source: http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */
extern const uint8_t MultiplyDeBruijnBitPosition[32];
return MultiplyDeBruijnBitPosition[((uint32_t)((v & -v) * 0x077CB531U)) >> 27];
}
#else
{
/* Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious */
unsigned r = 0;
while ((v & 0x01) == 0) {
v >>= 1;
r++;
};
return r;
}
#endif
#ifdef __cplusplus
}
#endif