[C/C++] ccpuid:CPUID信息模塊 V1.02版,支持Mac OS X,支持純C,增加CPUF常數


新版本——
http://www.cnblogs.com/zyl910/archive/2012/10/13/ccpuid_v103.html

 

作者:zyl910

  之前的ccpuid V1.01版只支持Windows和Linux平台。現在的V1.02版增加對Mac OS X平台的支持,還做了這些改進——支持純C、增加CPUF常數、x86平台判斷。


一、更新說明

1.1 支持Mac OS X平台

  之前我發現了Mac OS X中的“/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/4.0/include”目錄中有intrin頭文件(http://www.cnblogs.com/zyl910/archive/2012/09/27/intrin_mac.html)。於是以為ccpuid不經過修改便能在Mac OS C中編譯。但是實際測試時發現,gcc報告找不到“cpuid.h”。
  但是很奇怪,“#include <xmmintrin.h>”卻能正常包含。
  雖然修改gcc的目錄配置也許能解決問題,但我沒有這么做,因為這樣會增加配置成本。

  而且,打開Mac OS X中的cpuid.h一看,發現它沒有定義__cpuid/__cpuid_count等宏。也就是說,就算正確包含了cpuid.h,也因缺少相關宏而報錯。

  換一下思路,直接使用內嵌匯編行不行呢?
  VC中的內嵌匯編不支持64位,於是只有使用intrin函數。而gcc的內嵌匯編不受該限制,64位下也可使用內嵌匯編,例如Fedora的cpuid.h中就是用內嵌匯編實現__cpuid等宏的。
  Mac下的gcc也是一種gcc,內嵌匯編的語法應該是一樣的。
  於是我試着將Fedora的cpuid.h中關於__cpuid等宏的的代碼,用Mac下的gcc編譯。果然編譯成功,運行正常。

  __cpuid的相關代碼修改成——

        #include <xmmintrin.h>    // MMX, SSE

        //#include <cpuid.h>    // mac 中的 llvm-gcc有時找不到cpuid.h,而且它沒有 __cpuid/__cpuid_count,干脆我們自己定義.
        #ifndef __cpuid_count
            // 下面代碼出自 GCC 4.7.0(Fedora 17) 的 cpuid.h
            #if defined(__i386__) && defined(__PIC__)
            /* %ebx may be the PIC register.  */
            #if __GNUC__ >= 3
            #define __cpuid(level, a, b, c, d)            \
              __asm__ ("xchg{l}\t{%%}ebx, %1\n\t"            \
                   "cpuid\n\t"                    \
                   "xchg{l}\t{%%}ebx, %1\n\t"            \
                   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)    \
                   : "0" (level))

            #define __cpuid_count(level, count, a, b, c, d)        \
              __asm__ ("xchg{l}\t{%%}ebx, %1\n\t"            \
                   "cpuid\n\t"                    \
                   "xchg{l}\t{%%}ebx, %1\n\t"            \
                   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)    \
                   : "0" (level), "2" (count))
            #else
            /* Host GCCs older than 3.0 weren't supporting Intel asm syntax
               nor alternatives in i386 code.  */
            #define __cpuid(level, a, b, c, d)            \
              __asm__ ("xchgl\t%%ebx, %1\n\t"            \
                   "cpuid\n\t"                    \
                   "xchgl\t%%ebx, %1\n\t"            \
                   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)    \
                   : "0" (level))

            #define __cpuid_count(level, count, a, b, c, d)        \
              __asm__ ("xchgl\t%%ebx, %1\n\t"            \
                   "cpuid\n\t"                    \
                   "xchgl\t%%ebx, %1\n\t"            \
                   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)    \
                   : "0" (level), "2" (count))
            #endif
            #else
            #define __cpuid(level, a, b, c, d)            \
              __asm__ ("cpuid\n\t"                    \
                   : "=a" (a), "=b" (b), "=c" (c), "=d" (d)    \
                   : "0" (level))

            #define __cpuid_count(level, count, a, b, c, d)        \
              __asm__ ("cpuid\n\t"                    \
                   : "=a" (a), "=b" (b), "=c" (c), "=d" (d)    \
                   : "0" (level), "2" (count))
            #endif
        #endif    // #ifndef __cpuid_count

 



1.2 支持純C

  ccpuid最初為了使用方便,於是將其封裝成類,使得只有C++程序才能使用該模塊,而純C程序不能使用。
  現在決定將其拆分為純C版和C++版,使純C程序也能使用。

  具體做法是——
1. 將原 ccpuid.h 拆分為 ccpuid.h 與 ccpuid.hpp。純C的依然保留在ccpuid.h,而C++部分移至ccpuid.hpp。
2. ccpuid.cpp中的全局函數移至ccpuid.h,並作為內聯函數。
3. 因純C不支持結構化異常處理, 忽略simd_mmx、simd_sse_level的 操作系統判斷。

  使用方法——
1. 對於純C程序:只需引入ccpuid.h這個頭文件就行了。
2. 對於C++程序:引入ccpuid.hpp,並在項目中加上ccpuid.cpp這個源文件一起編譯。

  注意為了避免全局變量問題,CPUFDesc、SseNames等數組仍是作為CCPUID類的靜態成員,所以它們只能在C++版中使用。


1.3 增加CPUF常數

  根據最新的Intel文檔——
《Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes:1, 2A, 2B, 2C, 3A, 3B, and 3C》044US. August 2012. http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
《Intel® Architecture Instruction Set Extensions Programming Reference》014. AUGUST 2012. http://software.intel.com/en-us/avx/
《Intel® Processor Identification and the CPUID Instruction》. May 2012. http://developer.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html

  增加了這些CPUF常數——
CPUID.(EAX=07H, ECX=0H):EBX.TSC_ADJUST(bit 1). // IA32_TSC_ADJUST MSR is supported if 1.
CPUID.(EAX=07H, ECX=0H):EBX.RDSEED(bit 18) // RDSEED instruction.
CPUID.(EAX=07H, ECX=0H):EBX.ADX(bit 19) // ADCX and ADOX instructions.
CPUID.(EAX=07H, ECX=0H):EBX.SMAP(bit 20) // Supervisor Mode Access Prevention.


1.4 x86平台判斷

  以前沒有考慮平台檢查,在非x86平台上編譯時會報錯。於是在V1.02版中加入了平台判斷,在非x86平台上返回0而不是無法編譯。

  判斷x86平台的具體做法是——
1. 對於GCC:判斷 __i386__ 或 __x86_64__ 宏是否存在。
2. 對於VC:判斷 _M_IX86 或 _M_X64 宏是否存在。

  然后根據上面的判斷結果定義CCPUID_X86宏。在simd_mmx等函數中就可以利用CCPUID_X86宏來避免編譯出錯。

  這樣做的有利於代碼的移植。例如某個程序使用了ccpuid來判斷CPU是否支持SSE,在x86平台上可以正常檢查,而在非x86平台上能返回0表示不支持,使得后續的SSE代碼不會在非x86平台上運行。


二、全部代碼

2.1 ccpuid.h: CPUID信息(純C版)

  全部代碼——

View Code
#ifndef __CCPUID_H_INCLUDED
#define __CCPUID_H_INCLUDED

#include <stddef.h>    // NULL等標准宏和類型.
// 統一使用“uint32_t”    //#include <basetsd.h>    // INT32、UINT32等規范類型名.
#include "stdint.h"


// intrinsics
#if (defined(__GNUC__))    // GCC
    #if (defined(__i386__) || defined(__x86_64__))
        #define CCPUID_X86    1    // 是x86平台.
        #include <xmmintrin.h>    // MMX, SSE
        //#include <cpuid.h>    // mac 中的 llvm-gcc有時找不到cpuid.h,而且它沒有 __cpuid/__cpuid_count,干脆我們自己定義.
        #ifndef __cpuid_count
            // 下面代碼出自 GCC 4.7.0(Fedora 17) 的 cpuid.h
            #if defined(__i386__) && defined(__PIC__)
            /* %ebx may be the PIC register.  */
            #if __GNUC__ >= 3
            #define __cpuid(level, a, b, c, d)            \
              __asm__ ("xchg{l}\t{%%}ebx, %1\n\t"            \
                   "cpuid\n\t"                    \
                   "xchg{l}\t{%%}ebx, %1\n\t"            \
                   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)    \
                   : "0" (level))

            #define __cpuid_count(level, count, a, b, c, d)        \
              __asm__ ("xchg{l}\t{%%}ebx, %1\n\t"            \
                   "cpuid\n\t"                    \
                   "xchg{l}\t{%%}ebx, %1\n\t"            \
                   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)    \
                   : "0" (level), "2" (count))
            #else
            /* Host GCCs older than 3.0 weren't supporting Intel asm syntax
               nor alternatives in i386 code.  */
            #define __cpuid(level, a, b, c, d)            \
              __asm__ ("xchgl\t%%ebx, %1\n\t"            \
                   "cpuid\n\t"                    \
                   "xchgl\t%%ebx, %1\n\t"            \
                   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)    \
                   : "0" (level))

            #define __cpuid_count(level, count, a, b, c, d)        \
              __asm__ ("xchgl\t%%ebx, %1\n\t"            \
                   "cpuid\n\t"                    \
                   "xchgl\t%%ebx, %1\n\t"            \
                   : "=a" (a), "=r" (b), "=c" (c), "=d" (d)    \
                   : "0" (level), "2" (count))
            #endif
            #else
            #define __cpuid(level, a, b, c, d)            \
              __asm__ ("cpuid\n\t"                    \
                   : "=a" (a), "=b" (b), "=c" (c), "=d" (d)    \
                   : "0" (level))

            #define __cpuid_count(level, count, a, b, c, d)        \
              __asm__ ("cpuid\n\t"                    \
                   : "=a" (a), "=b" (b), "=c" (c), "=d" (d)    \
                   : "0" (level), "2" (count))
            #endif
        #endif    // #ifndef __cpuid_count
    #endif    // #if (defined(__i386__) || defined(__x86_64__) )

#elif defined(_MSC_VER)    // MSVC
    #if (defined(_M_IX86) || defined(_M_X64))
        #define CCPUID_X86    1    // 是x86平台.
        #if _MSC_VER >=1400    // VC2005
            #include <intrin.h>    // CPUID, MMX, SSE
        #elif _MSC_VER >=1200    // VC6
            #include <xmmintrin.h>    // MMX, SSE
        #endif    // #if _MSC_VER >=1400
    #endif

#else
    #error Only supports MSVC or GCC.
#endif    // #if defined(__GNUC__)


// INLINE
#ifndef INLINE
    #if defined(_MSC_VER)    // MSVC
        #define INLINE    __inline
    #else    // C99
        #define INLINE    inline
    #endif
#endif


#if defined __cplusplus
extern "C" {
#endif

////////////////////////////////////////
// getcpuid: 獲取CPUID信息的基礎函數.
////////////////////////////////////////

INLINE void getcpuidex(uint32_t CPUInfo[4], uint32_t InfoType, uint32_t ECXValue)
{
    if (NULL==CPUInfo)    return;

#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))    // GCC
    __cpuid_count(InfoType, ECXValue, CPUInfo[0],CPUInfo[1],CPUInfo[2],CPUInfo[3]);
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))    // MSVC
    #if defined(_M_X64) || _MSC_VER>=1600    // 64位下不支持內聯匯編. 1600: VS2010, 據說VC2008 SP1之后才支持__cpuidex.
        __cpuidex((int*)CPUInfo, (int)InfoType, (int)ECXValue);
    #else
        _asm{
            // load. 讀取參數到寄存器.
            mov edi, CPUInfo;    // 准備用edi尋址CPUInfo
            mov eax, InfoType;
            mov ecx, ECXValue;
            // CPUID
            cpuid;
            // save. 將寄存器保存到CPUInfo
            mov    [edi], eax;
            mov    [edi+4], ebx;
            mov    [edi+8], ecx;
            mov    [edi+12], edx;
        }
    #endif
#else
    // 不支持,返回0 .
    CPUInfo[0] = CPUInfo[1] = CPUInfo[2] = CPUInfo[3] = 0;
#endif    // #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
}

INLINE void getcpuid(uint32_t CPUInfo[4], uint32_t InfoType)
{
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))    // GCC
    __cpuid(InfoType, CPUInfo[0],CPUInfo[1],CPUInfo[2],CPUInfo[3]);
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))    // MSVC
    #if _MSC_VER>=1400    // VC2005才支持__cpuid
        __cpuid((int*)CPUInfo, (int)InfoType);
    #else
        getcpuidex(CPUInfo, InfoType, 0);
    #endif
#else
    getcpuidex(CPUInfo, InfoType, 0);
#endif    // #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
}


// 存儲單條CPUID信息的結構體.
typedef struct tagCPUIDINFO{
    uint32_t    fid;    // 功能號. 即CPUID指令的EAX參數.
    uint32_t    fidsub;    // 子功能號. 即CPUID指令的ECX參數.
    union{
        uint32_t    dw[4];    // 返回的信息.
        struct{
            uint32_t    _eax;
            uint32_t    _ebx;
            uint32_t    _ecx;
            uint32_t    _edx;
        };
    };
}CPUIDINFO, *LPCPUIDINFO;
typedef const CPUIDINFO* LPCCPUIDINFO;




////////////////////////////////////////
// CPUIDFIELD: CPUID字段的統一編號方案.
//
// http://www.cnblogs.com/zyl910/archive/2012/06/29/getcpuidfield.html
////////////////////////////////////////

typedef uint32_t CPUIDFIELD;

#define  CPUIDFIELD_MASK_POS    0x0000001F    // 位偏移. 0~31.
#define  CPUIDFIELD_MASK_LEN    0x000003E0    // 位長. 1~32
#define  CPUIDFIELD_MASK_REG    0x00000C00    // 寄存器. 0=EAX, 1=EBX, 2=ECX, 3=EDX.
#define  CPUIDFIELD_MASK_FIDSUB    0x000FF000    // 子功能號(低8位).
#define  CPUIDFIELD_MASK_FID    0xFFF00000    // 功能號(最高4位 和 低8位).

#define CPUIDFIELD_SHIFT_POS    0
#define CPUIDFIELD_SHIFT_LEN    5
#define CPUIDFIELD_SHIFT_REG    10
#define CPUIDFIELD_SHIFT_FIDSUB    12
#define CPUIDFIELD_SHIFT_FID    20

#define CPUIDFIELD_MAKE(fid,fidsub,reg,pos,len)    (((fid)&0xF0000000U) \
    | ((fid)<<CPUIDFIELD_SHIFT_FID & 0x0FF00000) \
    | ((fidsub)<<CPUIDFIELD_SHIFT_FIDSUB & CPUIDFIELD_MASK_FIDSUB) \
    | ((reg)<<CPUIDFIELD_SHIFT_REG & CPUIDFIELD_MASK_REG) \
    | ((pos)<<CPUIDFIELD_SHIFT_POS & CPUIDFIELD_MASK_POS) \
    | (((len)-1)<<CPUIDFIELD_SHIFT_LEN & CPUIDFIELD_MASK_LEN) \
    )
#define CPUIDFIELD_FID(cpuidfield)    ( ((uint32_t)(cpuidfield)&0xF0000000U) | (((uint32_t)(cpuidfield) & 0x0FF00000)>>CPUIDFIELD_SHIFT_FID) )
#define CPUIDFIELD_FIDSUB(cpuidfield)    ( ((cpuidfield) & CPUIDFIELD_MASK_FIDSUB)>>CPUIDFIELD_SHIFT_FIDSUB )
#define CPUIDFIELD_REG(cpuidfield)    ( ((cpuidfield) & CPUIDFIELD_MASK_REG)>>CPUIDFIELD_SHIFT_REG )
#define CPUIDFIELD_POS(cpuidfield)    ( ((cpuidfield) & CPUIDFIELD_MASK_POS)>>CPUIDFIELD_SHIFT_POS )
#define CPUIDFIELD_LEN(cpuidfield)    ( (((cpuidfield) & CPUIDFIELD_MASK_LEN)>>CPUIDFIELD_SHIFT_LEN) + 1 )

// CPUID字段的描述.
typedef struct tagCPUIDFIELDDESC{
    CPUIDFIELD    cpuf;
    int    reserved;
    const char* szName;
    const char* szDesc;
}CPUIDFIELDDESC, *LPCPUIDFIELDDESC;
typedef const CPUIDFIELDDESC* LPCCPUIDFIELDDESC;

