Use bitmath builtins for FindLastBit

This commit is contained in:
Jonathan G Rennison
2023-08-18 13:38:39 +01:00
parent c49651ae7b
commit 87911bdf47
3 changed files with 28 additions and 3 deletions

View File

@@ -62,7 +62,7 @@ uint8 FindFirstBit64(uint64 x)
* @param x The value to search * @param x The value to search
* @return The position of the last bit set * @return The position of the last bit set
*/ */
uint8 FindLastBit(uint64 x) uint8 FindLastBit64(uint64 x)
{ {
if (x == 0) return 0; if (x == 0) return 0;

View File

@@ -240,7 +240,32 @@ static inline uint8 FindFirstBit(T value)
#endif #endif
} }
uint8 FindLastBit(uint64 x); /**
* Search the last set bit in an integer variable.
*
* @param value The value to search
* @return The position of the last bit set, or 0 when value is 0
*/
template <typename T>
static inline uint8 FindLastBit(T value)
{
static_assert(sizeof(T) <= sizeof(unsigned long long));
#ifdef WITH_BITMATH_BUILTINS
if (value == 0) return 0;
typename std::make_unsigned<T>::type unsigned_value = value;
if (sizeof(T) <= sizeof(unsigned int)) {
return __builtin_clz(1) - __builtin_clz(unsigned_value);
} else if (sizeof(T) == sizeof(unsigned long)) {
return __builtin_clzl(1) - __builtin_clzl(unsigned_value);
} else {
return __builtin_clzll(1) - __builtin_ctzll(unsigned_value);
}
#else
extern uint8 FindLastBit64(uint64 x);
return FindLastBit64(value);
#endif
}
/** /**
* Finds the position of the first non-zero bit in an integer. * Finds the position of the first non-zero bit in an integer.

View File

@@ -459,7 +459,7 @@ protected:
* integer, so at about 31 bits because of the sign bit, the * integer, so at about 31 bits because of the sign bit, the
* least significant bits are removed. * least significant bits are removed.
*/ */
int mult_range = FindLastBit(x_axis_offset) + FindLastBit(abs(datapoint)); int mult_range = FindLastBit<uint64>(x_axis_offset) + FindLastBit<uint64>(abs(datapoint));
int reduce_range = std::max(mult_range - 31, 0); int reduce_range = std::max(mult_range - 31, 0);
/* Handle negative values differently (don't shift sign) */ /* Handle negative values differently (don't shift sign) */