Merge pull request #11130 from Minty-Meeo/count-zeroes-c++20
Replace BitUtils with C++20: Counting Zeroes
This commit is contained in:
commit
5b63f9aa5e
|
@ -559,11 +559,11 @@ struct LogicalImm
|
||||||
// pick the next sequence of ones. This ensures we get a complete element
|
// 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.
|
// 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 u64 normalized = std::rotr(value, rotation);
|
||||||
|
|
||||||
const int element_size = Common::CountTrailingZeros(normalized & (normalized + 1));
|
const int element_size = std::countr_zero(normalized & (normalized + 1));
|
||||||
const int ones = Common::CountTrailingZeros(~normalized);
|
const int ones = std::countr_one(normalized);
|
||||||
|
|
||||||
// Check the value is repeating; also ensures element size is a power of two.
|
// Check the value is repeating; also ensures element size is a power of two.
|
||||||
|
|
||||||
|
@ -578,8 +578,8 @@ struct LogicalImm
|
||||||
// segment.
|
// segment.
|
||||||
|
|
||||||
r = static_cast<u8>((element_size - rotation) & (element_size - 1));
|
r = static_cast<u8>((element_size - rotation) & (element_size - 1));
|
||||||
s = (((~element_size + 1) << 1) | (ones - 1)) & 0x3f;
|
s = static_cast<u8>((((~element_size + 1) << 1) | (ones - 1)) & 0x3f);
|
||||||
n = (element_size >> 6) & 1;
|
n = Common::ExtractBit<6>(element_size);
|
||||||
|
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,6 @@
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <intrin.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
|
@ -316,105 +312,4 @@ T ExpandValue(T value, size_t left_shift_amount)
|
||||||
return (value << left_shift_amount) |
|
return (value << left_shift_amount) |
|
||||||
(T(-ExtractBit<0>(value)) >> (BitSize<T>() - 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
|
} // namespace Common
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/BitUtils.h"
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
namespace MathUtil
|
namespace MathUtil
|
||||||
|
@ -193,5 +193,5 @@ float MathFloatVectorSum(const std::vector<float>&);
|
||||||
// Rounds down. 0 -> undefined
|
// Rounds down. 0 -> undefined
|
||||||
constexpr int IntLog2(u64 val)
|
constexpr int IntLog2(u64 val)
|
||||||
{
|
{
|
||||||
return 63 - Common::CountLeadingZeros(val);
|
return 63 - std::countl_zero(val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ void Interpreter::cmpl(UGeckoInstruction inst)
|
||||||
|
|
||||||
void Interpreter::cntlzwx(UGeckoInstruction inst)
|
void Interpreter::cntlzwx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
rGPR[inst.RA] = u32(Common::CountLeadingZeros(rGPR[inst.RS]));
|
rGPR[inst.RA] = u32(std::countl_zero(rGPR[inst.RS]));
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
Helper_UpdateCR0(rGPR[inst.RA]);
|
Helper_UpdateCR0(rGPR[inst.RA]);
|
||||||
|
|
|
@ -2660,7 +2660,7 @@ void Jit64::cntlzwx(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (gpr.IsImm(s))
|
if (gpr.IsImm(s))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate32(a, Common::CountLeadingZeros(gpr.Imm32(s)));
|
gpr.SetImmediate32(a, static_cast<u32>(std::countl_zero(gpr.Imm32(s))));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -528,7 +528,7 @@ void JitArm64::cntlzwx(UGeckoInstruction inst)
|
||||||
|
|
||||||
if (gpr.IsImm(s))
|
if (gpr.IsImm(s))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(a, Common::CountLeadingZeros(gpr.GetImm(s)));
|
gpr.SetImmediate(a, static_cast<u32>(std::countl_zero(gpr.GetImm(s))));
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC0(gpr.GetImm(a));
|
ComputeRC0(gpr.GetImm(a));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
#include "VideoBackends/Metal/MTLStateTracker.h"
|
#include "VideoBackends/Metal/MTLStateTracker.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/BitUtils.h"
|
|
||||||
|
|
||||||
#include "VideoBackends/Metal/MTLObjectCache.h"
|
#include "VideoBackends/Metal/MTLObjectCache.h"
|
||||||
#include "VideoBackends/Metal/MTLPerfQuery.h"
|
#include "VideoBackends/Metal/MTLPerfQuery.h"
|
||||||
|
@ -713,8 +713,8 @@ static constexpr NSString* LABEL_UTIL = @"Utility Draw";
|
||||||
static NSRange RangeOfBits(u32 value)
|
static NSRange RangeOfBits(u32 value)
|
||||||
{
|
{
|
||||||
ASSERT(value && "Value must be nonzero");
|
ASSERT(value && "Value must be nonzero");
|
||||||
u32 low = Common::CountTrailingZeros(value);
|
int low = std::countr_zero(value);
|
||||||
u32 high = 31 - Common::CountLeadingZeros(value);
|
int high = 31 - std::countl_zero(value);
|
||||||
return NSMakeRange(low, high + 1 - low);
|
return NSMakeRange(low, high + 1 - low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
#include "Common/BitUtils.h"
|
#include "Common/BitUtils.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
@ -82,7 +83,7 @@ inline u32 CompressZ16(u32 z24depth, DepthFormat format)
|
||||||
// If exponent is at the MAX (3, 7, or 12) then the next bit might still be a one, and can't
|
// If exponent is at the MAX (3, 7, or 12) then the next bit might still be a one, and can't
|
||||||
// be skipped, so the mantissa simply contains the next 14/13/12 bits
|
// be skipped, so the mantissa simply contains the next 14/13/12 bits
|
||||||
|
|
||||||
u32 leading_ones = Common::CountLeadingZeros((~z24depth) << 8);
|
u32 leading_ones = static_cast<u32>(std::countl_one(z24depth << 8));
|
||||||
bool next_bit_is_one = false; // AKA: Did we clamp leading_ones?
|
bool next_bit_is_one = false; // AKA: Did we clamp leading_ones?
|
||||||
u32 exp_bits;
|
u32 exp_bits;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue