diff --git a/src/core/bitmath_func.cpp b/src/core/bitmath_func.cpp index 600ba5ce69..6026903805 100644 --- a/src/core/bitmath_func.cpp +++ b/src/core/bitmath_func.cpp @@ -62,7 +62,7 @@ uint8 FindFirstBit64(uint64 x) * @param x The value to search * @return The position of the last bit set */ -uint8 FindLastBit(uint64 x) +uint8 FindLastBit64(uint64 x) { if (x == 0) return 0; diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index e082a89bab..bf7e64dad1 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -240,7 +240,32 @@ static inline uint8 FindFirstBit(T value) #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 +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::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. diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 051e9f234b..35ad60813e 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -459,7 +459,7 @@ protected: * integer, so at about 31 bits because of the sign bit, the * least significant bits are removed. */ - int mult_range = FindLastBit(x_axis_offset) + FindLastBit(abs(datapoint)); + int mult_range = FindLastBit(x_axis_offset) + FindLastBit(abs(datapoint)); int reduce_range = std::max(mult_range - 31, 0); /* Handle negative values differently (don't shift sign) */