diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /include/llvm/Support/MathExtras.h | |
parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) |
Notes
Diffstat (limited to 'include/llvm/Support/MathExtras.h')
-rw-r--r-- | include/llvm/Support/MathExtras.h | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index a37a16784e2a..b59f21b4998e 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -23,22 +23,30 @@ #include <limits> #include <type_traits> -#ifdef _MSC_VER -#include <intrin.h> -#endif - #ifdef __ANDROID_NDK__ #include <android/api-level.h> #endif +#ifdef _MSC_VER +// Declare these intrinsics manually rather including intrin.h. It's very +// expensive, and MathExtras.h is popular. +// #include <intrin.h> +extern "C" { +unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask); +unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask); +unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask); +unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask); +} +#endif + namespace llvm { -/// \brief The behavior an operation has on an input of 0. +/// The behavior an operation has on an input of 0. enum ZeroBehavior { - /// \brief The returned value is undefined. + /// The returned value is undefined. ZB_Undefined, - /// \brief The returned value is numeric_limits<T>::max() + /// The returned value is numeric_limits<T>::max() ZB_Max, - /// \brief The returned value is numeric_limits<T>::digits + /// The returned value is numeric_limits<T>::digits ZB_Width }; @@ -101,7 +109,7 @@ template <typename T> struct TrailingZerosCounter<T, 8> { #endif } // namespace detail -/// \brief Count number of 0's from the least significant bit to the most +/// Count number of 0's from the least significant bit to the most /// stopping at the first 1. /// /// Only unsigned integral types are allowed. @@ -170,7 +178,7 @@ template <typename T> struct LeadingZerosCounter<T, 8> { #endif } // namespace detail -/// \brief Count number of 0's from the most significant bit to the least +/// Count number of 0's from the most significant bit to the least /// stopping at the first 1. /// /// Only unsigned integral types are allowed. @@ -185,7 +193,7 @@ std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB); } -/// \brief Get the index of the first set bit starting from the least +/// Get the index of the first set bit starting from the least /// significant bit. /// /// Only unsigned integral types are allowed. @@ -199,7 +207,7 @@ template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { return countTrailingZeros(Val, ZB_Undefined); } -/// \brief Create a bitmask with the N right-most bits set to 1, and all other +/// 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!"); @@ -208,25 +216,25 @@ template <typename T> T maskTrailingOnes(unsigned N) { return N == 0 ? 0 : (T(-1) >> (Bits - N)); } -/// \brief Create a bitmask with the N left-most bits set to 1, and all other +/// Create a bitmask with the N left-most bits set to 1, and all other /// bits set to 0. Only unsigned types are allowed. template <typename T> T maskLeadingOnes(unsigned N) { return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N); } -/// \brief Create a bitmask with the N right-most bits set to 0, and all other +/// Create a bitmask with the N right-most bits set to 0, and all other /// bits set to 1. Only unsigned types are allowed. template <typename T> T maskTrailingZeros(unsigned N) { return maskLeadingOnes<T>(CHAR_BIT * sizeof(T) - N); } -/// \brief Create a bitmask with the N left-most bits set to 0, and all other +/// Create a bitmask with the N left-most bits set to 0, and all other /// bits set to 1. Only unsigned types are allowed. template <typename T> T maskLeadingZeros(unsigned N) { return maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N); } -/// \brief Get the index of the last set bit starting from the least +/// Get the index of the last set bit starting from the least /// significant bit. /// /// Only unsigned integral types are allowed. @@ -243,7 +251,7 @@ template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { (std::numeric_limits<T>::digits - 1); } -/// \brief Macro compressed bit reversal table for 256 bits. +/// Macro compressed bit reversal table for 256 bits. /// /// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable static const unsigned char BitReverseTable256[256] = { @@ -256,7 +264,7 @@ static const unsigned char BitReverseTable256[256] = { #undef R6 }; -/// \brief Reverse the bits in \p Val. +/// Reverse the bits in \p Val. template <typename T> T reverseBits(T Val) { unsigned char in[sizeof(Val)]; @@ -442,7 +450,7 @@ inline uint64_t ByteSwap_64(uint64_t Value) { return sys::SwapByteOrder_64(Value); } -/// \brief Count the number of ones from the most significant bit to the first +/// Count the number of ones from the most significant bit to the first /// zero bit. /// /// Ex. countLeadingOnes(0xFF0FFF00) == 8. @@ -455,10 +463,10 @@ std::size_t countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) { static_assert(std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, "Only unsigned integral types are allowed."); - return countLeadingZeros(~Value, ZB); + return countLeadingZeros<T>(~Value, ZB); } -/// \brief Count the number of ones from the least significant bit to the first +/// Count the number of ones from the least significant bit to the first /// zero bit. /// /// Ex. countTrailingOnes(0x00FF00FF) == 8. @@ -471,7 +479,7 @@ std::size_t countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) { static_assert(std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, "Only unsigned integral types are allowed."); - return countTrailingZeros(~Value, ZB); + return countTrailingZeros<T>(~Value, ZB); } namespace detail { @@ -505,7 +513,7 @@ template <typename T> struct PopulationCounter<T, 8> { }; } // namespace detail -/// \brief Count the number of set bits in a value. +/// Count the number of set bits in a value. /// Ex. countPopulation(0xF000F000) = 8 /// Returns 0 if the word is zero. template <typename T> @@ -608,7 +616,7 @@ constexpr inline uint64_t MinAlign(uint64_t A, uint64_t B) { return (A | B) & (1 + ~(A | B)); } -/// \brief Aligns \c Addr to \c Alignment bytes, rounding up. +/// Aligns \c Addr to \c Alignment bytes, rounding up. /// /// Alignment should be a power of two. This method rounds up, so /// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8. @@ -621,7 +629,7 @@ inline uintptr_t alignAddr(const void *Addr, size_t Alignment) { return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1)); } -/// \brief Returns the necessary adjustment for aligning \c Ptr to \c Alignment +/// Returns the necessary adjustment for aligning \c Ptr to \c Alignment /// bytes, rounding up. inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) { return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr; |