mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-02 02:51:42 +00:00
[wpiutil] Upgrade to LLVM 17.0.1 (#5482)
This commit is contained in:
@@ -25,55 +25,10 @@
|
||||
|
||||
namespace wpi {
|
||||
|
||||
/// The behavior an operation has on an input of 0.
|
||||
enum ZeroBehavior {
|
||||
/// The returned value is undefined.
|
||||
ZB_Undefined,
|
||||
/// The returned value is numeric_limits<T>::max()
|
||||
ZB_Max
|
||||
};
|
||||
|
||||
/// Count number of 0's from the least significant bit to the most
|
||||
/// stopping at the first 1.
|
||||
///
|
||||
/// Only unsigned integral types are allowed.
|
||||
///
|
||||
/// Returns std::numeric_limits<T>::digits on an input of 0.
|
||||
template <typename T> unsigned countTrailingZeros(T Val) {
|
||||
static_assert(std::is_unsigned_v<T>,
|
||||
"Only unsigned integral types are allowed.");
|
||||
return std::countr_zero(Val);
|
||||
}
|
||||
|
||||
/// Count number of 0's from the most significant bit to the least
|
||||
/// stopping at the first 1.
|
||||
///
|
||||
/// Only unsigned integral types are allowed.
|
||||
///
|
||||
/// Returns std::numeric_limits<T>::digits on an input of 0.
|
||||
template <typename T> unsigned countLeadingZeros(T Val) {
|
||||
static_assert(std::is_unsigned_v<T>,
|
||||
"Only unsigned integral types are allowed.");
|
||||
return std::countl_zero(Val);
|
||||
}
|
||||
|
||||
/// Get the index of the first set bit starting from the least
|
||||
/// significant bit.
|
||||
///
|
||||
/// Only unsigned integral types are allowed.
|
||||
///
|
||||
/// \param ZB the behavior on an input of 0.
|
||||
template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
|
||||
if (ZB == ZB_Max && Val == 0)
|
||||
return (std::numeric_limits<T>::max)();
|
||||
|
||||
return std::countr_zero(Val);
|
||||
}
|
||||
|
||||
/// Create a bitmask with the N right-most bits set to 1, and all other
|
||||
/// bits set to 0. Only unsigned types are allowed.
|
||||
template <typename T> T maskTrailingOnes(unsigned N) {
|
||||
static_assert(std::is_unsigned<T>::value, "Invalid type!");
|
||||
static_assert(std::is_unsigned_v<T>, "Invalid type!");
|
||||
const unsigned Bits = CHAR_BIT * sizeof(T);
|
||||
assert(N <= Bits && "Invalid bit index");
|
||||
return N == 0 ? 0 : (T(-1) >> (Bits - N));
|
||||
@@ -97,21 +52,6 @@ template <typename T> T maskLeadingZeros(unsigned N) {
|
||||
return maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
|
||||
}
|
||||
|
||||
/// Get the index of the last set bit starting from the least
|
||||
/// significant bit.
|
||||
///
|
||||
/// Only unsigned integral types are allowed.
|
||||
///
|
||||
/// \param ZB the behavior on an input of 0.
|
||||
template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
|
||||
if (ZB == ZB_Max && Val == 0)
|
||||
return (std::numeric_limits<T>::max)();
|
||||
|
||||
// Use ^ instead of - because both gcc and llvm can remove the associated ^
|
||||
// in the __builtin_clz intrinsic on x86.
|
||||
return std::countl_zero(Val) ^ (std::numeric_limits<T>::digits - 1);
|
||||
}
|
||||
|
||||
/// Macro compressed bit reversal table for 256 bits.
|
||||
///
|
||||
/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
|
||||
@@ -304,42 +244,6 @@ constexpr inline bool isPowerOf2_64(uint64_t Value) {
|
||||
return std::has_single_bit(Value);
|
||||
}
|
||||
|
||||
/// Count the number of ones from the most significant bit to the first
|
||||
/// zero bit.
|
||||
///
|
||||
/// Ex. countLeadingOnes(0xFF0FFF00) == 8.
|
||||
/// Only unsigned integral types are allowed.
|
||||
///
|
||||
/// Returns std::numeric_limits<T>::digits on an input of all ones.
|
||||
template <typename T> unsigned countLeadingOnes(T Value) {
|
||||
static_assert(std::is_unsigned_v<T>,
|
||||
"Only unsigned integral types are allowed.");
|
||||
return std::countl_one<T>(Value);
|
||||
}
|
||||
|
||||
/// Count the number of ones from the least significant bit to the first
|
||||
/// zero bit.
|
||||
///
|
||||
/// Ex. countTrailingOnes(0x00FF00FF) == 8.
|
||||
/// Only unsigned integral types are allowed.
|
||||
///
|
||||
/// Returns std::numeric_limits<T>::digits on an input of all ones.
|
||||
template <typename T> unsigned countTrailingOnes(T Value) {
|
||||
static_assert(std::is_unsigned_v<T>,
|
||||
"Only unsigned integral types are allowed.");
|
||||
return std::countr_one<T>(Value);
|
||||
}
|
||||
|
||||
/// Count the number of set bits in a value.
|
||||
/// Ex. countPopulation(0xF000F000) = 8
|
||||
/// Returns 0 if the word is zero.
|
||||
template <typename T>
|
||||
inline unsigned countPopulation(T Value) {
|
||||
static_assert(std::is_unsigned_v<T>,
|
||||
"Only unsigned integral types are allowed.");
|
||||
return (unsigned)std::popcount(Value);
|
||||
}
|
||||
|
||||
/// Return true if the argument contains a non-empty sequence of ones with the
|
||||
/// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true.
|
||||
/// If true, \p MaskIdx will specify the index of the lowest set bit and \p
|
||||
@@ -403,34 +307,6 @@ inline unsigned Log2_64_Ceil(uint64_t Value) {
|
||||
return static_cast<unsigned>(64 - std::countl_zero(Value - 1));
|
||||
}
|
||||
|
||||
/// This function takes a 64-bit integer and returns the bit equivalent double.
|
||||
inline double BitsToDouble(uint64_t Bits) {
|
||||
static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes");
|
||||
return wpi::bit_cast<double>(Bits);
|
||||
}
|
||||
|
||||
/// This function takes a 32-bit integer and returns the bit equivalent float.
|
||||
inline float BitsToFloat(uint32_t Bits) {
|
||||
static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes");
|
||||
return wpi::bit_cast<float>(Bits);
|
||||
}
|
||||
|
||||
/// This function takes a double and returns the bit equivalent 64-bit integer.
|
||||
/// Note that copying doubles around changes the bits of NaNs on some hosts,
|
||||
/// notably x86, so this routine cannot be used if these bits are needed.
|
||||
inline uint64_t DoubleToBits(double Double) {
|
||||
static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes");
|
||||
return wpi::bit_cast<uint64_t>(Double);
|
||||
}
|
||||
|
||||
/// This function takes a float and returns the bit equivalent 32-bit integer.
|
||||
/// Note that copying floats around changes the bits of NaNs on some hosts,
|
||||
/// notably x86, so this routine cannot be used if these bits are needed.
|
||||
inline uint32_t FloatToBits(float Float) {
|
||||
static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes");
|
||||
return wpi::bit_cast<uint32_t>(Float);
|
||||
}
|
||||
|
||||
/// A and B are either alignments or offsets. Return the minimum alignment that
|
||||
/// may be assumed after adding the two together.
|
||||
constexpr inline uint64_t MinAlign(uint64_t A, uint64_t B) {
|
||||
@@ -454,12 +330,6 @@ constexpr inline uint64_t NextPowerOf2(uint64_t A) {
|
||||
return A + 1;
|
||||
}
|
||||
|
||||
/// Returns the power of two which is less than or equal to the given value.
|
||||
/// Essentially, it is a floor operation across the domain of powers of two.
|
||||
inline uint64_t PowerOf2Floor(uint64_t A) {
|
||||
return std::bit_floor(A);
|
||||
}
|
||||
|
||||
/// Returns the power of two which is greater than or equal to the given value.
|
||||
/// Essentially, it is a ceil operation across the domain of powers of two.
|
||||
inline uint64_t PowerOf2Ceil(uint64_t A) {
|
||||
@@ -567,7 +437,7 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) {
|
||||
/// Subtract two unsigned integers, X and Y, of type T and return the absolute
|
||||
/// value of the result.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_unsigned<T>::value, T> AbsoluteDifference(T X, T Y) {
|
||||
std::enable_if_t<std::is_unsigned_v<T>, T> AbsoluteDifference(T X, T Y) {
|
||||
return X > Y ? (X - Y) : (Y - X);
|
||||
}
|
||||
|
||||
@@ -575,7 +445,7 @@ std::enable_if_t<std::is_unsigned<T>::value, T> AbsoluteDifference(T X, T Y) {
|
||||
/// maximum representable value of T on overflow. ResultOverflowed indicates if
|
||||
/// the result is larger than the maximum representable value of type T.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_unsigned<T>::value, T>
|
||||
std::enable_if_t<std::is_unsigned_v<T>, T>
|
||||
SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
|
||||
bool Dummy;
|
||||
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
|
||||
@@ -604,7 +474,7 @@ std::enable_if_t<std::is_unsigned_v<T>, T> SaturatingAdd(T X, T Y, T Z,
|
||||
/// maximum representable value of T on overflow. ResultOverflowed indicates if
|
||||
/// the result is larger than the maximum representable value of type T.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_unsigned<T>::value, T>
|
||||
std::enable_if_t<std::is_unsigned_v<T>, T>
|
||||
SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
|
||||
bool Dummy;
|
||||
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
|
||||
@@ -650,7 +520,7 @@ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
|
||||
/// overflow. ResultOverflowed indicates if the result is larger than the
|
||||
/// maximum representable value of type T.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_unsigned<T>::value, T>
|
||||
std::enable_if_t<std::is_unsigned_v<T>, T>
|
||||
SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) {
|
||||
bool Dummy;
|
||||
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
|
||||
@@ -669,7 +539,7 @@ extern const float huge_valf;
|
||||
/// Add two signed integers, computing the two's complement truncated result,
|
||||
/// returning true if overflow occurred.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_signed<T>::value, T> AddOverflow(T X, T Y, T &Result) {
|
||||
std::enable_if_t<std::is_signed_v<T>, T> AddOverflow(T X, T Y, T &Result) {
|
||||
#if __has_builtin(__builtin_add_overflow)
|
||||
return __builtin_add_overflow(X, Y, &Result);
|
||||
#else
|
||||
@@ -695,7 +565,7 @@ std::enable_if_t<std::is_signed<T>::value, T> AddOverflow(T X, T Y, T &Result) {
|
||||
/// Subtract two signed integers, computing the two's complement truncated
|
||||
/// result, returning true if an overflow ocurred.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_signed<T>::value, T> SubOverflow(T X, T Y, T &Result) {
|
||||
std::enable_if_t<std::is_signed_v<T>, T> SubOverflow(T X, T Y, T &Result) {
|
||||
#if __has_builtin(__builtin_sub_overflow)
|
||||
return __builtin_sub_overflow(X, Y, &Result);
|
||||
#else
|
||||
@@ -721,7 +591,7 @@ std::enable_if_t<std::is_signed<T>::value, T> SubOverflow(T X, T Y, T &Result) {
|
||||
/// Multiply two signed integers, computing the two's complement truncated
|
||||
/// result, returning true if an overflow ocurred.
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_signed<T>::value, T> MulOverflow(T X, T Y, T &Result) {
|
||||
std::enable_if_t<std::is_signed_v<T>, T> MulOverflow(T X, T Y, T &Result) {
|
||||
// Perform the unsigned multiplication on absolute values.
|
||||
using U = std::make_unsigned_t<T>;
|
||||
const U UX = X < 0 ? (0 - static_cast<U>(X)) : static_cast<U>(X);
|
||||
|
||||
Reference in New Issue
Block a user