#define CPUF_LFuncStd    CPUIDFIELD_MAKE(0,0,0,0,32)
#define CPUF_Stepping    CPUIDFIELD_MAKE(1,0,0,0,4)
#define CPUF_BaseModel    CPUIDFIELD_MAKE(1,0,0,4,4)
#define CPUF_BaseFamily    CPUIDFIELD_MAKE(1,0,0,8,4)
#define CPUF_ProcessorType    CPUIDFIELD_MAKE(1,0,0,12,2)
#define CPUF_ExtModel    CPUIDFIELD_MAKE(1,0,0,16,4)
#define CPUF_ExtFamily    CPUIDFIELD_MAKE(1,0,0,20,8)
#define CPUF_BrandId8    CPUIDFIELD_MAKE(1,0,1,0,8)
#define CPUF_CLFlush    CPUIDFIELD_MAKE(1,0,1,8,8)
#define CPUF_MaxApicId    CPUIDFIELD_MAKE(1,0,1,16,8)
#define CPUF_ApicId    CPUIDFIELD_MAKE(1,0,1,24,8)
#define CPUF_SSE3    CPUIDFIELD_MAKE(1,0,2,0,1)
#define CPUF_PCLMULQDQ    CPUIDFIELD_MAKE(1,0,2,1,1)
#define CPUF_DTES64    CPUIDFIELD_MAKE(1,0,2,2,1)
#define CPUF_MONITOR    CPUIDFIELD_MAKE(1,0,2,3,1)
#define CPUF_DS_CPL    CPUIDFIELD_MAKE(1,0,2,4,1)
#define CPUF_VMX    CPUIDFIELD_MAKE(1,0,2,5,1)
#define CPUF_SMX    CPUIDFIELD_MAKE(1,0,2,6,1)
#define CPUF_EIST    CPUIDFIELD_MAKE(1,0,2,7,1)
#define CPUF_TM2    CPUIDFIELD_MAKE(1,0,2,8,1)
#define CPUF_SSSE3    CPUIDFIELD_MAKE(1,0,2,9,1)
#define CPUF_CNXT_ID    CPUIDFIELD_MAKE(1,0,2,10,1)
#define CPUF_FMA    CPUIDFIELD_MAKE(1,0,2,12,1)
#define CPUF_CX16    CPUIDFIELD_MAKE(1,0,2,13,1)
#define CPUF_xTPR    CPUIDFIELD_MAKE(1,0,2,14,1)
#define CPUF_PDCM    CPUIDFIELD_MAKE(1,0,2,15,1)
#define CPUF_PCID    CPUIDFIELD_MAKE(1,0,2,17,1)
#define CPUF_DCA    CPUIDFIELD_MAKE(1,0,2,18,1)
#define CPUF_SSE41    CPUIDFIELD_MAKE(1,0,2,19,1)
#define CPUF_SSE42    CPUIDFIELD_MAKE(1,0,2,20,1)
#define CPUF_x2APIC    CPUIDFIELD_MAKE(1,0,2,21,1)
#define CPUF_MOVBE    CPUIDFIELD_MAKE(1,0,2,22,1)
#define CPUF_POPCNT    CPUIDFIELD_MAKE(1,0,2,23,1)
#define CPUF_TSC_DEADLINE    CPUIDFIELD_MAKE(1,0,2,24,1)
#define CPUF_AES    CPUIDFIELD_MAKE(1,0,2,25,1)
#define CPUF_XSAVE    CPUIDFIELD_MAKE(1,0,2,26,1)
#define CPUF_OSXSAVE    CPUIDFIELD_MAKE(1,0,2,27,1)
#define CPUF_AVX    CPUIDFIELD_MAKE(1,0,2,28,1)
#define CPUF_F16C    CPUIDFIELD_MAKE(1,0,2,29,1)
#define CPUF_RDRAND    CPUIDFIELD_MAKE(1,0,2,30,1)
#define CPUF_FPU    CPUIDFIELD_MAKE(1,0,3,0,1)
#define CPUF_VME    CPUIDFIELD_MAKE(1,0,3,1,1)
#define CPUF_DE    CPUIDFIELD_MAKE(1,0,3,2,1)
#define CPUF_PSE    CPUIDFIELD_MAKE(1,0,3,3,1)
#define CPUF_TSC    CPUIDFIELD_MAKE(1,0,3,4,1)
#define CPUF_MSR    CPUIDFIELD_MAKE(1,0,3,5,1)
#define CPUF_PAE    CPUIDFIELD_MAKE(1,0,3,6,1)
#define CPUF_MCE    CPUIDFIELD_MAKE(1,0,3,7,1)
#define CPUF_CX8    CPUIDFIELD_MAKE(1,0,3,8,1)
#define CPUF_APIC    CPUIDFIELD_MAKE(1,0,3,9,1)
#define CPUF_SEP    CPUIDFIELD_MAKE(1,0,3,11,1)
#define CPUF_MTRR    CPUIDFIELD_MAKE(1,0,3,12,1)
#define CPUF_PGE    CPUIDFIELD_MAKE(1,0,3,13,1)
#define CPUF_MCA    CPUIDFIELD_MAKE(1,0,3,14,1)
#define CPUF_CMOV    CPUIDFIELD_MAKE(1,0,3,15,1)
#define CPUF_PAT    CPUIDFIELD_MAKE(1,0,3,16,1)
#define CPUF_PSE36    CPUIDFIELD_MAKE(1,0,3,17,1)
#define CPUF_PSN    CPUIDFIELD_MAKE(1,0,3,18,1)
#define CPUF_CLFSH    CPUIDFIELD_MAKE(1,0,3,19,1)
#define CPUF_DS    CPUIDFIELD_MAKE(1,0,3,21,1)
#define CPUF_ACPI    CPUIDFIELD_MAKE(1,0,3,22,1)
#define CPUF_MMX    CPUIDFIELD_MAKE(1,0,3,23,1)
#define CPUF_FXSR    CPUIDFIELD_MAKE(1,0,3,24,1)
#define CPUF_SSE    CPUIDFIELD_MAKE(1,0,3,25,1)
#define CPUF_SSE2    CPUIDFIELD_MAKE(1,0,3,26,1)
#define CPUF_SS    CPUIDFIELD_MAKE(1,0,3,27,1)
#define CPUF_HTT    CPUIDFIELD_MAKE(1,0,3,28,1)
#define CPUF_TM    CPUIDFIELD_MAKE(1,0,3,29,1)
#define CPUF_PBE    CPUIDFIELD_MAKE(1,0,3,31,1)
#define CPUF_Cache_Type    CPUIDFIELD_MAKE(4,0,0,0,5)
#define CPUF_Cache_Level    CPUIDFIELD_MAKE(4,0,0,5,3)
#define CPUF_CACHE_SI    CPUIDFIELD_MAKE(4,0,0,8,1)
#define CPUF_CACHE_FA    CPUIDFIELD_MAKE(4,0,0,9,1)
#define CPUF_MaxApicIdShare    CPUIDFIELD_MAKE(4,0,0,14,12)
#define CPUF_MaxApicIdCore    CPUIDFIELD_MAKE(4,0,0,26,6)
#define CPUF_Cache_LineSize    CPUIDFIELD_MAKE(4,0,1,0,12)
#define CPUF_Cache_Partitions    CPUIDFIELD_MAKE(4,0,1,12,10)
#define CPUF_Cache_Ways    CPUIDFIELD_MAKE(4,0,1,22,10)
#define CPUF_Cache_Sets    CPUIDFIELD_MAKE(4,0,2,0,32)
#define CPUF_CACHE_INVD    CPUIDFIELD_MAKE(4,0,3,0,1)
#define CPUF_CACHE_INCLUSIVENESS    CPUIDFIELD_MAKE(4,0,3,1,1)
#define CPUF_CACHE_COMPLEXINDEX    CPUIDFIELD_MAKE(4,0,3,2,1)
#define CPUF_MonLineSizeMin    CPUIDFIELD_MAKE(5,0,0,0,16)
#define CPUF_MonLineSizeMax    CPUIDFIELD_MAKE(5,0,1,0,16)
#define CPUF_EMX    CPUIDFIELD_MAKE(5,0,2,0,1)
#define CPUF_IBE    CPUIDFIELD_MAKE(5,0,2,1,1)
#define CPUF_MWAIT_Number_C0    CPUIDFIELD_MAKE(5,0,3,0,4)
#define CPUF_MWAIT_Number_C1    CPUIDFIELD_MAKE(5,0,3,4,4)
#define CPUF_MWAIT_Number_C2    CPUIDFIELD_MAKE(5,0,3,8,4)
#define CPUF_MWAIT_Number_C3    CPUIDFIELD_MAKE(5,0,3,12,4)
#define CPUF_MWAIT_Number_C4    CPUIDFIELD_MAKE(5,0,3,16,4)
#define CPUF_DTS    CPUIDFIELD_MAKE(6,0,0,0,1)
#define CPUF_TURBO_BOOST    CPUIDFIELD_MAKE(6,0,0,1,1)
#define CPUF_ARAT    CPUIDFIELD_MAKE(6,0,0,2,1)
#define CPUF_PLN    CPUIDFIELD_MAKE(6,0,0,4,1)
#define CPUF_ECMD    CPUIDFIELD_MAKE(6,0,0,5,1)
#define CPUF_PTM    CPUIDFIELD_MAKE(6,0,0,6,1)
#define CPUF_DTS_ITs    CPUIDFIELD_MAKE(6,0,1,0,4)
#define CPUF_PERF    CPUIDFIELD_MAKE(6,0,2,0,1)
#define CPUF_ACNT2    CPUIDFIELD_MAKE(6,0,2,1,1)
#define CPUF_ENERGY_PERF_BIAS    CPUIDFIELD_MAKE(6,0,2,3,1)
#define CPUF_Max07Subleaf    CPUIDFIELD_MAKE(7,0,0,0,32)
#define CPUF_FSGSBASE    CPUIDFIELD_MAKE(7,0,1,0,1)
#define CPUF_TSC_ADJUST    CPUIDFIELD_MAKE(7,0,1,1,1)
#define CPUF_BMI1    CPUIDFIELD_MAKE(7,0,1,3,1)
#define CPUF_HLE    CPUIDFIELD_MAKE(7,0,1,4,1)
#define CPUF_AVX2    CPUIDFIELD_MAKE(7,0,1,5,1)
#define CPUF_SMEP    CPUIDFIELD_MAKE(7,0,1,7,1)
#define CPUF_BMI2    CPUIDFIELD_MAKE(7,0,1,8,1)
#define CPUF_ERMS    CPUIDFIELD_MAKE(7,0,1,9,1)
#define CPUF_INVPCID    CPUIDFIELD_MAKE(7,0,1,10,1)
#define CPUF_RTM    CPUIDFIELD_MAKE(7,0,1,11,1)
#define CPUF_RDSEED    CPUIDFIELD_MAKE(7,0,1,18,1)
#define CPUF_ADX    CPUIDFIELD_MAKE(7,0,1,19,1)
#define CPUF_SMAP    CPUIDFIELD_MAKE(7,0,1,20,1)
#define CPUF_PLATFORM_DCA_CAP    CPUIDFIELD_MAKE(9,0,0,0,32)
#define CPUF_APM_Version    CPUIDFIELD_MAKE(0xA,0,0,0,8)
#define CPUF_APM_Counters    CPUIDFIELD_MAKE(0xA,0,0,8,8)
#define CPUF_APM_Bits    CPUIDFIELD_MAKE(0xA,0,0,16,8)
#define CPUF_APM_Length    CPUIDFIELD_MAKE(0xA,0,0,24,8)
#define CPUF_APM_CC    CPUIDFIELD_MAKE(0xA,0,1,0,1)
#define CPUF_APM_IR    CPUIDFIELD_MAKE(0xA,0,1,1,1)
#define CPUF_APM_RC    CPUIDFIELD_MAKE(0xA,0,1,2,1)
#define CPUF_APM_LLCR    CPUIDFIELD_MAKE(0xA,0,1,3,1)
#define CPUF_APM_LLCM    CPUIDFIELD_MAKE(0xA,0,1,4,1)
#define CPUF_APM_BIR    CPUIDFIELD_MAKE(0xA,0,1,5,1)
#define CPUF_APM_BMR    CPUIDFIELD_MAKE(0xA,0,1,6,1)
#define CPUF_APM_FC_Number    CPUIDFIELD_MAKE(0xA,0,3,0,5)
#define CPUF_APM_FC_Bits    CPUIDFIELD_MAKE(0xA,0,3,5,8)
#define CPUF_Topology_Bits    CPUIDFIELD_MAKE(0xB,0,0,0,5)
#define CPUF_Topology_Number    CPUIDFIELD_MAKE(0xB,0,1,0,16)
#define CPUF_Topology_Level    CPUIDFIELD_MAKE(0xB,0,2,0,8)
#define CPUF_Topology_Type    CPUIDFIELD_MAKE(0xB,0,2,8,8)
#define CPUF_X2APICID    CPUIDFIELD_MAKE(0xB,0,3,0,32)
#define CPUF_XFeatureSupportedMaskLo    CPUIDFIELD_MAKE(0xD,0,0,0,32)
#define CPUF_XFeatureEnabledSizeMax    CPUIDFIELD_MAKE(0xD,0,1,0,32)
#define CPUF_XFeatureSupportedSizeMax    CPUIDFIELD_MAKE(0xD,0,2,0,32)
#define CPUF_XFeatureSupportedMaskHi    CPUIDFIELD_MAKE(0xD,0,3,0,32)
#define CPUF_XSAVEOPT    CPUIDFIELD_MAKE(0xD,1,0,0,1)
#define CPUF_YmmSaveStateSize    CPUIDFIELD_MAKE(0xD,2,0,0,32)
#define CPUF_YmmSaveStateOffset    CPUIDFIELD_MAKE(0xD,2,1,0,32)
#define CPUF_LwpSaveStateSize    CPUIDFIELD_MAKE(0xD,62,0,0,32)
#define CPUF_LwpSaveStateOffset    CPUIDFIELD_MAKE(0xD,62,1,0,32)
#define CPUF_LFuncExt    CPUIDFIELD_MAKE(0x80000000U,0,0,0,32)
#define CPUF_BrandId16    CPUIDFIELD_MAKE(0x80000001U,0,1,0,16)
#define CPUF_PkgType    CPUIDFIELD_MAKE(0x80000001U,0,1,28,4)
#define CPUF_LahfSahf    CPUIDFIELD_MAKE(0x80000001U,0,2,0,1)
#define CPUF_CmpLegacy    CPUIDFIELD_MAKE(0x80000001U,0,2,1,1)
#define CPUF_SVM    CPUIDFIELD_MAKE(0x80000001U,0,2,2,1)
#define CPUF_ExtApicSpace    CPUIDFIELD_MAKE(0x80000001U,0,2,3,1)
#define CPUF_AltMovCr8    CPUIDFIELD_MAKE(0x80000001U,0,2,4,1)
#define CPUF_ABM    CPUIDFIELD_MAKE(0x80000001U,0,2,5,1)
#define CPUF_SSE4A    CPUIDFIELD_MAKE(0x80000001U,0,2,6,1)
#define CPUF_MisAlignSse    CPUIDFIELD_MAKE(0x80000001U,0,2,7,1)
#define CPUF_3DNowPrefetch    CPUIDFIELD_MAKE(0x80000001U,0,2,8,1)
#define CPUF_OSVW    CPUIDFIELD_MAKE(0x80000001U,0,2,9,1)
#define CPUF_IBS    CPUIDFIELD_MAKE(0x80000001U,0,2,10,1)
#define CPUF_XOP    CPUIDFIELD_MAKE(0x80000001U,0,2,11,1)
#define CPUF_SKINIT    CPUIDFIELD_MAKE(0x80000001U,0,2,12,1)
#define CPUF_WDT    CPUIDFIELD_MAKE(0x80000001U,0,2,13,1)
#define CPUF_LWP    CPUIDFIELD_MAKE(0x80000001U,0,2,15,1)
#define CPUF_FMA4    CPUIDFIELD_MAKE(0x80000001U,0,2,16,1)
#define CPUF_BIT_NODEID    CPUIDFIELD_MAKE(0x80000001U,0,2,19,1)
#define CPUF_TBM    CPUIDFIELD_MAKE(0x80000001U,0,2,21,1)
#define CPUF_TopologyExtensions    CPUIDFIELD_MAKE(0x80000001U,0,2,22,1)
#define CPUF_SYSCALL    CPUIDFIELD_MAKE(0x80000001U,0,3,11,1)
#define CPUF_XD    CPUIDFIELD_MAKE(0x80000001U,0,3,20,1)
#define CPUF_MmxExt    CPUIDFIELD_MAKE(0x80000001U,0,3,22,1)
#define CPUF_FFXSR    CPUIDFIELD_MAKE(0x80000001U,0,3,25,1)
#define CPUF_Page1GB    CPUIDFIELD_MAKE(0x80000001U,0,3,26,1)
#define CPUF_RDTSCP    CPUIDFIELD_MAKE(0x80000001U,0,3,27,1)
#define CPUF_LM    CPUIDFIELD_MAKE(0x80000001U,0,3,29,1)
#define CPUF_3DNowExt    CPUIDFIELD_MAKE(0x80000001U,0,3,30,1)
#define CPUF_3DNow    CPUIDFIELD_MAKE(0x80000001U,0,3,31,1)
#define CPUF_L1ITlb2and4MSize    CPUIDFIELD_MAKE(0x80000005U,0,0,0,8)
#define CPUF_L1ITlb2and4MAssoc    CPUIDFIELD_MAKE(0x80000005U,0,0,8,8)
#define CPUF_L1DTlb2and4MSize    CPUIDFIELD_MAKE(0x80000005U,0,0,16,8)
#define CPUF_L1DTlb2and4MAssoc    CPUIDFIELD_MAKE(0x80000005U,0,0,24,8)
#define CPUF_L1ITlb4KSize    CPUIDFIELD_MAKE(0x80000005U,0,1,0,8)
#define CPUF_L1ITlb4KAssoc    CPUIDFIELD_MAKE(0x80000005U,0,1,8,8)
#define CPUF_L1DTlb4KSize    CPUIDFIELD_MAKE(0x80000005U,0,1,16,8)
#define CPUF_L1DTlb4KAssoc    CPUIDFIELD_MAKE(0x80000005U,0,1,24,8)
#define CPUF_L1DcLineSize    CPUIDFIELD_MAKE(0x80000005U,0,2,0,8)
#define CPUF_L1DcLinesPerTag    CPUIDFIELD_MAKE(0x80000005U,0,2,8,8)
#define CPUF_L1DcAssoc    CPUIDFIELD_MAKE(0x80000005U,0,2,16,8)
#define CPUF_L1DcSize    CPUIDFIELD_MAKE(0x80000005U,0,2,24,8)
#define CPUF_L1IcLineSize    CPUIDFIELD_MAKE(0x80000005U,0,3,0,8)
#define CPUF_L1IcLinesPerTag    CPUIDFIELD_MAKE(0x80000005U,0,3,8,8)
#define CPUF_L1IcAssoc    CPUIDFIELD_MAKE(0x80000005U,0,3,16,8)
#define CPUF_L1IcSize    CPUIDFIELD_MAKE(0x80000005U,0,3,24,8)
#define CPUF_L2ITlb2and4MSize    CPUIDFIELD_MAKE(0x80000006U,0,0,0,12)
#define CPUF_L2ITlb2and4MAssoc    CPUIDFIELD_MAKE(0x80000006U,0,0,12,4)
#define CPUF_L2DTlb2and4MSize    CPUIDFIELD_MAKE(0x80000006U,0,0,16,12)
#define CPUF_L2DTlb2and4MAssoc    CPUIDFIELD_MAKE(0x80000006U,0,0,28,4)
#define CPUF_L2ITlb4KSize    CPUIDFIELD_MAKE(0x80000006U,0,1,0,12)
#define CPUF_L2ITlb4KAssoc    CPUIDFIELD_MAKE(0x80000006U,0,1,12,4)
#define CPUF_L2DTlb4KSize    CPUIDFIELD_MAKE(0x80000006U,0,1,16,12)
#define CPUF_L2DTlb4KAssoc    CPUIDFIELD_MAKE(0x80000006U,0,1,28,4)
#define CPUF_L2LineSize    CPUIDFIELD_MAKE(0x80000006U,0,2,0,8)
#define CPUF_L2LinesPerTag    CPUIDFIELD_MAKE(0x80000006U,0,2,8,4)
#define CPUF_L2Assoc    CPUIDFIELD_MAKE(0x80000006U,0,2,12,4)
#define CPUF_L2Size    CPUIDFIELD_MAKE(0x80000006U,0,2,16,16)
#define CPUF_L3LineSize    CPUIDFIELD_MAKE(0x80000006U,0,3,0,8)
#define CPUF_L3LinesPerTag    CPUIDFIELD_MAKE(0x80000006U,0,3,8,4)
#define CPUF_L3Assoc    CPUIDFIELD_MAKE(0x80000006U,0,3,12,4)
#define CPUF_L3Size    CPUIDFIELD_MAKE(0x80000006U,0,3,18,14)
#define CPUF_TS    CPUIDFIELD_MAKE(0x80000007U,0,3,0,1)
#define CPUF_FID    CPUIDFIELD_MAKE(0x80000007U,0,3,1,1)
#define CPUF_VID    CPUIDFIELD_MAKE(0x80000007U,0,3,2,1)
#define CPUF_TTP    CPUIDFIELD_MAKE(0x80000007U,0,3,3,1)
#define CPUF_HTC    CPUIDFIELD_MAKE(0x80000007U,0,3,4,1)
#define CPUF_100MHzSteps    CPUIDFIELD_MAKE(0x80000007U,0,3,6,1)
#define CPUF_HwPstate    CPUIDFIELD_MAKE(0x80000007U,0,3,7,1)
#define CPUF_TscInvariant    CPUIDFIELD_MAKE(0x80000007U,0,3,8,1)
#define CPUF_CPB    CPUIDFIELD_MAKE(0x80000007U,0,3,9,1)
#define CPUF_EffFreqRO    CPUIDFIELD_MAKE(0x80000007U,0,3,10,1)
#define CPUF_PhysAddrSize    CPUIDFIELD_MAKE(0x80000008U,0,0,0,8)
#define CPUF_LinAddrSize    CPUIDFIELD_MAKE(0x80000008U,0,0,8,8)
#define CPUF_GuestPhysAddrSize    CPUIDFIELD_MAKE(0x80000008U,0,0,16,8)
#define CPUF_NC    CPUIDFIELD_MAKE(0x80000008U,0,2,0,8)
#define CPUF_ApicIdCoreIdSize    CPUIDFIELD_MAKE(0x80000008U,0,2,12,4)
#define CPUF_SvmRev    CPUIDFIELD_MAKE(0x8000000AU,0,0,0,8)
#define CPUF_NASID    CPUIDFIELD_MAKE(0x8000000AU,0,1,0,32)
#define CPUF_NP    CPUIDFIELD_MAKE(0x8000000AU,0,3,0,1)
#define CPUF_LbrVirt    CPUIDFIELD_MAKE(0x8000000AU,0,3,1,1)
#define CPUF_SVML    CPUIDFIELD_MAKE(0x8000000AU,0,3,2,1)
#define CPUF_NRIPS    CPUIDFIELD_MAKE(0x8000000AU,0,3,3,1)
#define CPUF_TscRateMsr    CPUIDFIELD_MAKE(0x8000000AU,0,3,4,1)
#define CPUF_VmcbClean    CPUIDFIELD_MAKE(0x8000000AU,0,3,5,1)
#define CPUF_FlushByAsid    CPUIDFIELD_MAKE(0x8000000AU,0,3,6,1)
#define CPUF_DecodeAssists    CPUIDFIELD_MAKE(0x8000000AU,0,3,7,1)
#define CPUF_PauseFilter    CPUIDFIELD_MAKE(0x8000000AU,0,3,10,1)
#define CPUF_PauseFilterThreshold    CPUIDFIELD_MAKE(0x8000000AU,0,3,12,1)
#define CPUF_L1ITlb1GSize    CPUIDFIELD_MAKE(0x80000019U,0,0,0,12)
#define CPUF_L1ITlb1GAssoc    CPUIDFIELD_MAKE(0x80000019U,0,0,12,4)
#define CPUF_L1DTlb1GSize    CPUIDFIELD_MAKE(0x80000019U,0,0,16,12)
#define CPUF_L1DTlb1GAssoc    CPUIDFIELD_MAKE(0x80000019U,0,0,28,4)
#define CPUF_L2ITlb1GSize    CPUIDFIELD_MAKE(0x80000019U,0,1,0,12)
#define CPUF_L2ITlb1GAssoc    CPUIDFIELD_MAKE(0x80000019U,0,1,12,4)
#define CPUF_L2DTlb1GSize    CPUIDFIELD_MAKE(0x80000019U,0,1,16,12)
#define CPUF_L2DTlb1GAssoc    CPUIDFIELD_MAKE(0x80000019U,0,1,28,4)
#define CPUF_FP128    CPUIDFIELD_MAKE(0x8000001AU,0,0,0,1)
#define CPUF_MOVU    CPUIDFIELD_MAKE(0x8000001AU,0,0,1,1)
#define CPUF_IBSFFV    CPUIDFIELD_MAKE(0x8000001BU,0,0,0,1)
#define CPUF_FetchSam    CPUIDFIELD_MAKE(0x8000001BU,0,0,1,1)
#define CPUF_OpSam    CPUIDFIELD_MAKE(0x8000001BU,0,0,2,1)
#define CPUF_RdWrOpCnt    CPUIDFIELD_MAKE(0x8000001BU,0,0,3,1)
#define CPUF_OpCnt    CPUIDFIELD_MAKE(0x8000001BU,0,0,4,1)
#define CPUF_BrnTrgt    CPUIDFIELD_MAKE(0x8000001BU,0,0,5,1)
#define CPUF_OpCntExt    CPUIDFIELD_MAKE(0x8000001BU,0,0,6,1)
#define CPUF_RipInvalidChk    CPUIDFIELD_MAKE(0x8000001BU,0,0,7,1)
#define CPUF_LwpAvail    CPUIDFIELD_MAKE(0x8000001CU,0,0,0,1)
#define CPUF_LwpVAL    CPUIDFIELD_MAKE(0x8000001CU,0,0,1,1)
#define CPUF_LwpIRE    CPUIDFIELD_MAKE(0x8000001CU,0,0,2,1)
#define CPUF_LwpBRE    CPUIDFIELD_MAKE(0x8000001CU,0,0,3,1)
#define CPUF_LwpDME    CPUIDFIELD_MAKE(0x8000001CU,0,0,4,1)
#define CPUF_LwpCNH    CPUIDFIELD_MAKE(0x8000001CU,0,0,5,1)
#define CPUF_LwpRNH    CPUIDFIELD_MAKE(0x8000001CU,0,0,6,1)
#define CPUF_LwpInt    CPUIDFIELD_MAKE(0x8000001CU,0,0,31,1)
#define CPUF_LwpCbSize    CPUIDFIELD_MAKE(0x8000001CU,0,1,0,8)
#define CPUF_LwpEventSize    CPUIDFIELD_MAKE(0x8000001CU,0,1,8,8)
#define CPUF_LwpMaxEvents    CPUIDFIELD_MAKE(0x8000001CU,0,1,16,8)
#define CPUF_LwpEventOffset    CPUIDFIELD_MAKE(0x8000001CU,0,1,24,8)
#define CPUF_LwpLatencyMax    CPUIDFIELD_MAKE(0x8000001CU,0,2,0,5)
#define CPUF_LwpDataAddress    CPUIDFIELD_MAKE(0x8000001CU,0,2,5,1)
#define CPUF_LwpLatencyRnd    CPUIDFIELD_MAKE(0x8000001CU,0,2,6,3)
#define CPUF_LwpVersion    CPUIDFIELD_MAKE(0x8000001CU,0,2,9,7)
#define CPUF_LwpMinBufferSize    CPUIDFIELD_MAKE(0x8000001CU,0,2,16,8)
#define CPUF_LwpBranchPrediction    CPUIDFIELD_MAKE(0x8000001CU,0,2,28,1)
#define CPUF_LwpIpFiltering    CPUIDFIELD_MAKE(0x8000001CU,0,2,29,1)
#define CPUF_LwpCacheLevels    CPUIDFIELD_MAKE(0x8000001CU,0,2,30,1)
#define CPUF_LwpCacheLatency    CPUIDFIELD_MAKE(0x8000001CU,0,2,31,1)
#define CPUF_D_LwpAvail    CPUIDFIELD_MAKE(0x8000001CU,0,3,0,1)
#define CPUF_D_LwpVAL    CPUIDFIELD_MAKE(0x8000001CU,0,3,1,1)
#define CPUF_D_LwpIRE    CPUIDFIELD_MAKE(0x8000001CU,0,3,2,1)
#define CPUF_D_LwpBRE    CPUIDFIELD_MAKE(0x8000001CU,0,3,3,1)
#define CPUF_D_LwpDME    CPUIDFIELD_MAKE(0x8000001CU,0,3,4,1)
#define CPUF_D_LwpCNH    CPUIDFIELD_MAKE(0x8000001CU,0,3,5,1)
#define CPUF_D_LwpRNH    CPUIDFIELD_MAKE(0x8000001CU,0,3,6,1)
#define CPUF_D_LwpInt    CPUIDFIELD_MAKE(0x8000001CU,0,3,31,1)
#define CPUF_CacheType    CPUIDFIELD_MAKE(0x8000001DU,0,0,0,5)
#define CPUF_CacheLevel    CPUIDFIELD_MAKE(0x8000001DU,0,0,5,3)
#define CPUF_SelfInitialization    CPUIDFIELD_MAKE(0x8000001DU,0,0,8,1)
#define CPUF_FullyAssociative    CPUIDFIELD_MAKE(0x8000001DU,0,0,9,1)
#define CPUF_NumSharingCache    CPUIDFIELD_MAKE(0x8000001DU,0,0,14,12)
#define CPUF_CacheLineSize    CPUIDFIELD_MAKE(0x8000001DU,0,1,0,12)
#define CPUF_CachePhysPartitions    CPUIDFIELD_MAKE(0x8000001DU,0,1,12,10)
#define CPUF_CacheNumWays    CPUIDFIELD_MAKE(0x8000001DU,0,1,22,10)
#define CPUF_CacheNumSets    CPUIDFIELD_MAKE(0x8000001DU,0,2,0,32)
#define CPUF_WBINVD    CPUIDFIELD_MAKE(0x8000001DU,0,3,0,1)
#define CPUF_CacheInclusive    CPUIDFIELD_MAKE(0x8000001DU,0,3,1,1)
#define CPUF_ExtendedApicId    CPUIDFIELD_MAKE(0x8000001EU,0,0,0,32)
#define CPUF_ComputeUnitId    CPUIDFIELD_MAKE(0x8000001EU,0,1,0,8)
#define CPUF_CoresPerComputeUnit    CPUIDFIELD_MAKE(0x8000001EU,0,1,8,2)
#define CPUF_NodeId    CPUIDFIELD_MAKE(0x8000001EU,0,2,0,8)
#define CPUF_NodesPerProcessor    CPUIDFIELD_MAKE(0x8000001EU,0,2,8,3)






