[+] 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));
|
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>
|
template <class T>
|
||||||
static auline bool AuBitScanForward(AuUInt8 &index, T value)
|
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 constexpr (sizeof(T) == sizeof(AuUInt64))
|
||||||
{
|
{
|
||||||
#if defined(AURORA_IS_32BIT)
|
#if defined(AURORA_IS_32BIT)
|
||||||
auto lower = static_cast<AuUInt32>(value & 0xffffffff));
|
auto lower = static_cast<AuUInt32>(value & 0xffffffff);
|
||||||
if (lower == 0)
|
if (lower == 0)
|
||||||
{
|
{
|
||||||
ret = __builtin_ctzl(static_cast<AuUInt32>((value >> 32) & 0xffffffff));
|
ret = __builtin_ctzl(static_cast<AuUInt32>((value >> 32) & 0xffffffff));
|
||||||
@ -173,6 +176,9 @@ static auline bool AuBitScanForward(AuUInt8 &index, T value)
|
|||||||
return success;
|
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>
|
template <class T>
|
||||||
static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
||||||
{
|
{
|
||||||
@ -192,6 +198,9 @@ static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ret += 32;
|
ret += 32;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -211,16 +220,16 @@ static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
|||||||
if constexpr (sizeof(T) == sizeof(AuUInt64))
|
if constexpr (sizeof(T) == sizeof(AuUInt64))
|
||||||
{
|
{
|
||||||
#if defined(AURORA_IS_32BIT)
|
#if defined(AURORA_IS_32BIT)
|
||||||
auto lower = static_cast<AuUInt32>((value >> 32) & 0xffffffff);
|
auto higher = static_cast<AuUInt32>((value >> 32) & 0xffffffff);
|
||||||
if (lower == 0)
|
if (higher == 0)
|
||||||
{
|
{
|
||||||
ret = __builtin_clzl(static_cast<AuUInt32>(value & 0xffffffff)));
|
ret = __builtin_clzl(static_cast<AuUInt32>(value & 0xffffffff));
|
||||||
ret = 63 - ret;
|
ret = 31 - ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = __builtin_clzl(static_cast<AuUInt32>(lower));
|
ret = __builtin_clzl(static_cast<AuUInt32>(higher));
|
||||||
ret = 31 - ret;
|
ret = 63 - ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
ret = __builtin_clzll(static_cast<AuUInt64>(value));
|
ret = __builtin_clzll(static_cast<AuUInt64>(value));
|
||||||
@ -258,6 +267,41 @@ static auline bool AuBitScanReverse(AuUInt8 &index, T value)
|
|||||||
return success;
|
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>
|
template <class T>
|
||||||
struct AuHalfWord
|
struct AuHalfWord
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user