kernel/util: Add fls to BitUtils.

Implemented using __builtin_clz where available, otherwise using
an algorithm derived from "Bit Twiddling Hacks" which is similar
to the one ramfs uses. GCC and Clang seem to unroll the loop on
x86 at least (but it doesn't matter there as the builtin exists,
implemented using the "bsr" instruction.)
This commit is contained in:
Augustin Cavalier
2024-09-02 14:16:05 -04:00
parent 31b7065940
commit b973a1b377
2 changed files with 25 additions and 56 deletions
+25
View File
@@ -40,6 +40,31 @@ count_set_bits(uint32 v)
}
static inline uint32
fls(uint32 value)
{
if (value == 0)
return 0;
#if __has_builtin(__builtin_clz)
return ((sizeof(value) * 8) - __builtin_clz(value));
#else
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
static const uint32 masks[] = {
0xaaaaaaaa,
0xcccccccc,
0xf0f0f0f0,
0xff00ff00,
0xffff0000
};
uint32 result = (value & masks[0]) != 0;
for (int i = 4; i > 0; i--)
result |= ((value & masks[i]) != 0) << i;
return result + 1;
#endif
}
static inline uint32
log2(uint32 v)
{