// 取得位域.
#ifndef __GETBITS32
#define __GETBITS32(src,pos,len)    ( ((src)>>(pos)) & (((uint32_t)-1)>>(32-len)) )
#endif

// 根據CPUIDFIELD從緩沖區中獲取字段.
INLINE uint32_t    getcpuidfield_buf(const uint32_t dwBuf[4], CPUIDFIELD cpuf)
{
    return __GETBITS32(dwBuf[CPUIDFIELD_REG(cpuf)], CPUIDFIELD_POS(cpuf), CPUIDFIELD_LEN(cpuf));
}

// 根據CPUIDFIELD獲取CPUID字段.
INLINE uint32_t    getcpuidfield(CPUIDFIELD cpuf)
{
    uint32_t dwBuf[4];
    getcpuidex(dwBuf, CPUIDFIELD_FID(cpuf), CPUIDFIELD_FIDSUB(cpuf));
    return getcpuidfield_buf(dwBuf, cpuf);
}



////////////////////////////////////////
// functions: 函數.
////////////////////////////////////////


// SSE系列指令集的支持級別. simd_sse_level 函數的返回值.
#define SIMD_SSE_NONE    0    // 不支持.
#define SIMD_SSE_1    1    // SSE
#define SIMD_SSE_2    2    // SSE2
#define SIMD_SSE_3    3    // SSE3
#define SIMD_SSE_3S    4    // SSSE3
#define SIMD_SSE_41    5    // SSE4.1
#define SIMD_SSE_42    6    // SSE4.2


// AVX系列指令集的支持級別. simd_avx_level 函數的返回值。
#define SIMD_AVX_NONE    0    // 不支持
#define SIMD_AVX_1    1    // AVX
#define SIMD_AVX_2    2    // AVX2




// functions declaration
//int cpu_getvendor(char* pvendor);
//int cpu_getbrand(char* pbrand);
//int    simd_mmx(int* phwmmx);
//int    simd_sse_level(int* phwsse);
//int    simd_avx_level(int* phwavx);


// 取得CPU廠商(Vendor).
//
// result: 成功時返回字符串的長度(一般為12)。失敗時返回0.
// pvendor: 接收廠商信息的字符串緩沖區。至少為13字節.
INLINE int cpu_getvendor(char* pvendor)
{
    uint32_t dwBuf[4];
    if (NULL==pvendor)    return 0;
    // Function 0: Vendor-ID and Largest Standard Function
    getcpuid(dwBuf, 0);
    // save. 保存到pvendor
    *(uint32_t *)&pvendor[0] = dwBuf[1];    // ebx: 前四個字符.
    *(uint32_t *)&pvendor[4] = dwBuf[3];    // edx: 中間四個字符.
    *(uint32_t *)&pvendor[8] = dwBuf[2];    // ecx: 最后四個字符.
    pvendor[12] = '\0';
    return 12;
}

// 取得CPU商標(Brand).
//
// result: 成功時返回字符串的長度(一般為48)。失敗時返回0.
// pbrand: 接收商標信息的字符串緩沖區。至少為49字節.
INLINE int cpu_getbrand(char* pbrand)
{
    uint32_t dwBuf[4];
    if (NULL==pbrand)    return 0;
    // Function 0x80000000: Largest Extended Function Number
    getcpuid(dwBuf, 0x80000000U);
    if (dwBuf[0] < 0x80000004U)    return 0;
    // Function 80000002h,80000003h,80000004h: Processor Brand String
    getcpuid((uint32_t *)&pbrand[0], 0x80000002U);    // 前16個字符.
    getcpuid((uint32_t *)&pbrand[16], 0x80000003U);    // 中間16個字符.
    getcpuid((uint32_t *)&pbrand[32], 0x80000004U);    // 最后16個字符.
    pbrand[48] = '\0';
    return 48;
}


// 是否支持MMX指令集.
//
// result: 返回操作系統是否支持MMX指令集. 非0表示支持, 0表示不支持.
// phwmmx: 返回硬件是否支持MMX指令集. 非0表示支持, 0表示不支持.
INLINE int    simd_mmx(int* phwmmx)
{
    int    rt = 0;    // result
    #ifdef CCPUID_X86
        const uint32_t    BIT_D_MMX = 0x00800000;    // bit 23
        uint32_t dwBuf[4];

        // check processor support
        getcpuid(dwBuf, 1);    // Function 1: Feature Information
        if ( dwBuf[3] & BIT_D_MMX )    rt=1;
        if (NULL!=phwmmx)    *phwmmx=rt;

        // check OS support
        // 純C不支持結構化異常處理, 忽略simd_mmx、simd_sse_level的 操作系統判斷.
        #if defined(__cplusplus)
            if ( rt )
            {
                #if defined(_M_X64) && defined(_MSC_VER) && !defined(__INTEL_COMPILER)
                    // VC編譯器不支持64位下的MMX.
                    rt=0;
                #else
                    try 
                    {
                        _mm_empty();    // MMX instruction: emms
                    }
                    catch(...)
                    {
                        rt=0;
                    }
                #endif    // #if defined(_M_X64) && defined(_MSC_VER)
            }
        #endif    // #if defined(__cplusplus)
    #else    // #ifdef CCPUID_X86
        if (NULL!=phwmmx)    *phwmmx=rt;
    #endif    // #ifdef CCPUID_X86
    return rt;
}

// 檢測SSE系列指令集的支持級別.
//
// result: 返回操作系統的SSE系列指令集支持級別. 詳見SIMD_SSE_常數.
// phwmmx: 返回硬件的SSE系列指令集支持級別. 詳見SIMD_SSE_常數.
INLINE int    simd_sse_level(int* phwsse)
{
    int    rt = SIMD_SSE_NONE;    // result
    #ifdef CCPUID_X86
        const uint32_t    BIT_D_SSE = 0x02000000;    // bit 25
        const uint32_t    BIT_D_SSE2 = 0x04000000;    // bit 26
        const uint32_t    BIT_C_SSE3 = 0x00000001;    // bit 0
        const uint32_t    BIT_C_SSSE3 = 0x00000100;    // bit 9
        const uint32_t    BIT_C_SSE41 = 0x00080000;    // bit 19
        const uint32_t    BIT_C_SSE42 = 0x00100000;    // bit 20
        uint32_t dwBuf[4];

        // check processor support
        getcpuid(dwBuf, 1);    // Function 1: Feature Information
        if ( dwBuf[3] & BIT_D_SSE )
        {
            rt = SIMD_SSE_1;
            if ( dwBuf[3] & BIT_D_SSE2 )
            {
                rt = SIMD_SSE_2;
                if ( dwBuf[2] & BIT_C_SSE3 )
                {
                    rt = SIMD_SSE_3;
                    if ( dwBuf[2] & BIT_C_SSSE3 )
                    {
                        rt = SIMD_SSE_3S;
                        if ( dwBuf[2] & BIT_C_SSE41 )
                        {
                            rt = SIMD_SSE_41;
                            if ( dwBuf[2] & BIT_C_SSE42 )
                            {
                                rt = SIMD_SSE_42;
                            }
                        }
                    }
                }
            }
        }
        if (NULL!=phwsse)    *phwsse=rt;

        // check OS support
        // 純C不支持結構化異常處理, 忽略simd_mmx、simd_sse_level的 操作系統判斷.
        #if defined(__cplusplus)
            try 
            {
                __m128 xmm1 = _mm_setzero_ps();    // SSE instruction: xorps
                int* pxmm1 = (int*)&xmm1;    // 避免GCC的 -Wstrict-aliasing 警告.
                if (0!=*pxmm1)    rt = SIMD_SSE_NONE;    // 避免Release模式編譯優化時剔除_mm_setzero_ps.
            }
            catch(...)
            {
                rt = SIMD_SSE_NONE;
            }
        #endif    // #if defined(__cplusplus)
    #else    // #ifdef CCPUID_X86
        if (NULL!=phwsse)    *phwsse=rt;
    #endif    // #ifdef CCPUID_X86
    return rt;
}

