/*** 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("{1:#0{0}b} {2:#0{0}b} {3:#0{0}b} {4:#0{0}b}", sizeof(decltype(lower)) * 8, lower, upper, upper2, upper3); #else return fmt::format("{1:#0{0}b} {2:#0{0}b}", sizeof(decltype(lower)) * 8, lower, upper); #endif } bool CpuBitId::CpuBitScanForward(AuUInt8 &index, AuUInt8 offset) const { #if defined(_AU_MASSIVE_CPUID) if (offset >= 192) { if (!AuBitScanForward(index, AuUInt64(upper3) >> AuUInt64(offset - 192))) return false; index += 192; } else if (offset >= 128) { if (!AuBitScanForward(index, AuUInt64(upper2) >> AuUInt64(offset - 128))) return false; index += 128; } else #endif if (offset >= 64) { if (!AuBitScanForward(index, AuUInt64(upper) >> AuUInt64(offset - 64))) return false; index += 64; } else { if (!AuBitScanForward(index, AuUInt64(lower) >> AuUInt64(0))) return false; } 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::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; } }