//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file contains some functions that are useful for math stuff. // //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_MATHEXTRAS_H #define LLVM_SUPPORT_MATHEXTRAS_H #include "llvm/Compiler.h" #include #include namespace llvm { /// \brief The behavior an operation has on an input of 0. enum ZeroBehavior { /// \brief The returned value is undefined. ZB_Undefined, /// \brief The returned value is numeric_limits::max() ZB_Max, /// \brief The returned value is numeric_limits::digits ZB_Width }; namespace detail { template struct LeadingZerosCounter { static std::size_t count(T Val, ZeroBehavior) { if (!Val) return std::numeric_limits::digits; // Bisection method. std::size_t ZeroBits = 0; for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { T Tmp = Val >> Shift; if (Tmp) Val = Tmp; else ZeroBits |= Shift; } return ZeroBits; } }; #if __GNUC__ >= 4 || _MSC_VER template struct LeadingZerosCounter { static std::size_t count(T Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 32; #if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_clz(Val); #elif _MSC_VER unsigned long Index; _BitScanReverse(&Index, Val); return Index ^ 31; #endif } }; #if !defined(_MSC_VER) || defined(_M_X64) template struct LeadingZerosCounter { static std::size_t count(T Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 64; #if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_clzll(Val); #elif _MSC_VER unsigned long Index; _BitScanReverse64(&Index, Val); return Index ^ 63; #endif } }; #endif #endif } // namespace detail /// \brief Count number of 0's from the most significant bit to the least /// stopping at the first 1. /// /// Only unsigned integral types are allowed. /// /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// valid arguments. template std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { static_assert(std::numeric_limits::is_integer && !std::numeric_limits::is_signed, "Only unsigned integral types are allowed."); return detail::LeadingZerosCounter::count(Val, ZB); } /// Log2_32 - This function returns the floor log base 2 of the specified value, /// -1 if the value is zero. (32 bit edition.) /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 inline unsigned Log2_32(uint32_t Value) { return 31 - countLeadingZeros(Value); } /// Log2_64 - This function returns the floor log base 2 of the specified value, /// -1 if the value is zero. (64 bit edition.) inline unsigned Log2_64(uint64_t Value) { return 63 - countLeadingZeros(Value); } /// Log2_32_Ceil - This function returns the ceil log base 2 of the specified /// value, 32 if the value is zero. (32 bit edition). /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 inline unsigned Log2_32_Ceil(uint32_t Value) { return 32 - countLeadingZeros(Value - 1); } /// Log2_64_Ceil - This function returns the ceil log base 2 of the specified /// value, 64 if the value is zero. (64 bit edition.) inline unsigned Log2_64_Ceil(uint64_t Value) { return 64 - countLeadingZeros(Value - 1); } /// BitsToDouble - This function takes a 64-bit integer and returns the bit /// equivalent double. inline double BitsToDouble(uint64_t Bits) { union { uint64_t L; double D; } T; T.L = Bits; return T.D; } /// BitsToFloat - This function takes a 32-bit integer and returns the bit /// equivalent float. inline float BitsToFloat(uint32_t Bits) { union { uint32_t I; float F; } T; T.I = Bits; return T.F; } /// DoubleToBits - 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) { union { uint64_t L; double D; } T; T.D = Double; return T.L; } /// FloatToBits - 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) { union { uint32_t I; float F; } T; T.F = Float; return T.I; } /// NextPowerOf2 - Returns the next power of two (in 64-bits) /// that is strictly greater than A. Returns zero on overflow. inline uint64_t NextPowerOf2(uint64_t A) { A |= (A >> 1); A |= (A >> 2); A |= (A >> 4); A |= (A >> 8); A |= (A >> 16); A |= (A >> 32); return A + 1; } } // namespace llvm #endif