// 檢測AVX系列指令集的支持級別.
//
// result: 返回操作系統的AVX系列指令集支持級別. 詳見SIMD_AVX_常數.
// phwavx: 返回硬件的AVX系列指令集支持級別. 詳見SIMD_AVX_常數.
INLINE int    simd_avx_level(int* phwavx)
{
    int    rt = SIMD_AVX_NONE;    // result
    #ifdef CCPUID_X86
        // check processor support
        if (0!=getcpuidfield(CPUF_AVX))
        {
            rt = SIMD_AVX_1;
            if (0!=getcpuidfield(CPUF_AVX2))
            {
                rt = SIMD_AVX_2;
            }
        }
        if (NULL!=phwavx)    *phwavx=rt;

        // check OS support
        if (0!=getcpuidfield(CPUF_OSXSAVE))    // XGETBV enabled for application use.
        {
            uint32_t n = getcpuidfield(CPUF_XFeatureSupportedMaskLo);    // XCR0: XFeatureSupportedMask register.
            if (6!=(n&6))    // XCR0[2:1] = ‘11b’ (XMM state and YMM state are enabled by OS).
            {
                rt = SIMD_AVX_NONE;
            }
        }
    #else    // #ifdef CCPUID_X86
        if (NULL!=phwavx)    *phwavx=rt;
    #endif    // #ifdef CCPUID_X86
    return rt;
}



#if defined __cplusplus
};
#endif

#endif    // #ifndef __CCPUID_H_INCLUDED

 


2.2 testccpuidc.c : [C] 測試ccpuid.h, 顯示CPUID信息

  全部代碼——

View Code
#include <stdio.h>

#include "ccpuid.h"


// 獲取程序位數(被編譯為多少位的代碼)
int GetProgramBits()
{
    return sizeof(int*) * 8;
}

int main(int argc, char* argv[])
{
    char szBuf[64];
    int bhwmmx;    // 硬件支持MMX.
    int bmmx;    // 操作系統支持MMX.
    int    nhwsse;    // 硬件支持SSE.
    int    nsse;    // 操作系統支持SSE.
    int    nhwavx;    // 硬件支持AVX.
    int    navx;    // 操作系統支持AVX.

    printf("testccpuidc v1.02 (%dbit)\n\n", GetProgramBits());

    // base
    cpu_getvendor(szBuf);
    printf("CPU Vendor:\t%s\n", szBuf);
    cpu_getbrand(szBuf);
    printf("CPU Brand:\t%s\n", szBuf);
    printf("LFuncStd:\t%.8Xh\n", getcpuidfield(CPUF_LFuncStd));
    printf("LFuncExt:\t%.8Xh\n", getcpuidfield(CPUF_LFuncExt));

    // mmx
    bmmx = simd_mmx(&bhwmmx);
    printf("MMX: %d\t// hw: %d\n", bmmx, bhwmmx);

    // sse
    nsse = simd_sse_level(&nhwsse);
    printf("SSE: %d\t// hw: %d\n", nsse, nhwsse);

    // avx
    navx = simd_avx_level(&nhwavx);
    printf("AVX: %d\t// hw: %d\n", navx, nhwavx);

    // misc
    printf("SSE4A:\t%d\n", getcpuidfield(CPUF_SSE4A));
    printf("AES:\t%d\n", getcpuidfield(CPUF_AES));
    printf("PCLMULQDQ:\t%d\n", getcpuidfield(CPUF_PCLMULQDQ));
    printf("F16C:\t%d\n", getcpuidfield(CPUF_F16C));
    printf("FMA:\t%d\n", getcpuidfield(CPUF_FMA));
    printf("FMA4:\t%d\n", getcpuidfield(CPUF_FMA4));
    printf("XOP:\t%d\n", getcpuidfield(CPUF_XOP));

    return 0;
}

 


2.3 ccpuid.hpp: CPUID信息(C++版頭文件)

  全部代碼——

View Code
#ifndef __CCPUID_HPP_INCLUDED
#define __CCPUID_HPP_INCLUDED

#include "ccpuid.h"

////////////////////////////////////////
// define struct
////////////////////////////////////////

#if defined __cplusplus
extern "C" {
#endif

#define MAX_CPUIDINFO    0x100    // CCPUID類中最多保存多少條CPUIDINFO信息。

#if defined __cplusplus
};
#endif


////////////////////////////////////////
// define class
////////////////////////////////////////

// CPUID工具類.
class CCPUID{
public:
    enum {
        CPUFDescLen = 296    // CPUIDFIELD描述信息數組的長度.
    };
    static const CPUIDFIELDDESC    CPUFDesc[CPUFDescLen];    // CPUIDFIELD描述信息數組.
    static const char*    CacheDesc[0x100];    // 緩存描述信息數組.
    static const char*    SseNames[7];    // SSE級別的名稱.
    static const char*    AvxNames[3];    // AVX級別的名稱.
    
    CPUIDINFO    Info[MAX_CPUIDINFO+1];    // CPUID信息數組.

    CCPUID();
    static CCPUID& cur() { if(0==_cur._InfoCount){ _cur.RefreshAll(); } return _cur; }    // 當前處理器的CCPUID.
    int InfoCount() const { return _InfoCount; }    // Info數組的有效項目數.
    void RefreshInfo();    // 刷新信息.
    void RefreshProperty();    // 刷新屬性.
    void RefreshAll();    // 刷新所有.
    LPCCPUIDINFO GetInfo(uint32_t InfoType, uint32_t ECXValue=0) const;    // 取得信息.
    void GetData(uint32_t CPUInfo[4], uint32_t InfoType, uint32_t ECXValue=0) const;    // 取得數據.
    uint32_t GetField(CPUIDFIELD cpuf) const;    // 取得CPUID字段
    // Property
    uint32_t LFuncStd() const { return _LFuncStd; }    // 最大的主功能號.
    uint32_t LFuncExt() const { return _LFuncExt; }    // 最大的擴展功能號.
    const char* Vendor() const { return _Vendor; }    // 廠商.
    const char* Brand() const { return _Brand; }    // 商標.
    const char* BrandTrim() const { return _BrandTrim; }    // 去掉首都空格后的商標.
    int mmx() const { return _mmx; }    // 系統支持MMX.
    int hwmmx() const { return _hwmmx; }    // 硬件支持MMX.
    int sse() const { return _sse; }    // 系統支持SSE.
    int hwsse() const { return _hwsse; }    // 硬件支持SSE.
    int avx() const { return _avx; }    // 系統支持AVX.
    int hwavx() const { return _hwavx; }    // 硬件支持AVX.

private:
    static CCPUID _cur;    // 當前處理器的CCPUID. 為了方便日常使用.

    int _InfoCount;    // Info數組的有效項目數.

    // Property
    uint32_t _LFuncStd;    // 最大的主功能號.
    uint32_t _LFuncExt;    // 最大的擴展功能號.
    char _Vendor[13];    // 廠商.
    char _Brand[49];    // 商標.
    const char* _BrandTrim;    // 去掉首都空格后的商標.
    int _mmx;    // 系統支持MMX.
    int _hwmmx;    // 硬件支持MMX.
    int _sse;    // 系統支持SSE.
    int _hwsse;    // 硬件支持SSE.
    int _avx;    // 系統支持AVX.
    int _hwavx;    // 硬件支持AVX.

    void RefreshInfo_Put(uint32_t fid, uint32_t fidsub, uint32_t CPUInfo[4]);
    int    simd_mmx(int* phwmmx) const;
    int    simd_sse_level(int* phwsse) const;
    int    simd_avx_level(int* phwavx) const;

};



#endif    // #ifndef __CCPUID_HPP_INCLUDED

 


2.4 ccpuid.cpp: CPUID信息(C++版源文件)

  全部代碼——

View Code
#include "ccpuid.hpp"

CCPUID CCPUID::_cur;

