1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker // This file defines some bit utilities.
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #ifndef BASE_BITS_H_
8*635a8641SAndroid Build Coastguard Worker #define BASE_BITS_H_
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
11*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
12*635a8641SAndroid Build Coastguard Worker
13*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
15*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
18*635a8641SAndroid Build Coastguard Worker #include <intrin.h>
19*635a8641SAndroid Build Coastguard Worker #endif
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker namespace base {
22*635a8641SAndroid Build Coastguard Worker namespace bits {
23*635a8641SAndroid Build Coastguard Worker
24*635a8641SAndroid Build Coastguard Worker // Returns true iff |value| is a power of 2.
25*635a8641SAndroid Build Coastguard Worker template <typename T,
26*635a8641SAndroid Build Coastguard Worker typename = typename std::enable_if<std::is_integral<T>::value>>
IsPowerOfTwo(T value)27*635a8641SAndroid Build Coastguard Worker constexpr inline bool IsPowerOfTwo(T value) {
28*635a8641SAndroid Build Coastguard Worker // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits.
29*635a8641SAndroid Build Coastguard Worker //
30*635a8641SAndroid Build Coastguard Worker // Only positive integers with a single bit set are powers of two. If only one
31*635a8641SAndroid Build Coastguard Worker // bit is set in x (e.g. 0b00000100000000) then |x-1| will have that bit set
32*635a8641SAndroid Build Coastguard Worker // to zero and all bits to its right set to 1 (e.g. 0b00000011111111). Hence
33*635a8641SAndroid Build Coastguard Worker // |x & (x-1)| is 0 iff x is a power of two.
34*635a8641SAndroid Build Coastguard Worker return value > 0 && (value & (value - 1)) == 0;
35*635a8641SAndroid Build Coastguard Worker }
36*635a8641SAndroid Build Coastguard Worker
37*635a8641SAndroid Build Coastguard Worker // Round up |size| to a multiple of alignment, which must be a power of two.
Align(size_t size,size_t alignment)38*635a8641SAndroid Build Coastguard Worker inline size_t Align(size_t size, size_t alignment) {
39*635a8641SAndroid Build Coastguard Worker DCHECK(IsPowerOfTwo(alignment));
40*635a8641SAndroid Build Coastguard Worker return (size + alignment - 1) & ~(alignment - 1);
41*635a8641SAndroid Build Coastguard Worker }
42*635a8641SAndroid Build Coastguard Worker
43*635a8641SAndroid Build Coastguard Worker // CountLeadingZeroBits(value) returns the number of zero bits following the
44*635a8641SAndroid Build Coastguard Worker // most significant 1 bit in |value| if |value| is non-zero, otherwise it
45*635a8641SAndroid Build Coastguard Worker // returns {sizeof(T) * 8}.
46*635a8641SAndroid Build Coastguard Worker // Example: 00100010 -> 2
47*635a8641SAndroid Build Coastguard Worker //
48*635a8641SAndroid Build Coastguard Worker // CountTrailingZeroBits(value) returns the number of zero bits preceding the
49*635a8641SAndroid Build Coastguard Worker // least significant 1 bit in |value| if |value| is non-zero, otherwise it
50*635a8641SAndroid Build Coastguard Worker // returns {sizeof(T) * 8}.
51*635a8641SAndroid Build Coastguard Worker // Example: 00100010 -> 1
52*635a8641SAndroid Build Coastguard Worker //
53*635a8641SAndroid Build Coastguard Worker // C does not have an operator to do this, but fortunately the various
54*635a8641SAndroid Build Coastguard Worker // compilers have built-ins that map to fast underlying processor instructions.
55*635a8641SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
56*635a8641SAndroid Build Coastguard Worker
57*635a8641SAndroid Build Coastguard Worker template <typename T, unsigned bits = sizeof(T) * 8>
58*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE
59*635a8641SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 4,
60*635a8641SAndroid Build Coastguard Worker unsigned>::type
CountLeadingZeroBits(T x)61*635a8641SAndroid Build Coastguard Worker CountLeadingZeroBits(T x) {
62*635a8641SAndroid Build Coastguard Worker static_assert(bits > 0, "invalid instantiation");
63*635a8641SAndroid Build Coastguard Worker unsigned long index;
64*635a8641SAndroid Build Coastguard Worker return LIKELY(_BitScanReverse(&index, static_cast<uint32_t>(x)))
65*635a8641SAndroid Build Coastguard Worker ? (31 - index - (32 - bits))
66*635a8641SAndroid Build Coastguard Worker : bits;
67*635a8641SAndroid Build Coastguard Worker }
68*635a8641SAndroid Build Coastguard Worker
69*635a8641SAndroid Build Coastguard Worker template <typename T, unsigned bits = sizeof(T) * 8>
70*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE
71*635a8641SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) == 8,
72*635a8641SAndroid Build Coastguard Worker unsigned>::type
CountLeadingZeroBits(T x)73*635a8641SAndroid Build Coastguard Worker CountLeadingZeroBits(T x) {
74*635a8641SAndroid Build Coastguard Worker static_assert(bits > 0, "invalid instantiation");
75*635a8641SAndroid Build Coastguard Worker unsigned long index;
76*635a8641SAndroid Build Coastguard Worker return LIKELY(_BitScanReverse64(&index, static_cast<uint64_t>(x)))
77*635a8641SAndroid Build Coastguard Worker ? (63 - index)
78*635a8641SAndroid Build Coastguard Worker : 64;
79*635a8641SAndroid Build Coastguard Worker }
80*635a8641SAndroid Build Coastguard Worker
81*635a8641SAndroid Build Coastguard Worker template <typename T, unsigned bits = sizeof(T) * 8>
82*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE
83*635a8641SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 4,
84*635a8641SAndroid Build Coastguard Worker unsigned>::type
CountTrailingZeroBits(T x)85*635a8641SAndroid Build Coastguard Worker CountTrailingZeroBits(T x) {
86*635a8641SAndroid Build Coastguard Worker static_assert(bits > 0, "invalid instantiation");
87*635a8641SAndroid Build Coastguard Worker unsigned long index;
88*635a8641SAndroid Build Coastguard Worker return LIKELY(_BitScanForward(&index, static_cast<uint32_t>(x))) ? index
89*635a8641SAndroid Build Coastguard Worker : bits;
90*635a8641SAndroid Build Coastguard Worker }
91*635a8641SAndroid Build Coastguard Worker
92*635a8641SAndroid Build Coastguard Worker template <typename T, unsigned bits = sizeof(T) * 8>
93*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE
94*635a8641SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) == 8,
95*635a8641SAndroid Build Coastguard Worker unsigned>::type
CountTrailingZeroBits(T x)96*635a8641SAndroid Build Coastguard Worker CountTrailingZeroBits(T x) {
97*635a8641SAndroid Build Coastguard Worker static_assert(bits > 0, "invalid instantiation");
98*635a8641SAndroid Build Coastguard Worker unsigned long index;
99*635a8641SAndroid Build Coastguard Worker return LIKELY(_BitScanForward64(&index, static_cast<uint64_t>(x))) ? index
100*635a8641SAndroid Build Coastguard Worker : 64;
101*635a8641SAndroid Build Coastguard Worker }
102*635a8641SAndroid Build Coastguard Worker
CountLeadingZeroBits32(uint32_t x)103*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE uint32_t CountLeadingZeroBits32(uint32_t x) {
104*635a8641SAndroid Build Coastguard Worker return CountLeadingZeroBits(x);
105*635a8641SAndroid Build Coastguard Worker }
106*635a8641SAndroid Build Coastguard Worker
107*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_64_BITS)
108*635a8641SAndroid Build Coastguard Worker
109*635a8641SAndroid Build Coastguard Worker // MSVC only supplies _BitScanForward64 when building for a 64-bit target.
CountLeadingZeroBits64(uint64_t x)110*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE uint64_t CountLeadingZeroBits64(uint64_t x) {
111*635a8641SAndroid Build Coastguard Worker return CountLeadingZeroBits(x);
112*635a8641SAndroid Build Coastguard Worker }
113*635a8641SAndroid Build Coastguard Worker
114*635a8641SAndroid Build Coastguard Worker #endif
115*635a8641SAndroid Build Coastguard Worker
116*635a8641SAndroid Build Coastguard Worker #elif defined(COMPILER_GCC)
117*635a8641SAndroid Build Coastguard Worker
118*635a8641SAndroid Build Coastguard Worker // __builtin_clz has undefined behaviour for an input of 0, even though there's
119*635a8641SAndroid Build Coastguard Worker // clearly a return value that makes sense, and even though some processor clz
120*635a8641SAndroid Build Coastguard Worker // instructions have defined behaviour for 0. We could drop to raw __asm__ to
121*635a8641SAndroid Build Coastguard Worker // do better, but we'll avoid doing that unless we see proof that we need to.
122*635a8641SAndroid Build Coastguard Worker template <typename T, unsigned bits = sizeof(T) * 8>
123*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE
124*635a8641SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 8,
125*635a8641SAndroid Build Coastguard Worker unsigned>::type
CountLeadingZeroBits(T value)126*635a8641SAndroid Build Coastguard Worker CountLeadingZeroBits(T value) {
127*635a8641SAndroid Build Coastguard Worker static_assert(bits > 0, "invalid instantiation");
128*635a8641SAndroid Build Coastguard Worker return LIKELY(value)
129*635a8641SAndroid Build Coastguard Worker ? bits == 64
130*635a8641SAndroid Build Coastguard Worker ? __builtin_clzll(static_cast<uint64_t>(value))
131*635a8641SAndroid Build Coastguard Worker : __builtin_clz(static_cast<uint32_t>(value)) - (32 - bits)
132*635a8641SAndroid Build Coastguard Worker : bits;
133*635a8641SAndroid Build Coastguard Worker }
134*635a8641SAndroid Build Coastguard Worker
135*635a8641SAndroid Build Coastguard Worker template <typename T, unsigned bits = sizeof(T) * 8>
136*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE
137*635a8641SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 8,
138*635a8641SAndroid Build Coastguard Worker unsigned>::type
CountTrailingZeroBits(T value)139*635a8641SAndroid Build Coastguard Worker CountTrailingZeroBits(T value) {
140*635a8641SAndroid Build Coastguard Worker return LIKELY(value) ? bits == 64
141*635a8641SAndroid Build Coastguard Worker ? __builtin_ctzll(static_cast<uint64_t>(value))
142*635a8641SAndroid Build Coastguard Worker : __builtin_ctz(static_cast<uint32_t>(value))
143*635a8641SAndroid Build Coastguard Worker : bits;
144*635a8641SAndroid Build Coastguard Worker }
145*635a8641SAndroid Build Coastguard Worker
CountLeadingZeroBits32(uint32_t x)146*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE uint32_t CountLeadingZeroBits32(uint32_t x) {
147*635a8641SAndroid Build Coastguard Worker return CountLeadingZeroBits(x);
148*635a8641SAndroid Build Coastguard Worker }
149*635a8641SAndroid Build Coastguard Worker
150*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_64_BITS)
151*635a8641SAndroid Build Coastguard Worker
CountLeadingZeroBits64(uint64_t x)152*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE uint64_t CountLeadingZeroBits64(uint64_t x) {
153*635a8641SAndroid Build Coastguard Worker return CountLeadingZeroBits(x);
154*635a8641SAndroid Build Coastguard Worker }
155*635a8641SAndroid Build Coastguard Worker
156*635a8641SAndroid Build Coastguard Worker #endif
157*635a8641SAndroid Build Coastguard Worker
158*635a8641SAndroid Build Coastguard Worker #endif
159*635a8641SAndroid Build Coastguard Worker
CountLeadingZeroBitsSizeT(size_t x)160*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE size_t CountLeadingZeroBitsSizeT(size_t x) {
161*635a8641SAndroid Build Coastguard Worker return CountLeadingZeroBits(x);
162*635a8641SAndroid Build Coastguard Worker }
163*635a8641SAndroid Build Coastguard Worker
CountTrailingZeroBitsSizeT(size_t x)164*635a8641SAndroid Build Coastguard Worker ALWAYS_INLINE size_t CountTrailingZeroBitsSizeT(size_t x) {
165*635a8641SAndroid Build Coastguard Worker return CountTrailingZeroBits(x);
166*635a8641SAndroid Build Coastguard Worker }
167*635a8641SAndroid Build Coastguard Worker
168*635a8641SAndroid Build Coastguard Worker // Returns the integer i such as 2^i <= n < 2^(i+1)
Log2Floor(uint32_t n)169*635a8641SAndroid Build Coastguard Worker inline int Log2Floor(uint32_t n) {
170*635a8641SAndroid Build Coastguard Worker return 31 - CountLeadingZeroBits(n);
171*635a8641SAndroid Build Coastguard Worker }
172*635a8641SAndroid Build Coastguard Worker
173*635a8641SAndroid Build Coastguard Worker // Returns the integer i such as 2^(i-1) < n <= 2^i
Log2Ceiling(uint32_t n)174*635a8641SAndroid Build Coastguard Worker inline int Log2Ceiling(uint32_t n) {
175*635a8641SAndroid Build Coastguard Worker // When n == 0, we want the function to return -1.
176*635a8641SAndroid Build Coastguard Worker // When n == 0, (n - 1) will underflow to 0xFFFFFFFF, which is
177*635a8641SAndroid Build Coastguard Worker // why the statement below starts with (n ? 32 : -1).
178*635a8641SAndroid Build Coastguard Worker return (n ? 32 : -1) - CountLeadingZeroBits(n - 1);
179*635a8641SAndroid Build Coastguard Worker }
180*635a8641SAndroid Build Coastguard Worker
181*635a8641SAndroid Build Coastguard Worker } // namespace bits
182*635a8641SAndroid Build Coastguard Worker } // namespace base
183*635a8641SAndroid Build Coastguard Worker
184*635a8641SAndroid Build Coastguard Worker #endif // BASE_BITS_H_
185