[+] AuBitScanForwardItr
[+] AuBitScanReverseItr [*] u64 on 32bit CPU fixes mostly under reverse bit itrs
This commit is contained in:
parent
a563ba611f
commit
4d7f4fab7d
@ -106,6 +106,9 @@ static auline void AuBitClear(T &value, AuUInt8 idx)
|
||||
value &= ~(T(1) << T(idx));
|
||||
}
|
||||
|
||||
/// Bit scan forward from LSB to MSB, returning LSB-indexed offset in index and true if found.
|
||||
/// xref MSDN for "_BitScanForward" intrin
|
||||
/// (+ u64 variants work on 32bit targets)
|
||||
template <class T>
|
||||
static auline bool AuBitScanForward(AuUInt8 &index, T value)
|
||||
{
|
||||
@ -144,7 +147,7 @@ static auline bool AuBitScanForward(AuUInt8 &index, T value)
|
||||
if constexpr (sizeof(T) == sizeof(AuUInt64))
|
||||
{
|
||||
#if defined(AURORA_IS_32BIT)
|
||||
auto lower = static_cast<AuUInt32>(value & 0xffffffff));
|
||||
auto lower = static_cast<AuUInt32>(value & 0xffffffff);
|
||||
if (lower == 0)
|
||||
{
|
||||
ret = __builtin_ctzl(static_cast<AuUInt32>((value >> 32) & 0xffffffff));
|
||||
@ -173,6 +176,9 @@ static auline bool AuBitScanForward(AuUInt8 &index, T value)
|
||||
return success;
|
||||
}
|
||||
|
||||
/// Bit scan reverse from MSB to LSB, returning LSB-indexed offset in index and true if found.
|
||||
/// xref MSDN for "_BitScanReverse" intrin
|
||||
/// (+ u64 variants work on 32bit targets)
|
||||
template <class T>
|
||||
static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
||||
{
|
||||
@ -192,6 +198,9 @@ static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += 32;
|
||||
}
|
||||
#else
|
||||
@ -211,16 +220,16 @@ static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
||||
if constexpr (sizeof(T) == sizeof(AuUInt64))
|
||||
{
|
||||
#if defined(AURORA_IS_32BIT)
|
||||
auto lower = static_cast<AuUInt32>((value >> 32) & 0xffffffff);
|
||||
if (lower == 0)
|
||||
auto higher = static_cast<AuUInt32>((value >> 32) & 0xffffffff);
|
||||
if (higher == 0)
|
||||
{
|
||||
ret = __builtin_clzl(static_cast<AuUInt32>(value & 0xffffffff)));
|
||||
ret = 63 - ret;
|
||||
ret = __builtin_clzl(static_cast<AuUInt32>(value & 0xffffffff));
|
||||
ret = 31 - ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = __builtin_clzl(static_cast<AuUInt32>(lower));
|
||||
ret = 31 - ret;
|
||||
ret = __builtin_clzl(static_cast<AuUInt32>(higher));
|
||||
ret = 63 - ret;
|
||||
}
|
||||
#else
|
||||
ret = __builtin_clzll(static_cast<AuUInt64>(value));
|
||||
@ -258,6 +267,41 @@ static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
||||
return success;
|
||||
}
|
||||
|
||||
/// AuBitScanForward utility - offsets value by uOffset of last uIndex
|
||||
template <class T>
|
||||
static auline bool AuBitScanForwardItr(AuUInt8 &uIndex, T value, AuUInt8 uOffset = 0)
|
||||
{
|
||||
if (AuBitScanForward<T>(uIndex, value >> uOffset))
|
||||
{
|
||||
uIndex += uOffset;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// AuBitScanReverse utility - offsets value by uOffset of last uIndex, starting at end bit offset, to break/false on 0.
|
||||
template <class T>
|
||||
static auline bool AuBitScanReverseItr(AuUInt8 &uIndex, T value, AuUInt8 uOffset = sizeof(T) * 8)
|
||||
{
|
||||
if (uOffset == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
AuUInt32 uBitOffset2 = AuUInt32(8 * sizeof(T)) - uOffset;
|
||||
if (AuBitScanReverse<T>(uIndex, (T(value) << uBitOffset2)))
|
||||
{
|
||||
uIndex -= uBitOffset2;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct AuHalfWord
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user