const CPUIDFIELDDESC CCPUID::CPUFDesc[] = {
    {CPUF_LFuncStd, 0, "LFuncStd", "largest standard function."}
    ,{CPUF_Stepping, 0, "Stepping", "processor stepping."}
    ,{CPUF_BaseModel, 0, "BaseModel", "base processor model."}
    ,{CPUF_BaseFamily, 0, "BaseFamily", "base processor family."}
    ,{CPUF_ProcessorType, 0, "ProcessorType", "processor type."}
    ,{CPUF_ExtModel, 0, "ExtModel", "processor extended model."}
    ,{CPUF_ExtFamily, 0, "ExtFamily", "processor extended family."}
    ,{CPUF_BrandId8, 0, "BrandId8", "8-bit brand ID."}
    ,{CPUF_CLFlush, 0, "CLFlush", "CLFLUSH line size. (*8)"}
    ,{CPUF_MaxApicId, 0, "MaxApicId", "Maximum number of addressable IDs for logical processors in this physical package."}
    ,{CPUF_ApicId, 0, "ApicId", "Initial local APIC physical ID(8-bit)."}
    ,{CPUF_SSE3, 0, "SSE3", "Streaming SIMD Extensions 3."}
    ,{CPUF_PCLMULQDQ, 0, "PCLMULQDQ", "PCLMULQDQ instruction."}
    ,{CPUF_DTES64, 0, "DTES64", "64-bit DS Area."}
    ,{CPUF_MONITOR, 0, "MONITOR", "MONITOR/MWAIT instructions."}
    ,{CPUF_DS_CPL, 0, "DS_CPL", "CPL Qualified Debug Store."}
    ,{CPUF_VMX, 0, "VMX", "Virtual Machine Extensions."}
    ,{CPUF_SMX, 0, "SMX", "Safer Mode Extensions."}
    ,{CPUF_EIST, 0, "EIST", "Enhanced Intel SpeedStep technology."}
    ,{CPUF_TM2, 0, "TM2", "Thermal Monitor 2."}
    ,{CPUF_SSSE3, 0, "SSSE3", "Supplemental Streaming SIMD Extensions 3 (SSSE3)."}
    ,{CPUF_CNXT_ID, 0, "CNXT_ID", "L1 Context ID."}
    ,{CPUF_FMA, 0, "FMA", "supports FMA extensions using YMM state."}
    ,{CPUF_CX16, 0, "CX16", "CMPXCHG16B instruction."}
    ,{CPUF_xTPR, 0, "xTPR", "xTPR Update Control. Can disable sending Task Priority messages."}
    ,{CPUF_PDCM, 0, "PDCM", "Perfmon and Debug Capability."}
    ,{CPUF_PCID, 0, "PCID", "Process Context Identifiers."}
    ,{CPUF_DCA, 0, "DCA", "Direct Cache Access."}
    ,{CPUF_SSE41, 0, "SSE41", "SSE4.1 instructions."}
    ,{CPUF_SSE42, 0, "SSE42", "SSE4.2 instructions."}
    ,{CPUF_x2APIC, 0, "x2APIC", "Extended xAPIC Support."}
    ,{CPUF_MOVBE, 0, "MOVBE", "MOVBE Instruction."}
    ,{CPUF_POPCNT, 0, "POPCNT", "POPCNT instruction."}
    ,{CPUF_TSC_DEADLINE, 0, "TSC_DEADLINE", "Local APIC timer supports one-shot operation using a TSC deadline value."}
    ,{CPUF_AES, 0, "AES", "Advanced Encryption Standard (AES) Instructions."}
    ,{CPUF_XSAVE, 0, "XSAVE", "XSAVE (and related) instructions are supported by hardware."}
    ,{CPUF_OSXSAVE, 0, "OSXSAVE", "XSAVE (and related) instructions are enabled."}
    ,{CPUF_AVX, 0, "AVX", "AVX instructions."}
    ,{CPUF_F16C, 0, "F16C", "half-precision convert instruction support."}
    ,{CPUF_RDRAND, 0, "RDRAND", "RDRAND instruction."}
    ,{CPUF_FPU, 0, "FPU", "Floating Point Unit On-Chip."}
    ,{CPUF_VME, 0, "VME", "Virtual 8086 Mode Enhancements."}
    ,{CPUF_DE, 0, "DE", "Debugging Extensions."}
    ,{CPUF_PSE, 0, "PSE", "Page Size Extension."}
    ,{CPUF_TSC, 0, "TSC", "Time Stamp Counter."}
    ,{CPUF_MSR, 0, "MSR", "Model Specific Registers RDMSR and WRMSR Instructions."}
    ,{CPUF_PAE, 0, "PAE", "Physical Address Extension."}
    ,{CPUF_MCE, 0, "MCE", "Machine Check Exception."}
    ,{CPUF_CX8, 0, "CX8", "CMPXCHG8B instruction."}
    ,{CPUF_APIC, 0, "APIC", "APIC(Advanced Programmable Interrupt Controller) On-Chip."}
    ,{CPUF_SEP, 0, "SEP", "Fast System Call instructions, SYSENTER and SYSEXIT."}
    ,{CPUF_MTRR, 0, "MTRR", "Memory Type Range Registers."}
    ,{CPUF_PGE, 0, "PGE", "Page Global Enable."}
    ,{CPUF_MCA, 0, "MCA", "Machine-Check Architecture."}
    ,{CPUF_CMOV, 0, "CMOV", "Conditional Move Instructions."}
    ,{CPUF_PAT, 0, "PAT", "Page Attribute Table."}
    ,{CPUF_PSE36, 0, "PSE36", "36-Bit Page Size Extension."}
    ,{CPUF_PSN, 0, "PSN", "Processor Serial Number."}
    ,{CPUF_CLFSH, 0, "CLFSH", "CLFLUSH Instruction."}
    ,{CPUF_DS, 0, "DS", "Debug Store."}
    ,{CPUF_ACPI, 0, "ACPI", "Thermal Monitor and Software Controlled Clock Facilities."}
    ,{CPUF_MMX, 0, "MMX", "MMX instructions."}
    ,{CPUF_FXSR, 0, "FXSR", "FXSAVE and FXRSTOR instructions."}
    ,{CPUF_SSE, 0, "SSE", "Streaming SIMD Extensions."}
    ,{CPUF_SSE2, 0, "SSE2", "Streaming SIMD Extensions 2."}
    ,{CPUF_SS, 0, "SS", "Self Snoop."}
    ,{CPUF_HTT, 0, "HTT", "Max APIC IDs reserved field is Valid."}
    ,{CPUF_TM, 0, "TM", "Thermal Monitor."}
    ,{CPUF_PBE, 0, "PBE", "Pending Break Enable."}
    ,{CPUF_Cache_Type, 0, "Cache_Type", "Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified)."}
    ,{CPUF_Cache_Level, 0, "Cache_Level", "Cache Level (Starts at 1)."}
    ,{CPUF_CACHE_SI, 0, "CACHE_SI", "Self Initializing cache level."}
    ,{CPUF_CACHE_FA, 0, "CACHE_FA", "Fully Associative cache."}
    ,{CPUF_MaxApicIdShare, 0, "MaxApicIdShare", "Maximum number of addressable IDs for logical processors sharing this cache (plus 1 encoding)."}
    ,{CPUF_MaxApicIdCore, 0, "MaxApicIdCore", "Maximum number of addressable IDs for processor cores in the physical package (plus 1 encoding)."}
    ,{CPUF_Cache_LineSize, 0, "Cache_LineSize", "System Coherency Line Size (plus 1 encoding)."}
    ,{CPUF_Cache_Partitions, 0, "Cache_Partitions", "Physical Line partitions (plus 1 encoding)."}
    ,{CPUF_Cache_Ways, 0, "Cache_Ways", "Ways of Associativity (plus 1 encoding)."}
    ,{CPUF_Cache_Sets, 0, "Cache_Sets", "Number of Sets (plus 1 encoding)."}
    ,{CPUF_CACHE_INVD, 0, "CACHE_INVD", "WBINVD/INVD behavior on lower level caches."}
    ,{CPUF_CACHE_INCLUSIVENESS, 0, "CACHE_INCLUSIVENESS", "Cache is inclusive of lower cache levels."}
    ,{CPUF_CACHE_COMPLEXINDEX, 0, "CACHE_COMPLEXINDEX", "Complex Cache Indexing."}
    ,{CPUF_MonLineSizeMin, 0, "MonLineSizeMin", "Smallest monitor line size in bytes."}
    ,{CPUF_MonLineSizeMax, 0, "MonLineSizeMax", "Largest monitor-line size in bytes."}
    ,{CPUF_EMX, 0, "EMX", "Enumerate MONITOR/MWAIT extensions."}
    ,{CPUF_IBE, 0, "IBE", "Interrupt Break-Event."}
    ,{CPUF_MWAIT_Number_C0, 0, "MWAIT_Number_C0", "Number of C0 sub C-states supported using MWAIT."}
    ,{CPUF_MWAIT_Number_C1, 0, "MWAIT_Number_C1", "Number of C1 sub C-states supported using MWAIT."}
    ,{CPUF_MWAIT_Number_C2, 0, "MWAIT_Number_C2", "Number of C2 sub C-states supported using MWAIT."}
    ,{CPUF_MWAIT_Number_C3, 0, "MWAIT_Number_C3", "Number of C3 sub C-states supported using MWAIT."}
    ,{CPUF_MWAIT_Number_C4, 0, "MWAIT_Number_C4", "Number of C4 sub C-states supported using MWAIT."}
    ,{CPUF_DTS, 0, "DTS", "Digital Thermal Sensor."}
    ,{CPUF_TURBO_BOOST, 0, "TURBO_BOOST", "Intel Turbo Boost Technology."}
    ,{CPUF_ARAT, 0, "ARAT", "Always Running APIC Timer."}
    ,{CPUF_PLN, 0, "PLN", "Power Limit Notification."}
    ,{CPUF_ECMD, 0, "ECMD", "Extended Clock Modulation Duty."}
    ,{CPUF_PTM, 0, "PTM", "Package Thermal Management."}
    ,{CPUF_DTS_ITs, 0, "DTS_ITs", "Number of Interrupt Thresholds in Digital Thermal Sensor."}
    ,{CPUF_PERF, 0, "PERF", "Hardware Coordination Feedback Capability."}
    ,{CPUF_ACNT2, 0, "ACNT2", "ACNT2 Capability."}
    ,{CPUF_ENERGY_PERF_BIAS, 0, "ENERGY_PERF_BIAS", "Performance-Energy Bias capability."}
    ,{CPUF_Max07Subleaf, 0, "Max07Subleaf", "Reports the maximum supported leaf 7 sub-leaf."}
    ,{CPUF_FSGSBASE, 0, "FSGSBASE", "Supports RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE."}
    ,{CPUF_TSC_ADJUST, 0, "TSC_ADJUST", "IA32_TSC_ADJUST MSR is supported if 1."}
    ,{CPUF_BMI1, 0, "BMI1", "The first group of advanced bit manipulation extensions (ANDN, BEXTR, BLSI, BLSMK, BLSR, TZCNT)."}
    ,{CPUF_HLE, 0, "HLE", "Hardware Lock Elision."}
    ,{CPUF_AVX2, 0, "AVX2", "AVX2 instructions."}
    ,{CPUF_SMEP, 0, "SMEP", "Supervisor Mode Execution Protection."}
    ,{CPUF_BMI2, 0, "BMI2", "The second group of advanced bit manipulation extensions (BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX)."}
    ,{CPUF_ERMS, 0, "ERMS", "Supports Enhanced REP MOVSB/STOSB."}
    ,{CPUF_INVPCID, 0, "INVPCID", "Invalidate Processor Context ID."}
    ,{CPUF_RTM, 0, "RTM", "Restricted Transactional Memory."}
    ,{CPUF_RDSEED, 0, "RDSEED", "RDSEED instruction."}
    ,{CPUF_ADX, 0, "ADX", "ADCX and ADOX instructions."}
    ,{CPUF_SMAP, 0, "SMAP", "Supervisor Mode Access Prevention."}
    ,{CPUF_PLATFORM_DCA_CAP, 0, "PLATFORM_DCA_CAP", "Value of PLATFORM_DCA_CAP MSR Bits [31:0] (Offset 1F8h)."}
    ,{CPUF_APM_Version, 0, "APM_Version", "Version ID of architectural performance monitoring."}
    ,{CPUF_APM_Counters, 0, "APM_Counters", "Number of general-purpose performance monitoring counters per logical processor."}
    ,{CPUF_APM_Bits, 0, "APM_Bits", "Bit width of general-purpose, performance monitoring counters."}
    ,{CPUF_APM_Length, 0, "APM_Length", "Length of EBX bit vector to enumerate architectural performance monitoring events."}
    ,{CPUF_APM_CC, 0, "APM_CC", "Core cycle event not available if 1."}
    ,{CPUF_APM_IR, 0, "APM_IR", "Instruction retired event not available if 1."}
    ,{CPUF_APM_RC, 0, "APM_RC", "Reference cycles event not available if 1."}
    ,{CPUF_APM_LLCR, 0, "APM_LLCR", "Last-level cache reference event not available if 1."}
    ,{CPUF_APM_LLCM, 0, "APM_LLCM", "Last-level cache misses event not available if 1."}
    ,{CPUF_APM_BIR, 0, "APM_BIR", "Branch instruction retired event not available if 1."}
    ,{CPUF_APM_BMR, 0, "APM_BMR", "Branch mispredict retired event not available if 1."}
    ,{CPUF_APM_FC_Number, 0, "APM_FC_Number", "Number of fixed-function performance counters."}
    ,{CPUF_APM_FC_Bits, 0, "APM_FC_Bits", "Bit width of fixed-function performance counters."}
    ,{CPUF_Topology_Bits, 0, "Topology_Bits", "Number of bits to shift right on x2APIC ID to get a unique topology ID of the next level type."}
    ,{CPUF_Topology_Number, 0, "Topology_Number", "Number of factory-configured logical processors at this level."}
    ,{CPUF_Topology_Level, 0, "Topology_Level", "Level number. Same value in ECX input."}
    ,{CPUF_Topology_Type, 0, "Topology_Type", "Level Type (0=Invalid, 1=Thread, 2=Core)."}
    ,{CPUF_X2APICID, 0, "X2APICID", "x2APIC ID."}
    ,{CPUF_XFeatureSupportedMaskLo, 0, "XFeatureSupportedMaskLo", "The lower 32 bits of XCR0(XFEATURE_ENABLED_MASK register)."}
    ,{CPUF_XFeatureEnabledSizeMax, 0, "XFeatureEnabledSizeMax", "Size in bytes of XSAVE/XRSTOR area for the currently enabled features in XCR0."}
    ,{CPUF_XFeatureSupportedSizeMax, 0, "XFeatureSupportedSizeMax", "Size in bytes of XSAVE/XRSTOR area for all features that the core supports."}
    ,{CPUF_XFeatureSupportedMaskHi, 0, "XFeatureSupportedMaskHi", "The upper 32 bits of XCR0(XFEATURE_ENABLED_MASK register)."}
    ,{CPUF_XSAVEOPT, 0, "XSAVEOPT", "XSAVEOPT is available."}
    ,{CPUF_YmmSaveStateSize, 0, "YmmSaveStateSize", "YMM save state byte size."}
    ,{CPUF_YmmSaveStateOffset, 0, "YmmSaveStateOffset", "YMM save state byte offset."}
    ,{CPUF_LwpSaveStateSize, 0, "LwpSaveStateSize", "LWP save state byte size."}
    ,{CPUF_LwpSaveStateOffset, 0, "LwpSaveStateOffset", "LWP save state byte offset."}
    ,{CPUF_LFuncExt, 0, "LFuncExt", "Largest extended function."}
    ,{CPUF_BrandId16, 0, "BrandId16", "16-bit Brand ID."}
    ,{CPUF_PkgType, 0, "PkgType", "Package type (Family[7:0] >= 10h)."}
    ,{CPUF_LahfSahf, 0, "LahfSahf", "LAHF and SAHF instruction support in 64-bit mode."}
    ,{CPUF_CmpLegacy, 0, "CmpLegacy", "core multi-processing legacy mode."}
    ,{CPUF_SVM, 0, "SVM", "secure virtual machine."}
    ,{CPUF_ExtApicSpace, 0, "ExtApicSpace", "extended APIC space."}
    ,{CPUF_AltMovCr8, 0, "AltMovCr8", "LOCK MOV CR0 means MOV CR8."}
    ,{CPUF_ABM, 0, "ABM", "advanced bit manipulation (LZCNT)."}
    ,{CPUF_SSE4A, 0, "SSE4A", "SSE4A instructions."}
    ,{CPUF_MisAlignSse, 0, "MisAlignSse", "misaligned SSE mode."}
    ,{CPUF_3DNowPrefetch, 0, "3DNowPrefetch", "PREFETCH and PREFETCHW instruction support."}
    ,{CPUF_OSVW, 0, "OSVW", "OS visible workaround."}
    ,{CPUF_IBS, 0, "IBS", "instruction based sampling."}
    ,{CPUF_XOP, 0, "XOP", "extended operation support."}
    ,{CPUF_SKINIT, 0, "SKINIT", "SKINIT and STGI are supported, independent of the value of MSRC000_0080[SVME]."}
    ,{CPUF_WDT, 0, "WDT", "watchdog timer support."}
    ,{CPUF_LWP, 0, "LWP", "lightweight profiling support."}
    ,{CPUF_FMA4, 0, "FMA4", "4-operand FMA instruction support."}
    ,{CPUF_BIT_NODEID, 0, "BIT_NODEID", "Indicates support for MSRC001_100C[NodeId, NodesPerProcessor]."}
    ,{CPUF_TBM, 0, "TBM", "Trailing bit manipulation instruction support."}
    ,{CPUF_TopologyExtensions, 0, "TopologyExtensions", "Topology extensions support."}
    ,{CPUF_SYSCALL, 0, "SYSCALL", "SYSCALL and SYSRET instructions."}
    ,{CPUF_XD, 0, "XD", "Execution Disable Bit."}
    ,{CPUF_MmxExt, 0, "MmxExt", "AMD extensions to MMX instructions."}
    ,{CPUF_FFXSR, 0, "FFXSR", "FXSAVE and FXRSTOR instruction optimizations."}
    ,{CPUF_Page1GB, 0, "Page1GB", "1-GB large page support."}
    ,{CPUF_RDTSCP, 0, "RDTSCP", "RDTSCP and TSC_AUX."}
    ,{CPUF_LM, 0, "LM", "64-bit long mode.(x86-64)"}
    ,{CPUF_3DNowExt, 0, "3DNowExt", "AMD extensions to 3DNow! instructions."}
    ,{CPUF_3DNow, 0, "3DNow", "3DNow! instructions."}
    ,{CPUF_L1ITlb2and4MSize, 0, "L1ITlb2and4MSize", "Instruction TLB number of entries for 2-MB and 4-MB pages."}
    ,{CPUF_L1ITlb2and4MAssoc, 0, "L1ITlb2and4MAssoc", "Instruction TLB associativity for 2-MB and 4-MB pages."}
    ,{CPUF_L1DTlb2and4MSize, 0, "L1DTlb2and4MSize", "Data TLB number of entries for 2-MB and 4-MB pages."}
    ,{CPUF_L1DTlb2and4MAssoc, 0, "L1DTlb2and4MAssoc", "Data TLB associativity for 2-MB and 4-MB pages."}
    ,{CPUF_L1ITlb4KSize, 0, "L1ITlb4KSize", "Instruction TLB number of entries for 4 KB pages."}
    ,{CPUF_L1ITlb4KAssoc, 0, "L1ITlb4KAssoc", "Instruction TLB associativity for 4KB pages."}
    ,{CPUF_L1DTlb4KSize, 0, "L1DTlb4KSize", "Data TLB number of entries for 4 KB pages."}
    ,{CPUF_L1DTlb4KAssoc, 0, "L1DTlb4KAssoc", "Data TLB associativity for 4 KB pages."}
    ,{CPUF_L1DcLineSize, 0, "L1DcLineSize", "L1 data cache line size in bytes."}
    ,{CPUF_L1DcLinesPerTag, 0, "L1DcLinesPerTag", "L1 data cache lines per tag."}
    ,{CPUF_L1DcAssoc, 0, "L1DcAssoc", "L1 data cache associativity."}
    ,{CPUF_L1DcSize, 0, "L1DcSize", "L1 data cache size in KB."}
    ,{CPUF_L1IcLineSize, 0, "L1IcLineSize", "L1 instruction cache line size in bytes"}
    ,{CPUF_L1IcLinesPerTag, 0, "L1IcLinesPerTag", "L1 instruction cache lines per tag."}
    ,{CPUF_L1IcAssoc, 0, "L1IcAssoc", "L1 instruction cache associativity."}
    ,{CPUF_L1IcSize, 0, "L1IcSize", "L1 instruction cache size KB."}
    ,{CPUF_L2ITlb2and4MSize, 0, "L2ITlb2and4MSize", "L2 instruction TLB number of entries for 2 MB and 4 MB pages."}
    ,{CPUF_L2ITlb2and4MAssoc, 0, "L2ITlb2and4MAssoc", "L2 instruction TLB associativity for 2 MB and 4 MB pages."}
    ,{CPUF_L2DTlb2and4MSize, 0, "L2DTlb2and4MSize", "L2 data TLB number of entries for 2 MB and 4 MB pages."}
    ,{CPUF_L2DTlb2and4MAssoc, 0, "L2DTlb2and4MAssoc", "L2 data TLB associativity for 2 MB and 4 MB pages."}
    ,{CPUF_L2ITlb4KSize, 0, "L2ITlb4KSize", "L2 instruction TLB number of entries for 4 KB pages."}
    ,{CPUF_L2ITlb4KAssoc, 0, "L2ITlb4KAssoc", "L2 instruction TLB associativity for 4 KB pages."}
    ,{CPUF_L2DTlb4KSize, 0, "L2DTlb4KSize", "L2 data TLB number of entries for 4 KB pages."}
    ,{CPUF_L2DTlb4KAssoc, 0, "L2DTlb4KAssoc", "L2 data TLB associativity for 4 KB pages."}
    ,{CPUF_L2LineSize, 0, "L2LineSize", "L2 cache line size in bytes."}
    ,{CPUF_L2LinesPerTag, 0, "L2LinesPerTag", "L2 cache lines per tag."}
    ,{CPUF_L2Assoc, 0, "L2Assoc", "L2 cache associativity."}
    ,{CPUF_L2Size, 0, "L2Size", "L2 cache size in KB."}
    ,{CPUF_L3LineSize, 0, "L3LineSize", "L3 cache line size in bytes."}
    ,{CPUF_L3LinesPerTag, 0, "L3LinesPerTag", "L3 cache lines per tag."}
    ,{CPUF_L3Assoc, 0, "L3Assoc", "L3 cache associativity."}
    ,{CPUF_L3Size, 0, "L3Size", "L3 cache size."}
    ,{CPUF_TS, 0, "TS", "Temperature sensor."}
    ,{CPUF_FID, 0, "FID", "Frequency ID control."}
    ,{CPUF_VID, 0, "VID", "Voltage ID control."}
    ,{CPUF_TTP, 0, "TTP", "THERMTRIP."}
    ,{CPUF_HTC, 0, "HTC", "TM: Hardware thermal control (HTC)."}
    ,{CPUF_100MHzSteps, 0, "100MHzSteps", "100 MHz multiplier Control."}
    ,{CPUF_HwPstate, 0, "HwPstate", "Hardware P-state control."}
    ,{CPUF_TscInvariant, 0, "TscInvariant", "TSC invariant."}
    ,{CPUF_CPB, 0, "CPB", "Core performance boost."}
    ,{CPUF_EffFreqRO, 0, "EffFreqRO", "Read-only effective frequency interface."}
    ,{CPUF_PhysAddrSize, 0, "PhysAddrSize", "Maximum physical byte address size in bits."}
    ,{CPUF_LinAddrSize, 0, "LinAddrSize", "Maximum linear byte address size in bits."}
    ,{CPUF_GuestPhysAddrSize, 0, "GuestPhysAddrSize", "Maximum guest physical byte address size in bits."}
    ,{CPUF_NC, 0, "NC", "number of physical cores - 1."}
    ,{CPUF_ApicIdCoreIdSize, 0, "ApicIdCoreIdSize", "APIC ID size. The number of bits in the initial APIC20[ApicId] value that indicate core ID within a processor."}
    ,{CPUF_SvmRev, 0, "SvmRev", "SVM revision."}
    ,{CPUF_NASID, 0, "NASID", "number of address space identifiers (ASID)."}
    ,{CPUF_NP, 0, "NP", "Nested paging."}
    ,{CPUF_LbrVirt, 0, "LbrVirt", "LBR virtualization."}
    ,{CPUF_SVML, 0, "SVML", "SVM lock. Indicates support for SVM-Lock."}
    ,{CPUF_NRIPS, 0, "NRIPS", "NRIP save. Indicates support for NRIP save on #VMEXIT."}
    ,{CPUF_TscRateMsr, 0, "TscRateMsr", "MSR based TSC rate control."}
    ,{CPUF_VmcbClean, 0, "VmcbClean", "VMCB clean bits. Indicates support for VMCB clean bits."}
    ,{CPUF_FlushByAsid, 0, "FlushByAsid", "Flush by ASID."}
    ,{CPUF_DecodeAssists, 0, "DecodeAssists", "Decode assists."}
    ,{CPUF_PauseFilter, 0, "PauseFilter", "Pause intercept filter."}
    ,{CPUF_PauseFilterThreshold, 0, "PauseFilterThreshold", "PAUSE filter threshold."}
    ,{CPUF_L1ITlb1GSize, 0, "L1ITlb1GSize", "L1 instruction TLB number of entries for 1 GB pages."}
    ,{CPUF_L1ITlb1GAssoc, 0, "L1ITlb1GAssoc", "L1 instruction TLB associativity for 1 GB pages."}
    ,{CPUF_L1DTlb1GSize, 0, "L1DTlb1GSize", "L1 data TLB number of entries for 1 GB pages."}
    ,{CPUF_L1DTlb1GAssoc, 0, "L1DTlb1GAssoc", "L1 data TLB associativity for 1 GB pages."}
    ,{CPUF_L2ITlb1GSize, 0, "L2ITlb1GSize", "L2 instruction TLB number of entries for 1 GB pages."}
    ,{CPUF_L2ITlb1GAssoc, 0, "L2ITlb1GAssoc", "L2 instruction TLB associativity for 1 GB pages."}
    ,{CPUF_L2DTlb1GSize, 0, "L2DTlb1GSize", "L2 data TLB number of entries for 1 GB pages."}
    ,{CPUF_L2DTlb1GAssoc, 0, "L2DTlb1GAssoc", "L2 data TLB associativity for 1 GB pages."}
    ,{CPUF_FP128, 0, "FP128", "128-bit SSE (multimedia) instructions are executed with full-width internal operations and pipelines rather than decomposing them into internal 64-bit suboperations."}
    ,{CPUF_MOVU, 0, "MOVU", "MOVU SSE (multimedia) instructions are more efficient and should be preferred to SSE(multimedia) MOVL/MOVH. MOVUPS is more efficient than MOVLPS/MOVHPS."}
    ,{CPUF_IBSFFV, 0, "IBSFFV", "IBS feature flags valid."}
    ,{CPUF_FetchSam, 0, "FetchSam", "IBS fetch sampling supported."}
    ,{CPUF_OpSam, 0, "OpSam", "IBS execution sampling supported."}
    ,{CPUF_RdWrOpCnt, 0, "RdWrOpCnt", "Read write of op counter supported."}
    ,{CPUF_OpCnt, 0, "OpCnt", "Op counting mode supported."}
    ,{CPUF_BrnTrgt, 0, "BrnTrgt", "Branch target address reporting supported."}
    ,{CPUF_OpCntExt, 0, "OpCntExt", "IbsOpCurCnt and IbsOpMaxCnt extend by 7 bits."}
    ,{CPUF_RipInvalidChk, 0, "RipInvalidChk", "Invalid RIP indication supported."}
    ,{CPUF_LwpAvail, 0, "LwpAvail", "LWP available."}
    ,{CPUF_LwpVAL, 0, "LwpVAL", "LWPVAL instruction available."}
    ,{CPUF_LwpIRE, 0, "LwpIRE", "instructions retired event available."}
    ,{CPUF_LwpBRE, 0, "LwpBRE", "branch retired event available."}
    ,{CPUF_LwpDME, 0, "LwpDME", "DC miss event available."}
    ,{CPUF_LwpCNH, 0, "LwpCNH", "core clocks not halted event available."}
    ,{CPUF_LwpRNH, 0, "LwpRNH", "core reference clocks not halted event available."}
    ,{CPUF_LwpInt, 0, "LwpInt", "interrupt on threshold overflow available."}
    ,{CPUF_LwpCbSize, 0, "LwpCbSize", "control block size. Size in bytes of the LWPCB."}
    ,{CPUF_LwpEventSize, 0, "LwpEventSize", "event record size. Size in bytes of an event record in the LWP event ring buffer."}
    ,{CPUF_LwpMaxEvents, 0, "LwpMaxEvents", "maximum EventId. Maximum EventId value that is supported."}
    ,{CPUF_LwpEventOffset, 0, "LwpEventOffset", "offset to the EventInterval1 field. Offset from the start of the LWPCB to the EventInterval1 field."}
    ,{CPUF_LwpLatencyMax, 0, "LwpLatencyMax", "latency counter bit size. Size in bits of the cache latency counters."}
    ,{CPUF_LwpDataAddress, 0, "LwpDataAddress", "data cache miss address valid."}
    ,{CPUF_LwpLatencyRnd, 0, "LwpLatencyRnd", "amount cache latency is rounded."}
    ,{CPUF_LwpVersion, 0, "LwpVersion", "version. Version of LWP implementation."}
    ,{CPUF_LwpMinBufferSize, 0, "LwpMinBufferSize", "event ring buffer size. Minimum size of the LWP event ring buffer, in units of 32 event records."}
    ,{CPUF_LwpBranchPrediction, 0, "LwpBranchPrediction", "branch prediction filtering supported."}
    ,{CPUF_LwpIpFiltering, 0, "LwpIpFiltering", "IP filtering supported."}
    ,{CPUF_LwpCacheLevels, 0, "LwpCacheLevels", "cache level filtering supported."}
    ,{CPUF_LwpCacheLatency, 0, "LwpCacheLatency", "cache latency filtering supported."}
    ,{CPUF_D_LwpAvail, 0, "D_LwpAvail", "lightweight profiling supported."}
    ,{CPUF_D_LwpVAL, 0, "D_LwpVAL", "LWPVAL instruction supported."}
    ,{CPUF_D_LwpIRE, 0, "D_LwpIRE", "instructions retired event supported."}
    ,{CPUF_D_LwpBRE, 0, "D_LwpBRE", "branch retired event supported."}
    ,{CPUF_D_LwpDME, 0, "D_LwpDME", "DC miss event supported."}
    ,{CPUF_D_LwpCNH, 0, "D_LwpCNH", "core clocks not halted event supported."}
    ,{CPUF_D_LwpRNH, 0, "D_LwpRNH", "core reference clocks not halted event supported."}
    ,{CPUF_D_LwpInt, 0, "D_LwpInt", "interrupt on threshold overflow supported."}
    ,{CPUF_CacheType, 0, "CacheType", "Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified)."}
    ,{CPUF_CacheLevel, 0, "CacheLevel", "Cache Level (Starts at 1)."}
    ,{CPUF_SelfInitialization, 0, "SelfInitialization", "Self Initializing cache level."}
    ,{CPUF_FullyAssociative, 0, "FullyAssociative", "Fully Associative cache."}
    ,{CPUF_NumSharingCache, 0, "NumSharingCache", "Number of cores sharing cache. The number of cores sharing this cache is NumSharingCache+1."}
    ,{CPUF_CacheLineSize, 0, "CacheLineSize", "Cache line size in bytes (plus 1 encoding)."}
    ,{CPUF_CachePhysPartitions, 0, "CachePhysPartitions", "Cache physical line partitions (plus 1 encoding)."}
    ,{CPUF_CacheNumWays, 0, "CacheNumWays", "Cache number of ways (plus 1 encoding)."}
    ,{CPUF_CacheNumSets, 0, "CacheNumSets", "Cache number of sets (plus 1 encoding)."}
    ,{CPUF_WBINVD, 0, "WBINVD", "Write-Back Invalidate/Invalidate (WBINVD/INVD)."}
    ,{CPUF_CacheInclusive, 0, "CacheInclusive", "Cache inclusive."}
    ,{CPUF_ExtendedApicId, 0, "ExtendedApicId", "extended APIC ID."}
    ,{CPUF_ComputeUnitId, 0, "ComputeUnitId", "compute unit ID. Identifies the processor compute unit ID."}
    ,{CPUF_CoresPerComputeUnit, 0, "CoresPerComputeUnit", "cores per compute unit. The number of cores per compute unit is CoresPerComputeUnit+1."}
    ,{CPUF_NodeId, 0, "NodeId", "Specifies the node ID."}
    ,{CPUF_NodesPerProcessor, 0, "NodesPerProcessor", "Specifies the number of nodes per processor."}
    };

