AuroraRuntime/Include/Aurora/HWInfo/CpuBitId.inl
2022-03-17 13:07:51 +00:00

236 lines
5.3 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CpuBitId.hpp
Date: 2022-1-24
Author: Reece
***/
#pragma once
namespace Aurora::HWInfo
{
CpuBitId::CpuBitId()
{
}
CpuBitId::~CpuBitId()
{
}
CpuBitId::CpuBitId(AuUInt8 id)
{
SetBit(id);
}
AuString CpuBitId::ToString() const
{
#if defined(_AU_MASSIVE_CPUID)
return fmt::format("{4:#0{0}b} {3:#0{0}b} {2:#0{0}b} {1:#0{0}b}", sizeof(decltype(lower)) * 8, lower, upper, upper2, upper3);
#else
return fmt::format("{2:#0{0}b} {1:#0{0}b}", sizeof(decltype(lower)) * 8, lower, upper);
#endif
}
inline AuUInt8 CpuBitId::CpuBitCount() const
{
return AuPopCnt(lower) +
AuPopCnt(upper)
#if defined(_AU_MASSIVE_CPUID)
+ AuPopCnt(upper2)
+ AuPopCnt(upper3)
#endif
;
}
bool CpuBitId::CpuBitScanForward(AuUInt8 &index, AuUInt8 offset) const
{
AuUInt8 tempIndex = index;
#if defined(_AU_MASSIVE_CPUID)
if (offset >= 192)
{
if (!AuBitScanForward(tempIndex, AuUInt64(upper3) >> AuUInt64(offset - 192)))
{
return false;
}
tempIndex += (192 + offset);
}
else if (offset >= 128)
{
if (!AuBitScanForward(tempIndex, AuUInt64(upper2) >> AuUInt64(offset - 128)))
{
return CpuBitScanForward(index, 128);
}
tempIndex += (128 + offset);
}
#else
if (offset >= 128)
{
return false;
}
#endif
else if (offset >= 64)
{
if (!AuBitScanForward(tempIndex, AuUInt64(upper) >> AuUInt64(offset - 64)))
{
return CpuBitScanForward(index, 128);
}
tempIndex += (64 + offset);
}
else
{
if (!AuBitScanForward(tempIndex, AuUInt64(lower) >> AuUInt64(offset)))
{
return CpuBitScanForward(index, 64);
}
tempIndex += offset;
}
index = tempIndex;
return true;
}
bool CpuBitId::HasValue() const
{
return lower || upper
#if defined(_AU_MASSIVE_CPUID)
|| upper2
|| upper3
#endif
;
}
void CpuBitId::Add(const CpuBitId &id)
{
lower |= id.lower;
upper |= id.upper;
#if defined(_AU_MASSIVE_CPUID)
upper2 |= id.upper2;
upper3 |= id.upper3;
#endif
}
CpuBitId CpuBitId::Not() const
{
CpuBitId ret = *this;
ret.lower = ~ret.lower;
ret.upper = ~ret.upper;
#if defined(_AU_MASSIVE_CPUID)
ret.upper2 = ~ret.upper2;
ret.upper3 = ~ret.upper3;
#endif
return ret;
}
CpuBitId CpuBitId::And(const CpuBitId &id) const
{
CpuBitId ret = *this;
ret.lower &= id.lower;
ret.upper &= id.upper;
#if defined(_AU_MASSIVE_CPUID)
ret.upper2 &= id.upper2;
ret.upper3 &= id.upper3;
#endif
return ret;
}
CpuBitId CpuBitId::Xor(const CpuBitId &id) const
{
CpuBitId ret = *this;
ret.lower ^= id.lower;
ret.upper ^= id.upper;
#if defined(_AU_MASSIVE_CPUID)
ret.upper2 ^= id.upper2;
ret.upper3 ^= id.upper3;
#endif
return ret;
}
CpuBitId CpuBitId::Or(const CpuBitId &id) const
{
CpuBitId ret = *this;
ret.lower |= id.lower;
ret.upper |= id.upper;
#if defined(_AU_MASSIVE_CPUID)
ret.upper2 |= id.upper2;
ret.upper3 |= id.upper3;
#endif
return ret;
}
CpuBitId &CpuBitId::operator=(const CpuBitId &id)
{
lower = id.lower;
upper = id.upper;
#if defined(_AU_MASSIVE_CPUID)
upper2 = id.upper2;
upper3 = id.upper3;
#endif
return *this;
}
CpuBitId::operator bool() const
{
return HasValue();
}
bool CpuBitId::TestCpuIdx(AuUInt8 idx) const
{
return TestBit(idx);
}
void CpuBitId::Clear()
{
lower = {};
upper = {};
}
void CpuBitId::SetBit(AuUInt8 idx)
{
#if defined(_AU_MASSIVE_CPUID)
if (idx >= 192)
upper3 |= AuUInt64(1) << AuUInt64(idx - 192);
else if (idx >= 128)
upper2 |= AuUInt64(1) << AuUInt64(idx - 128);
else
#endif
if (idx >= 64)
upper |= AuUInt64(1) << AuUInt64(idx - 64);
else
lower |= AuUInt64(1) << AuUInt64(idx);
}
void CpuBitId::ClearBit(AuUInt8 idx)
{
#if defined(_AU_MASSIVE_CPUID)
if (idx >= 192)
upper3 &= ~(AuUInt64(1) << AuUInt64(idx - 192));
else if (idx >= 128)
upper2 &= ~(AuUInt64(1) << AuUInt64(idx - 128));
else
#endif
if (idx >= 64)
upper &= ~(AuUInt64(1) << AuUInt64(idx - 64));
else
lower &= ~(AuUInt64(1) << AuUInt64(idx));
}
bool CpuBitId::TestBit(AuUInt8 idx) const
{
bool ret {};
#if defined(_AU_MASSIVE_CPUID)
if (idx >= 192)
ret = upper3 & (AuUInt64(1) << AuUInt64(idx - 192));
else if (idx >= 128)
ret = upper2 & (AuUInt64(1) << AuUInt64(idx - 128));
else
#endif
if (idx >= 64)
ret = upper & (AuUInt64(1) << AuUInt64(idx - 64));
else
ret = lower & (AuUInt64(1) << AuUInt64(idx));
return ret;
}
}