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