const char*    CCPUID::CacheDesc[] = {
    "Null descriptor, this byte contains no information"
    ,"Instruction TLB: 4 KByte pages, 4-way set associative, 32 entries"
    ,"Instruction TLB: 4 MByte pages, fully associative, 2 entries"
    ,"Data TLB: 4 KByte pages, 4-way set associative, 64 entries"
    ,"Data TLB: 4 MByte pages, 4-way set associative, 8 entries"
    ,"Data TLB1: 4 MByte pages, 4-way set associative, 32 entries"
    ,"1st-level instruction cache: 8 KBytes, 4-way set associative, 32 byte line size"
    ,""
    ,"1st-level instruction cache: 16 KBytes, 4-way set associative, 32 byte line size"
    ,"1st-level instruction cache: 32KBytes, 4-way set associative, 64 byte line size"
    ,"1st-level data cache: 8 KBytes, 2-way set associative, 32 byte line size"
    ,"Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries"
    ,"1st-level data cache: 16 KBytes, 4-way set associative, 32 byte line size"
    ,"1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size"
    ,"1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size"
    ,"3rd-level cache: 512 KBytes, 4-way set associative, 64 byte line size, 2 lines per sector"
    ,"3rd-level cache: 1 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector"
    ,""
    ,"3rd-level cache: 2 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector"
    ,""
    ,""
    ,""
    ,"3rd-level cache: 4 MBytes, 8-way set associative, 64 byte line size, 2 lines per sector"
    ,""
    ,""
    ,"1st-level data cache: 32 KBytes, 8-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,"1st-level instruction cache: 32 KBytes, 8-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"No 2nd-level cache or, if processor contains a valid 2nd-level cache, no 3rd-level cache"
    ,"2nd-level cache: 128 KBytes, 4-way set associative, 32 byte line size"
    ,"2nd-level cache: 256 KBytes, 4-way set associative, 32 byte line size"
    ,"2nd-level cache: 512 KBytes, 4-way set associative, 32 byte line size"
    ,"2nd-level cache: 1 MByte, 4-way set associative, 32 byte line size"
    ,"2nd-level cache: 2 MByte, 4-way set associative, 32 byte line size"
    ,"3rd-level cache: 4 MByte, 4-way set associative, 64 byte line size"
    ,"3rd-level cache: 8 MByte, 8-way set associative, 64 byte line size"
    ,"2nd-level cache: 3MByte, 12-way set associative, 64 byte line size"
    ,"3rd-level cache: 4MB, 16-way set associative, 64-byte line size (Intel Xeon processor MP, Family 0FH, Model 06H); 2nd-level cache: 4 MByte, 16-way set associative, 64 byte line size"
    ,"3rd-level cache: 6MByte, 12-way set associative, 64 byte line size"
    ,"3rd-level cache: 8MByte, 16-way set associative, 64 byte line size"
    ,"3rd-level cache: 12MByte, 12-way set associative, 64 byte line size"
    ,"3rd-level cache: 16MByte, 16-way set associative, 64 byte line size"
    ,"2nd-level cache: 6MByte, 24-way set associative, 64 byte line size"
    ,"Instruction TLB: 4 KByte pages, 32 entries"
    ,"Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 64 entries"
    ,"Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 128 entries"
    ,"Instruction TLB: 4 KByte and 2-MByte or 4-MByte pages, 256 entries"
    ,""
    ,""
    ,"Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries"
    ,"Data TLB0: 4 MByte pages, 4-way set associative, 16 entries"
    ,"Data TLB0: 4 KByte pages, 4-way associative, 16 entries"
    ,"Data TLB0: 4 KByte pages, fully associative, 16 entries"
    ,"Data TLB0: 2-MByte or 4 MByte pages, 4-way set associative, 32 entries"
    ,"Data TLB: 4 KByte and 4 MByte pages, 64 entries"
    ,"Data TLB: 4 KByte and 4 MByte pages,128 entries"
    ,"Data TLB: 4 KByte and 4 MByte pages,256 entries"
    ,""
    ,""
    ,""
    ,"1st-level data cache: 16 KByte, 8-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"1st-level data cache: 8 KByte, 4-way set associative, 64 byte line size"
    ,"1st-level data cache: 16 KByte, 4-way set associative, 64 byte line size"
    ,"1st-level data cache: 32 KByte, 4-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Trace cache: 12 K-μop, 8-way set associative"
    ,"Trace cache: 16 K-μop, 8-way set associative"
    ,"Trace cache: 32 K-μop, 8-way set associative"
    ,""
    ,""
    ,""
    ,"Instruction TLB: 2M/4M pages, fully associative, 8 entries"
    ,""
    ,"2nd-level cache: 1 MByte, 4-way set associative, 64byte line size"
    ,"2nd-level cache: 128 KByte, 8-way set associative, 64 byte line size, 2 lines per sector"
    ,"2nd-level cache: 256 KByte, 8-way set associative, 64 byte line size, 2 lines per sector"
    ,"2nd-level cache: 512 KByte, 8-way set associative, 64 byte line size, 2 lines per sector"
    ,"2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size, 2 lines per sector"
    ,"2nd-level cache: 2 MByte, 8-way set associative, 64byte line size"
    ,""
    ,"2nd-level cache: 512 KByte, 2-way set associative, 64-byte line size"
    ,"2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size"
    ,""
    ,"2nd-level cache: 256 KByte, 8-way set associative, 32 byte line size"
    ,"2nd-level cache: 512 KByte, 8-way set associative, 32 byte line size"
    ,"2nd-level cache: 1 MByte, 8-way set associative, 32 byte line size"
    ,"2nd-level cache: 2 MByte, 8-way set associative, 32 byte line size"
    ,"2nd-level cache: 512 KByte, 4-way set associative, 64 byte line size"
    ,"2nd-level cache: 1 MByte, 8-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Instruction TLB: 4 KByte pages, 4-way set associative, 128 entries"
    ,"Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries"
    ,"Instruction TLB: 4KByte pages, 4-way set associative, 64 entries"
    ,"Data TLB: 4 KByte pages, 4-way set associative, 128 entries"
    ,"Data TLB1: 4 KByte pages, 4-way associative, 256 entries"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Data TLB1: 4 KByte pages, 4-way associative, 64 entries"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size"
    ,"3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size"
    ,"3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,"3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size"
    ,"3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size"
    ,"3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,"3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size"
    ,"3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size"
    ,"3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,"3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size"
    ,"3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size"
    ,"3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"3rd-level cache: 12MByte, 24-way set associative, 64 byte line size"
    ,"3rd-level cache: 18MByte, 24-way set associative, 64 byte line size"
    ,"3rd-level cache: 24MByte, 24-way set associative, 64 byte line size"
    ,""
    ,""
    ,""
    ,"64-Byte prefetching"
    ,"128-Byte prefetching"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters"
};

const char*    CCPUID::SseNames[] = {
    "None",
    "SSE",
    "SSE2",
    "SSE3",
    "SSSE3",
    "SSE4.1",
    "SSE4.2",
};

const char*    CCPUID::AvxNames[] = {
    "None",
    "AVX",
    "AVX2"
};



////////////////////////////////////////////////////////////
// CCPUID
////////////////////////////////////////////////////////////

// 構造函數.
CCPUID::CCPUID()
    :_InfoCount(0), _LFuncStd(0), _LFuncExt(0), _BrandTrim(0)
{
    _Vendor[0] = '\0';
    _Brand[0] = '\0';
}

// 刷新信息.在Info數組中追加一項.
void CCPUID::RefreshInfo_Put(uint32_t fid, uint32_t fidsub, uint32_t CPUInfo[4])
{
    if (_InfoCount>=MAX_CPUIDINFO)    return;
    Info[_InfoCount].fid = fid;
    Info[_InfoCount].fidsub = fidsub;
    Info[_InfoCount].dw[0] = CPUInfo[0];
    Info[_InfoCount].dw[1] = CPUInfo[1];
    Info[_InfoCount].dw[2] = CPUInfo[2];
    Info[_InfoCount].dw[3] = CPUInfo[3];
    ++_InfoCount;
}

// 刷新信息.
void CCPUID::RefreshInfo()
{
    uint32_t CPUInfo[4];
    uint32_t nmax;
    uint32_t i,j;

    // == 將CPUID信息保存到Info數組 ==
    _InfoCount = 0;

    // 標准功能.
    getcpuid(CPUInfo, 0);
    RefreshInfo_Put(0, 0, CPUInfo);
    nmax = CPUInfo[0];    // CPUID(0).EAX[31:0]=LFuncStd
    _LFuncStd = nmax;
    for(i=1; i<=nmax; ++i)
    {
        getcpuidex(CPUInfo, i, 0);
        RefreshInfo_Put(i, 0, CPUInfo);
        // fidsub
        if (0x4==i)    // Deterministic Cache Parameters (Function 04h)
        {
            j=1;
            while(true)
            {
                getcpuidex(CPUInfo, i, j);
                if (0==(CPUInfo[0]&0x1F))    break;    // EAX[4:0]=Cache_Type
                RefreshInfo_Put(i, j, CPUInfo);
                // next
                ++j;
            }
        }
        else if (0xB==i)    // x2APIC Features / Processor Topology (Function 0Bh)
        {
            j=1;
            while(true)
            {
                getcpuidex(CPUInfo, i, j);
                if (0==CPUInfo[0] && 0==CPUInfo[1])    break;    // until EAX=0 and EBX=0
                RefreshInfo_Put(i, j, CPUInfo);
                // next
                ++j;
            }
        }
        else if (0xD==i)    // XSAVE Features (Function 0Dh)
        {
            // fidsub = 1
            j=1;
            getcpuidex(CPUInfo, i, j);
            RefreshInfo_Put(i, j, CPUInfo);
            // fidsub >= 2
            for(j=2; j<=63; ++j)
            {
                getcpuidex(CPUInfo, i, j);
                if (0!=CPUInfo[0]
                    || 0!=CPUInfo[1]
                    || 0!=CPUInfo[2]
                    || 0!=CPUInfo[3])
                {
                    RefreshInfo_Put(i, j, CPUInfo);
                }
            }
        }
    }

    // 擴展功能.
    getcpuid(CPUInfo, 0x80000000U);
    RefreshInfo_Put(0x80000000U, 0, CPUInfo);
    nmax = CPUInfo[0];    // CPUID(0x80000000).EAX[31:0]=LFuncExt
    _LFuncExt = nmax;
    if (nmax!=0)
    {
        for(i=0x80000001U; i<=nmax; ++i)
        {
            getcpuidex(CPUInfo, i, 0);
            RefreshInfo_Put(i, 0, CPUInfo);
            // fidsub
            if (0x8000001DU==i)    // Cache Properties (Function 8000001Dh)
            {
                j=1;
                while(true)
                {
                    getcpuidex(CPUInfo, i, j);
                    if (0==(CPUInfo[0]&0x1F))    break;    // EAX[4:0]=Cache_Type
                    RefreshInfo_Put(i, j, CPUInfo);
                    // next
                    ++j;
                }
            }
        }
    }

}

// 刷新屬性.
void CCPUID::RefreshProperty()
{
    uint32_t dwBuf[4];

    // Vendor
    GetData(dwBuf, 0);    // Function 0: Vendor-ID and Largest Standard Function
    uint32_t* pVendor = (uint32_t *)_Vendor;    // 避免GCC的 -Wstrict-aliasing 警告.
    pVendor[0] = dwBuf[1];    // ebx: 前四個字符.
    pVendor[1] = dwBuf[3];    // edx: 中間四個字符.
    pVendor[2] = dwBuf[2];    // ecx: 最后四個字符.
    _Vendor[12] = '\0';

    // Brand
    _Brand[0] = '\0';
    if (_LFuncExt >= 0x80000004)
    {
        // Function 80000002h,80000003h,80000004h: Processor Brand String
        GetData((uint32_t *)&_Brand[0], 0x80000002);    // 前16個字符.
        GetData((uint32_t *)&_Brand[16], 0x80000003);    // 中間16個字符.
        GetData((uint32_t *)&_Brand[32], 0x80000004);    // 最后16個字符.
        _Brand[48] = '\0';
    }
    _BrandTrim = &_Brand[0];
    while('\0'!=*_BrandTrim && ' '==*_BrandTrim) ++_BrandTrim;    // 去除首都空格.

    // SIMD
    _mmx = simd_mmx(&_hwmmx);
    _sse = simd_sse_level(&_hwsse);
    _avx = simd_avx_level(&_hwavx);

}

// 刷新所有.
void CCPUID::RefreshAll()
{
    RefreshInfo();
    RefreshProperty();
}

// 取得信息.
//
// return: 成功時返回LPCPUIDINFO. 如果失敗, 便返回NULL.
// InfoType: 功能號. 即CPUID指令的eax參數.
// ECXValue: 子功能號. 即CPUID指令的ecx參數.
LPCCPUIDINFO CCPUID::GetInfo(uint32_t InfoType, uint32_t ECXValue) const
{
    // 順序搜索.
    for(int i=0; i<InfoCount(); ++i)
    {
        const CPUIDINFO& v = Info[i];
        if (InfoType==v.fid && ECXValue==v.fidsub)
        {
            return &v;
        }
    }
    return NULL;
}

// 取得數據.
//
// CPUInfo: 成功時返回4個DWORD. 如果失敗, 便返回全0.
// InfoType: 功能號. 即CPUID指令的eax參數.
// ECXValue: 子功能號. 即CPUID指令的ecx參數.
void CCPUID::GetData(uint32_t CPUInfo[4], uint32_t InfoType, uint32_t ECXValue) const
{
    LPCCPUIDINFO p = GetInfo(InfoType, ECXValue);
    if (NULL==p)
    {
        CPUInfo[0] = 0;
        CPUInfo[1] = 0;
        CPUInfo[2] = 0;
        CPUInfo[3] = 0;
        return;
    }
    CPUInfo[0] = p->dw[0];
    CPUInfo[1] = p->dw[1];
    CPUInfo[2] = p->dw[2];
    CPUInfo[3] = p->dw[3];
}

// 取得CPUID字段
uint32_t CCPUID::GetField(CPUIDFIELD cpuf) const
{
    LPCCPUIDINFO p = GetInfo(CPUIDFIELD_FID(cpuf), CPUIDFIELD_FIDSUB(cpuf));
    if (NULL==p)    return 0;
    return getcpuidfield_buf(p->dw, cpuf);
}

int    CCPUID::simd_mmx(int* phwmmx) const
{
    int    rt = 0;    // result
    #ifdef CCPUID_X86
        const uint32_t    BIT_D_MMX = 0x00800000;    // bit 23
        uint32_t dwBuf[4];

        // check processor support
        GetData(dwBuf, 1);    // Function 1: Feature Information
        if ( dwBuf[3] & BIT_D_MMX )    rt=1;
        if (NULL!=phwmmx)    *phwmmx=rt;

        // check OS support
        if ( rt )
        {
            #if defined(_M_X64) && defined(_MSC_VER) && !defined(__INTEL_COMPILER)
                // VC編譯器不支持64位下的MMX.
                rt=0;
            #else
                try 
                {
                    _mm_empty();    // MMX instruction: emms
                }
                catch(...)
                {
                    rt=0;
                }
            #endif    // #if defined(_M_X64) && defined(_MSC_VER)
        }
    #else    // #ifdef CCPUID_X86
        if (NULL!=phwmmx)    *phwmmx=rt;
    #endif    // #ifdef CCPUID_X86
    return rt;
}

