Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- llvm/ADT/bit.h - C++20 <bit> ----------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// This file implements the C++20 <bit> header.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_ADT_BIT_H
  15. #define LLVM_ADT_BIT_H
  16.  
  17. #include "llvm/Support/Compiler.h"
  18. #include <cstdint>
  19. #include <limits>
  20. #include <type_traits>
  21.  
  22. #if !__has_builtin(__builtin_bit_cast)
  23. #include <cstring>
  24. #endif
  25.  
  26. #if defined(_MSC_VER) && !defined(_DEBUG)
  27. #include <cstdlib>  // for _byteswap_{ushort,ulong,uint64}
  28. #endif
  29.  
  30. #ifdef _MSC_VER
  31. // Declare these intrinsics manually rather including intrin.h. It's very
  32. // expensive, and bit.h is popular via MathExtras.h.
  33. // #include <intrin.h>
  34. extern "C" {
  35. unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask);
  36. unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask);
  37. unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask);
  38. unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask);
  39. }
  40. #endif
  41.  
  42. namespace llvm {
  43.  
  44. // This implementation of bit_cast is different from the C++20 one in two ways:
  45. //  - It isn't constexpr because that requires compiler support.
  46. //  - It requires trivially-constructible To, to avoid UB in the implementation.
  47. template <
  48.     typename To, typename From,
  49.     typename = std::enable_if_t<sizeof(To) == sizeof(From)>,
  50.     typename = std::enable_if_t<std::is_trivially_constructible<To>::value>,
  51.     typename = std::enable_if_t<std::is_trivially_copyable<To>::value>,
  52.     typename = std::enable_if_t<std::is_trivially_copyable<From>::value>>
  53. [[nodiscard]] inline To bit_cast(const From &from) noexcept {
  54. #if __has_builtin(__builtin_bit_cast)
  55.   return __builtin_bit_cast(To, from);
  56. #else
  57.   To to;
  58.   std::memcpy(&to, &from, sizeof(To));
  59.   return to;
  60. #endif
  61. }
  62.  
  63. /// Reverses the bytes in the given integer value V.
  64. template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
  65. [[nodiscard]] constexpr T byteswap(T V) noexcept {
  66.   if constexpr (sizeof(T) == 1) {
  67.     return V;
  68.   } else if constexpr (sizeof(T) == 2) {
  69.     uint16_t UV = V;
  70. #if defined(_MSC_VER) && !defined(_DEBUG)
  71.     // The DLL version of the runtime lacks these functions (bug!?), but in a
  72.     // release build they're replaced with BSWAP instructions anyway.
  73.     return _byteswap_ushort(UV);
  74. #else
  75.     uint16_t Hi = UV << 8;
  76.     uint16_t Lo = UV >> 8;
  77.     return Hi | Lo;
  78. #endif
  79.   } else if constexpr (sizeof(T) == 4) {
  80.     uint32_t UV = V;
  81. #if __has_builtin(__builtin_bswap32)
  82.     return __builtin_bswap32(UV);
  83. #elif defined(_MSC_VER) && !defined(_DEBUG)
  84.     return _byteswap_ulong(UV);
  85. #else
  86.     uint32_t Byte0 = UV & 0x000000FF;
  87.     uint32_t Byte1 = UV & 0x0000FF00;
  88.     uint32_t Byte2 = UV & 0x00FF0000;
  89.     uint32_t Byte3 = UV & 0xFF000000;
  90.     return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
  91. #endif
  92.   } else if constexpr (sizeof(T) == 8) {
  93.     uint64_t UV = V;
  94. #if __has_builtin(__builtin_bswap64)
  95.     return __builtin_bswap64(UV);
  96. #elif defined(_MSC_VER) && !defined(_DEBUG)
  97.     return _byteswap_uint64(UV);
  98. #else
  99.     uint64_t Hi = llvm::byteswap<uint32_t>(UV);
  100.     uint32_t Lo = llvm::byteswap<uint32_t>(UV >> 32);
  101.     return (Hi << 32) | Lo;
  102. #endif
  103.   } else {
  104.     static_assert(!sizeof(T *), "Don't know how to handle the given type.");
  105.     return 0;
  106.   }
  107. }
  108.  
  109. template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
  110. [[nodiscard]] constexpr inline bool has_single_bit(T Value) noexcept {
  111.   return (Value != 0) && ((Value & (Value - 1)) == 0);
  112. }
  113.  
  114. namespace detail {
  115. template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
  116.   static unsigned count(T Val) {
  117.     if (!Val)
  118.       return std::numeric_limits<T>::digits;
  119.     if (Val & 0x1)
  120.       return 0;
  121.  
  122.     // Bisection method.
  123.     unsigned ZeroBits = 0;
  124.     T Shift = std::numeric_limits<T>::digits >> 1;
  125.     T Mask = std::numeric_limits<T>::max() >> Shift;
  126.     while (Shift) {
  127.       if ((Val & Mask) == 0) {
  128.         Val >>= Shift;
  129.         ZeroBits |= Shift;
  130.       }
  131.       Shift >>= 1;
  132.       Mask >>= Shift;
  133.     }
  134.     return ZeroBits;
  135.   }
  136. };
  137.  
  138. #if defined(__GNUC__) || defined(_MSC_VER)
  139. template <typename T> struct TrailingZerosCounter<T, 4> {
  140.   static unsigned count(T Val) {
  141.     if (Val == 0)
  142.       return 32;
  143.  
  144. #if __has_builtin(__builtin_ctz) || defined(__GNUC__)
  145.     return __builtin_ctz(Val);
  146. #elif defined(_MSC_VER)
  147.     unsigned long Index;
  148.     _BitScanForward(&Index, Val);
  149.     return Index;
  150. #endif
  151.   }
  152. };
  153.  
  154. #if !defined(_MSC_VER) || defined(_M_X64)
  155. template <typename T> struct TrailingZerosCounter<T, 8> {
  156.   static unsigned count(T Val) {
  157.     if (Val == 0)
  158.       return 64;
  159.  
  160. #if __has_builtin(__builtin_ctzll) || defined(__GNUC__)
  161.     return __builtin_ctzll(Val);
  162. #elif defined(_MSC_VER)
  163.     unsigned long Index;
  164.     _BitScanForward64(&Index, Val);
  165.     return Index;
  166. #endif
  167.   }
  168. };
  169. #endif
  170. #endif
  171. } // namespace detail
  172.  
  173. /// Count number of 0's from the least significant bit to the most
  174. ///   stopping at the first 1.
  175. ///
  176. /// Only unsigned integral types are allowed.
  177. ///
  178. /// Returns std::numeric_limits<T>::digits on an input of 0.
  179. template <typename T> [[nodiscard]] int countr_zero(T Val) {
  180.   static_assert(std::is_unsigned_v<T>,
  181.                 "Only unsigned integral types are allowed.");
  182.   return llvm::detail::TrailingZerosCounter<T, sizeof(T)>::count(Val);
  183. }
  184.  
  185. namespace detail {
  186. template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
  187.   static unsigned count(T Val) {
  188.     if (!Val)
  189.       return std::numeric_limits<T>::digits;
  190.  
  191.     // Bisection method.
  192.     unsigned ZeroBits = 0;
  193.     for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
  194.       T Tmp = Val >> Shift;
  195.       if (Tmp)
  196.         Val = Tmp;
  197.       else
  198.         ZeroBits |= Shift;
  199.     }
  200.     return ZeroBits;
  201.   }
  202. };
  203.  
  204. #if defined(__GNUC__) || defined(_MSC_VER)
  205. template <typename T> struct LeadingZerosCounter<T, 4> {
  206.   static unsigned count(T Val) {
  207.     if (Val == 0)
  208.       return 32;
  209.  
  210. #if __has_builtin(__builtin_clz) || defined(__GNUC__)
  211.     return __builtin_clz(Val);
  212. #elif defined(_MSC_VER)
  213.     unsigned long Index;
  214.     _BitScanReverse(&Index, Val);
  215.     return Index ^ 31;
  216. #endif
  217.   }
  218. };
  219.  
  220. #if !defined(_MSC_VER) || defined(_M_X64)
  221. template <typename T> struct LeadingZerosCounter<T, 8> {
  222.   static unsigned count(T Val) {
  223.     if (Val == 0)
  224.       return 64;
  225.  
  226. #if __has_builtin(__builtin_clzll) || defined(__GNUC__)
  227.     return __builtin_clzll(Val);
  228. #elif defined(_MSC_VER)
  229.     unsigned long Index;
  230.     _BitScanReverse64(&Index, Val);
  231.     return Index ^ 63;
  232. #endif
  233.   }
  234. };
  235. #endif
  236. #endif
  237. } // namespace detail
  238.  
  239. /// Count number of 0's from the most significant bit to the least
  240. ///   stopping at the first 1.
  241. ///
  242. /// Only unsigned integral types are allowed.
  243. ///
  244. /// Returns std::numeric_limits<T>::digits on an input of 0.
  245. template <typename T> [[nodiscard]] int countl_zero(T Val) {
  246.   static_assert(std::is_unsigned_v<T>,
  247.                 "Only unsigned integral types are allowed.");
  248.   return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::count(Val);
  249. }
  250.  
  251. /// Count the number of ones from the most significant bit to the first
  252. /// zero bit.
  253. ///
  254. /// Ex. countl_one(0xFF0FFF00) == 8.
  255. /// Only unsigned integral types are allowed.
  256. ///
  257. /// Returns std::numeric_limits<T>::digits on an input of all ones.
  258. template <typename T> [[nodiscard]] int countl_one(T Value) {
  259.   static_assert(std::is_unsigned_v<T>,
  260.                 "Only unsigned integral types are allowed.");
  261.   return llvm::countl_zero<T>(~Value);
  262. }
  263.  
  264. /// Count the number of ones from the least significant bit to the first
  265. /// zero bit.
  266. ///
  267. /// Ex. countr_one(0x00FF00FF) == 8.
  268. /// Only unsigned integral types are allowed.
  269. ///
  270. /// Returns std::numeric_limits<T>::digits on an input of all ones.
  271. template <typename T> [[nodiscard]] int countr_one(T Value) {
  272.   static_assert(std::is_unsigned_v<T>,
  273.                 "Only unsigned integral types are allowed.");
  274.   return llvm::countr_zero<T>(~Value);
  275. }
  276.  
  277. /// Returns the number of bits needed to represent Value if Value is nonzero.
  278. /// Returns 0 otherwise.
  279. ///
  280. /// Ex. bit_width(5) == 3.
  281. template <typename T> [[nodiscard]] int bit_width(T Value) {
  282.   static_assert(std::is_unsigned_v<T>,
  283.                 "Only unsigned integral types are allowed.");
  284.   return std::numeric_limits<T>::digits - llvm::countl_zero(Value);
  285. }
  286.  
  287. /// Returns the largest integral power of two no greater than Value if Value is
  288. /// nonzero.  Returns 0 otherwise.
  289. ///
  290. /// Ex. bit_floor(5) == 4.
  291. template <typename T> [[nodiscard]] T bit_floor(T Value) {
  292.   static_assert(std::is_unsigned_v<T>,
  293.                 "Only unsigned integral types are allowed.");
  294.   if (!Value)
  295.     return 0;
  296.   return T(1) << (llvm::bit_width(Value) - 1);
  297. }
  298.  
  299. /// Returns the smallest integral power of two no smaller than Value if Value is
  300. /// nonzero.  Returns 0 otherwise.
  301. ///
  302. /// Ex. bit_ceil(5) == 8.
  303. ///
  304. /// The return value is undefined if the input is larger than the largest power
  305. /// of two representable in T.
  306. template <typename T> [[nodiscard]] T bit_ceil(T Value) {
  307.   static_assert(std::is_unsigned_v<T>,
  308.                 "Only unsigned integral types are allowed.");
  309.   if (Value < 2)
  310.     return 1;
  311.   return T(1) << llvm::bit_width<T>(Value - 1u);
  312. }
  313.  
  314. namespace detail {
  315. template <typename T, std::size_t SizeOfT> struct PopulationCounter {
  316.   static int count(T Value) {
  317.     // Generic version, forward to 32 bits.
  318.     static_assert(SizeOfT <= 4, "Not implemented!");
  319. #if defined(__GNUC__)
  320.     return (int)__builtin_popcount(Value);
  321. #else
  322.     uint32_t v = Value;
  323.     v = v - ((v >> 1) & 0x55555555);
  324.     v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
  325.     return int(((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24);
  326. #endif
  327.   }
  328. };
  329.  
  330. template <typename T> struct PopulationCounter<T, 8> {
  331.   static int count(T Value) {
  332. #if defined(__GNUC__)
  333.     return (int)__builtin_popcountll(Value);
  334. #else
  335.     uint64_t v = Value;
  336.     v = v - ((v >> 1) & 0x5555555555555555ULL);
  337.     v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
  338.     v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
  339.     return int((uint64_t)(v * 0x0101010101010101ULL) >> 56);
  340. #endif
  341.   }
  342. };
  343. } // namespace detail
  344.  
  345. /// Count the number of set bits in a value.
  346. /// Ex. popcount(0xF000F000) = 8
  347. /// Returns 0 if the word is zero.
  348. template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
  349. [[nodiscard]] inline int popcount(T Value) noexcept {
  350.   return detail::PopulationCounter<T, sizeof(T)>::count(Value);
  351. }
  352.  
  353. } // namespace llvm
  354.  
  355. #endif
  356.