Move BitUtils.h outside of kernel directory
It is not specific to the kernel Change-Id: I334c39b39d74f61b30215fb5489dec09e318dacd Reviewed-on: https://review.haiku-os.org/c/haiku/+/10049 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
2172f376f8
commit
cf930b7e6c
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, [email protected]
|
||||
*/
|
||||
#ifndef KERNEL_UTIL_BITUTIL_H
|
||||
#define KERNEL_UTIL_BITUTIL_H
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html
|
||||
static inline uint32
|
||||
next_power_of_2(uint32 v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html
|
||||
static inline uint32
|
||||
count_set_bits(uint32 v)
|
||||
{
|
||||
v = v - ((v >> 1) & 0x55555555);
|
||||
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
|
||||
return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
static const int MultiplyDeBruijnBitPosition[32] = {
|
||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
||||
};
|
||||
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
|
||||
return MultiplyDeBruijnBitPosition[(uint32)(v * 0x07C4ACDDU) >> 27];
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
bitmap_shift(T* bits, size_t bitCount, ssize_t shift)
|
||||
{
|
||||
if (shift == 0)
|
||||
return;
|
||||
|
||||
const size_t bitsPerElement = sizeof(T) * 8;
|
||||
const size_t elementsCount = (bitCount + bitsPerElement - 1) / bitsPerElement;
|
||||
const size_t absoluteShift = (shift > 0) ? shift : -shift;
|
||||
const size_t nElements = absoluteShift / bitsPerElement;
|
||||
const size_t nBits = absoluteShift % bitsPerElement;
|
||||
if (nElements != 0) {
|
||||
if (shift > 0) {
|
||||
// "Left" shift.
|
||||
memmove(&bits[nElements], bits, sizeof(T) * (elementsCount - nElements));
|
||||
memset(bits, 0, sizeof(T) * nElements);
|
||||
} else if (shift < 0) {
|
||||
// "Right" shift.
|
||||
memmove(bits, &bits[nElements], sizeof(T) * (elementsCount - nElements));
|
||||
memset(&bits[elementsCount - nElements], 0, sizeof(T) * nElements);
|
||||
}
|
||||
}
|
||||
|
||||
// If the shift was by a multiple of the element size, nothing more to do.
|
||||
if (nBits == 0)
|
||||
return;
|
||||
|
||||
// One set of bits comes from the "current" element and are shifted in the
|
||||
// direction of the shift; the other set comes from the next-processed
|
||||
// element and are shifted in the opposite direction.
|
||||
if (shift > 0) {
|
||||
// "Left" shift.
|
||||
for (ssize_t i = elementsCount - 1; i >= 0; i--) {
|
||||
T low = 0;
|
||||
if (i != 0)
|
||||
low = bits[i - 1] >> (bitsPerElement - nBits);
|
||||
const T high = bits[i] << nBits;
|
||||
bits[i] = low | high;
|
||||
}
|
||||
} else if (shift < 0) {
|
||||
// "Right" shift.
|
||||
for (size_t i = 0; i < elementsCount; i++) {
|
||||
const T low = bits[i] >> nBits;
|
||||
T high = 0;
|
||||
if (i != (elementsCount - 1))
|
||||
high = bits[i + 1] << (bitsPerElement - nBits);
|
||||
bits[i] = low | high;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // KERNEL_UTIL_BITUTIL_H
|
||||
|
||||
Reference in New Issue
Block a user