Replace BitUtils with C++20: Counting Zeroes

With the upgrade to C++20, std::countl_zero and std::countr_zero can replace these home-spun implementations from the BitUtil.h library.
This commit is contained in:
Minty-Meeo
2022-10-10 04:03:15 -05:00
parent d853da3b0b
commit 05bebee802
8 changed files with 15 additions and 119 deletions

View File

@ -559,11 +559,11 @@ struct LogicalImm
// pick the next sequence of ones. This ensures we get a complete element
// that has not been cut-in-half due to rotation across the word boundary.
const int rotation = Common::CountTrailingZeros(value & (value + 1));
const int rotation = std::countr_zero(value & (value + 1));
const u64 normalized = std::rotr(value, rotation);
const int element_size = Common::CountTrailingZeros(normalized & (normalized + 1));
const int ones = Common::CountTrailingZeros(~normalized);
const int element_size = std::countr_zero(normalized & (normalized + 1));
const int ones = std::countr_one(normalized);
// Check the value is repeating; also ensures element size is a power of two.
@ -578,8 +578,8 @@ struct LogicalImm
// segment.
r = static_cast<u8>((element_size - rotation) & (element_size - 1));
s = (((~element_size + 1) << 1) | (ones - 1)) & 0x3f;
n = (element_size >> 6) & 1;
s = static_cast<u8>((((~element_size + 1) << 1) | (ones - 1)) & 0x3f);
n = Common::ExtractBit<6>(element_size);
valid = true;
}

View File

@ -11,10 +11,6 @@
#include <initializer_list>
#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace Common
{
///
@ -316,105 +312,4 @@ T ExpandValue(T value, size_t left_shift_amount)
return (value << left_shift_amount) |
(T(-ExtractBit<0>(value)) >> (BitSize<T>() - left_shift_amount));
}
template <typename T>
constexpr int CountLeadingZerosConst(T value)
{
int result = sizeof(T) * 8;
while (value)
{
result--;
value >>= 1;
}
return result;
}
constexpr int CountLeadingZeros(uint64_t value)
{
#if defined(__GNUC__)
return value ? __builtin_clzll(value) : 64;
#elif defined(_MSC_VER)
if (std::is_constant_evaluated())
{
return CountLeadingZerosConst(value);
}
else
{
unsigned long index = 0;
return _BitScanReverse64(&index, value) ? 63 - index : 64;
}
#else
return CountLeadingZerosConst(value);
#endif
}
constexpr int CountLeadingZeros(uint32_t value)
{
#if defined(__GNUC__)
return value ? __builtin_clz(value) : 32;
#elif defined(_MSC_VER)
if (std::is_constant_evaluated())
{
return CountLeadingZerosConst(value);
}
else
{
unsigned long index = 0;
return _BitScanReverse(&index, value) ? 31 - index : 32;
}
#else
return CountLeadingZerosConst(value);
#endif
}
template <typename T>
constexpr int CountTrailingZerosConst(T value)
{
int result = sizeof(T) * 8;
while (value)
{
result--;
value <<= 1;
}
return result;
}
constexpr int CountTrailingZeros(uint64_t value)
{
#if defined(__GNUC__)
return value ? __builtin_ctzll(value) : 64;
#elif defined(_MSC_VER)
if (std::is_constant_evaluated())
{
return CountTrailingZerosConst(value);
}
else
{
unsigned long index = 0;
return _BitScanForward64(&index, value) ? index : 64;
}
#else
return CountTrailingZerosConst(value);
#endif
}
constexpr int CountTrailingZeros(uint32_t value)
{
#if defined(__GNUC__)
return value ? __builtin_ctz(value) : 32;
#elif defined(_MSC_VER)
if (std::is_constant_evaluated())
{
return CountTrailingZerosConst(value);
}
else
{
unsigned long index = 0;
return _BitScanForward(&index, value) ? index : 32;
}
#else
return CountTrailingZerosConst(value);
#endif
}
} // namespace Common

View File

@ -4,12 +4,12 @@
#pragma once
#include <algorithm>
#include <bit>
#include <cmath>
#include <limits>
#include <type_traits>
#include <vector>
#include "Common/BitUtils.h"
#include "Common/CommonTypes.h"
namespace MathUtil
@ -193,5 +193,5 @@ float MathFloatVectorSum(const std::vector<float>&);
// Rounds down. 0 -> undefined
constexpr int IntLog2(u64 val)
{
return 63 - Common::CountLeadingZeros(val);
return 63 - std::countl_zero(val);
}