xref: /aosp_15_r20/external/abseil-cpp/absl/numeric/internal/bits.h (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2020 The Abseil Authors
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #ifndef ABSL_NUMERIC_INTERNAL_BITS_H_
16*9356374aSAndroid Build Coastguard Worker #define ABSL_NUMERIC_INTERNAL_BITS_H_
17*9356374aSAndroid Build Coastguard Worker 
18*9356374aSAndroid Build Coastguard Worker #include <cstdint>
19*9356374aSAndroid Build Coastguard Worker #include <limits>
20*9356374aSAndroid Build Coastguard Worker #include <type_traits>
21*9356374aSAndroid Build Coastguard Worker 
22*9356374aSAndroid Build Coastguard Worker // Clang on Windows has __builtin_clzll; otherwise we need to use the
23*9356374aSAndroid Build Coastguard Worker // windows intrinsic functions.
24*9356374aSAndroid Build Coastguard Worker #if defined(_MSC_VER) && !defined(__clang__)
25*9356374aSAndroid Build Coastguard Worker #include <intrin.h>
26*9356374aSAndroid Build Coastguard Worker #endif
27*9356374aSAndroid Build Coastguard Worker 
28*9356374aSAndroid Build Coastguard Worker #include "absl/base/attributes.h"
29*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
30*9356374aSAndroid Build Coastguard Worker 
31*9356374aSAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__)
32*9356374aSAndroid Build Coastguard Worker // GCC
33*9356374aSAndroid Build Coastguard Worker #define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) 1
34*9356374aSAndroid Build Coastguard Worker #else
35*9356374aSAndroid Build Coastguard Worker #define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) ABSL_HAVE_BUILTIN(x)
36*9356374aSAndroid Build Coastguard Worker #endif
37*9356374aSAndroid Build Coastguard Worker 
38*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountl) && \
39*9356374aSAndroid Build Coastguard Worker     ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll)
40*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_CONSTEXPR_POPCOUNT constexpr
41*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 1
42*9356374aSAndroid Build Coastguard Worker #else
43*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_CONSTEXPR_POPCOUNT
44*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 0
45*9356374aSAndroid Build Coastguard Worker #endif
46*9356374aSAndroid Build Coastguard Worker 
47*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz) && \
48*9356374aSAndroid Build Coastguard Worker     ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll)
49*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_CONSTEXPR_CLZ constexpr
50*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 1
51*9356374aSAndroid Build Coastguard Worker #else
52*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_CONSTEXPR_CLZ
53*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 0
54*9356374aSAndroid Build Coastguard Worker #endif
55*9356374aSAndroid Build Coastguard Worker 
56*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz) && \
57*9356374aSAndroid Build Coastguard Worker     ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll)
58*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_CONSTEXPR_CTZ constexpr
59*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 1
60*9356374aSAndroid Build Coastguard Worker #else
61*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_CONSTEXPR_CTZ
62*9356374aSAndroid Build Coastguard Worker #define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 0
63*9356374aSAndroid Build Coastguard Worker #endif
64*9356374aSAndroid Build Coastguard Worker 
65*9356374aSAndroid Build Coastguard Worker namespace absl {
66*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
67*9356374aSAndroid Build Coastguard Worker namespace numeric_internal {
68*9356374aSAndroid Build Coastguard Worker 
IsPowerOf2(unsigned int x)69*9356374aSAndroid Build Coastguard Worker constexpr bool IsPowerOf2(unsigned int x) noexcept {
70*9356374aSAndroid Build Coastguard Worker   return x != 0 && (x & (x - 1)) == 0;
71*9356374aSAndroid Build Coastguard Worker }
72*9356374aSAndroid Build Coastguard Worker 
73*9356374aSAndroid Build Coastguard Worker template <class T>
RotateRight(T x,int s)74*9356374aSAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateRight(
75*9356374aSAndroid Build Coastguard Worker     T x, int s) noexcept {
76*9356374aSAndroid Build Coastguard Worker   static_assert(std::is_unsigned<T>::value, "T must be unsigned");
77*9356374aSAndroid Build Coastguard Worker   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
78*9356374aSAndroid Build Coastguard Worker                 "T must have a power-of-2 size");
79*9356374aSAndroid Build Coastguard Worker 
80*9356374aSAndroid Build Coastguard Worker   return static_cast<T>(x >> (s & (std::numeric_limits<T>::digits - 1))) |
81*9356374aSAndroid Build Coastguard Worker          static_cast<T>(x << ((-s) & (std::numeric_limits<T>::digits - 1)));
82*9356374aSAndroid Build Coastguard Worker }
83*9356374aSAndroid Build Coastguard Worker 
84*9356374aSAndroid Build Coastguard Worker template <class T>
RotateLeft(T x,int s)85*9356374aSAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft(
86*9356374aSAndroid Build Coastguard Worker     T x, int s) noexcept {
87*9356374aSAndroid Build Coastguard Worker   static_assert(std::is_unsigned<T>::value, "T must be unsigned");
88*9356374aSAndroid Build Coastguard Worker   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
89*9356374aSAndroid Build Coastguard Worker                 "T must have a power-of-2 size");
90*9356374aSAndroid Build Coastguard Worker 
91*9356374aSAndroid Build Coastguard Worker   return static_cast<T>(x << (s & (std::numeric_limits<T>::digits - 1))) |
92*9356374aSAndroid Build Coastguard Worker          static_cast<T>(x >> ((-s) & (std::numeric_limits<T>::digits - 1)));
93*9356374aSAndroid Build Coastguard Worker }
94*9356374aSAndroid Build Coastguard Worker 
95*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount32(uint32_t x)96*9356374aSAndroid Build Coastguard Worker Popcount32(uint32_t x) noexcept {
97*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcount)
98*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(unsigned int) == sizeof(x),
99*9356374aSAndroid Build Coastguard Worker                 "__builtin_popcount does not take 32-bit arg");
100*9356374aSAndroid Build Coastguard Worker   return __builtin_popcount(x);
101*9356374aSAndroid Build Coastguard Worker #else
102*9356374aSAndroid Build Coastguard Worker   x -= ((x >> 1) & 0x55555555);
103*9356374aSAndroid Build Coastguard Worker   x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
104*9356374aSAndroid Build Coastguard Worker   return static_cast<int>((((x + (x >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24);
105*9356374aSAndroid Build Coastguard Worker #endif
106*9356374aSAndroid Build Coastguard Worker }
107*9356374aSAndroid Build Coastguard Worker 
108*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount64(uint64_t x)109*9356374aSAndroid Build Coastguard Worker Popcount64(uint64_t x) noexcept {
110*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll)
111*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(unsigned long long) == sizeof(x),  // NOLINT(runtime/int)
112*9356374aSAndroid Build Coastguard Worker                 "__builtin_popcount does not take 64-bit arg");
113*9356374aSAndroid Build Coastguard Worker   return __builtin_popcountll(x);
114*9356374aSAndroid Build Coastguard Worker #else
115*9356374aSAndroid Build Coastguard Worker   x -= (x >> 1) & 0x5555555555555555ULL;
116*9356374aSAndroid Build Coastguard Worker   x = ((x >> 2) & 0x3333333333333333ULL) + (x & 0x3333333333333333ULL);
117*9356374aSAndroid Build Coastguard Worker   return static_cast<int>(
118*9356374aSAndroid Build Coastguard Worker       (((x + (x >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56);
119*9356374aSAndroid Build Coastguard Worker #endif
120*9356374aSAndroid Build Coastguard Worker }
121*9356374aSAndroid Build Coastguard Worker 
122*9356374aSAndroid Build Coastguard Worker template <class T>
123*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount(T x)124*9356374aSAndroid Build Coastguard Worker Popcount(T x) noexcept {
125*9356374aSAndroid Build Coastguard Worker   static_assert(std::is_unsigned<T>::value, "T must be unsigned");
126*9356374aSAndroid Build Coastguard Worker   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
127*9356374aSAndroid Build Coastguard Worker                 "T must have a power-of-2 size");
128*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(x) <= sizeof(uint64_t), "T is too large");
129*9356374aSAndroid Build Coastguard Worker   return sizeof(x) <= sizeof(uint32_t) ? Popcount32(x) : Popcount64(x);
130*9356374aSAndroid Build Coastguard Worker }
131*9356374aSAndroid Build Coastguard Worker 
132*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes32(uint32_t x)133*9356374aSAndroid Build Coastguard Worker CountLeadingZeroes32(uint32_t x) {
134*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz)
135*9356374aSAndroid Build Coastguard Worker   // Use __builtin_clz, which uses the following instructions:
136*9356374aSAndroid Build Coastguard Worker   //  x86: bsr, lzcnt
137*9356374aSAndroid Build Coastguard Worker   //  ARM64: clz
138*9356374aSAndroid Build Coastguard Worker   //  PPC: cntlzd
139*9356374aSAndroid Build Coastguard Worker 
140*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(unsigned int) == sizeof(x),
141*9356374aSAndroid Build Coastguard Worker                 "__builtin_clz does not take 32-bit arg");
142*9356374aSAndroid Build Coastguard Worker   // Handle 0 as a special case because __builtin_clz(0) is undefined.
143*9356374aSAndroid Build Coastguard Worker   return x == 0 ? 32 : __builtin_clz(x);
144*9356374aSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && !defined(__clang__)
145*9356374aSAndroid Build Coastguard Worker   unsigned long result = 0;  // NOLINT(runtime/int)
146*9356374aSAndroid Build Coastguard Worker   if (_BitScanReverse(&result, x)) {
147*9356374aSAndroid Build Coastguard Worker     return 31 - result;
148*9356374aSAndroid Build Coastguard Worker   }
149*9356374aSAndroid Build Coastguard Worker   return 32;
150*9356374aSAndroid Build Coastguard Worker #else
151*9356374aSAndroid Build Coastguard Worker   int zeroes = 28;
152*9356374aSAndroid Build Coastguard Worker   if (x >> 16) {
153*9356374aSAndroid Build Coastguard Worker     zeroes -= 16;
154*9356374aSAndroid Build Coastguard Worker     x >>= 16;
155*9356374aSAndroid Build Coastguard Worker   }
156*9356374aSAndroid Build Coastguard Worker   if (x >> 8) {
157*9356374aSAndroid Build Coastguard Worker     zeroes -= 8;
158*9356374aSAndroid Build Coastguard Worker     x >>= 8;
159*9356374aSAndroid Build Coastguard Worker   }
160*9356374aSAndroid Build Coastguard Worker   if (x >> 4) {
161*9356374aSAndroid Build Coastguard Worker     zeroes -= 4;
162*9356374aSAndroid Build Coastguard Worker     x >>= 4;
163*9356374aSAndroid Build Coastguard Worker   }
164*9356374aSAndroid Build Coastguard Worker   return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes;
165*9356374aSAndroid Build Coastguard Worker #endif
166*9356374aSAndroid Build Coastguard Worker }
167*9356374aSAndroid Build Coastguard Worker 
168*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes16(uint16_t x)169*9356374aSAndroid Build Coastguard Worker CountLeadingZeroes16(uint16_t x) {
170*9356374aSAndroid Build Coastguard Worker #if ABSL_HAVE_BUILTIN(__builtin_clzg)
171*9356374aSAndroid Build Coastguard Worker   return x == 0 ? 16 : __builtin_clzg(x);
172*9356374aSAndroid Build Coastguard Worker #elif ABSL_HAVE_BUILTIN(__builtin_clzs)
173*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(unsigned short) == sizeof(x),  // NOLINT(runtime/int)
174*9356374aSAndroid Build Coastguard Worker                 "__builtin_clzs does not take 16-bit arg");
175*9356374aSAndroid Build Coastguard Worker   return x == 0 ? 16 : __builtin_clzs(x);
176*9356374aSAndroid Build Coastguard Worker #else
177*9356374aSAndroid Build Coastguard Worker   return CountLeadingZeroes32(x) - 16;
178*9356374aSAndroid Build Coastguard Worker #endif
179*9356374aSAndroid Build Coastguard Worker }
180*9356374aSAndroid Build Coastguard Worker 
181*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes64(uint64_t x)182*9356374aSAndroid Build Coastguard Worker CountLeadingZeroes64(uint64_t x) {
183*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll)
184*9356374aSAndroid Build Coastguard Worker   // Use __builtin_clzll, which uses the following instructions:
185*9356374aSAndroid Build Coastguard Worker   //  x86: bsr, lzcnt
186*9356374aSAndroid Build Coastguard Worker   //  ARM64: clz
187*9356374aSAndroid Build Coastguard Worker   //  PPC: cntlzd
188*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(unsigned long long) == sizeof(x),  // NOLINT(runtime/int)
189*9356374aSAndroid Build Coastguard Worker                 "__builtin_clzll does not take 64-bit arg");
190*9356374aSAndroid Build Coastguard Worker 
191*9356374aSAndroid Build Coastguard Worker   // Handle 0 as a special case because __builtin_clzll(0) is undefined.
192*9356374aSAndroid Build Coastguard Worker   return x == 0 ? 64 : __builtin_clzll(x);
193*9356374aSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && !defined(__clang__) && \
194*9356374aSAndroid Build Coastguard Worker     (defined(_M_X64) || defined(_M_ARM64))
195*9356374aSAndroid Build Coastguard Worker   // MSVC does not have __buitin_clzll. Use _BitScanReverse64.
196*9356374aSAndroid Build Coastguard Worker   unsigned long result = 0;  // NOLINT(runtime/int)
197*9356374aSAndroid Build Coastguard Worker   if (_BitScanReverse64(&result, x)) {
198*9356374aSAndroid Build Coastguard Worker     return 63 - result;
199*9356374aSAndroid Build Coastguard Worker   }
200*9356374aSAndroid Build Coastguard Worker   return 64;
201*9356374aSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && !defined(__clang__)
202*9356374aSAndroid Build Coastguard Worker   // MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse
203*9356374aSAndroid Build Coastguard Worker   unsigned long result = 0;  // NOLINT(runtime/int)
204*9356374aSAndroid Build Coastguard Worker   if ((x >> 32) &&
205*9356374aSAndroid Build Coastguard Worker       _BitScanReverse(&result, static_cast<unsigned long>(x >> 32))) {
206*9356374aSAndroid Build Coastguard Worker     return 31 - result;
207*9356374aSAndroid Build Coastguard Worker   }
208*9356374aSAndroid Build Coastguard Worker   if (_BitScanReverse(&result, static_cast<unsigned long>(x))) {
209*9356374aSAndroid Build Coastguard Worker     return 63 - result;
210*9356374aSAndroid Build Coastguard Worker   }
211*9356374aSAndroid Build Coastguard Worker   return 64;
212*9356374aSAndroid Build Coastguard Worker #else
213*9356374aSAndroid Build Coastguard Worker   int zeroes = 60;
214*9356374aSAndroid Build Coastguard Worker   if (x >> 32) {
215*9356374aSAndroid Build Coastguard Worker     zeroes -= 32;
216*9356374aSAndroid Build Coastguard Worker     x >>= 32;
217*9356374aSAndroid Build Coastguard Worker   }
218*9356374aSAndroid Build Coastguard Worker   if (x >> 16) {
219*9356374aSAndroid Build Coastguard Worker     zeroes -= 16;
220*9356374aSAndroid Build Coastguard Worker     x >>= 16;
221*9356374aSAndroid Build Coastguard Worker   }
222*9356374aSAndroid Build Coastguard Worker   if (x >> 8) {
223*9356374aSAndroid Build Coastguard Worker     zeroes -= 8;
224*9356374aSAndroid Build Coastguard Worker     x >>= 8;
225*9356374aSAndroid Build Coastguard Worker   }
226*9356374aSAndroid Build Coastguard Worker   if (x >> 4) {
227*9356374aSAndroid Build Coastguard Worker     zeroes -= 4;
228*9356374aSAndroid Build Coastguard Worker     x >>= 4;
229*9356374aSAndroid Build Coastguard Worker   }
230*9356374aSAndroid Build Coastguard Worker   return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[x] + zeroes;
231*9356374aSAndroid Build Coastguard Worker #endif
232*9356374aSAndroid Build Coastguard Worker }
233*9356374aSAndroid Build Coastguard Worker 
234*9356374aSAndroid Build Coastguard Worker template <typename T>
235*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int
CountLeadingZeroes(T x)236*9356374aSAndroid Build Coastguard Worker CountLeadingZeroes(T x) {
237*9356374aSAndroid Build Coastguard Worker   static_assert(std::is_unsigned<T>::value, "T must be unsigned");
238*9356374aSAndroid Build Coastguard Worker   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
239*9356374aSAndroid Build Coastguard Worker                 "T must have a power-of-2 size");
240*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(T) <= sizeof(uint64_t), "T too large");
241*9356374aSAndroid Build Coastguard Worker   return sizeof(T) <= sizeof(uint16_t)
242*9356374aSAndroid Build Coastguard Worker              ? CountLeadingZeroes16(static_cast<uint16_t>(x)) -
243*9356374aSAndroid Build Coastguard Worker                    (std::numeric_limits<uint16_t>::digits -
244*9356374aSAndroid Build Coastguard Worker                     std::numeric_limits<T>::digits)
245*9356374aSAndroid Build Coastguard Worker              : (sizeof(T) <= sizeof(uint32_t)
246*9356374aSAndroid Build Coastguard Worker                     ? CountLeadingZeroes32(static_cast<uint32_t>(x)) -
247*9356374aSAndroid Build Coastguard Worker                           (std::numeric_limits<uint32_t>::digits -
248*9356374aSAndroid Build Coastguard Worker                            std::numeric_limits<T>::digits)
249*9356374aSAndroid Build Coastguard Worker                     : CountLeadingZeroes64(x));
250*9356374aSAndroid Build Coastguard Worker }
251*9356374aSAndroid Build Coastguard Worker 
252*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroesNonzero32(uint32_t x)253*9356374aSAndroid Build Coastguard Worker CountTrailingZeroesNonzero32(uint32_t x) {
254*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz)
255*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(unsigned int) == sizeof(x),
256*9356374aSAndroid Build Coastguard Worker                 "__builtin_ctz does not take 32-bit arg");
257*9356374aSAndroid Build Coastguard Worker   return __builtin_ctz(x);
258*9356374aSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && !defined(__clang__)
259*9356374aSAndroid Build Coastguard Worker   unsigned long result = 0;  // NOLINT(runtime/int)
260*9356374aSAndroid Build Coastguard Worker   _BitScanForward(&result, x);
261*9356374aSAndroid Build Coastguard Worker   return result;
262*9356374aSAndroid Build Coastguard Worker #else
263*9356374aSAndroid Build Coastguard Worker   int c = 31;
264*9356374aSAndroid Build Coastguard Worker   x &= ~x + 1;
265*9356374aSAndroid Build Coastguard Worker   if (x & 0x0000FFFF) c -= 16;
266*9356374aSAndroid Build Coastguard Worker   if (x & 0x00FF00FF) c -= 8;
267*9356374aSAndroid Build Coastguard Worker   if (x & 0x0F0F0F0F) c -= 4;
268*9356374aSAndroid Build Coastguard Worker   if (x & 0x33333333) c -= 2;
269*9356374aSAndroid Build Coastguard Worker   if (x & 0x55555555) c -= 1;
270*9356374aSAndroid Build Coastguard Worker   return c;
271*9356374aSAndroid Build Coastguard Worker #endif
272*9356374aSAndroid Build Coastguard Worker }
273*9356374aSAndroid Build Coastguard Worker 
274*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroesNonzero64(uint64_t x)275*9356374aSAndroid Build Coastguard Worker CountTrailingZeroesNonzero64(uint64_t x) {
276*9356374aSAndroid Build Coastguard Worker #if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll)
277*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(unsigned long long) == sizeof(x),  // NOLINT(runtime/int)
278*9356374aSAndroid Build Coastguard Worker                 "__builtin_ctzll does not take 64-bit arg");
279*9356374aSAndroid Build Coastguard Worker   return __builtin_ctzll(x);
280*9356374aSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && !defined(__clang__) && \
281*9356374aSAndroid Build Coastguard Worker     (defined(_M_X64) || defined(_M_ARM64))
282*9356374aSAndroid Build Coastguard Worker   unsigned long result = 0;  // NOLINT(runtime/int)
283*9356374aSAndroid Build Coastguard Worker   _BitScanForward64(&result, x);
284*9356374aSAndroid Build Coastguard Worker   return result;
285*9356374aSAndroid Build Coastguard Worker #elif defined(_MSC_VER) && !defined(__clang__)
286*9356374aSAndroid Build Coastguard Worker   unsigned long result = 0;  // NOLINT(runtime/int)
287*9356374aSAndroid Build Coastguard Worker   if (static_cast<uint32_t>(x) == 0) {
288*9356374aSAndroid Build Coastguard Worker     _BitScanForward(&result, static_cast<unsigned long>(x >> 32));
289*9356374aSAndroid Build Coastguard Worker     return result + 32;
290*9356374aSAndroid Build Coastguard Worker   }
291*9356374aSAndroid Build Coastguard Worker   _BitScanForward(&result, static_cast<unsigned long>(x));
292*9356374aSAndroid Build Coastguard Worker   return result;
293*9356374aSAndroid Build Coastguard Worker #else
294*9356374aSAndroid Build Coastguard Worker   int c = 63;
295*9356374aSAndroid Build Coastguard Worker   x &= ~x + 1;
296*9356374aSAndroid Build Coastguard Worker   if (x & 0x00000000FFFFFFFF) c -= 32;
297*9356374aSAndroid Build Coastguard Worker   if (x & 0x0000FFFF0000FFFF) c -= 16;
298*9356374aSAndroid Build Coastguard Worker   if (x & 0x00FF00FF00FF00FF) c -= 8;
299*9356374aSAndroid Build Coastguard Worker   if (x & 0x0F0F0F0F0F0F0F0F) c -= 4;
300*9356374aSAndroid Build Coastguard Worker   if (x & 0x3333333333333333) c -= 2;
301*9356374aSAndroid Build Coastguard Worker   if (x & 0x5555555555555555) c -= 1;
302*9356374aSAndroid Build Coastguard Worker   return c;
303*9356374aSAndroid Build Coastguard Worker #endif
304*9356374aSAndroid Build Coastguard Worker }
305*9356374aSAndroid Build Coastguard Worker 
306*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroesNonzero16(uint16_t x)307*9356374aSAndroid Build Coastguard Worker CountTrailingZeroesNonzero16(uint16_t x) {
308*9356374aSAndroid Build Coastguard Worker #if ABSL_HAVE_BUILTIN(__builtin_ctzg)
309*9356374aSAndroid Build Coastguard Worker   return __builtin_ctzg(x);
310*9356374aSAndroid Build Coastguard Worker #elif ABSL_HAVE_BUILTIN(__builtin_ctzs)
311*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(unsigned short) == sizeof(x),  // NOLINT(runtime/int)
312*9356374aSAndroid Build Coastguard Worker                 "__builtin_ctzs does not take 16-bit arg");
313*9356374aSAndroid Build Coastguard Worker   return __builtin_ctzs(x);
314*9356374aSAndroid Build Coastguard Worker #else
315*9356374aSAndroid Build Coastguard Worker   return CountTrailingZeroesNonzero32(x);
316*9356374aSAndroid Build Coastguard Worker #endif
317*9356374aSAndroid Build Coastguard Worker }
318*9356374aSAndroid Build Coastguard Worker 
319*9356374aSAndroid Build Coastguard Worker template <class T>
320*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int
CountTrailingZeroes(T x)321*9356374aSAndroid Build Coastguard Worker CountTrailingZeroes(T x) noexcept {
322*9356374aSAndroid Build Coastguard Worker   static_assert(std::is_unsigned<T>::value, "T must be unsigned");
323*9356374aSAndroid Build Coastguard Worker   static_assert(IsPowerOf2(std::numeric_limits<T>::digits),
324*9356374aSAndroid Build Coastguard Worker                 "T must have a power-of-2 size");
325*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(T) <= sizeof(uint64_t), "T too large");
326*9356374aSAndroid Build Coastguard Worker   return x == 0 ? std::numeric_limits<T>::digits
327*9356374aSAndroid Build Coastguard Worker                 : (sizeof(T) <= sizeof(uint16_t)
328*9356374aSAndroid Build Coastguard Worker                        ? CountTrailingZeroesNonzero16(static_cast<uint16_t>(x))
329*9356374aSAndroid Build Coastguard Worker                        : (sizeof(T) <= sizeof(uint32_t)
330*9356374aSAndroid Build Coastguard Worker                               ? CountTrailingZeroesNonzero32(
331*9356374aSAndroid Build Coastguard Worker                                     static_cast<uint32_t>(x))
332*9356374aSAndroid Build Coastguard Worker                               : CountTrailingZeroesNonzero64(x)));
333*9356374aSAndroid Build Coastguard Worker }
334*9356374aSAndroid Build Coastguard Worker 
335*9356374aSAndroid Build Coastguard Worker // If T is narrower than unsigned, T{1} << bit_width will be promoted.  We
336*9356374aSAndroid Build Coastguard Worker // want to force it to wraparound so that bit_ceil of an invalid value are not
337*9356374aSAndroid Build Coastguard Worker // core constant expressions.
338*9356374aSAndroid Build Coastguard Worker template <class T>
339*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline
340*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, T>::type
BitCeilPromotionHelper(T x,T promotion)341*9356374aSAndroid Build Coastguard Worker     BitCeilPromotionHelper(T x, T promotion) {
342*9356374aSAndroid Build Coastguard Worker   return (T{1} << (x + promotion)) >> promotion;
343*9356374aSAndroid Build Coastguard Worker }
344*9356374aSAndroid Build Coastguard Worker 
345*9356374aSAndroid Build Coastguard Worker template <class T>
346*9356374aSAndroid Build Coastguard Worker ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline
347*9356374aSAndroid Build Coastguard Worker     typename std::enable_if<std::is_unsigned<T>::value, T>::type
BitCeilNonPowerOf2(T x)348*9356374aSAndroid Build Coastguard Worker     BitCeilNonPowerOf2(T x) {
349*9356374aSAndroid Build Coastguard Worker   // If T is narrower than unsigned, it undergoes promotion to unsigned when we
350*9356374aSAndroid Build Coastguard Worker   // shift.  We calculate the number of bits added by the wider type.
351*9356374aSAndroid Build Coastguard Worker   return BitCeilPromotionHelper(
352*9356374aSAndroid Build Coastguard Worker       static_cast<T>(std::numeric_limits<T>::digits - CountLeadingZeroes(x)),
353*9356374aSAndroid Build Coastguard Worker       T{sizeof(T) >= sizeof(unsigned) ? 0
354*9356374aSAndroid Build Coastguard Worker                                       : std::numeric_limits<unsigned>::digits -
355*9356374aSAndroid Build Coastguard Worker                                             std::numeric_limits<T>::digits});
356*9356374aSAndroid Build Coastguard Worker }
357*9356374aSAndroid Build Coastguard Worker 
358*9356374aSAndroid Build Coastguard Worker }  // namespace numeric_internal
359*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
360*9356374aSAndroid Build Coastguard Worker }  // namespace absl
361*9356374aSAndroid Build Coastguard Worker 
362*9356374aSAndroid Build Coastguard Worker #endif  // ABSL_NUMERIC_INTERNAL_BITS_H_
363