int    CCPUID::simd_sse_level(int* phwsse) const
{
    int    rt = SIMD_SSE_NONE;    // result
    #ifdef CCPUID_X86
        const uint32_t    BIT_D_SSE = 0x02000000;    // bit 25
        const uint32_t    BIT_D_SSE2 = 0x04000000;    // bit 26
        const uint32_t    BIT_C_SSE3 = 0x00000001;    // bit 0
        const uint32_t    BIT_C_SSSE3 = 0x00000100;    // bit 9
        const uint32_t    BIT_C_SSE41 = 0x00080000;    // bit 19
        const uint32_t    BIT_C_SSE42 = 0x00100000;    // bit 20
        uint32_t dwBuf[4];

        // check processor support
        GetData(dwBuf, 1);    // Function 1: Feature Information
        if ( dwBuf[3] & BIT_D_SSE )
        {
            rt = SIMD_SSE_1;
            if ( dwBuf[3] & BIT_D_SSE2 )
            {
                rt = SIMD_SSE_2;
                if ( dwBuf[2] & BIT_C_SSE3 )
                {
                    rt = SIMD_SSE_3;
                    if ( dwBuf[2] & BIT_C_SSSE3 )
                    {
                        rt = SIMD_SSE_3S;
                        if ( dwBuf[2] & BIT_C_SSE41 )
                        {
                            rt = SIMD_SSE_41;
                            if ( dwBuf[2] & BIT_C_SSE42 )
                            {
                                rt = SIMD_SSE_42;
                            }
                        }
                    }
                }
            }
        }
        if (NULL!=phwsse)    *phwsse=rt;

        // check OS support
        try 
        {
            __m128 xmm1 = _mm_setzero_ps();    // SSE instruction: xorps
            int* pxmm1 = (int*)&xmm1;    // 避免GCC的 -Wstrict-aliasing 警告.
            if (0!=*pxmm1)    rt = SIMD_SSE_NONE;    // 避免Release模式編譯優化時剔除_mm_setzero_ps.
        }
        catch(...)
        {
            rt = SIMD_SSE_NONE;
        }
    #else    // #ifdef CCPUID_X86
        if (NULL!=phwsse)    *phwsse=rt;
    #endif    // #ifdef CCPUID_X86
    return rt;
}

int    CCPUID::simd_avx_level(int* phwavx) const
{
    int    rt = SIMD_AVX_NONE;    // result
    #ifdef CCPUID_X86
        // check processor support
        if (0!=GetField(CPUF_AVX))
        {
            rt = SIMD_AVX_1;
            if (0!=GetField(CPUF_AVX2))
            {
                rt = SIMD_AVX_2;
            }
        }
        if (NULL!=phwavx)    *phwavx=rt;

        // check OS support
        if (0!=GetField(CPUF_OSXSAVE))    // XGETBV enabled for application use.
        {
            uint32_t n = GetField(CPUF_XFeatureSupportedMaskLo);    // XCR0: XFeatureSupportedMask register.
            if (6!=(n&6))    // XCR0[2:1] = ‘11b’ (XMM state and YMM state are enabled by OS).
            {
                rt = SIMD_AVX_NONE;
            }
        }
    #else    // #ifdef CCPUID_X86
        if (NULL!=phwavx)    *phwavx=rt;
    #endif    // #ifdef CCPUID_X86
    return rt;
}

 


2.5 testccpuid.cpp : [C++] 測試ccpuid.hpp, 顯示所有的CPUID信息

  全部代碼——

View Code
#include <stdio.h>

#include "ccpuid.hpp"

bool bShowDesc = true;    // 顯示描述信息

// 獲取程序位數(被編譯為多少位的代碼)
int GetProgramBits()
{
    return sizeof(int*) * 8;
}

// 打印CPUID字段_某項.
void prtCcpuid_Item(uint32_t fid, uint32_t fidsub, const uint32_t CPUInfo[4])
{
    static const char* RegName[4] = { "EAX", "EBX", "ECX", "EDX" };
    uint32_t mask = CPUIDFIELD_MASK_FID | CPUIDFIELD_MASK_FIDSUB;
    uint32_t cur =  CPUIDFIELD_MAKE(fid, fidsub, 0, 0, 1) & mask;
    int i;
    for(i=0; i<CCPUID::CPUFDescLen; ++i)
    {
        const CPUIDFIELDDESC& v = CCPUID::CPUFDesc[i];
        if ((v.cpuf&mask)==cur)
        {
            CPUIDFIELD f = v.cpuf;
            uint32_t bits = CPUIDFIELD_LEN(f);
            uint32_t pos = CPUIDFIELD_POS(f);
            uint32_t reg = CPUIDFIELD_REG(f);
            uint32_t n = getcpuidfield_buf(CPUInfo, f);    //UINT32 n = __GETBITS32(CPUInfo[reg], pos, bits);
            if (bits>1)
            {
                printf("\t%s[%2d:%2d]", RegName[reg], pos+bits-1, pos);
            }
            else
            {
                printf("\t%s[   %2d]", RegName[reg], pos);
            }
            printf("=%s:\t0x%X\t(%u)", v.szName, n, n);
            if (bShowDesc)
            {
                printf("\t// %s", v.szDesc);
            }
            printf("\n");

        }
    }
}

// 打印CPUID字段.
void prtCcpuid(const CCPUID& ccid)
{
    int i;
    for(i=0; i<ccid.InfoCount(); ++i)
    {
        const CPUIDINFO& v = ccid.Info[i];
        printf("0x%.8X[%d]:\t%.8X\t%.8X\t%.8X\t%.8X\n", v.fid, v.fidsub, v.dw[0], v.dw[1], v.dw[2], v.dw[3]);
        // 檢查子功能號. 如果是規范的子功能號,便故意設為0,根據子功能號0的字段來解析各個子功能號的信息。
        uint32_t fidsub = v.fidsub;
        switch(v.fid)
        {
        case 0x4: fidsub=0;
        case 0xB: fidsub=0;
        case 0x8000001D: fidsub=0;
        }
        // item
        prtCcpuid_Item(v.fid, fidsub, v.dw);
        // otheritem
        if (0==v.fid)    // Vendor-ID (Function 02h)
        {
            printf("\tVendor:\t%s\n", ccid.Vendor());
        }
        else if (0x80000004==v.fid)    // Processor Brand String (Function 80000002h,80000003h,80000004h)
        {
            printf("\tBrand:\t%s\n", ccid.Brand());
        }
        else if (0x2==v.fid)    // Cache Descriptors (Function 02h)
        {
            for(int j=0; j<=3; ++j)
            {
                uint32_t n = v.dw[j];
                if (n>0)    // 最高位為0,且不是全0
                {
                    for(int k=0; k<=3; ++k)
                    {
                        if (j>0 || k>0)    // EAX的低8位不是緩存信息
                        {
                            int by = n & 0x00FF;
                            if (by>0)
                            {
                                printf("\t0x%.2X:\t%s\n", by, CCPUID::CacheDesc[by]);
                            }
                        }
                        n >>= 8;
                    }
                }
            }
        }
    }
}

int main(int argc, char* argv[])
{
    int i;

    //CCPUID ccid;
    //ccid.RefreshAll();
    CCPUID& ccid = CCPUID::cur();

    printf("testccpuid v1.02 (%dbit)\n\n", GetProgramBits());

    // base info
    printf("CCPUID.Vendor:\t%s\n", ccid.Vendor());
    //printf("CCPUID.Brand:\t%s\n", ccid.Brand());
    printf("CCPUID.BrandTrim:\t%s\n", ccid.BrandTrim());
    printf("CCPUID.InfoCount:\t%d\n", ccid.InfoCount());
    printf("CCPUID.LFuncStd:\t%.8Xh\n", ccid.LFuncStd());
    printf("CCPUID.LFuncExt:\t%.8Xh\n", ccid.LFuncExt());

    // simd info
    printf("CCPUID.MMX:\t%d\t// hw: %d\n", ccid.mmx(), ccid.hwmmx());
    printf("CCPUID.SSE:\t%d\t// hw: %d\n", ccid.sse(), ccid.hwsse());
    for(i=1; i<(int)(sizeof(CCPUID::SseNames)/sizeof(CCPUID::SseNames[0])); ++i)
    {
        if (ccid.hwsse()>=i)    printf("\t%s\n", CCPUID::SseNames[i]);
    }
    printf("SSE4A:\t%d\n", ccid.GetField(CPUF_SSE4A));
    printf("AES:\t%d\n", ccid.GetField(CPUF_AES));
    printf("PCLMULQDQ:\t%d\n", ccid.GetField(CPUF_PCLMULQDQ));
    printf("CCPUID.AVX:\t%d\t// hw: %d\n", ccid.avx(), ccid.hwavx());
    for(i=1; i<(int)(sizeof(CCPUID::AvxNames)/sizeof(CCPUID::AvxNames[0])); ++i)
    {
        if (ccid.hwavx()>=i)    printf("\t%s\n", CCPUID::AvxNames[i]);
    }
    printf("F16C:\t%d\n", ccid.GetField(CPUF_F16C));
    printf("FMA:\t%d\n", ccid.GetField(CPUF_FMA));
    printf("FMA4:\t%d\n", ccid.GetField(CPUF_FMA4));
    printf("XOP:\t%d\n", ccid.GetField(CPUF_XOP));

    // field info
    printf("== fields ==\n");
    prtCcpuid(ccid);

    return 0;
}

 


2.6 makefile

  makefile——

makefile
# flags
CC = g++
CFLAGS = -Wall -msse
LFLAGS =

# args
RELEASE =0
BITS =

# [args] 生成模式. 0代表debug模式, 1代表release模式. make RELEASE=1.
ifeq ($(RELEASE),0)
    # debug
    CFLAGS += -g
else
    # release
    CFLAGS += -static -O3 -DNDEBUG
    LFLAGS += -static
endif

# [args] 程序位數. 32代表32位程序, 64代表64位程序, 其他默認. make BITS=32.
ifeq ($(BITS),32)
    CFLAGS += -m32
    LFLAGS += -m32
else
    ifeq ($(BITS),64)
        CFLAGS += -m64
        LFLAGS += -m64
    else
    endif
endif


.PHONY : all clean

# files
TARGETS = testccpuid testccpuidc
OBJS = testccpuid.o ccpuid.o

all : $(TARGETS)

testccpuid : $(OBJS)
    $(CC) $(LFLAGS) -o $@ $^


ccpuid.o : ccpuid.cpp ccpuid.hpp ccpuid.h
    $(CC) $(CFLAGS) -c $<

testccpuid.o : testccpuid.cpp ccpuid.hpp ccpuid.h
    $(CC) $(CFLAGS) -c $<


testccpuidc : testccpuidc.c ccpuid.h
    gcc $(CFLAGS) -o $@ $<


clean :
    rm -f $(OBJS) $(TARGETS) $(addsuffix .exe,$(TARGETS))

 


三、測試結果

  在以下編譯器中成功編譯——
VC6:x86版。
VC2003:x86版。
VC2005:x86版。
VC2010:x86版、x64版。
GCC 4.7.0(Fedora 17 x64):x86版、x64版。
GCC 4.6.2(MinGW (20120426)):x86版。
GCC 4.6.1(TDM-GCC (MinGW-w64)):x86版、x64版。
llvm-gcc-4.2(Mac OS X Lion 10.7.4, Xcode 4.4.1):x86版、x64版。


  在虛擬機中Mac OS X Lion 10.7.4系統上運行testccpuid,它對Intel i3-2310M的檢測結果為——

testccpuid v1.02 (64bit)

CCPUID.Vendor:    GenuineIntel
CCPUID.BrandTrim:    Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz
CCPUID.InfoCount:    17
CCPUID.LFuncStd:    00000005h
CCPUID.LFuncExt:    80000008h
CCPUID.MMX:    1    // hw: 1
CCPUID.SSE:    3    // hw: 3
    SSE
    SSE2
    SSE3
SSE4A:    0
AES:    0
PCLMULQDQ:    0
CCPUID.AVX:    0    // hw: 0
F16C:    0
FMA:    0
FMA4:    0
XOP:    0
== fields ==
0x00000000[0]:    00000005    756E6547    6C65746E    49656E69
    EAX[31: 0]=LFuncStd:    0x5    (5)    // largest standard function.
    Vendor:    GenuineIntel
0x00000001[0]:    000206A7    01020800    00000201    178BFBFF
    EAX[ 3: 0]=Stepping:    0x7    (7)    // processor stepping.
    EAX[ 7: 4]=BaseModel:    0xA    (10)    // base processor model.
    EAX[11: 8]=BaseFamily:    0x6    (6)    // base processor family.
    EAX[13:12]=ProcessorType:    0x0    (0)    // processor type.
    EAX[19:16]=ExtModel:    0x2    (2)    // processor extended model.
    EAX[27:20]=ExtFamily:    0x0    (0)    // processor extended family.
    EBX[ 7: 0]=BrandId8:    0x0    (0)    // 8-bit brand ID.
    EBX[15: 8]=CLFlush:    0x8    (8)    // CLFLUSH line size. (*8)
    EBX[23:16]=MaxApicId:    0x2    (2)    // Maximum number of addressable IDs for logical processors in this physical package.
    EBX[31:24]=ApicId:    0x1    (1)    // Initial local APIC physical ID(8-bit).
    ECX[    0]=SSE3:    0x1    (1)    // Streaming SIMD Extensions 3.
    ECX[    1]=PCLMULQDQ:    0x0    (0)    // PCLMULQDQ instruction.
    ECX[    2]=DTES64:    0x0    (0)    // 64-bit DS Area.
    ECX[    3]=MONITOR:    0x0    (0)    // MONITOR/MWAIT instructions.
    ECX[    4]=DS_CPL:    0x0    (0)    // CPL Qualified Debug Store.
    ECX[    5]=VMX:    0x0    (0)    // Virtual Machine Extensions.
    ECX[    6]=SMX:    0x0    (0)    // Safer Mode Extensions.
    ECX[    7]=EIST:    0x0    (0)    // Enhanced Intel SpeedStep technology.
    ECX[    8]=TM2:    0x0    (0)    // Thermal Monitor 2.
    ECX[    9]=SSSE3:    0x1    (1)    // Supplemental Streaming SIMD Extensions 3 (SSSE3).
    ECX[   10]=CNXT_ID:    0x0    (0)    // L1 Context ID.
    ECX[   12]=FMA:    0x0    (0)    // supports FMA extensions using YMM state.
    ECX[   13]=CX16:    0x0    (0)    // CMPXCHG16B instruction.
    ECX[   14]=xTPR:    0x0    (0)    // xTPR Update Control. Can disable sending Task Priority messages.
    ECX[   15]=PDCM:    0x0    (0)    // Perfmon and Debug Capability.
    ECX[   17]=PCID:    0x0    (0)    // Process Context Identifiers.
    ECX[   18]=DCA:    0x0    (0)    // Direct Cache Access.
    ECX[   19]=SSE41:    0x0    (0)    // SSE4.1 instructions.
    ECX[   20]=SSE42:    0x0    (0)    // SSE4.2 instructions.
    ECX[   21]=x2APIC:    0x0    (0)    // Extended xAPIC Support.
    ECX[   22]=MOVBE:    0x0    (0)    // MOVBE Instruction.
    ECX[   23]=POPCNT:    0x0    (0)    // POPCNT instruction.
    ECX[   24]=TSC_DEADLINE:    0x0    (0)    // Local APIC timer supports one-shot operation using a TSC deadline value.
    ECX[   25]=AES:    0x0    (0)    // Advanced Encryption Standard (AES) Instructions.
    ECX[   26]=XSAVE:    0x0    (0)    // XSAVE (and related) instructions are supported by hardware.
    ECX[   27]=OSXSAVE:    0x0    (0)    // XSAVE (and related) instructions are enabled.
    ECX[   28]=AVX:    0x0    (0)    // AVX instructions.
    ECX[   29]=F16C:    0x0    (0)    // half-precision convert instruction support.
    ECX[   30]=RDRAND:    0x0    (0)    // RDRAND instruction.
    EDX[    0]=FPU:    0x1    (1)    // Floating Point Unit On-Chip.
    EDX[    1]=VME:    0x1    (1)    // Virtual 8086 Mode Enhancements.
    EDX[    2]=DE:    0x1    (1)    // Debugging Extensions.
    EDX[    3]=PSE:    0x1    (1)    // Page Size Extension.
    EDX[    4]=TSC:    0x1    (1)    // Time Stamp Counter.
    EDX[    5]=MSR:    0x1    (1)    // Model Specific Registers RDMSR and WRMSR Instructions.
    EDX[    6]=PAE:    0x1    (1)    // Physical Address Extension.
    EDX[    7]=MCE:    0x1    (1)    // Machine Check Exception.
    EDX[    8]=CX8:    0x1    (1)    // CMPXCHG8B instruction.
    EDX[    9]=APIC:    0x1    (1)    // APIC(Advanced Programmable Interrupt Controller) On-Chip.
    EDX[   11]=SEP:    0x1    (1)    // Fast System Call instructions, SYSENTER and SYSEXIT.
    EDX[   12]=MTRR:    0x1    (1)    // Memory Type Range Registers.
    EDX[   13]=PGE:    0x1    (1)    // Page Global Enable.
    EDX[   14]=MCA:    0x1    (1)    // Machine-Check Architecture.
    EDX[   15]=CMOV:    0x1    (1)    // Conditional Move Instructions.
    EDX[   16]=PAT:    0x1    (1)    // Page Attribute Table.
    EDX[   17]=PSE36:    0x1    (1)    // 36-Bit Page Size Extension.
    EDX[   18]=PSN:    0x0    (0)    // Processor Serial Number.
    EDX[   19]=CLFSH:    0x1    (1)    // CLFLUSH Instruction.
    EDX[   21]=DS:    0x0    (0)    // Debug Store.
    EDX[   22]=ACPI:    0x0    (0)    // Thermal Monitor and Software Controlled Clock Facilities.
    EDX[   23]=MMX:    0x1    (1)    // MMX instructions.
    EDX[   24]=FXSR:    0x1    (1)    // FXSAVE and FXRSTOR instructions.
    EDX[   25]=SSE:    0x1    (1)    // Streaming SIMD Extensions.
    EDX[   26]=SSE2:    0x1    (1)    // Streaming SIMD Extensions 2.
    EDX[   27]=SS:    0x0    (0)    // Self Snoop.
    EDX[   28]=HTT:    0x1    (1)    // Max APIC IDs reserved field is Valid.
    EDX[   29]=TM:    0x0    (0)    // Thermal Monitor.
    EDX[   31]=PBE:    0x0    (0)    // Pending Break Enable.
0x00000002[0]:    76035A01    00F0B2FF    00000000    00CA0000
    0x5A:    Data TLB: 4 KByte and 4 MByte pages, 64 entries
    0x03:    Data TLB: 4 KByte pages, 4-way set associative, 64 entries
    0x76:    Instruction TLB: 2M/4M pages, fully associative, 8 entries
    0xFF:    CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters
    0xB2:    Instruction TLB: 4KByte pages, 4-way set associative, 64 entries
    0xF0:    64-Byte prefetching
    0xCA:    Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries
0x00000003[0]:    00000000    00000000    00000000    00000000
0x00000004[0]:    04000021    01C0003F    0000003F    00000000
    EAX[ 4: 0]=Cache_Type:    0x1    (1)    // Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified).
    EAX[ 7: 5]=Cache_Level:    0x1    (1)    // Cache Level (Starts at 1).
    EAX[    8]=CACHE_SI:    0x0    (0)    // Self Initializing cache level.
    EAX[    9]=CACHE_FA:    0x0    (0)    // Fully Associative cache.
    EAX[25:14]=MaxApicIdShare:    0x0    (0)    // Maximum number of addressable IDs for logical processors sharing this cache (plus 1 encoding).
    EAX[31:26]=MaxApicIdCore:    0x1    (1)    // Maximum number of addressable IDs for processor cores in the physical package (plus 1 encoding).
    EBX[11: 0]=Cache_LineSize:    0x3F    (63)    // System Coherency Line Size (plus 1 encoding).
    EBX[21:12]=Cache_Partitions:    0x0    (0)    // Physical Line partitions (plus 1 encoding).
    EBX[31:22]=Cache_Ways:    0x7    (7)    // Ways of Associativity (plus 1 encoding).
    ECX[31: 0]=Cache_Sets:    0x3F    (63)    // Number of Sets (plus 1 encoding).
    EDX[    0]=CACHE_INVD:    0x0    (0)    // WBINVD/INVD behavior on lower level caches.
    EDX[    1]=CACHE_INCLUSIVENESS:    0x0    (0)    // Cache is inclusive of lower cache levels.
    EDX[    2]=CACHE_COMPLEXINDEX:    0x0    (0)    // Complex Cache Indexing.
0x00000004[1]:    04000021    01C0003F    0000003F    00000000
    EAX[ 4: 0]=Cache_Type:    0x1    (1)    // Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified).
    EAX[ 7: 5]=Cache_Level:    0x1    (1)    // Cache Level (Starts at 1).
    EAX[    8]=CACHE_SI:    0x0    (0)    // Self Initializing cache level.
    EAX[    9]=CACHE_FA:    0x0    (0)    // Fully Associative cache.
    EAX[25:14]=MaxApicIdShare:    0x0    (0)    // Maximum number of addressable IDs for logical processors sharing this cache (plus 1 encoding).
    EAX[31:26]=MaxApicIdCore:    0x1    (1)    // Maximum number of addressable IDs for processor cores in the physical package (plus 1 encoding).
    EBX[11: 0]=Cache_LineSize:    0x3F    (63)    // System Coherency Line Size (plus 1 encoding).
    EBX[21:12]=Cache_Partitions:    0x0    (0)    // Physical Line partitions (plus 1 encoding).
    EBX[31:22]=Cache_Ways:    0x7    (7)    // Ways of Associativity (plus 1 encoding).
    ECX[31: 0]=Cache_Sets:    0x3F    (63)    // Number of Sets (plus 1 encoding).
    EDX[    0]=CACHE_INVD:    0x0    (0)    // WBINVD/INVD behavior on lower level caches.
    EDX[    1]=CACHE_INCLUSIVENESS:    0x0    (0)    // Cache is inclusive of lower cache levels.
    EDX[    2]=CACHE_COMPLEXINDEX:    0x0    (0)    // Complex Cache Indexing.
0x00000004[2]:    04004041    05C0003F    00000FFF    00000000
    EAX[ 4: 0]=Cache_Type:    0x1    (1)    // Cache Type (0=Null, 1=Data, 2=Instruction, 3=Unified).
    EAX[ 7: 5]=Cache_Level:    0x2    (2)    // Cache Level (Starts at 1).
    EAX[    8]=CACHE_SI:    0x0    (0)    // Self Initializing cache level.
    EAX[    9]=CACHE_FA:    0x0    (0)    // Fully Associative cache.
    EAX[25:14]=MaxApicIdShare:    0x1    (1)    // Maximum number of addressable IDs for logical processors sharing this cache (plus 1 encoding).
    EAX[31:26]=MaxApicIdCore:    0x1    (1)    // Maximum number of addressable IDs for processor cores in the physical package (plus 1 encoding).
    EBX[11: 0]=Cache_LineSize:    0x3F    (63)    // System Coherency Line Size (plus 1 encoding).
    EBX[21:12]=Cache_Partitions:    0x0    (0)    // Physical Line partitions (plus 1 encoding).
    EBX[31:22]=Cache_Ways:    0x17    (23)    // Ways of Associativity (plus 1 encoding).
    ECX[31: 0]=Cache_Sets:    0xFFF    (4095)    // Number of Sets (plus 1 encoding).
    EDX[    0]=CACHE_INVD:    0x0    (0)    // WBINVD/INVD behavior on lower level caches.
    EDX[    1]=CACHE_INCLUSIVENESS:    0x0    (0)    // Cache is inclusive of lower cache levels.
    EDX[    2]=CACHE_COMPLEXINDEX:    0x0    (0)    // Complex Cache Indexing.
0x00000005[0]:    00000000    00000000    00000003    00000000
    EAX[15: 0]=MonLineSizeMin:    0x0    (0)    // Smallest monitor line size in bytes.
    EBX[15: 0]=MonLineSizeMax:    0x0    (0)    // Largest monitor-line size in bytes.
    ECX[    0]=EMX:    0x1    (1)    // Enumerate MONITOR/MWAIT extensions.
    ECX[    1]=IBE:    0x1    (1)    // Interrupt Break-Event.
    EDX[ 3: 0]=MWAIT_Number_C0:    0x0    (0)    // Number of C0 sub C-states supported using MWAIT.
    EDX[ 7: 4]=MWAIT_Number_C1:    0x0    (0)    // Number of C1 sub C-states supported using MWAIT.
    EDX[11: 8]=MWAIT_Number_C2:    0x0    (0)    // Number of C2 sub C-states supported using MWAIT.
    EDX[15:12]=MWAIT_Number_C3:    0x0    (0)    // Number of C3 sub C-states supported using MWAIT.
    EDX[19:16]=MWAIT_Number_C4:    0x0    (0)    // Number of C4 sub C-states supported using MWAIT.
0x80000000[0]:    80000008    00000000    00000000    00000000
    EAX[31: 0]=LFuncExt:    0x80000008    (2147483656)    // Largest extended function.
0x80000001[0]:    00000000    00000000    00000001    20100800
    EBX[15: 0]=BrandId16:    0x0    (0)    // 16-bit Brand ID.
    EBX[31:28]=PkgType:    0x0    (0)    // Package type (Family[7:0] >= 10h).
    ECX[    0]=LahfSahf:    0x1    (1)    // LAHF and SAHF instruction support in 64-bit mode.
    ECX[    1]=CmpLegacy:    0x0    (0)    // core multi-processing legacy mode.
    ECX[    2]=SVM:    0x0    (0)    // secure virtual machine.
    ECX[    3]=ExtApicSpace:    0x0    (0)    // extended APIC space.
    ECX[    4]=AltMovCr8:    0x0    (0)    // LOCK MOV CR0 means MOV CR8.
    ECX[    5]=ABM:    0x0    (0)    // advanced bit manipulation (LZCNT).
    ECX[    6]=SSE4A:    0x0    (0)    // SSE4A instructions.
    ECX[    7]=MisAlignSse:    0x0    (0)    // misaligned SSE mode.
    ECX[    8]=3DNowPrefetch:    0x0    (0)    // PREFETCH and PREFETCHW instruction support.
    ECX[    9]=OSVW:    0x0    (0)    // OS visible workaround.
    ECX[   10]=IBS:    0x0    (0)    // instruction based sampling.
    ECX[   11]=XOP:    0x0    (0)    // extended operation support.
    ECX[   12]=SKINIT:    0x0    (0)    // SKINIT and STGI are supported, independent of the value of MSRC000_0080[SVME].
    ECX[   13]=WDT:    0x0    (0)    // watchdog timer support.
    ECX[   15]=LWP:    0x0    (0)    // lightweight profiling support.
    ECX[   16]=FMA4:    0x0    (0)    // 4-operand FMA instruction support.
    ECX[   19]=BIT_NODEID:    0x0    (0)    // Indicates support for MSRC001_100C[NodeId, NodesPerProcessor].
    ECX[   21]=TBM:    0x0    (0)    // Trailing bit manipulation instruction support.
    ECX[   22]=TopologyExtensions:    0x0    (0)    // Topology extensions support.
    EDX[   11]=SYSCALL:    0x1    (1)    // SYSCALL and SYSRET instructions.
    EDX[   20]=XD:    0x1    (1)    // Execution Disable Bit.
    EDX[   22]=MmxExt:    0x0    (0)    // AMD extensions to MMX instructions.
    EDX[   25]=FFXSR:    0x0    (0)    // FXSAVE and FXRSTOR instruction optimizations.
    EDX[   26]=Page1GB:    0x0    (0)    // 1-GB large page support.
    EDX[   27]=RDTSCP:    0x0    (0)    // RDTSCP and TSC_AUX.
    EDX[   29]=LM:    0x1    (1)    // 64-bit long mode.(x86-64)
    EDX[   30]=3DNowExt:    0x0    (0)    // AMD extensions to 3DNow! instructions.
    EDX[   31]=3DNow:    0x0    (0)    // 3DNow! instructions.
0x80000002[0]:    20202020    49202020    6C65746E    20295228
0x80000003[0]:    65726F43    294D5428    2D336920    30313332
0x80000004[0]:    5043204D    20402055    30312E32    007A4847
    Brand:           Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz
0x80000005[0]:    00000000    00000000    00000000    00000000
    EAX[ 7: 0]=L1ITlb2and4MSize:    0x0    (0)    // Instruction TLB number of entries for 2-MB and 4-MB pages.
    EAX[15: 8]=L1ITlb2and4MAssoc:    0x0    (0)    // Instruction TLB associativity for 2-MB and 4-MB pages.
    EAX[23:16]=L1DTlb2and4MSize:    0x0    (0)    // Data TLB number of entries for 2-MB and 4-MB pages.
    EAX[31:24]=L1DTlb2and4MAssoc:    0x0    (0)    // Data TLB associativity for 2-MB and 4-MB pages.
    EBX[ 7: 0]=L1ITlb4KSize:    0x0    (0)    // Instruction TLB number of entries for 4 KB pages.
    EBX[15: 8]=L1ITlb4KAssoc:    0x0    (0)    // Instruction TLB associativity for 4KB pages.
    EBX[23:16]=L1DTlb4KSize:    0x0    (0)    // Data TLB number of entries for 4 KB pages.
    EBX[31:24]=L1DTlb4KAssoc:    0x0    (0)    // Data TLB associativity for 4 KB pages.
    ECX[ 7: 0]=L1DcLineSize:    0x0    (0)    // L1 data cache line size in bytes.
    ECX[15: 8]=L1DcLinesPerTag:    0x0    (0)    // L1 data cache lines per tag.
    ECX[23:16]=L1DcAssoc:    0x0    (0)    // L1 data cache associativity.
    ECX[31:24]=L1DcSize:    0x0    (0)    // L1 data cache size in KB.
    EDX[ 7: 0]=L1IcLineSize:    0x0    (0)    // L1 instruction cache line size in bytes
    EDX[15: 8]=L1IcLinesPerTag:    0x0    (0)    // L1 instruction cache lines per tag.
    EDX[23:16]=L1IcAssoc:    0x0    (0)    // L1 instruction cache associativity.
    EDX[31:24]=L1IcSize:    0x0    (0)    // L1 instruction cache size KB.
0x80000006[0]:    00000000    00000000    01006040    00000000
    EAX[11: 0]=L2ITlb2and4MSize:    0x0    (0)    // L2 instruction TLB number of entries for 2 MB and 4 MB pages.
    EAX[15:12]=L2ITlb2and4MAssoc:    0x0    (0)    // L2 instruction TLB associativity for 2 MB and 4 MB pages.
    EAX[27:16]=L2DTlb2and4MSize:    0x0    (0)    // L2 data TLB number of entries for 2 MB and 4 MB pages.
    EAX[31:28]=L2DTlb2and4MAssoc:    0x0    (0)    // L2 data TLB associativity for 2 MB and 4 MB pages.
    EBX[11: 0]=L2ITlb4KSize:    0x0    (0)    // L2 instruction TLB number of entries for 4 KB pages.
    EBX[15:12]=L2ITlb4KAssoc:    0x0    (0)    // L2 instruction TLB associativity for 4 KB pages.
    EBX[27:16]=L2DTlb4KSize:    0x0    (0)    // L2 data TLB number of entries for 4 KB pages.
    EBX[31:28]=L2DTlb4KAssoc:    0x0    (0)    // L2 data TLB associativity for 4 KB pages.
    ECX[ 7: 0]=L2LineSize:    0x40    (64)    // L2 cache line size in bytes.
    ECX[11: 8]=L2LinesPerTag:    0x0    (0)    // L2 cache lines per tag.
    ECX[15:12]=L2Assoc:    0x6    (6)    // L2 cache associativity.
    ECX[31:16]=L2Size:    0x100    (256)    // L2 cache size in KB.
    EDX[ 7: 0]=L3LineSize:    0x0    (0)    // L3 cache line size in bytes.
    EDX[11: 8]=L3LinesPerTag:    0x0    (0)    // L3 cache lines per tag.
    EDX[15:12]=L3Assoc:    0x0    (0)    // L3 cache associativity.
    EDX[31:18]=L3Size:    0x0    (0)    // L3 cache size.
0x80000007[0]:    00000000    00000000    00000000    00000000
    EDX[    0]=TS:    0x0    (0)    // Temperature sensor.
    EDX[    1]=FID:    0x0    (0)    // Frequency ID control.
    EDX[    2]=VID:    0x0    (0)    // Voltage ID control.
    EDX[    3]=TTP:    0x0    (0)    // THERMTRIP.
    EDX[    4]=HTC:    0x0    (0)    // TM: Hardware thermal control (HTC).
    EDX[    6]=100MHzSteps:    0x0    (0)    // 100 MHz multiplier Control.
    EDX[    7]=HwPstate:    0x0    (0)    // Hardware P-state control.
    EDX[    8]=TscInvariant:    0x0    (0)    // TSC invariant.
    EDX[    9]=CPB:    0x0    (0)    // Core performance boost.
    EDX[   10]=EffFreqRO:    0x0    (0)    // Read-only effective frequency interface.
0x80000008[0]:    00003024    00000000    00000000    00000000
    EAX[ 7: 0]=PhysAddrSize:    0x24    (36)    // Maximum physical byte address size in bits.
    EAX[15: 8]=LinAddrSize:    0x30    (48)    // Maximum linear byte address size in bits.
    EAX[23:16]=GuestPhysAddrSize:    0x0    (0)    // Maximum guest physical byte address size in bits.
    ECX[ 7: 0]=NC:    0x0    (0)    // number of physical cores - 1.
    ECX[15:12]=ApicIdCoreIdSize:    0x0    (0)    // APIC ID size. The number of bits in the initial APIC20[ApicId] value that indicate core ID within a processor.

 

 

參考文獻——
《Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes:1, 2A, 2B, 2C, 3A, 3B, and 3C》044US. August 2012. http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
《Intel® Architecture Instruction Set Extensions Programming Reference》014. AUGUST 2012. http://software.intel.com/en-us/avx/
《Intel® Processor Identification and the CPUID Instruction》. May 2012. http://developer.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html
《AMD64 Architecture Programmer's Manual Volume 3: General Purpose and System Instructions》. December 2011. http://support.amd.com/us/Processor_TechDocs/24594_APM_v3.pdf
《AMD CPUID Specification》. September 2010. http://support.amd.com/us/Embedded_TechDocs/25481.pdf
《x86 architecture CPUID》. http://www.sandpile.org/x86/cpuid.htm
《Haswell New Instruction Descriptions Now Available! 》. Mark Buxton. http://software.intel.com/en-us/blogs/2011/06/13/haswell-new-instruction-descriptions-now-available/
[IDF2012]ARCS002《Introduction to the upcoming Intel® Advanced Vector Extensions 2 (Intel® AVX2)》. 王有偉, Henry Ou. 2012-4.
[IDF2012]ARCS002《即將推出的英特爾® 高級矢量擴展指令集2(英特爾® AVX2)介紹》. 王有偉, Henry Ou. 2012-4.
《x86/x64 指令系統》. mik(鄧志). http://www.mouseos.com/x64/default.html
《[x86]SIMD指令集發展歷程表(MMX、SSE、AVX等)》. http://www.cnblogs.com/zyl910/archive/2012/02/26/x86_simd_table.html
《如何在各個版本的VC及64位下使用CPUID指令》. http://www.cnblogs.com/zyl910/archive/2012/05/21/vcgetcpuid.html
《[VC兼容32位和64位] 檢查MMX和SSE系列指令集的支持級別》. http://www.cnblogs.com/zyl910/archive/2012/05/25/checksimd64.html
《[VC] CPUIDFIELD:CPUID字段的統一編號、讀取方案。范例:檢查SSE4A、AES、PCLMULQDQ指令》. http://www.cnblogs.com/zyl910/archive/2012/06/29/getcpuidfield.html
《[VC] 檢測AVX系列指令集的支持級別(AVX、AVX2、F16C、FMA、FMA4、XOP)》. http://www.cnblogs.com/zyl910/archive/2012/07/04/checkavx.html
《[C#] cmdarg_ui:“簡單參數命令行程序”的通用圖形界面》.  http://www.cnblogs.com/zyl910/archive/2012/06/19/cmdarg_ui.html
《[C/C++] 顯示各種C/C++編譯器的預定義宏(C11標准、C++11標准、VC、BCB、Intel、GCC)》. http://www.cnblogs.com/zyl910/archive/2012/08/02/printmacro.html
《[C] 讓VC、BCB支持C99的整數類型(stdint.h、inttypes.h)(兼容GCC)》. http://www.cnblogs.com/zyl910/archive/2012/08/08/c99int.html
《GCC 64位程序的makefile條件編譯心得——32位版與64位版、debug版與release版(兼容MinGW、TDM-GCC)》. http://www.cnblogs.com/zyl910/archive/2012/08/14/gcc64_make.html
《[C] 在GCC中獲取CPUID信息(兼容VC)》. http://www.cnblogs.com/zyl910/archive/2012/08/06/getcpuid_gcc.html
《ccpuid:CPUID信息模塊。范例:顯示所有的CPUID信息》. http://www.cnblogs.com/zyl910/archive/2012/07/11/ccpuid.html
《ccpuid:CPUID信息模塊 V1.01版,支持GCC(兼容32位或64位的Windows/Linux)》. http://www.cnblogs.com/zyl910/archive/2012/08/22/ccpuid_v101.html


源碼下載——
http://files.cnblogs.com/zyl910/ccpuid_v102.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM