Commit 7dfd16b3 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[utils] Remove WhichPowerOf2_64 and generalize WhichPowerOf2

The WhichPowerOf2 function now takes arbitrary integer arguments, and
hence subsumes the WhichPowerOf2_64 function.

R=mstarzinger@chromium.org

Change-Id: I0692a17bbbe0074425d7c330342bc6fa34fb9d5c
Reviewed-on: https://chromium-review.googlesource.com/568495
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46646}
parent 050dec2b
...@@ -532,7 +532,7 @@ int32_t LeftShiftForReducedMultiply(Matcher* m) { ...@@ -532,7 +532,7 @@ int32_t LeftShiftForReducedMultiply(Matcher* m) {
if (m->right().HasValue() && m->right().Value() >= 3) { if (m->right().HasValue() && m->right().Value() >= 3) {
uint64_t value_minus_one = m->right().Value() - 1; uint64_t value_minus_one = m->right().Value() - 1;
if (base::bits::IsPowerOfTwo(value_minus_one)) { if (base::bits::IsPowerOfTwo(value_minus_one)) {
return WhichPowerOf2_64(value_minus_one); return WhichPowerOf2(value_minus_one);
} }
} }
return 0; return 0;
......
...@@ -52,61 +52,28 @@ inline bool CStringEquals(const char* s1, const char* s2) { ...@@ -52,61 +52,28 @@ inline bool CStringEquals(const char* s1, const char* s2) {
return (s1 == s2) || (s1 != NULL && s2 != NULL && strcmp(s1, s2) == 0); return (s1 == s2) || (s1 != NULL && s2 != NULL && strcmp(s1, s2) == 0);
} }
// X must be a power of 2. Returns the number of trailing zeros. // X must be a power of 2. Returns the number of trailing zeros.
inline int WhichPowerOf2(uint32_t x) { template <typename T,
DCHECK(base::bits::IsPowerOfTwo(x)); typename = typename std::enable_if<std::is_integral<T>::value>::type>
int bits = 0; inline int WhichPowerOf2(T x) {
#ifdef DEBUG
uint32_t original_x = x;
#endif
if (x >= 0x10000) {
bits += 16;
x >>= 16;
}
if (x >= 0x100) {
bits += 8;
x >>= 8;
}
if (x >= 0x10) {
bits += 4;
x >>= 4;
}
switch (x) {
default: UNREACHABLE();
case 8: bits++; // Fall through.
case 4: bits++; // Fall through.
case 2: bits++; // Fall through.
case 1: break;
}
DCHECK_EQ(static_cast<uint32_t>(1) << bits, original_x);
return bits;
}
// X must be a power of 2. Returns the number of trailing zeros.
inline int WhichPowerOf2_64(uint64_t x) {
DCHECK(base::bits::IsPowerOfTwo(x)); DCHECK(base::bits::IsPowerOfTwo(x));
int bits = 0; int bits = 0;
#ifdef DEBUG #ifdef DEBUG
uint64_t original_x = x; const T original_x = x;
#endif #endif
if (x >= 0x100000000L) { constexpr int max_bits = sizeof(T) * 8;
bits += 32; static_assert(max_bits <= 64, "integral types are not bigger than 64 bits");
x >>= 32; // Avoid shifting by more than the bit width of x to avoid compiler warnings.
} #define CHECK_BIGGER(s) \
if (x >= 0x10000) { if (max_bits > s && x >= T{1} << (max_bits > s ? s : 0)) { \
bits += 16; bits += s; \
x >>= 16; x >>= max_bits > s ? s : 0; \
} }
if (x >= 0x100) { CHECK_BIGGER(32)
bits += 8; CHECK_BIGGER(16)
x >>= 8; CHECK_BIGGER(8)
} CHECK_BIGGER(4)
if (x >= 0x10) { #undef CHECK_BIGGER
bits += 4;
x >>= 4;
}
switch (x) { switch (x) {
default: UNREACHABLE(); default: UNREACHABLE();
case 8: bits++; // Fall through. case 8: bits++; // Fall through.
...@@ -114,11 +81,10 @@ inline int WhichPowerOf2_64(uint64_t x) { ...@@ -114,11 +81,10 @@ inline int WhichPowerOf2_64(uint64_t x) {
case 2: bits++; // Fall through. case 2: bits++; // Fall through.
case 1: break; case 1: break;
} }
DCHECK_EQ(static_cast<uint64_t>(1) << bits, original_x); DCHECK_EQ(T{1} << bits, original_x);
return bits; return bits;
} }
inline int MostSignificantBit(uint32_t x) { inline int MostSignificantBit(uint32_t x) {
static const int msb4[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4}; static const int msb4[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
int nibble = 0; int nibble = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment