236 lines
5.3 KiB
C++
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, 192);
|
|
}
|
|
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;
|
|
}
|
|
} |