diff --git a/CMakeLists.txt b/CMakeLists.txt index e3eda96..4f9acbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,8 @@ set(EHS_SOURCES include/ehs/system/OS.h include/ehs/system/Semaphore.h include/ehs/system/System.h + include/ehs/system/AVX2.h + include/ehs/system/AVX512.h src/json/Json.cpp include/ehs/json/Json.h src/json/JsonBase.cpp include/ehs/json/JsonBase.h @@ -252,7 +254,7 @@ elseif (IS_OS_LINUX) endif () if (IS_ARCH_AMD64) - list(APPEND EHS_SOURCES src/system/CPU_GCC_AMD64.asm src/HRNG_GCC.asm src/Math_GCC_AMD64.asm) + list(APPEND EHS_SOURCES src/system/CPU_GCC_AMD64.asm src/HRNG_GCC.asm src/Math_GCC_AMD64.asm src/system/AVX2_GCC_AMD64.asm src/system/AVX512_GCC_AMD64.asm) elseif (IS_ARCH_ARM64) list(APPEND EHS_SOURCES src/system/CPU_ARM64.cpp src/HRNG_ARM64.cpp src/Math_GCC_ARM64.s) endif () diff --git a/include/ehs/Log.h b/include/ehs/Log.h index 7eccf5a..c38d4fc 100644 --- a/include/ehs/Log.h +++ b/include/ehs/Log.h @@ -134,17 +134,17 @@ namespace ehs #ifndef EHS_LOG_INT #ifdef EHS_DEBUG - #define EHS_LOG_INT(type, code, msg) ehs::Log::Raise({type, {ehs::GetAcronym_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg}) + #define EHS_LOG_INT(type, code, msg) ehs::Log::Raise(ehs::Log(type, {ehs::GetAcronym_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg)) #else - #define EHS_LOG_INT(type, code, msg) ehs::Log::Raise({type, {ehs::GetAcronym_8(), EHS_FUNC}, code, msg}) + #define EHS_LOG_INT(type, code, msg) ehs::Log::Raise(ehs::Log(type, {ehs::GetAcronym_8(), EHS_FUNC}, code, msg)) #endif #endif #ifndef EHS_LOG #ifdef EHS_DEBUG - #define EHS_LOG(type, code, msg) ehs::Log::Raise({type, {ehs::GetAppName_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg}) + #define EHS_LOG(type, code, msg) ehs::Log::Raise(ehs::Log(type, {ehs::GetAppName_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg)) #else - #define EHS_LOG(type, code, msg) ehs::Log::Raise({type, {ehs::GetAppName_8(), EHS_FUNC}, code, msg}) + #define EHS_LOG(type, code, msg) ehs::Log::Raise(ehs::Log(type, {ehs::GetAppName_8(), EHS_FUNC}, code, msg)) #endif #endif diff --git a/include/ehs/system/AVX2.h b/include/ehs/system/AVX2.h new file mode 100644 index 0000000..7744cad --- /dev/null +++ b/include/ehs/system/AVX2.h @@ -0,0 +1,36 @@ +#pragma once + +#include "ehs/Types.h" + +namespace ehs +{ + class AVX2 + { + public: + /// Compares two unaligned 4 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 4 elements are equal. False otherwise. + static bool CompareUnaligned(const UInt_64 *a, const UInt_64 *b); + + /// Compares two unaligned 4 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 4 elements are equal. False otherwise. + static bool CompareUnaligned(const SInt_64 *a, const SInt_64 *b); + + /// Compares two aligned 4 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 4 elements are equal. False otherwise. + /// @note The parameters "a", and "b" must have alignas(32). + static bool CompareAligned(const UInt_64 *a, const UInt_64 *b); + + /// Compares two aligned 4 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 4 elements are equal. False otherwise. + /// @note The parameters "a", and "b" must have alignas(32). + static bool CompareAligned(const SInt_64 *a, const SInt_64 *b); + }; +} diff --git a/include/ehs/system/AVX512.h b/include/ehs/system/AVX512.h new file mode 100644 index 0000000..ca13a1a --- /dev/null +++ b/include/ehs/system/AVX512.h @@ -0,0 +1,36 @@ +#pragma once + +#include "ehs/Types.h" + +namespace ehs +{ + class AVX512 + { + public: + /// Compares two unaligned 8 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 8 elements are equal. False otherwise. + static bool CompareUnaligned(const UInt_64 *a, const UInt_64 *b); + + /// Compares two unaligned 8 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 8 elements are equal. False otherwise. + static bool CompareUnaligned(const SInt_64 *a, const SInt_64 *b); + + /// Compares two aligned 8 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 8 elements are equal. False otherwise. + /// @note The parameters "a", and "b" must have alignas(32). + static bool CompareAligned(const UInt_64 *a, const UInt_64 *b); + + /// Compares two aligned 8 element vectors using 64-bit integers. + /// @param [in] a First vector. + /// @param [in] b Second vector. + /// @returns True if all 8 elements are equal. False otherwise. + /// @note The parameters "a", and "b" must have alignas(32). + static bool CompareAligned(const SInt_64 *a, const SInt_64 *b); + }; +} \ No newline at end of file diff --git a/include/ehs/system/CPU.h b/include/ehs/system/CPU.h index e512fca..3b3e5cf 100644 --- a/include/ehs/system/CPU.h +++ b/include/ehs/system/CPU.h @@ -38,6 +38,70 @@ namespace ehs #endif public: + static const bool hasFPU; + static const bool hasVME; + static const bool hasDE; + static const bool hasPSE; + static const bool hasTSC; + static const bool hasMSR; + static const bool hasPAE; + static const bool hasMCE; + static const bool hasCX8; + static const bool hasAPIC; + static const bool hasSEP; + static const bool hasMTRR; + static const bool hasPGE; + static const bool hasMCA; + static const bool hasCMOV; + static const bool hasPSE_36; + static const bool hasPSN; + static const bool hasCLFSH; + static const bool hasDS; + static const bool hasACPI; + static const bool hasMMX; + static const bool hasFXSR; + static const bool hasSSE; + static const bool hasSSE2; + static const bool hasSS; + static const bool hasHTT; + static const bool hasTM; + static const bool hasIA64; + static const bool hasPBE; + static const bool hasSSE3; + static const bool hasPCLMULQDQ; + static const bool hasDTES64; + static const bool hasMONITOR; + static const bool hasVMX; + static const bool hasSMX; + static const bool hasEST; + static const bool hasTM2; + static const bool hasSSSE3; + static const bool hasCNXT_ID; + static const bool hasSDBG; + static const bool hasFMA; + static const bool hasCX16; + static const bool hasXTPR; + static const bool hasPDCM; + static const bool hasPCID; + static const bool hasDCA; + static const bool hasSSE4_1; + static const bool hasSSE4_2; + static const bool hasX2APIC; + static const bool hasMOVBE; + static const bool hasPOPCNT; + static const bool hasTSC_DEADLINE; + static const bool hasAES; + static const bool hasXSAVE; + static const bool hasOSXSAVE; + static const bool hasAVX; + static const bool hasF16C; + static const bool hasRDRND; + static const bool hasHYPERVISOR; + static const bool hasAVX2; + static const bool hasAVX512F; + static const bool hasRDSEED; + static const bool hasADX; + static Architecture GetArchitecture(); static UInt_8 PointerSize(); @@ -68,153 +132,155 @@ namespace ehs static UInt_8 GetExtFamilyId(); - static UInt_32 GetFeatureBits_1(); - - static bool HasFPU(); - - static bool HasVME(); - - static bool HasDE(); - - static bool HasPSE(); - - static bool HasTSC(); - - static bool HasMSR(); - - static bool HasPAE(); - - static bool HasMCE(); - - static bool HasCX8(); - - static bool HasAPIC(); - - static bool HasSEP(); - - static bool HasMTRR(); - - static bool HasPGE(); - - static bool HasMCA(); - - static bool HasCMOV(); - - static bool HasPAT(); - - static bool HasPSE_36(); - - static bool HasPSN(); - - static bool HasCLFSH(); - - static bool HasDS(); - - static bool HasACPI(); - - static bool HasMMX(); - - static bool HasFXSR(); - - static bool HasSSE(); - - static bool HasSSE2(); - - static bool HasSS(); - - static bool HasHTT(); - - static bool HasTM(); - - static bool HasIA64(); - - static bool HasPBE(); - - static UInt_32 GetFeatureBits_2(); - - static bool HasSSE3(); - - static bool HasPCLMULQDQ(); - - static bool HasDTES64(); - - static bool HasMONITOR(); - - static bool HasDS_CPL(); - - static bool HasVMX(); - - static bool HasSMX(); - - static bool HasEST(); - - static bool HasTM2(); - - static bool HasSSSE3(); - - static bool HasCNXT_ID(); - - static bool HasSDBG(); - - static bool HasFMA(); - - static bool HasCX16(); - - static bool HasXTPR(); - - static bool HasPDCM(); - - static bool HasPCID(); - - static bool HasDCA(); - - static bool HasSSE4_1(); - - static bool HasSSE4_2(); - - static bool HasX2APIC(); - - static bool HasMOVBE(); - - static bool HasPOPCNT(); - - static bool HasTSC_DEADLINE(); - - static bool HasAES(); - - static bool HasXSAVE(); - - static bool HasOSXSAVE(); - - static bool HasAVX(); - - static bool HasF16C(); - - static bool HasRDRND(); - - static bool HasHYPERVISOR(); - - static UInt_32 GetExtFeatureBits_1(); - - static bool HasAVX2(); - - static bool HasRDSEED(); - - static bool HasADX(); - - static UInt_32 GetExtFeatureBits_2(); - - static UInt_32 GetExtFeatureBits_3(); - - /// Retrieves the CPU brand as a null-terminated ASCII string. - /// @param[out] input A 48 byte character array representing the brand. + /// Retrieves the CPU brand as a null-terminated ASCII string. + /// @param[out] input A 48 byte character array representing the brand. static void GetBrand(Char_8* input); static UInt_8 GetCacheLineSize(); + static UInt_32 GetFeatureBits_1(); + + static UInt_32 GetFeatureBits_2(); + + static UInt_32 GetExtFeatureBits_1(); + + static UInt_32 GetExtFeatureBits_2(); + + static UInt_32 GetExtFeatureBits_3(); + + private: + static bool RetrieveFPU(); + + static bool RetrieveVME(); + + static bool RetrieveDE(); + + static bool RetrievePSE(); + + static bool RetrieveTSC(); + + static bool RetrieveMSR(); + + static bool RetrievePAE(); + + static bool RetrieveMCE(); + + static bool RetrieveCX8(); + + static bool RetrieveAPIC(); + + static bool RetrieveSEP(); + + static bool RetrieveMTRR(); + + static bool RetrievePGE(); + + static bool RetrieveMCA(); + + static bool RetrieveCMOV(); + + static bool RetrievePAT(); + + static bool RetrievePSE_36(); + + static bool RetrievePSN(); + + static bool RetrieveCLFSH(); + + static bool RetrieveDS(); + + static bool RetrieveACPI(); + + static bool RetrieveMMX(); + + static bool RetrieveFXSR(); + + static bool RetrieveSSE(); + + static bool RetrieveSSE2(); + + static bool RetrieveSS(); + + static bool RetrieveHTT(); + + static bool RetrieveTM(); + + static bool RetrieveIA64(); + + static bool RetrievePBE(); + + static bool RetrieveSSE3(); + + static bool RetrievePCLMULQDQ(); + + static bool RetrieveDTES64(); + + static bool RetrieveMONITOR(); + + static bool RetrieveDS_CPL(); + + static bool RetrieveVMX(); + + static bool RetrieveSMX(); + + static bool RetrieveEST(); + + static bool RetrieveTM2(); + + static bool RetrieveSSSE3(); + + static bool RetrieveCNXT_ID(); + + static bool RetrieveSDBG(); + + static bool RetrieveFMA(); + + static bool RetrieveCX16(); + + static bool RetrieveXTPR(); + + static bool RetrievePDCM(); + + static bool RetrievePCID(); + + static bool RetrieveDCA(); + + static bool RetrieveSSE4_1(); + + static bool RetrieveSSE4_2(); + + static bool RetrieveX2APIC(); + + static bool RetrieveMOVBE(); + + static bool RetrievePOPCNT(); + + static bool RetrieveTSC_DEADLINE(); + + static bool RetrieveAES(); + + static bool RetrieveXSAVE(); + + static bool RetrieveOSXSAVE(); + + static bool RetrieveAVX(); + + static bool RetrieveF16C(); + + static bool RetrieveRDRND(); + + static bool RetrieveHYPERVISOR(); + + static bool RetrieveAVX2(); + + static bool RetrieveAVX512F(); + + static bool RetrieveRDSEED(); + + static bool RetrieveADX(); + //static Str_8 ToStr(); - private: static UInt_64 RetrieveTSC_Freq(); static UInt_64 CalculateTSC_Freq(); diff --git a/src/Math.cpp b/src/Math.cpp index 790a04e..31ec2ef 100644 --- a/src/Math.cpp +++ b/src/Math.cpp @@ -36,9 +36,9 @@ namespace ehs double Math::Sqrt(const double from) { #if defined(EHS_ARCH_X64) - if (CPU::HasAVX()) + if (CPU::hasAVX) return Sqrt_AVX(from); - else if (CPU::HasSSE()) + else if (CPU::hasSSE) return Sqrt_SSE2(from); double temp = 0.0; @@ -59,9 +59,9 @@ namespace ehs float Math::Sqrt(const float from) { #if defined(EHS_ARCH_X64) - if (CPU::HasAVX()) + if (CPU::hasAVX) return Sqrt_AVX(from); - else if (CPU::HasSSE()) + else if (CPU::hasSSE) return Sqrt_SSE(from); float temp = 0.0f; diff --git a/src/Util.cpp b/src/Util.cpp index 6274956..c373964 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -1,5 +1,9 @@ #include "ehs/Util.h" +#include "ehs/system/CPU.h" +#include "ehs/system/AVX2.h" +#include "ehs/system/AVX512.h" + namespace ehs { bool Util::Compare(const void* const a, const void* const b, const UInt_64 size) @@ -11,7 +15,21 @@ namespace ehs while (i < size) { - if (remainder >= sizeof(UInt_64)) + if (CPU::hasAVX512F && remainder >= 64) + { + if (!AVX512::CompareUnaligned((UInt_64*)&aBytes[i], (UInt_64*)&bBytes[i])) + return false; + + i += 64; + } + else if (CPU::hasAVX2 && remainder >= 32) + { + if (!AVX2::CompareUnaligned((UInt_64*)&aBytes[i], (UInt_64*)&bBytes[i])) + return false; + + i += 32; + } + else if (remainder >= sizeof(UInt_64)) { if (*(UInt_64*)&aBytes[i] != *(UInt_64*)&bBytes[i]) return false; @@ -118,4 +136,4 @@ namespace ehs remainder = size - i; } } -} \ No newline at end of file +} diff --git a/src/system/AVX2_GCC_AMD64.asm b/src/system/AVX2_GCC_AMD64.asm new file mode 100644 index 0000000..2db1829 --- /dev/null +++ b/src/system/AVX2_GCC_AMD64.asm @@ -0,0 +1,49 @@ +global _ZN3ehs4AVX216CompareUnalignedEPKmS2_ +global _ZN3ehs4AVX216CompareUnalignedEPKlS2_ +global _ZN3ehs4AVX214CompareAlignedEPKmS2_ +global _ZN3ehs4AVX214CompareAlignedEPKlS2_ + +section .text + _ZN3ehs4AVX216CompareUnalignedEPKmS2_: + VMOVDQU YMM0, [RDI] + VMOVDQU YMM1, [RSI] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + _ZN3ehs4AVX216CompareUnalignedEPKlS2_: + VMOVDQU YMM0, [RDI] + VMOVDQU YMM1, [RSI] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + _ZN3ehs4AVX214CompareAlignedEPKmS2_: + VMOVDQA YMM0, [RDI] + VMOVDQA YMM1, [RSI] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET + + _ZN3ehs4AVX214CompareAlignedEPKlS2_: + VMOVDQA YMM0, [RDI] + VMOVDQA YMM1, [RSI] + VPCMPEQQ YMM2, YMM0, YMM1 + + VPMOVMSKB EAX, YMM2 + CMP EAX, 0xFFFFFFFF + SETE AL + + RET \ No newline at end of file diff --git a/src/system/AVX512_GCC_AMD64.asm b/src/system/AVX512_GCC_AMD64.asm new file mode 100644 index 0000000..6a3c698 --- /dev/null +++ b/src/system/AVX512_GCC_AMD64.asm @@ -0,0 +1,49 @@ +global _ZN3ehs6AVX51216CompareUnalignedEPKmS2_ +global _ZN3ehs6AVX51216CompareUnalignedEPKlS2_ +global _ZN3ehs6AVX51214CompareAlignedEPKmS2_ +global _ZN3ehs6AVX51214CompareAlignedEPKlS2_ + +section .text + _ZN3ehs6AVX51216CompareUnalignedEPKmS2_: + VMOVDQU64 ZMM0, [RDI] + VMOVDQU64 ZMM1, [RSI] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + _ZN3ehs6AVX51216CompareUnalignedEPKlS2_: + VMOVDQU64 ZMM0, [RDI] + VMOVDQU64 ZMM1, [RSI] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + _ZN3ehs6AVX51214CompareAlignedEPKmS2_: + VMOVDQA64 ZMM0, [RDI] + VMOVDQA64 ZMM1, [RSI] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET + + _ZN3ehs6AVX51214CompareAlignedEPKlS2_: + VMOVDQA64 ZMM0, [RDI] + VMOVDQA64 ZMM1, [RSI] + + VPCMPEQQ K1, ZMM0, ZMM1 + + KORTESTQ K1, K1 + SETC AL + + RET \ No newline at end of file diff --git a/src/system/CPU.cpp b/src/system/CPU.cpp index ccab72e..7cc8c75 100644 --- a/src/system/CPU.cpp +++ b/src/system/CPU.cpp @@ -10,6 +10,70 @@ namespace ehs UInt_64 CPU::TSC_Freq = 0; #endif + const bool CPU::hasFPU = RetrieveFPU(); + const bool CPU::hasVME = RetrieveVME(); + const bool CPU::hasDE = RetrieveDE(); + const bool CPU::hasPSE = RetrievePSE(); + const bool CPU::hasTSC = RetrieveTSC(); + const bool CPU::hasMSR = RetrieveMSR(); + const bool CPU::hasPAE = RetrievePAE(); + const bool CPU::hasMCE = RetrieveMCE(); + const bool CPU::hasCX8 = RetrieveCX8(); + const bool CPU::hasAPIC = RetrieveAPIC(); + const bool CPU::hasSEP = RetrieveSEP(); + const bool CPU::hasMTRR = RetrieveMTRR(); + const bool CPU::hasPGE = RetrievePGE(); + const bool CPU::hasMCA = RetrieveMCA(); + const bool CPU::hasCMOV = RetrieveCMOV(); + const bool CPU::hasPSE_36 = RetrievePSE_36(); + const bool CPU::hasPSN = RetrievePSN(); + const bool CPU::hasCLFSH = RetrieveCLFSH(); + const bool CPU::hasDS = RetrieveDS(); + const bool CPU::hasACPI = RetrieveACPI(); + const bool CPU::hasMMX = RetrieveMMX(); + const bool CPU::hasFXSR = RetrieveFXSR(); + const bool CPU::hasSSE = RetrieveSSE(); + const bool CPU::hasSSE2 = RetrieveSSE2(); + const bool CPU::hasSS = RetrieveSS(); + const bool CPU::hasHTT = RetrieveHTT(); + const bool CPU::hasTM = RetrieveTM(); + const bool CPU::hasIA64 = RetrieveIA64(); + const bool CPU::hasPBE = RetrievePBE(); + const bool CPU::hasSSE3 = RetrieveSSE3(); + const bool CPU::hasPCLMULQDQ = RetrievePCLMULQDQ(); + const bool CPU::hasDTES64 = RetrieveDTES64(); + const bool CPU::hasMONITOR = RetrieveMONITOR(); + const bool CPU::hasVMX = RetrieveVMX(); + const bool CPU::hasSMX = RetrieveSMX(); + const bool CPU::hasEST = RetrieveEST(); + const bool CPU::hasTM2 = RetrieveTM2(); + const bool CPU::hasSSSE3 = RetrieveSSSE3(); + const bool CPU::hasCNXT_ID = RetrieveCNXT_ID(); + const bool CPU::hasSDBG = RetrieveSDBG(); + const bool CPU::hasFMA = RetrieveFMA(); + const bool CPU::hasCX16 = RetrieveCX16(); + const bool CPU::hasXTPR = RetrieveXTPR(); + const bool CPU::hasPDCM = RetrievePDCM(); + const bool CPU::hasPCID = RetrievePCID(); + const bool CPU::hasDCA = RetrieveDCA(); + const bool CPU::hasSSE4_1 = RetrieveSSE4_1(); + const bool CPU::hasSSE4_2 = RetrieveSSE4_2(); + const bool CPU::hasX2APIC = RetrieveX2APIC(); + const bool CPU::hasMOVBE = RetrieveMOVBE(); + const bool CPU::hasPOPCNT = RetrievePOPCNT(); + const bool CPU::hasTSC_DEADLINE = RetrieveTSC_DEADLINE(); + const bool CPU::hasAES = RetrieveAES(); + const bool CPU::hasXSAVE = RetrieveXSAVE(); + const bool CPU::hasOSXSAVE = RetrieveOSXSAVE(); + const bool CPU::hasAVX = RetrieveAVX(); + const bool CPU::hasF16C = RetrieveF16C(); + const bool CPU::hasRDRND = RetrieveRDRND(); + const bool CPU::hasHYPERVISOR = RetrieveHYPERVISOR(); + const bool CPU::hasAVX2 = RetrieveAVX2(); + const bool CPU::hasAVX512F = RetrieveAVX512F(); + const bool CPU::hasRDSEED = RetrieveRDSEED(); + const bool CPU::hasADX = RetrieveADX(); + Architecture CPU::GetArchitecture() { #if defined(EHS_ARCH_X64) @@ -119,324 +183,589 @@ namespace ehs return (UInt_8)(GetInfoBits() >> 20); } - bool CPU::HasFPU() + bool CPU::RetrieveFPU() { - return GetFeatureBits_1() & 0b00000000000000000000000000000001; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000000001; + #else + return false; + #endif } - bool CPU::HasVME() + bool CPU::RetrieveVME() { - return GetFeatureBits_1() & 0b00000000000000000000000000000010; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000000010; + #else + return false; + #endif } - bool CPU::HasDE() + bool CPU::RetrieveDE() { - return GetFeatureBits_1() & 0b00000000000000000000000000000100; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000000100; + #else + return false; + #endif } - bool CPU::HasPSE() + bool CPU::RetrievePSE() { - return GetFeatureBits_1() & 0b00000000000000000000000000001000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000001000; + #else + return false; + #endif } - bool CPU::HasTSC() + bool CPU::RetrieveTSC() { - return GetFeatureBits_1() & 0b00000000000000000000000000010000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000010000; + #else + return false; + #endif } - bool CPU::HasMSR() + bool CPU::RetrieveMSR() { - return GetFeatureBits_1() & 0b00000000000000000000000000100000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000000100000; + #else + return false; + #endif } - bool CPU::HasPAE() + bool CPU::RetrievePAE() { - return GetFeatureBits_1() & 0b00000000000000000000000001000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000001000000; + #else + return false; + #endif } - bool CPU::HasMCE() + bool CPU::RetrieveMCE() { - return GetFeatureBits_1() & 0b00000000000000000000000010000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000010000000; + #else + return false; + #endif } - bool CPU::HasCX8() + bool CPU::RetrieveCX8() { - return GetFeatureBits_1() & 0b00000000000000000000000100000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000000100000000; + #else + return false; + #endif } - bool CPU::HasAPIC() + bool CPU::RetrieveAPIC() { - return GetFeatureBits_1() & 0b00000000000000000000001000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000001000000000; + #else + return false; + #endif } - bool CPU::HasSEP() + bool CPU::RetrieveSEP() { - return GetFeatureBits_1() & 0b00000000000000000000100000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000000100000000000; + #else + return false; + #endif } - bool CPU::HasMTRR() + bool CPU::RetrieveMTRR() { - return GetFeatureBits_1() & 0b00000000000000000001000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000001000000000000; + #else + return false; + #endif } - bool CPU::HasPGE() + bool CPU::RetrievePGE() { - return GetFeatureBits_1() & 0b00000000000000000010000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000010000000000000; + #else + return false; + #endif } - bool CPU::HasMCA() + bool CPU::RetrieveMCA() { - return GetFeatureBits_1() & 0b00000000000000000100000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000000100000000000000; + #else + return false; + #endif } - bool CPU::HasCMOV() + bool CPU::RetrieveCMOV() { - return GetFeatureBits_1() & 0b00000000000000001000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000001000000000000000; + #else + return false; + #endif } - bool CPU::HasPAT() + bool CPU::RetrievePAT() { - return GetFeatureBits_1() & 0b00000000000000010000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000010000000000000000; + #else + return false; + #endif } - bool CPU::HasPSE_36() + bool CPU::RetrievePSE_36() { - return GetFeatureBits_1() & 0b00000000000000100000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000000100000000000000000; + #else + return false; + #endif } - bool CPU::HasPSN() + bool CPU::RetrievePSN() { - return GetFeatureBits_1() & 0b00000000000001000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000001000000000000000000; + #else + return false; + #endif } - bool CPU::HasCLFSH() + bool CPU::RetrieveCLFSH() { - return GetFeatureBits_1() & 0b00000000000010000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000000010000000000000000000; + #else + return false; + #endif } - bool CPU::HasDS() + bool CPU::RetrieveDS() { - return GetFeatureBits_1() & 0b00000000001000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000001000000000000000000000; + #else + return false; + #endif } - bool CPU::HasACPI() + bool CPU::RetrieveACPI() { - return GetFeatureBits_1() & 0b00000000010000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000010000000000000000000000; + #else + return false; + #endif } - bool CPU::HasMMX() + bool CPU::RetrieveMMX() { - return GetFeatureBits_1() & 0b00000000100000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000000100000000000000000000000; + #else + return false; + #endif } - bool CPU::HasFXSR() + bool CPU::RetrieveFXSR() { - return GetFeatureBits_1() & 0b00000001000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000001000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE() + bool CPU::RetrieveSSE() { - return GetFeatureBits_1() & 0b00000010000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000010000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE2() + bool CPU::RetrieveSSE2() { - return GetFeatureBits_1() & 0b00000100000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00000100000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasSS() + bool CPU::RetrieveSS() { - return GetFeatureBits_1() & 0b00001000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00001000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasHTT() + bool CPU::RetrieveHTT() { - return GetFeatureBits_1() & 0b00010000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00010000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasTM() + bool CPU::RetrieveTM() { - return GetFeatureBits_1() & 0b00100000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b00100000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasIA64() + bool CPU::RetrieveIA64() { - return GetFeatureBits_1() & 0b01000000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b01000000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasPBE() + bool CPU::RetrievePBE() { - return GetFeatureBits_1() & 0b10000000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_1() & 0b10000000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE3() + bool CPU::RetrieveSSE3() { - return GetFeatureBits_2() & 0b00000000000000000000000000000001; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000000001; + #else + return false; + #endif } - bool CPU::HasPCLMULQDQ() + bool CPU::RetrievePCLMULQDQ() { - return GetFeatureBits_2() & 0b00000000000000000000000000000010; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000000010; + #else + return false; + #endif } - bool CPU::HasDTES64() + bool CPU::RetrieveDTES64() { - return GetFeatureBits_2() & 0b00000000000000000000000000000100; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000000100; + #else + return false; + #endif } - bool CPU::HasMONITOR() + bool CPU::RetrieveMONITOR() { - return GetFeatureBits_2() & 0b00000000000000000000000000001000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000001000; + #else + return false; + #endif } - bool CPU::HasDS_CPL() + bool CPU::RetrieveDS_CPL() { - return GetFeatureBits_2() & 0b00000000000000000000000000010000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000010000; + #else + return false; + #endif } - bool CPU::HasVMX() + bool CPU::RetrieveVMX() { - return GetFeatureBits_2() & 0b00000000000000000000000000100000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000000100000; + #else + return false; + #endif } - bool CPU::HasSMX() + bool CPU::RetrieveSMX() { - return GetFeatureBits_2() & 0b00000000000000000000000001000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000001000000; + #else + return false; + #endif } - bool CPU::HasEST() + bool CPU::RetrieveEST() { - return GetFeatureBits_2() & 0b00000000000000000000000010000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000010000000; + #else + return false; + #endif } - bool CPU::HasTM2() + bool CPU::RetrieveTM2() { - return GetFeatureBits_2() & 0b00000000000000000000000100000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000000100000000; + #else + return false; + #endif } - bool CPU::HasSSSE3() + bool CPU::RetrieveSSSE3() { - return GetFeatureBits_2() & 0b00000000000000000000001000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000001000000000; + #else + return false; + #endif } - bool CPU::HasCNXT_ID() + bool CPU::RetrieveCNXT_ID() { - return GetFeatureBits_2() & 0b00000000000000000000010000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000010000000000; + #else + return false; + #endif } - bool CPU::HasSDBG() + bool CPU::RetrieveSDBG() { - return GetFeatureBits_2() & 0b00000000000000000000100000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000000100000000000; + #else + return false; + #endif } - bool CPU::HasFMA() + bool CPU::RetrieveFMA() { - return GetFeatureBits_2() & 0b00000000000000000001000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000001000000000000; + #else + return false; + #endif } - bool CPU::HasCX16() + bool CPU::RetrieveCX16() { - return GetFeatureBits_2() & 0b00000000000000000010000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000010000000000000; + #else + return false; + #endif } - bool CPU::HasXTPR() + bool CPU::RetrieveXTPR() { - return GetFeatureBits_2() & 0b00000000000000000100000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000000100000000000000; + #else + return false; + #endif } - bool CPU::HasPDCM() + bool CPU::RetrievePDCM() { - return GetFeatureBits_2() & 0b00000000000000001000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000001000000000000000; + #else + return false; + #endif } - bool CPU::HasPCID() + bool CPU::RetrievePCID() { - return GetFeatureBits_2() & 0b00000000000000100000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000000100000000000000000; + #else + return false; + #endif } - bool CPU::HasDCA() + bool CPU::RetrieveDCA() { - return GetFeatureBits_2() & 0b00000000000001000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000001000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE4_1() + bool CPU::RetrieveSSE4_1() { - return GetFeatureBits_2() & 0b00000000000010000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000010000000000000000000; + #else + return false; + #endif } - bool CPU::HasSSE4_2() + bool CPU::RetrieveSSE4_2() { - return GetFeatureBits_2() & 0b00000000000100000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000000100000000000000000000; + #else + return false; + #endif } - bool CPU::HasX2APIC() + bool CPU::RetrieveX2APIC() { - return GetFeatureBits_2() & 0b00000000001000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000001000000000000000000000; + #else + return false; + #endif } - bool CPU::HasMOVBE() + bool CPU::RetrieveMOVBE() { - return GetFeatureBits_2() & 0b00000000010000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000010000000000000000000000; + #else + return false; + #endif } - bool CPU::HasPOPCNT() + bool CPU::RetrievePOPCNT() { - return GetFeatureBits_2() & 0b00000000100000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000000100000000000000000000000; + #else + return false; + #endif } - bool CPU::HasTSC_DEADLINE() + bool CPU::RetrieveTSC_DEADLINE() { - return GetFeatureBits_2() & 0b00000001000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000001000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasAES() + bool CPU::RetrieveAES() { - return GetFeatureBits_2() & 0b00000010000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000010000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasXSAVE() + bool CPU::RetrieveXSAVE() { - return GetFeatureBits_2() & 0b00000100000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00000100000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasOSXSAVE() + bool CPU::RetrieveOSXSAVE() { - return GetFeatureBits_2() & 0b00001000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00001000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasAVX() + bool CPU::RetrieveAVX() { - return GetFeatureBits_2() & 0b00010000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00010000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasF16C() + bool CPU::RetrieveF16C() { - return GetFeatureBits_2() & 0b00100000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b00100000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasRDRND() + bool CPU::RetrieveRDRND() { - return GetFeatureBits_2() & 0b01000000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b01000000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasHYPERVISOR() + bool CPU::RetrieveHYPERVISOR() { - return GetFeatureBits_2() & 0b10000000000000000000000000000000; + #ifdef EHS_ARCH_X64 + return GetFeatureBits_2() & 0b10000000000000000000000000000000; + #else + return false; + #endif } - bool CPU::HasAVX2() + bool CPU::RetrieveAVX2() { - return GetExtFeatureBits_1() & 0b00000000000000000000000000100000; + #ifdef EHS_ARCH_X64 + return GetExtFeatureBits_1() & 0b00000000000000000000000000100000; + #else + return false; + #endif } - bool CPU::HasRDSEED() + bool CPU::RetrieveAVX512F() { - return GetExtFeatureBits_1() & 0b00000000000001000000000000000000; + #ifdef EHS_ARCH_X64 + return GetExtFeatureBits_1() & 0b00000000000000001000000000000000; + #else + return false; + #endif } - bool CPU::HasADX() + bool CPU::RetrieveRDSEED() { - return GetExtFeatureBits_1() & 0b00000000000010000000000000000000; + #ifdef EHS_ARCH_X64 + return GetExtFeatureBits_1() & 0b00000000000001000000000000000000; + #else + return false; + #endif + } + + bool CPU::RetrieveADX() + { + #ifdef EHS_ARCH_X64 + return GetExtFeatureBits_1() & 0b00000000000010000000000000000000; + #else + return false; + #endif } /*