diff --git a/like2015/cpuid.h b/like2015/cpuid.h index 3537a2c..5c34946 100644 --- a/like2015/cpuid.h +++ b/like2015/cpuid.h @@ -9,7 +9,7 @@ namespace like { template - struct cpuid_base_t + struct cpuid_info_t { // eax unsigned : 32; @@ -26,21 +26,21 @@ namespace like } }; template - std::ostream & operator << (std::ostream & os, cpuid_base_t const & cpuid) + std::ostream & operator << (std::ostream & os, cpuid_info_t const &) { return os; } - template <> struct cpuid_base_t<0x00> + template <> struct cpuid_info_t<0x00> { // eax unsigned uMaxLeaf : 32; // ebx - unsigned uEBX : 32; + unsigned : 32; // ecx - unsigned uECX : 32; + unsigned : 32; // edx - unsigned uEDX : 32; + unsigned : 32; unsigned max_leaf() const { @@ -49,26 +49,39 @@ namespace like __m128i vendor_identification_string() const { - return _mm_set_epi32(0, uECX, uEDX, uEBX); + return _mm_set_epi32(0, reinterpret_cast(this)[2], reinterpret_cast(this)[3], reinterpret_cast(this)[1]); } }; template <> - std::ostream & operator << (std::ostream & os, cpuid_base_t<0x00> const & cpuid) + std::ostream & operator << (std::ostream & os, cpuid_info_t<0x00> const & cpuid) { - return os << cpuid.vendor_identification_string().m128i_i8; + return os << ' ' << cpuid.vendor_identification_string().m128i_i8; } - template <> struct cpuid_base_t<0x01> + template <> struct cpuid_info_t<0x01> { // eax - unsigned : 32; - // ebx + unsigned uSteppingID : 4; // [bits 3:0] + unsigned uModelID : 4; // [bits 7:4] + unsigned uFamilyID : 4; // [bits 11:8] + enum + { + ORIGINAL_OEM_PROCESSOR = 0, + INTEL_OVERDRIVE_PROCESSOR = 1, + DUAL_PROCESSOR = 2, + INTEL_RESERVED = 3, + } emProcessorType: 2; + unsigned : 2; // [bits 15:14] + unsigned uExtendedModelID : 4; // [bits 19:16] + unsigned uExtendedFamilyID : 8; // [bits 27:20] + unsigned : 4; // [bits 31:28] + // ebx unsigned uProcessorBrandIndex : 8; // [bits 7:0] unsigned uLineSizeCLFLUSH : 8; // [bits 15:8] unsigned uMaxNumOfID : 8; // [bits 23:16] - unsigned uInitialAPIC_ID: 8; // [bits 31:24] - // ecx - unsigned uSSE3: 1; // bit 0 + unsigned uInitialAPIC_ID : 8; // [bits 31:24] + // ecx + unsigned uSSE3 : 1; // bit 0 unsigned uPCLMULQDQ : 1; // bit 1 unsigned uDTES64 : 1; // bit 2 unsigned uMONITOR : 1; // bit 3 @@ -90,11 +103,11 @@ namespace like unsigned uSSE4_1 : 1; // bit 19 unsigned uSSE4_2 : 1; // bit 20 unsigned u_x2APIC : 1; // bit 21 - unsigned uMOVBE: 1; // bit 22 + unsigned uMOVBE : 1; // bit 22 unsigned uPOPCNT : 1; // bit 23 unsigned uTSC_Deadline : 1; // bit 24 unsigned uAES : 1; // bit 25 - unsigned uXSAVE: 1; // bit 26 + unsigned uXSAVE : 1; // bit 26 unsigned uOSXSAVE : 1; // bit 27 unsigned uAVX : 1; // bit 28 unsigned uF16C : 1; // bit 29 @@ -125,7 +138,7 @@ namespace like unsigned uDS : 1; // bit 21: Debug Store unsigned uACPI : 1; // bit 22: Thermal Monitor and Software Controlled Clock Facilities unsigned uMMX : 1; // bit 23 - unsigned uFXSR: 1; // bit 24 + unsigned uFXSR : 1; // bit 24 unsigned uSSE : 1; // bit 25 unsigned uSSE2 : 1; // bit 26 unsigned uSS : 1; // bit 27: Self Snoop @@ -134,100 +147,103 @@ namespace like unsigned : 1; // bit 30 unsigned uPBE : 1; // bit 31: Pending Break Enable }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x01> const & cpuid) - { + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x01> const & cpuid) + { + char const cFill = os.fill('0'); + int const nMasks = os.setf(std::ios_base::hex | std::ios_base::uppercase); + os.unsetf(std::ios_base::dec); + os + << ' ' << std::setw(2) << (cpuid.uFamilyID != 0x0F ? cpuid.uFamilyID : (cpuid.uExtendedFamilyID + cpuid.uFamilyID)) + << '_' << std::setw(2) << (cpuid.uFamilyID == 0x06 || cpuid.uFamilyID == 0x0F ? ((cpuid.uExtendedModelID << 4) + cpuid.uModelID) : cpuid.uModelID) << 'H'; + os.setf(nMasks); + os.fill(cFill); return os << - (cpuid.uSSE3 ? '+' : '-') << "SSE3" << ' ' << //unsigned uSSE3 : 1; // bit 0 - (cpuid.uPCLMULQDQ ? '+' : '-') << "PCLMULQDQ" << ' ' << //unsigned uPCLMULQDQ : 1; // bit 1 - //unsigned uDTES64 : 1; // bit 2 - (cpuid.uMONITOR ? '+' : '-') << "MONITOR" << ' ' << //unsigned uMONITOR : 1; // bit 3 - //unsigned uDS_CPL : 1; // bit 4 - (cpuid.uVMX ? '+' : '-') << "VMX" << ' ' << //unsigned uVMX : 1; // bit 5 - (cpuid.uSMX ? '+' : '-') << "SMX" << ' ' << //unsigned uSMX : 1; // bit 6: Safer Mode Extensions - (cpuid.uEIST ? '+' : '-') << "EIST" << ' ' << //unsigned uEIST : 1; // bit 7: Enhanced Intel SpeedStep technology - (cpuid.uTM2 ? '+' : '-') << "TM2" << ' ' << //unsigned uTM2 : 1; // bit 8: Thermal Monitor 2 - (cpuid.uSSSE3 ? '+' : '-') << "SSSE3" << ' ' << //unsigned uSSSE3 : 1; // bit 9 - //unsigned uCNXT_ID : 1; // bit 10: L1 Context ID - //unsigned uSDBG : 1; // bit 11 - (cpuid.uFMA ? '+' : '-') << "FMA" << ' ' << //unsigned uFMA : 1; // bit 12 - (cpuid.uCMPXCHG16B ? '+' : '-') << "CMPXCHG16B" << ' ' << //unsigned uCMPXCHG16B : 1; // bit 13 - //unsigned u_xTPR_UpdateControl : 1; // bit 14 - (cpuid.uPDCM ? '+' : '-') << "PDCM" << ' ' << //unsigned uPDCM : 1; // bit 15: Perfmon and Debug Capability - //unsigned : 1; // bit 16 - //unsigned uPCID : 1; // bit 17: Process-context identifiers - //unsigned uDCA : 1; // bit 18 - (cpuid.uSSE4_1 ? '+' : '-') << "SSE4.1" << ' ' << //unsigned uSSE4_1 : 1; // bit 19 - (cpuid.uSSE4_2 ? '+' : '-') << "SSE4.2" << ' ' << //unsigned uSSE4_2 : 1; // bit 20 - (cpuid.u_x2APIC ? '+' : '-') << "x2APIC" << ' ' << //unsigned u_x2APIC : 1; // bit 21 - (cpuid.uMOVBE ? '+' : '-') << "MOVBE" << ' ' << //unsigned uMOVBE : 1; // bit 22 - (cpuid.uPOPCNT ? '+' : '-') << "POPCNT" << ' ' << //unsigned uPOPCNT : 1; // bit 23 - (cpuid.uTSC_Deadline ? '+' : '-') << "TSC-Deadline" << ' ' << //unsigned uTSC_Deadline : 1; // bit 24 - (cpuid.uAES ? '+' : '-') << "AES" << ' ' << //unsigned uAES : 1; // bit 25 - (cpuid.uXSAVE ? '+' : '-') << "XSAVE" << ' ' << //unsigned uXSAVE : 1; // bit 26 - (cpuid.uOSXSAVE ? '+' : '-') << "OSXSAVE" << ' ' << //unsigned uOSXSAVE : 1; // bit 27 - (cpuid.uAVX ? '+' : '-') << "AVX" << ' ' << //unsigned uAVX : 1; // bit 28 - (cpuid.uF16C ? '+' : '-') << "F16C" << ' ' << //unsigned uF16C : 1; // bit 29 - (cpuid.uRDRAND ? '+' : '-') << "RDRAND" << ' ' << //unsigned uRDRAND : 1; // bit 30 - //unsigned : 1; - (cpuid.uFPU ? '+' : '-') << "FPU" << ' ' << //unsigned uFPU : 1; // bit 0 - (cpuid.uVME ? '+' : '-') << "VME" << ' ' << //unsigned uVME : 1; // bit 1: Virtual 8086 Mode Enhancements - (cpuid.uDE ? '+' : '-') << "DE" << ' ' << //unsigned uDE : 1; // bit 2: Debugging Extensions - (cpuid.uPSE ? '+' : '-') << "PSE" << ' ' << //unsigned uPSE : 1; // bit 3: Page Size Extension - (cpuid.uTSC ? '+' : '-') << "TSC" << ' ' << //unsigned uTSC : 1; // bit 4 - (cpuid.uMSR ? '+' : '-') << "MSR" << ' ' << //unsigned uMSR : 1; // bit 5 - (cpuid.uPAE ? '+' : '-') << "PAE" << ' ' << //unsigned uPAE : 1; // bit 6 - (cpuid.uMCE ? '+' : '-') << "MCE" << ' ' << //unsigned uMCE : 1; // bit 7: Machine Check Exception - (cpuid.uCX8 ? '+' : '-') << "CX8" << ' ' << //unsigned uCX8 : 1; // bit 8: CMPXCHG8B Instruction - (cpuid.uAPIC ? '+' : '-') << "APIC" << ' ' << //unsigned uAPIC : 1; // bit 9 - //unsigned : 1; // bit 10 - (cpuid.uSEP ? '+' : '-') << "SEP" << ' ' << //unsigned uSEP : 1; // bit 11: SYSENTER and SYSEXIT Instructions - (cpuid.uMTRR ? '+' : '-') << "MTRR" << ' ' << //unsigned uMTRR : 1; // bit 12 - (cpuid.uPGE ? '+' : '-') << "PGE" << ' ' << //unsigned uPGE : 1; // bit 13: Page Global Bit - (cpuid.uMCA ? '+' : '-') << "MCA" << ' ' << //unsigned uMCA : 1; // bit 14 Machine Check Architecture - (cpuid.uCMOV ? '+' : '-') << "CMOV" << ' ' << //unsigned uCMOV : 1; // bit 15 - (cpuid.uPAT ? '+' : '-') << "PAT" << ' ' << //unsigned uPAT : 1; // bit 16: Page Attribute Table - (cpuid.uPSE36 ? '+' : '-') << "PSE36" << ' ' << //unsigned uPSE36 : 1; // bit 17: 36-Bit Page Size Extension - (cpuid.uPSN ? '+' : '-') << "PSN" << ' ' << //unsigned uPSN : 1; // bit 18: Processor Serial Number - (cpuid.uCLFSH ? '+' : '-') << "CLFSH" << ' ' << //unsigned uCLFSH : 1; // bit 19 - //unsigned : 1; // bit 20 - (cpuid.uDS ? '+' : '-') << "DS" << ' ' << //unsigned uDS : 1; // bit 21: Debug Store - (cpuid.uACPI ? '+' : '-') << "ACPI" << ' ' << //unsigned uACPI : 1; // bit 22: Thermal Monitor and Software Controlled Clock Facilities - (cpuid.uMMX ? '+' : '-') << "MMX" << ' ' << //unsigned uMMX : 1; // bit 23 - (cpuid.uFXSR ? '+' : '-') << "FXSR" << ' ' << //unsigned uFXSR : 1; // bit 24 - (cpuid.uSSE ? '+' : '-') << "SSE" << ' ' << //unsigned uSSE : 1; // bit 25 - (cpuid.uSSE2 ? '+' : '-') << "SSE2" << ' ' << //unsigned uSSE2 : 1; // bit 26 - (cpuid.uSS ? '+' : '-') << "SS" << ' ' << //unsigned uSS : 1; // bit 27: Self Snoop - (cpuid.uHTT ? '+' : '-') << "HTT" << ' ' << //unsigned uHTT : 1; // bit 28: Max APIC IDs reserved field is Valid - (cpuid.uTM ? '+' : '-') << "TM" << ' ' << //unsigned uTM : 1; // bit 29: Thermal Monitor - //unsigned : 1; // bit 30 - (cpuid.uPBE ? '+' : '-') << "PBE" << ' ';//unsigned uPBE : 1; // bit 31: Pending Break Enable + (cpuid.uSSE3 ? " +SSE3" : " -SSE3") << //unsigned uSSE3 : 1; // bit 0 + (cpuid.uPCLMULQDQ ? " +PCLMULQDQ" : " -PCLMULQDQ") << //unsigned uPCLMULQDQ : 1; // bit 1 + //unsigned uDTES64 : 1; // bit 2 + (cpuid.uMONITOR ? " +MONITOR" : " -MONITOR") << //unsigned uMONITOR : 1; // bit 3 + //unsigned uDS_CPL : 1; // bit 4 + (cpuid.uVMX ? " +VMX" : " -VMX") << //unsigned uVMX : 1; // bit 5 + (cpuid.uSMX ? " +SMX" : " -SMX") << //unsigned uSMX : 1; // bit 6: Safer Mode Extensions + (cpuid.uEIST ? " +EIST" : " -EIST") << //unsigned uEIST : 1; // bit 7: Enhanced Intel SpeedStep technology + (cpuid.uTM2 ? " +TM2" : " -TM2") << //unsigned uTM2 : 1; // bit 8: Thermal Monitor 2 + (cpuid.uSSSE3 ? " +SSSE3" : " -SSSE3") << //unsigned uSSSE3 : 1; // bit 9 + //unsigned uCNXT_ID : 1; // bit 10: L1 Context ID + //unsigned uSDBG : 1; // bit 11 + (cpuid.uFMA ? " +FMA" : " -FMA") << //unsigned uFMA : 1; // bit 12 + (cpuid.uCMPXCHG16B ? " +CMPXCHG16B" : " -CMPXCHG16B") << //unsigned uCMPXCHG16B : 1; // bit 13 + //unsigned u_xTPR_UpdateControl : 1; // bit 14 + (cpuid.uPDCM ? " +PDCM" : " -PDCM") << //unsigned uPDCM : 1; // bit 15: Perfmon and Debug Capability + //unsigned : 1; // bit 16 + //unsigned uPCID : 1; // bit 17: Process-context identifiers + //unsigned uDCA : 1; // bit 18 + (cpuid.uSSE4_1 ? " +SSE4.1" : " -SSE4.1") << //unsigned uSSE4_1 : 1; // bit 19 + (cpuid.uSSE4_2 ? " +SSE4.2" : " -SSE4.2") << //unsigned uSSE4_2 : 1; // bit 20 + (cpuid.u_x2APIC ? " +x2APIC" : " -x2APIC") << //unsigned u_x2APIC : 1; // bit 21 + (cpuid.uMOVBE ? " +MOVBE" : " -MOVBE") << //unsigned uMOVBE : 1; // bit 22 + (cpuid.uPOPCNT ? " +POPCNT" : " -POPCNT") << //unsigned uPOPCNT : 1; // bit 23 + (cpuid.uTSC_Deadline ? " +TSC-Deadline" : " -TSC-Deadline") << //unsigned uTSC_Deadline : 1; // bit 24 + (cpuid.uAES ? " +AES" : " -AES") << //unsigned uAES : 1; // bit 25 + (cpuid.uXSAVE ? " +XSAVE" : " -XSAVE") << //unsigned uXSAVE : 1; // bit 26 + (cpuid.uOSXSAVE ? " +OSXSAVE" : " -OSXSAVE") << //unsigned uOSXSAVE : 1; // bit 27 + (cpuid.uAVX ? " +AVX" : " -AVX") << //unsigned uAVX : 1; // bit 28 + (cpuid.uF16C ? " +F16C" : " -F16C") << //unsigned uF16C : 1; // bit 29 + (cpuid.uRDRAND ? " +RDRAND" : " -RDRAND") << //unsigned uRDRAND : 1; // bit 30 + //unsigned : 1; + (cpuid.uFPU ? " +FPU" : " -FPU") << //unsigned uFPU : 1; // bit 0 + (cpuid.uVME ? " +VME" : " -VME") << //unsigned uVME : 1; // bit 1: Virtual 8086 Mode Enhancements + (cpuid.uDE ? " +DE" : " -DE") << //unsigned uDE : 1; // bit 2: Debugging Extensions + (cpuid.uPSE ? " +PSE" : " -PSE") << //unsigned uPSE : 1; // bit 3: Page Size Extension + (cpuid.uTSC ? " +TSC" : " -TSC") << //unsigned uTSC : 1; // bit 4 + (cpuid.uMSR ? " +MSR" : " -MSR") << //unsigned uMSR : 1; // bit 5 + (cpuid.uPAE ? " +PAE" : " -PAE") << //unsigned uPAE : 1; // bit 6 + (cpuid.uMCE ? " +MCE" : " -MCE") << //unsigned uMCE : 1; // bit 7: Machine Check Exception + (cpuid.uCX8 ? " +CX8" : " -CX8") << //unsigned uCX8 : 1; // bit 8: CMPXCHG8B Instruction + (cpuid.uAPIC ? " +APIC" : " -APIC") << //unsigned uAPIC : 1; // bit 9 + //unsigned : 1; // bit 10 + (cpuid.uSEP ? " +SEP" : " -SEP") << //unsigned uSEP : 1; // bit 11: SYSENTER and SYSEXIT Instructions + (cpuid.uMTRR ? " +MTRR" : " -MTRR") << //unsigned uMTRR : 1; // bit 12 + (cpuid.uPGE ? " +PGE" : " -PGE") << //unsigned uPGE : 1; // bit 13: Page Global Bit + (cpuid.uMCA ? " +MCA" : " -MCA") << //unsigned uMCA : 1; // bit 14 Machine Check Architecture + (cpuid.uCMOV ? " +CMOV" : " -CMOV") << //unsigned uCMOV : 1; // bit 15 + (cpuid.uPAT ? " +PAT" : " -PAT") << //unsigned uPAT : 1; // bit 16: Page Attribute Table + (cpuid.uPSE36 ? " +PSE36" : " -PSE36") << //unsigned uPSE36 : 1; // bit 17: 36-Bit Page Size Extension + (cpuid.uPSN ? " +PSN" : " -PSN") << //unsigned uPSN : 1; // bit 18: Processor Serial Number + (cpuid.uCLFSH ? " +CLFSH" : " -CLFSH") << //unsigned uCLFSH : 1; // bit 19 + //unsigned : 1; // bit 20 + (cpuid.uDS ? " +DS" : " -DS") << //unsigned uDS : 1; // bit 21: Debug Store + (cpuid.uACPI ? " +ACPI" : " -ACPI") << //unsigned uACPI : 1; // bit 22: Thermal Monitor and Software Controlled Clock Facilities + (cpuid.uMMX ? " +MMX" : " -MMX") << //unsigned uMMX : 1; // bit 23 + (cpuid.uFXSR ? " +FXSR" : " -FXSR") << //unsigned uFXSR : 1; // bit 24 + (cpuid.uSSE ? " +SSE" : " -SSE") << //unsigned uSSE : 1; // bit 25 + (cpuid.uSSE2 ? " +SSE2" : " -SSE2") << //unsigned uSSE2 : 1; // bit 26 + (cpuid.uSS ? " +SS" : " -SS") << //unsigned uSS : 1; // bit 27: Self Snoop + (cpuid.uHTT ? " +HTT" : " -HTT") << //unsigned uHTT : 1; // bit 28: Max APIC IDs reserved field is Valid + (cpuid.uTM ? " +TM" : " -TM") << //unsigned uTM : 1; // bit 29: Thermal Monitor + //unsigned : 1; // bit 30 + (cpuid.uPBE ? " +PBE" : " -PBE");//unsigned uPBE : 1; // bit 31: Pending Break Enable } - template <> struct cpuid_base_t<0x02> + template struct cpuid_info_t<0x04, nECX> { // eax - unsigned uEAX; - // ebx - unsigned uEBX; - // ecx - unsigned uECX; - // edx - unsigned uEDX; - }; - template struct cpuid_base_t<0x04, nECX> - { - // eax - unsigned uCacheTypeField : 5; // [bits 04:00] + enum + { + NO_MORE_CACHES = 0, + DATA_CACHE = 1, + INSTRUCTION_CACHE = 2, + UNIFIED_CACHE = 3, + } emCacheTypeField: 5; // [bits 04:00] unsigned uCacheLevel : 3; // [bits 07:05] unsigned uSelfInitializingCacheLevel : 1; // bit 8 unsigned uFullyAssociativeCache : 1; // bit 9 unsigned : 4; // [bits 13:10] unsigned uMaximumNumberOfAddressableIDsForLogicalProcessors : 12; // [bits 25:14] unsigned uMaximumNumberOfAddressableIDsForProcessorCores : 6; // [bits 31:26] - // ebx + // ebx unsigned uSystemCoherencyLineSize : 12; // [bits 11:0] unsigned uPhysicalLinePartitions : 10; // [bits 21:12] unsigned uWaysOfAssociativity : 10; // [bits 31:22] - // ecx + // ecx unsigned uNumberOfSets : 32; // edx unsigned uWriteBackInvalidate_Invalidate : 1; // bit 0 @@ -237,42 +253,42 @@ namespace like unsigned max_sub_leaf() const { - return ~0; + return ~0U; } bool is_sub_leaf(unsigned) const { - return uCacheTypeField != 0; + return emCacheTypeField != NO_MORE_CACHES; } }; - template std::ostream & operator << (std::ostream & os, cpuid_base_t<0x04, nECX> const & cpuid) + template std::ostream & operator << (std::ostream & os, cpuid_info_t<0x04, nECX> const & cpuid) { - switch (cpuid.uCacheTypeField) + switch (cpuid.emCacheTypeField) { - case 0: + case cpuid.NO_MORE_CACHES: return os; - case 1: - os << "D-Cache" << ' '; + case cpuid.DATA_CACHE: + os << " D-Cache"; break; - case 2: - os << "I-Cache" << ' '; + case cpuid.INSTRUCTION_CACHE: + os << " I-Cache"; break; - case 3: - os << "U-Cache" << ' '; + case cpuid.UNIFIED_CACHE: + os << " U-Cache"; break; } return os << 'L' << (cpuid.uCacheLevel) << ' ' << - std::setw(2) << (cpuid.uMaximumNumberOfAddressableIDsForLogicalProcessors + 1) << "processors" << ' ' << - std::setw(1) << (cpuid.uMaximumNumberOfAddressableIDsForProcessorCores + 1) << "cores" << ' ' << - std::setw(2) << (cpuid.uWaysOfAssociativity + 1) << "ways" << ' ' << + std::setw(2) << (cpuid.uMaximumNumberOfAddressableIDsForLogicalProcessors ? " +processor(s)" : " -processor(s)") << + std::setw(1) << (cpuid.uMaximumNumberOfAddressableIDsForProcessorCores ? " +core(s)" : " -core(s)") << + std::setw(2) << (cpuid.uWaysOfAssociativity ? " +way(s)" : " -way(s)") << '*' << ' ' << - std::setw(1) << (cpuid.uPhysicalLinePartitions + 1) << "partitions" << ' ' << + std::setw(1) << (cpuid.uPhysicalLinePartitions ? " +partition(s)" : " -partition(s)") << '*' << ' ' << - std::setw(2) << (cpuid.uSystemCoherencyLineSize + 1) << "B" << ' ' << + std::setw(2) << (cpuid.uSystemCoherencyLineSize ? " +B" : " -B") << '*' << ' ' << - std::setw(4) << (cpuid.uNumberOfSets + 1) << "sets" << ' '; + std::setw(4) << (cpuid.uNumberOfSets ? " +set(s)" : " -set(s)"); } - template <> struct cpuid_base_t<0x05> + template <> struct cpuid_info_t<0x05> { // eax unsigned uSmallestLineSizeMONITOR : 16; // [bits 15:0] @@ -294,22 +310,22 @@ namespace like unsigned uNumberOfC6 : 4; unsigned uNumberOfC7 : 4; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x05> const & cpuid) - { - return os << - '[' << (cpuid.uSmallestLineSizeMONITOR) << 'B' << ',' << (cpuid.uLargestLineSizeMONITOR) << 'B' << ']' << ' ' << - (cpuid.uMWAIT_Extension ? '+' : '-') << "MWAIT" << ' ' << - (cpuid.uInterruptsAsBreakEvent ? '+' : '-') << "InterruptsAsBreakEvent" << ' ' << - "C0/" << (cpuid.uNumberOfC0) << ' ' << - "C1/" << (cpuid.uNumberOfC1) << ' ' << - "C2/" << (cpuid.uNumberOfC2) << ' ' << - "C3/" << (cpuid.uNumberOfC3) << ' ' << - "C4/" << (cpuid.uNumberOfC4) << ' ' << - "C5/" << (cpuid.uNumberOfC5) << ' ' << - "C6/" << (cpuid.uNumberOfC6) << ' ' << - "C7/" << (cpuid.uNumberOfC7) << ' '; + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x05> const & cpuid) + { + return os + << " [" << (cpuid.uSmallestLineSizeMONITOR) << "B," << (cpuid.uLargestLineSizeMONITOR) << "B]" + << (cpuid.uMWAIT_Extension ? " +MWAIT" : " -MWAIT") + << (cpuid.uInterruptsAsBreakEvent ? " +InterruptsAsBreakEvent" : " -InterruptsAsBreakEvent") + << ' ' << "C0/" << (cpuid.uNumberOfC0) + << ' ' << "C1/" << (cpuid.uNumberOfC1) + << ' ' << "C2/" << (cpuid.uNumberOfC2) + << ' ' << "C3/" << (cpuid.uNumberOfC3) + << ' ' << "C4/" << (cpuid.uNumberOfC4) + << ' ' << "C5/" << (cpuid.uNumberOfC5) + << ' ' << "C6/" << (cpuid.uNumberOfC6) + << ' ' << "C7/" << (cpuid.uNumberOfC7); } - template <> struct cpuid_base_t<0x06> + template <> struct cpuid_info_t<0x06> { // eax unsigned uDigitalThermalSensor : 1; // bit 0 @@ -338,20 +354,20 @@ namespace like // edx unsigned : 32; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x06> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x06> const & cpuid) { return os << - (cpuid.uDigitalThermalSensor ? '+' : '-') << "ThermalSensor" << ' ' << - (cpuid.uIntelTurboBoostTechnology ? '+' : '-') << "TurboBoost" << ' ' << - (cpuid.uARAT ? '+' : '-') << "ARAT" << ' ' << - (cpuid.uPLN ? '+' : '-') << "PLN" << ' ' << - (cpuid.uECMD ? '+' : '-') << "ECMD" << ' ' << - (cpuid.uPTM ? '+' : '-') << "PTM" << ' ' << - (cpuid.uHWP ? '+' : '-') << "HWP" << ' ' << - (cpuid.uHDC ? '+' : '-') << "HDC" << ' ' << - (cpuid.uSETBH ? '+' : '-') << "SETBH" << ' '; + (cpuid.uDigitalThermalSensor ? " +ThermalSensor" : " -ThermalSensor") << + (cpuid.uIntelTurboBoostTechnology ? " +TurboBoost" : " -TurboBoost") << + (cpuid.uARAT ? " +ARAT" : " -ARAT") << + (cpuid.uPLN ? " +PLN" : " -PLN") << + (cpuid.uECMD ? " +ECMD" : " -ECMD") << + (cpuid.uPTM ? " +PTM" : " -PTM") << + (cpuid.uHWP ? " +HWP" : " -HWP") << + (cpuid.uHDC ? " +HDC" : " -HDC") << + (cpuid.uSETBH ? " +SETBH" : " -SETBH"); } - template <> struct cpuid_base_t<0x07> + template <> struct cpuid_info_t<0x07> { // eax unsigned uMaxSubLeaf : 32; @@ -388,7 +404,7 @@ namespace like unsigned uSHA : 1; // bit 29 unsigned uAVX512BW : 1; // bit 30 unsigned uAVX512VL : 1; // bit 31 - // ecx + // ecx unsigned uPREFTEHCHWT1 : 1; // bit 0 unsigned uAVX512VBMI : 1; // bit 1 unsigned : 1; @@ -403,44 +419,44 @@ namespace like return uMaxSubLeaf; } }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x07> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x07> const & cpuid) { return os << - (cpuid.uFSGSBASE ? '+' : '-') << "FSGSBASE" << ' ' << - (cpuid.uIntelSGX ? '+' : '-') << "SGX" << ' ' << - (cpuid.uBMI1 ? '+' : '-') << "BMI1" << ' ' << - (cpuid.uHLE ? '+' : '-') << "HLE" << ' ' << - (cpuid.uAVX2 ? '+' : '-') << "AVX2" << ' ' << - (cpuid.uSMEP ? '+' : '-') << "SMEP" << ' ' << - (cpuid.uBMI2 ? '+' : '-') << "BMI2" << ' ' << - (cpuid.uFastStringOperation ? '+' : '-') << "Fast-String" << ' ' << - (cpuid.uINVPCID ? '+' : '-') << "INVPCID" << ' ' << - (cpuid.uRTM ? '+' : '-') << "RTM" << ' ' << - (cpuid.uPQM ? '+' : '-') << "PQM" << ' ' << - (cpuid.uIntelMPX ? '+' : '-') << "MPX" << ' ' << - (cpuid.uPQE ? '+' : '-') << "PQE" << ' ' << - (cpuid.uAVX512F ? '+' : '-') << "AVX512F" << ' ' << // bit 16: avx-512 foundation - (cpuid.uAVX512DQ ? '+' : '-') << "AVX512DQ" << ' ' << // bit 17: avx-512 doubleword and quadword instructions - (cpuid.uRDSEED ? '+' : '-') << "RDSEED" << ' ' << - (cpuid.uADX ? '+' : '-') << "ADX" << ' ' << - (cpuid.uSMAP ? '+' : '-') << "SMAP" << ' ' << - (cpuid.uAVX512IFMA ? '+' : '-') << "AVX512IFMA" << ' ' << // bit 21 - (cpuid.uPCOMMIT ? '+' : '-') << "PCOMMIT" << ' ' << // bit 22 - (cpuid.uCLFLUSHOPT ? '+' : '-') << "CLFLUSHOPT" << ' ' << - (cpuid.uCLWB ? '+' : '-') << "CLWB" << ' ' << - (cpuid.uIntelProcessorTrace ? '+' : '-') << "PT" << ' ' << - (cpuid.uAVX512PF ? '+' : '-') << "AVX512PF" << ' ' << - (cpuid.uAVX512ER ? '+' : '-') << "AVX512ER" << ' ' << - (cpuid.uAVX512CD ? '+' : '-') << "AVX512CD" << ' ' << - (cpuid.uSHA ? '+' : '-') << "SHA" << ' ' << // bit 29 - (cpuid.uAVX512BW ? '+' : '-') << "AVX512BW" << ' ' << - (cpuid.uAVX512VL ? '+' : '-') << "AVX512VL" << ' ' << - (cpuid.uPREFTEHCHWT1 ? '+' : '-') << "PREFTEHCHWT1" << ' ' << - (cpuid.uAVX512VBMI ? '+' : '-') << "AVX512VBMI" << ' ' << - (cpuid.uPKU ? '+' : '-') << "PKU" << ' ' << - (cpuid.uOSPKE ? '+' : '-') << "OSPKE" << ' '; + (cpuid.uFSGSBASE ? " +FSGSBASE " : " -FSGSBASE ") << + (cpuid.uIntelSGX ? " +SGX " : " -SGX ") << + (cpuid.uBMI1 ? " +BMI1 " : " -BMI1 ") << + (cpuid.uHLE ? " +HLE " : " -HLE ") << + (cpuid.uAVX2 ? " +AVX2 " : " -AVX2 ") << + (cpuid.uSMEP ? " +SMEP " : " -SMEP ") << + (cpuid.uBMI2 ? " +BMI2 " : " -BMI2 ") << + (cpuid.uFastStringOperation ? " +FastString " : " -FastString ") << + (cpuid.uINVPCID ? " +INVPCID " : " -INVPCID ") << + (cpuid.uRTM ? " +RTM " : " -RTM ") << + (cpuid.uPQM ? " +PQM " : " -PQM ") << + (cpuid.uIntelMPX ? " +MPX " : " -MPX ") << + (cpuid.uPQE ? " +PQE " : " -PQE ") << + (cpuid.uAVX512F ? " +AVX512F " : " -AVX512F ") << // bit 16: avx-512 foundation + (cpuid.uAVX512DQ ? " +AVX512DQ " : " -AVX512DQ ") << // bit 17: avx-512 doubleword and quadword instructions + (cpuid.uRDSEED ? " +RDSEED " : " -RDSEED ") << + (cpuid.uADX ? " +ADX " : " -ADX ") << + (cpuid.uSMAP ? " +SMAP " : " -SMAP ") << + (cpuid.uAVX512IFMA ? " +AVX512IFMA " : " -AVX512IFMA ") << // bit 21 + (cpuid.uPCOMMIT ? " +PCOMMIT " : " -PCOMMIT ") << // bit 22 + (cpuid.uCLFLUSHOPT ? " +CLFLUSHOPT " : " -CLFLUSHOPT ") << + (cpuid.uCLWB ? " +CLWB " : " -CLWB ") << + (cpuid.uIntelProcessorTrace ? " +PT " : " -PT ") << + (cpuid.uAVX512PF ? " +AVX512PF " : " -AVX512PF ") << + (cpuid.uAVX512ER ? " +AVX512ER " : " -AVX512ER ") << + (cpuid.uAVX512CD ? " +AVX512CD " : " -AVX512CD ") << + (cpuid.uSHA ? " +SHA " : " -SHA ") << // bit 29 + (cpuid.uAVX512BW ? " +AVX512BW " : " -AVX512BW ") << + (cpuid.uAVX512VL ? " +AVX512VL " : " -AVX512VL ") << + (cpuid.uPREFTEHCHWT1 ? " +PREFTEHCHWT1 " : " -PREFTEHCHWT1 ") << + (cpuid.uAVX512VBMI ? " +AVX512VBMI " : " -AVX512VBMI ") << + (cpuid.uPKU ? " +PKU " : " -PKU ") << + (cpuid.uOSPKE ? " +OSPKE " : " -OSPKE "); } - template <> struct cpuid_base_t<0x09> + template <> struct cpuid_info_t<0x09> { // eax unsigned uIA32_PLATFORM_DCA_CAP : 32; @@ -451,14 +467,14 @@ namespace like // edx unsigned : 32; }; - template <> struct cpuid_base_t<0x0A> + template <> struct cpuid_info_t<0x0A> { // eax unsigned uVersionID : 8; // [bits 7:0]: Version ID of architectural performance monitoring unsigned uNumOfGP : 8; // [bits 15:8]: Number of general-purpose performance monitoring counter per logical processor unsigned uBitWidthOfGP : 8; // [bits 23:16]: Bit width of general-purpose, performance monitoring counter unsigned uLengethOfEBX : 8; // [bits 31:24]: Length of EBX bit vector to enumerate architectural performance monitoring events - // ebx + // ebx unsigned uCoreCycleEventUnavailable : 1; // bit 0 unsigned uInstructionRetiredEventUnavailable : 1; // bit 1 unsigned uReferenceCyclesEventUnavailable : 1; // bit 2 @@ -474,16 +490,16 @@ namespace like unsigned uBitWidthOfFixedFunctionPerformanceCounters : 8; // [bits 12:5] unsigned : 19; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0A> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0A> const & cpuid) { - os << (cpuid.uNumOfGP) << '*' << (cpuid.uBitWidthOfGP) << 'b' << ' '; + os << ' ' << (cpuid.uNumOfGP) << '*' << (cpuid.uBitWidthOfGP) << 'b'; if (cpuid.uVersionID > 1) { - os << (cpuid.uNumOfFixedFunctionPerformanceCounters) << '*' << (cpuid.uBitWidthOfFixedFunctionPerformanceCounters) << 'b' << ' '; + os << ' ' << (cpuid.uNumOfFixedFunctionPerformanceCounters) << '*' << (cpuid.uBitWidthOfFixedFunctionPerformanceCounters) << 'b' << ' '; } return os; } - template struct cpuid_base_t<0x0B, nECX> + template struct cpuid_info_t<0x0B, nECX> { // eax unsigned uNumOfBitsToShift : 5; // [bits 4:0] @@ -500,33 +516,36 @@ namespace like unsigned max_sub_leaf() const { - return ~0; + return ~0U; } bool is_sub_leaf(unsigned) const { return uLevelType != 0; } }; - template std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0B, nECX> const & cpuid) + template std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0B, nECX> const & cpuid) { switch (cpuid.uLevelType) { case 0: - os << "Invalid" << ' '; - break; + os << " Invalid"; + return os; case 1: - os << "SMT" << ' '; + os << std::setw(8) << " SMT"; break; case 2: - os << "Core" << ' '; + os << std::setw(8) << " Core"; break; default: - os << "Reserved" << ' '; + os << std::setw(8) << " Reserved"; break; } + os << " x2APIC-ID=" << cpuid.u_x2APIC_ID; + os << " Topology-ID=" << (cpuid.u_x2APIC_ID >> cpuid.uNumOfBitsToShift); + os << " Logical-Processor=" << (cpuid.uNumOfLogicalProcessors); return os; } - template <> struct cpuid_base_t<0x0D> + template <> struct cpuid_info_t<0x0D> { // eax unsigned uStateX87 : 1; // bit 0 @@ -534,12 +553,14 @@ namespace like unsigned uStateAVX : 1; unsigned uStateBNDREGS : 1; // bit 3 unsigned uStateBNDCSR : 1; // bit 4 - unsigned uStateAVX512 : 3; // [bits 7:5] + unsigned uStateOpmask : 1; // bit 5 + unsigned uStateZMM_Hi256 : 1; // bit 6 + unsigned uStateHi16_ZMM : 1; // bit 7 unsigned uStatePT : 1; // bit 8 unsigned uStatePKRU : 1; // bit 9 unsigned : 22; // ebx - unsigned uSizeXCR0: 32; + unsigned uSizeXCR0 : 32; // ecx unsigned uSize : 32; // edx @@ -552,20 +573,23 @@ namespace like return uIndex; } }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D> const & cpuid) { return os << - (cpuid.uStateX87 ? '+' : '-') << "x87" << ' ' << - (cpuid.uStateSSE ? '+' : '-') << "SSE" << ' ' << - (cpuid.uStateAVX ? '+' : '-') << "AVX" << ' ' << - (cpuid.uStateBNDREGS ? '+' : '-') << "BNDREGS" << ' ' << - (cpuid.uStateBNDCSR ? '+' : '-') << "BNDCSR" << ' ' << - (cpuid.uStatePT ? '+' : '-') << "PT" << ' ' << - (cpuid.uStatePKRU ? '+' : '-') << "PKRU" << ' ' << - (cpuid.uSizeXCR0) << 'B' << ' ' << - (cpuid.uSize) << 'B' << ' '; + (cpuid.uStateX87 ? " +x87" : " -x87") << + (cpuid.uStateSSE ? " +SSE" : " -SSE") << + (cpuid.uStateAVX ? " +AVX" : " -AVX") << + (cpuid.uStateBNDREGS ? " +BNDREGS" : " -BNDREGS") << + (cpuid.uStateBNDCSR ? " +BNDCSR" : " -BNDCSR") << + (cpuid.uStateOpmask ? " +Opmask" : " -Opmask") << + (cpuid.uStateZMM_Hi256 ? " +ZMM_Hi256" : " -ZMM_Hi256") << + (cpuid.uStateHi16_ZMM ? " +Hi16_ZMM" : " -Hi16_ZMM") << + (cpuid.uStatePT ? " +PT" : " -PT") << + (cpuid.uStatePKRU ? " +PKRU" : " -PKRU") << + ' ' << (cpuid.uSizeXCR0) << 'B' << + ' ' << (cpuid.uSize) << 'B'; } - template <> struct cpuid_base_t<0x0D, 1> + template <> struct cpuid_info_t<0x0D, 1> { // eax unsigned uXSAVEOPT : 1; // bit 0 @@ -584,16 +608,16 @@ namespace like return true; } }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 1> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 1> const & cpuid) { return os << - (cpuid.uXSAVEOPT ? '+' : '-') << "XSAVEOPT" << ' ' << - (cpuid.uCompactionExtensions ? '+' : '-') << "Compaction-Extensions" << ' ' << - (cpuid.uXGETBV ? '+' : '-') << "XGETBV" << ' ' << - (cpuid.uXSAVES_IA32_XSS ? '+' : '-') << "XSAVES-IA32_XSS" << ' ' << - (cpuid.uSize) << 'B' << ' '; + (cpuid.uXSAVEOPT ? " +XSAVEOPT" : " -XSAVEOPT") << + (cpuid.uCompactionExtensions ? " +Compaction-Extensions" : " -Compaction-Extensions") << + (cpuid.uXGETBV ? " +XGETBV" : " -XGETBV") << + (cpuid.uXSAVES_IA32_XSS ? " +XSAVES-IA32_XSS" : " -XSAVES-IA32_XSS") << + ' ' << (cpuid.uSize) << 'B'; } - template struct cpuid_base_t<0x0D, nECX> // AVX state, BNGREG state, BNDCSR state, Opmask state, ZMM_Hi256 state, Hi16_ZMM state, PT state, PKRU state + template struct cpuid_info_t<0x0D, nECX> // AVX state, BNGREG state, BNDCSR state, Opmask state, ZMM_Hi256 state, Hi16_ZMM state, PT state, PKRU state { // eax unsigned uSize; @@ -611,16 +635,16 @@ namespace like return static_cast(nECX) <= uMaxECX; } }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 2> const & cpuid) { return os << "AVX"; } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 3> const & cpuid) { return os << "BNGREG"; } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 4> const & cpuid) { return os << "BNGCSR"; } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 5> const & cpuid) { return os << "Opmask"; } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 6> const & cpuid) { return os << "ZMM_Hi256"; } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 7> const & cpuid) { return os << "Hi16_ZMM"; } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 8> const & cpuid) { return os << "PT"; } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x0D, 9> const & cpuid) { return os << "PKRU"; } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 2> const & cpuid) { return os << " AVX " << std::setw(3) << cpuid.uSize << 'B' << " @ " << std::setw(4) << cpuid.uOffset << 'B'; } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 3> const & cpuid) { return os << " BNGREG " << std::setw(3) << cpuid.uSize << 'B' << " @ " << std::setw(4) << cpuid.uOffset << 'B'; } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 4> const & cpuid) { return os << " BNGCSR " << std::setw(3) << cpuid.uSize << 'B' << " @ " << std::setw(4) << cpuid.uOffset << 'B'; } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 5> const & cpuid) { return os << " Opmask " << std::setw(3) << cpuid.uSize << 'B' << " @ " << std::setw(4) << cpuid.uOffset << 'B'; } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 6> const & cpuid) { return os << " ZMM_Hi256" << std::setw(3) << cpuid.uSize << 'B' << " @ " << std::setw(4) << cpuid.uOffset << 'B'; } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 7> const & cpuid) { return os << " Hi16_ZMM " << std::setw(3) << cpuid.uSize << 'B' << " @ " << std::setw(4) << cpuid.uOffset << 'B'; } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 8> const & cpuid) { return os << " PT " << std::setw(3) << cpuid.uSize << 'B' << " @ " << std::setw(4) << cpuid.uOffset << 'B'; } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x0D, 9> const & cpuid) { return os << " PKRU " << std::setw(3) << cpuid.uSize << 'B' << " @ " << std::setw(4) << cpuid.uOffset << 'B'; } - template <> struct cpuid_base_t<0x0F> + template <> struct cpuid_info_t<0x0F> { // eax unsigned : 32; @@ -640,7 +664,7 @@ namespace like return uIndex; } }; - template <> struct cpuid_base_t<0x0F, 1> + template <> struct cpuid_info_t<0x0F, 1> { // eax unsigned : 32; @@ -657,7 +681,7 @@ namespace like return 1 <= uMaxECX; } }; - template <> struct cpuid_base_t<0x10> + template <> struct cpuid_info_t<0x10> { // eax unsigned : 32; @@ -677,7 +701,7 @@ namespace like return uIndex; } }; - template <> struct cpuid_base_t<0x10, 1> + template <> struct cpuid_info_t<0x10, 1> { // eax unsigned uNumOfCapacity : 5; // [bits 4:0] @@ -698,7 +722,7 @@ namespace like return 1 <= uMaxECX; } }; - template <> struct cpuid_base_t<0x12> + template <> struct cpuid_info_t<0x12> { // eax unsigned uSGX1 : 1; // bit 0 @@ -713,13 +737,13 @@ namespace like unsigned uMaxEnclaveSize_64 : 8; // [15:8] unsigned : 16; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x12> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x12> const & cpuid) { return os << - (cpuid.uSGX1 ? '+' : '-') << "SGX1" << ' ' << - (cpuid.uSGX2 ? '+' : '-') << "SGX2" << ' '; + (cpuid.uSGX1 ? " +SGX1" : " -SGX1") << + (cpuid.uSGX2 ? " +SGX2" : " -SGX2"); } - template <> struct cpuid_base_t<0x14> + template <> struct cpuid_info_t<0x14> { // eax unsigned uMaxSubLeaf : 32; @@ -736,7 +760,7 @@ namespace like unsigned uOutputToTraceTransportSubsystem : 1; // bit 3 unsigned : 27; unsigned uLIP : 1; // bit 31: Generated packets which contain IP payloads have LIP values, which include the CS base component. - // edx + // edx unsigned : 32; unsigned max_sub_leaf() const @@ -744,16 +768,16 @@ namespace like return uMaxSubLeaf; } }; - template <> struct cpuid_base_t<0x14, 1> + template <> struct cpuid_info_t<0x14, 1> { // eax unsigned uNumOfConfigurableAddressRanges : 3; // [bits 2:0] unsigned : 13; unsigned uMTC_PeriodEncodingsBitmap : 16; // [bits 31:16] - // ebx + // ebx unsigned uCycleThresholdValueEncodingsBitmap : 16; // [bits 15:0] unsigned uConfigurablePSB_FrequencyEncodingsBitmap : 16; // [bits 31:16] - // ecx + // ecx unsigned : 32; // edx unsigned : 32; @@ -763,7 +787,7 @@ namespace like return 1 <= uMaxECX; } }; - template <> struct cpuid_base_t<0x15> + template <> struct cpuid_info_t<0x15> { // eax unsigned uCoreCrystalClock : 32; @@ -774,12 +798,11 @@ namespace like // edx unsigned : 32; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x15> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x15> const & cpuid) { - return os << - cpuid.uTSC << '/' << cpuid.uCoreCrystalClock << ' '; + return os << ' ' << cpuid.uTSC << '/' << cpuid.uCoreCrystalClock; } - template <> struct cpuid_base_t<0x16> + template <> struct cpuid_info_t<0x16> { // eax unsigned uProcessorBaseFrequencyMHz : 16; // [bits 15:0] @@ -793,14 +816,14 @@ namespace like // edx unsigned : 32; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x16> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x16> const & cpuid) { - return os << - cpuid.uProcessorBaseFrequencyMHz << "MHz" << ' ' << - cpuid.uMaximumFrequencyMHz << "MHz" << ' ' << - cpuid.uBusFrequencyMHz << "MHz" << ' '; + return os + << ' ' << cpuid.uProcessorBaseFrequencyMHz << "MHz" + << ' ' << cpuid.uMaximumFrequencyMHz << "MHz" + << ' ' << cpuid.uBusFrequencyMHz << "MHz"; } - template <> struct cpuid_base_t<0x17> + template <> struct cpuid_info_t<0x17> { // eax unsigned uMaxSOCID_Index : 32; @@ -818,7 +841,7 @@ namespace like return uMaxSOCID_Index; } }; - template <> struct cpuid_base_t<0x17, 1> + template <> struct cpuid_info_t<0x17, 1> { char ac[16]; @@ -831,7 +854,7 @@ namespace like return 1 <= uMaxECX; } }; - template <> struct cpuid_base_t<0x17, 2> + template <> struct cpuid_info_t<0x17, 2> { char ac[16]; @@ -840,7 +863,7 @@ namespace like return 2 <= uMaxECX; } }; - template <> struct cpuid_base_t<0x17, 3> + template <> struct cpuid_info_t<0x17, 3> { char ac[16]; @@ -849,11 +872,11 @@ namespace like return 3 <= uMaxECX; } }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x17, 1> const & cpuid) { return os.write(cpuid.ac, 16); } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x17, 2> const & cpuid) { return os.write(cpuid.ac, 16); } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x17, 3> const & cpuid) { return os.write(cpuid.ac, 16); } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x17, 1> const & cpuid) { return (os << ' ').write(cpuid.ac, 16); } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x17, 2> const & cpuid) { return (os << ' ').write(cpuid.ac, 16); } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x17, 3> const & cpuid) { return (os << ' ').write(cpuid.ac, 16); } - template <> struct cpuid_base_t<0x80000000> + template <> struct cpuid_info_t<0x80000000> { // eax unsigned uMaxLeaf : 32; @@ -869,7 +892,7 @@ namespace like return uMaxLeaf; } }; - template <> struct cpuid_base_t<0x80000001> + template <> struct cpuid_info_t<0x80000001> { // eax unsigned uExtendedProcessorSignatureAndFeatureBits : 32; @@ -894,16 +917,17 @@ namespace like unsigned uIntel64 : 1; // bit 29 unsigned : 2; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x80000001> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x80000001> const & cpuid) { return os << - (cpuid.uLZCNT ? '+' : '-') << "LZCNT" << ' ' << - (cpuid.uPREFTEHCHW ? '+' : '-') << "PREFTEHCHW" << ' ' << - (cpuid.u1GBytePages ? '+' : '-') << "1GBytePages" << ' ' << - (cpuid.uRDTSCP ? '+' : '-') << "RDTSCP" << ' ' << - (cpuid.uIntel64 ? '+' : '-') << "x64" << ' '; + (cpuid.uLZCNT ? " +LZCNT" : " -LZCNT") << + (cpuid.uPREFTEHCHW ? " +PREFTEHCHW" : " -PREFTEHCHW") << + (cpuid.uExecuteDiableBit ? " +ExecuteDisable" : " -ExecuteDisable") << + (cpuid.u1GBytePages ? " +1GBytePages" : " -1GBytePages") << + (cpuid.uRDTSCP ? " +RDTSCP" : " -RDTSCP") << + (cpuid.uIntel64 ? " +x64" : " -x64"); } - template <> struct cpuid_base_t<0x80000002> + template <> struct cpuid_info_t<0x80000002> { char ac[16]; @@ -912,18 +936,18 @@ namespace like return ac; } }; - template <> struct cpuid_base_t<0x80000003> + template <> struct cpuid_info_t<0x80000003> { char ac[16]; }; - template <> struct cpuid_base_t<0x80000004> + template <> struct cpuid_info_t<0x80000004> { char ac[16]; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x80000002> const & cpuid) { return os.write(cpuid.ac, 16); } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x80000003> const & cpuid) { return os.write(cpuid.ac, 16); } - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x80000004> const & cpuid) { return os.write(cpuid.ac, 16); } - template <> struct cpuid_base_t<0x80000006> + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x80000002> const & cpuid) { return (os << ' ').write(cpuid.ac, 16); } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x80000003> const & cpuid) { return (os << ' ').write(cpuid.ac, 16); } + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x80000004> const & cpuid) { return (os << ' ').write(cpuid.ac, 16); } + template <> struct cpuid_info_t<0x80000006> { // eax unsigned : 32; @@ -934,39 +958,39 @@ namespace like unsigned : 4; unsigned uL2Associativity : 4; // [bits 15:12] unsigned uCacheSize1K : 16; // [bits 31:16] - // edx + // edx unsigned : 32; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x80000006> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x80000006> const & cpuid) { - os << (cpuid.uCacheLineSize) << "B" << ' '; + os << (cpuid.uCacheLineSize ? " +B " : " -B "); switch (cpuid.uL2Associativity) { case 0: - os << "Disabled" << ' '; + os << " Disabled "; break; case 1: - os << "DirectMapped" << ' '; + os << " DirectMapped "; break; case 2: - os << "2-way" << ' '; + os << " 2-way "; break; case 4: - os << "4-way" << ' '; + os << " 4-way "; break; case 6: - os << "8-way" << ' '; + os << " 8-way "; break; case 8: - os << "16-way" << ' '; + os << " 16-way "; break; case 0xF: - os << "FullyAssociative" << ' '; + os << " FullyAssociative "; break; } - return os << (cpuid.uCacheSize1K) << "KB" << ' '; + return os << (cpuid.uCacheSize1K ? " +KB " : " -KB "); } - template <> struct cpuid_base_t<0x80000007> + template <> struct cpuid_info_t<0x80000007> { // eax unsigned : 32; @@ -979,12 +1003,12 @@ namespace like unsigned uInvariantTSC : 1; // bit 8 unsigned : 23; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x80000007> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x80000007> const & cpuid) { return os << - (cpuid.uInvariantTSC ? '+' : '-') << "InvariantTSC" << ' '; + (cpuid.uInvariantTSC ? " +InvariantTSC " : " -InvariantTSC "); } - template <> struct cpuid_base_t<0x80000008> + template <> struct cpuid_info_t<0x80000008> { // eax unsigned uNumOfPhysicalAddressBits : 8; // [bits 7:0] @@ -997,18 +1021,18 @@ namespace like // edx unsigned : 32; }; - template <> std::ostream & operator << (std::ostream & os, cpuid_base_t<0x80000008> const & cpuid) + template <> std::ostream & operator << (std::ostream & os, cpuid_info_t<0x80000008> const & cpuid) { - return os << - (cpuid.uNumOfPhysicalAddressBits) << 'b' << ' ' << - (cpuid.uNumOfLinearAddressBits) << 'b' << ' '; + return os + << ' ' << (cpuid.uNumOfPhysicalAddressBits) << 'b' + << ' ' << (cpuid.uNumOfLinearAddressBits) << 'b'; } template - struct alignas(16) cpuid_t - : cpuid_base_t + struct cpuid_t + : cpuid_info_t { - static_assert(sizeof(cpuid_base_t) == 16, "CPUID expects 4 32-bit integers"); + static_assert(sizeof(cpuid_info_t) == 16, "CPUID expects 4 32-bit integers"); cpuid_t() { @@ -1027,16 +1051,15 @@ namespace like } int nMask = os.setf(std::ios_base::hex); os.unsetf(std::ios_base::dec); - os << - std::setw(8) << static_cast(nEAX) << ' ' << - std::setw(3) << static_cast(nECX) << ' ' << - std::setw(8) << reinterpret_cast(this)[0] << ' ' << - std::setw(8) << reinterpret_cast(this)[1] << ' ' << - std::setw(8) << reinterpret_cast(this)[2] << ' ' << - std::setw(8) << reinterpret_cast(this)[3] << ' '; + os << std::setw(8) << static_cast(nEAX) + << ' ' << std::setw(3) << static_cast(nECX) + << ' ' << std::setw(8) << reinterpret_cast(this)[0] + << ' ' << std::setw(8) << reinterpret_cast(this)[1] + << ' ' << std::setw(8) << reinterpret_cast(this)[2] + << ' ' << std::setw(8) << reinterpret_cast(this)[3]; os.setf(nMask); os << - static_castconst&>(*this) << std::endl; + static_castconst&>(*this) << std::endl; return os; } std::istream & scan(std::istream & is) @@ -1053,7 +1076,8 @@ namespace like std::streampos uPos = is.tellg(); - unsigned uEAX = ~nEAX, uECX = ~nECX; + unsigned uEAX = static_cast(~nEAX); + unsigned uECX = static_cast(~nECX); { int nMask = is.setf(std::ios_base::hex | std::ios_base::skipws); is.unsetf(std::ios_base::dec); @@ -1076,10 +1100,10 @@ namespace like return is; } - char ac[2000]; + char acLocal[2000]; do { - is.getline(ac, std::size(ac)); + is.getline(acLocal, std::size(acLocal)); } while (is.fail() && !is.eof()); return is; } @@ -1089,6 +1113,11 @@ namespace like { return cpuid.print(os); } + template + std::istream & operator >> (std::istream & is, cpuid_t & cpuid) + { + return cpuid.scan(is); + } struct cpuid_soc_vendor_brand_string_t : cpuid_t<0x17, 1> @@ -1100,6 +1129,10 @@ namespace like return reinterpret_cast(this); } }; + std::ostream & operator << (std::ostream & os, cpuid_soc_vendor_brand_string_t const & cpuid) + { + return os.write(cpuid, sizeof(cpuid)); + } struct cpuid_processor_brand_string_t : cpuid_t<0x80000002> , cpuid_t<0x80000003> @@ -1110,6 +1143,10 @@ namespace like return reinterpret_cast(this); } }; + std::ostream & operator << (std::ostream & os, cpuid_processor_brand_string_t const & cpuid) + { + return os.write(cpuid, sizeof(cpuid)); + } // template @@ -1123,11 +1160,11 @@ namespace like : cpuid_sub_leaf_t(is) , cpuid_t(is) {} - std::ostream & print_sub_leaf(std::ostream & os, unsigned uMaxSubLeaf = ~0) const + std::ostream & print_sub_leaf(std::ostream & os) const { - cpuid_sub_leaf_t::print_sub_leaf(os, uMaxSubLeaf); + cpuid_sub_leaf_t::print_sub_leaf(os); - if (cpuid_t::is_sub_leaf(uMaxSubLeaf)) + if (cpuid_t::is_sub_leaf(cpuid_t::max_sub_leaf())) { cpuid_t::print(os); } @@ -1148,7 +1185,7 @@ namespace like cpuid_sub_leaf_t(std::istream & is) : cpuid_t(is) {} - std::ostream & print_sub_leaf(std::ostream & os, unsigned uMaxSubLeaf = ~0) const + std::ostream & print_sub_leaf(std::ostream & os) const { return cpuid_t::print(os); } @@ -1170,7 +1207,7 @@ namespace like template <> struct cpuid_leaf_traits<0x14> { enum { MAX_ECX = 1 }; }; template <> struct cpuid_leaf_traits<0x17> { enum { MAX_ECX = 3 }; }; template - struct alignas(16) cpuid_leaf_t + struct cpuid_leaf_t : cpuid_sub_leaf_t::MAX_ECX> { cpuid_leaf_t() @@ -1178,30 +1215,30 @@ namespace like cpuid_leaf_t(std::istream & is) : cpuid_sub_leaf_t::MAX_ECX>(is) {} - template std::ostream & print_leaf(std::ostream & os) const - { - return cpuid_sub_leaf_t::MAX_ECX>::print_sub_leaf(os, cpuid_t::max_sub_leaf()); - } - template <> - std::ostream & print_leaf<0>(std::ostream & os) const { return cpuid_sub_leaf_t::MAX_ECX>::print_sub_leaf(os); } - std::ostream & print_leaf(std::ostream & os) const - { - return print_leaf::MAX_ECX>(os); - } std::istream & scan_leaf(std::istream & is) { return cpuid_sub_leaf_t::MAX_ECX>::scan_sub_leaf(is); } }; + template + std::ostream & operator << (std::ostream & os, cpuid_leaf_t const & cpuid_leaf) + { + return cpuid_leaf.print_leaf(os); + } + template + std::istream & operator >> (std::istream & is, cpuid_leaf_t & cpuid_leaf) + { + return cpuid_leaf.scan_leaf(is); + } // template - struct alignas(16) cpuid_tree_t + struct cpuid_tree_t : cpuid_tree_t , cpuid_leaf_t { @@ -1211,19 +1248,15 @@ namespace like : cpuid_tree_t(is) , cpuid_leaf_t(is) {} - std::ostream & print_tree(std::ostream & os, unsigned uMaxLeaf) const + std::ostream & print_tree(std::ostream & os) const { - cpuid_tree_t::print_tree(os, uMaxLeaf); - if (static_cast(nEAX) <= uMaxLeaf) + cpuid_tree_t::print_tree(os); + if (static_cast(nEAX) <= max_leaf()) { cpuid_leaf_t::print_leaf(os); } return os; } - std::ostream & print_tree(std::ostream & os) const - { - return print_tree(os, max_leaf()); - } std::istream & scan_tree(std::istream & is) { cpuid_tree_t::scan_tree(is); @@ -1231,7 +1264,7 @@ namespace like } }; template <> - struct alignas(16) cpuid_tree_t<0> + struct cpuid_tree_t<0> : cpuid_leaf_t<0> { cpuid_tree_t() @@ -1239,7 +1272,7 @@ namespace like cpuid_tree_t(std::istream & is) : cpuid_leaf_t<0>(is) {} - std::ostream & print_tree(std::ostream & os, unsigned uMaxLeaf = ~0) const + std::ostream & print_tree(std::ostream & os) const { return print_leaf(os); } @@ -1249,7 +1282,7 @@ namespace like } }; template <> - struct alignas(16) cpuid_tree_t<0x80000000> + struct cpuid_tree_t<0x80000000> : cpuid_leaf_t<0x80000000> { cpuid_tree_t() @@ -1257,7 +1290,7 @@ namespace like cpuid_tree_t(std::istream & is) : cpuid_leaf_t<0x80000000>(is) {} - std::ostream & print_tree(std::ostream & os, unsigned uMaxLeaf = ~0) const + std::ostream & print_tree(std::ostream & os) const { return print_leaf(os); }