Aprimoramento do Módulo ccpuid: Compatibilidade Multiplataforma e Expansão de Recursos CPUID

O módulo ccpuid, originalmente focado nas plataformas Windows e Linux, foi atualizado para a versão V1.02, incorporando compatibilidade com Mac OS X. Esta nova versão introduz melhorias significativas, como suporte a C puro, a inclusão de novas constantes CPUF e um mecanismo aprimorado para detecção de platfaormas x86.

1.1 Suporte a Mac OS X

A integração com Mac OS X apresentou desafios específicos. Embora o diretório /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/4.0/include contivesse arquivos de cabeçalho de intrínsecos como xmmintrin.h, o compilador llvm-gcc frequentemente falhava ao encontrar cpuid.h. Além disso, mesmo quando encontrado, o cpuid.h do Mac OS X não definia as macros essenciais __cpuid e __cpuid_count.

A solução envolveu a implementação de macros de assembly inline diretamente no código, baseadas na abordagem utilizada no cpuid.h do Fedora. Essa estratégia permitiu contornar as dependências do cabeçalho específico do sistema e garantir a funcionalidade da instrução CPUID em ambientes Mac OS X, tanto em arquiteturas de 32 bits (com código independente de posição, PIC) quanto em 64 bits. As macros adaptadas para __cpuid e __cpuid_count são as seguintes:

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

// Em Mac, llvm-gcc pode não encontrar cpuid.h ou não definir __cpuid/__cpuid_count.
// Portanto, definimos nossas próprias macros.
#ifndef __cpuid_count
    // Código baseado no cpuid.h do GCC 4.7.0 (Fedora 17)
    #if defined(__i386__) && defined(__PIC__)
    /* %ebx pode ser o registrador PIC.  */
    #if __GNUC__ >= 3
    #define __cpuid(nivel, 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" (nivel))

    #define __cpuid_count(nivel, contagem, 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" (nivel), "2" (contagem))
    #else
    /* Compiladores GCC anteriores à versão 3.0 não suportavam
       sintaxe Intel asm nem alternativas em código i386.  */
    #define __cpuid(nivel, 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" (nivel))

    #define __cpuid_count(nivel, contagem, 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" (nivel), "2" (contagem))
    #endif
    #else
    #define __cpuid(nivel, a, b, c, d)            \
      __asm__ ("cpuid\n\t"                    \
               : "=a" (a), "=b" (b), "=c" (c), "=d" (d)    \
               : "0" (nivel))

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

1.2 Suporte a C Puro

O módulo ccpuid foi originalmente projetado com uma interface orientada a objetos (C++), o que impedia seu uso em projetos puramente em C. Para resolver isso, a arquitetura foi revisada, dividindo-o em duas partes:

  1. Um cabeçalho ccpuid.h contendo funções e estruturas compatíveis com C. Funções globais foram movidas para este cabeçalho e marcadas como inline para facilitar a compilação.
  2. Um cabeçalho ccpuid.hpp, que fornece a interface da classe C++ CCPUID, e um arrquivo de implementação ccpuid.cpp.

É importante notar que, devido à ausência de tratamento de exceções estruturado em C puro, as funções de detecção de suporte a SIMD (como MMX e SSE) não incluem a verificação de suporte do sistema operacional nesta versão. Além disso, arrays como CPUFDesc e SseNames permanecem como membros estáticos da classe CCPUID, sendo acessíveis apenas na versão C++.

A utilização do módulo é simplificada: projetos em C devem incluir apenas ccpuid.h, enquanto projetos em C++ devem incluir ccpuid.hpp e compilar ccpuid.cpp junto com o projeto.

1.3 Adição de Constantes CPUF

Com base em documentações atualizadas da Intel (como os Manuais do Desenvolvedor de Software de Arquiteturas Intel® 64 e IA-32), foram adicionadas novas constantes CPUF para identificar recursos específicos do processador. As novas constantes incluem:

  • CPUID.(EAX=07H, ECX=0H):EBX.TSC_ADJUST (bit 1): Indica suporte ao MSR IA32_TSC_ADJUST.
  • CPUID.(EAX=07H, ECX=0H):EBX.RDSEED (bit 18): Indica suporte à instrução RDSEED.
  • CPUID.(EAX=07H, ECX=0H):EBX.ADX (bit 19): Indica suporte às instruções ADCX e ADOX.
  • CPUID.(EAX=07H, ECX=0H):EBX.SMAP (bit 20): Indica suporte a Supervisor Mode Access Prevention.

1.4 Detecção de Plataforma x86

Para melhorar a portabilidade e evitar erros de compilação em arquiteturas não x86, a versão V1.02 introduziu um mecanismo de detecção de plataforma. Agora, o código verifica a presença de macros específicas do compilador para determinar se está sendo compilado em um ambiente x86:

  • Para GCC: Verifica as macros __i386__ ou __x86_64__.
  • Para MSVC: Verifica as macros _M_IX86 ou _M_X64.

Com base nesta detecção, a macro CCPUID_X86 é definida. Funções que dependem da arquitetura x86, como as de detecção de SIMD (simd_mmx, etc.), utilizam CCPUID_X86 para condicionar a compilação do código específico. Em plataformas não x86, essas funções agora retornam 0 (indicando falta de suporte), em vez de causar falhas na compilação, o que facilita a integração do módulo em projetos multiplataforma.

  1. Implementação do Código

2.1 ccpuid.h: Informações CPUID (Versão C Pura)

#ifndef __CCPUID_H_INCLUDED
#define __CCPUID_H_INCLUDED

#include <stddef.h>    // Macros e tipos padrão como NULL.
#include "stdint.h"    // Tipos normativos como uint32_t.


// Intrínsecos
#if (defined(__GNUC__))    // Compiladores GCC
    #if (defined(__i386__) || defined(__x86_64__))
        #define CCPUID_X86    1    // É uma plataforma x86.
        #include <xmmintrin.h>    // MMX, SSE
        // Em Mac, llvm-gcc pode não encontrar cpuid.h ou não definir __cpuid/__cpuid_count.
        // Portanto, definimos nossas próprias macros.
        #ifndef __cpuid_count
            // Código baseado no cpuid.h do GCC 4.7.0 (Fedora 17)
            #if defined(__i386__) && defined(__PIC__)
            /* %ebx pode ser o registrador PIC.  */
            #if __GNUC__ >= 3
            #define __cpuid(nivel, 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" (nivel))

            #define __cpuid_count(nivel, contagem, 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" (nivel), "2" (contagem))
            #else
            /* Compiladores GCC anteriores à versão 3.0 não suportavam
               sintaxe Intel asm nem alternativas em código i386.  */
            #define __cpuid(nivel, 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" (nivel))

            #define __cpuid_count(nivel, contagem, 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" (nivel), "2" (contagem))
            #endif
            #else
            #define __cpuid(nivel, a, b, c, d)            \
              __asm__ ("cpuid\n\t"                    \
                       : "=a" (a), "=b" (b), "=c" (c), "=d" (d)    \
                       : "0" (nivel))

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

#elif defined(_MSC_VER)    // Compiladores MSVC
    #if (defined(_M_IX86) || defined(_M_X64))
        #define CCPUID_X86    1    // É uma plataforma x86.
        #if _MSC_VER >=1400    // VC2005 e superior
            #include <intrin.h>    // CPUID, MMX, SSE
        #elif _MSC_VER >=1200    // VC6
            #include <xmmintrin.h>    // MMX, SSE
        #endif    // #if _MSC_VER >=1400
    #endif

#else
    #error Somente suporta MSVC ou 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

////////////////////////////////////////
// obterInfoCPUID: Função base para obter informações CPUID.
////////////////////////////////////////

INLINE void obterInfoCPUIDExt(uint32_t infoCPU[4], uint32_t tipoInfo, uint32_t valorECX)
{
    if (NULL==infoCPU)    return;

#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))    // GCC
    __cpuid_count(tipoInfo, valorECX, infoCPU[0], infoCPU[1], infoCPU[2], infoCPU[3]);
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))    // MSVC
    #if defined(_M_X64) || _MSC_VER>=1600    // 64 bits não suporta assembly inline. 1600: VS2010, __cpuidex suportado a partir do SP1 do VC2008.
        __cpuidex((int*)infoCPU, (int)tipoInfo, (int)valorECX);
    #else
        _asm{
            // Carregar. Ler parâmetros para os registradores.
            mov edi, infoCPU;    // Preparar edi para endereçar infoCPU
            mov eax, tipoInfo;
            mov ecx, valorECX;
            // CPUID
            cpuid;
            // Salvar. Armazenar registradores em infoCPU
            mov    [edi], eax;
            mov    [edi+4], ebx;
            mov    [edi+8], ecx;
            mov    [edi+12], edx;
        }
    #endif
#else
    // Não suportado, retorna 0.
    infoCPU[0] = infoCPU[1] = infoCPU[2] = infoCPU[3] = 0;
#endif    // #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
}

INLINE void obterInfoCPUID(uint32_t infoCPU[4], uint32_t tipoInfo)
{
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))    // GCC
    __cpuid(tipoInfo, infoCPU[0], infoCPU[1], infoCPU[2], infoCPU[3]);
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))    // MSVC
    #if _MSC_VER>=1400    // VC2005 e superior suporta __cpuid
        __cpuid((int*)infoCPU, (int)tipoInfo);
    #else
        obterInfoCPUIDExt(infoCPU, tipoInfo, 0);
    #endif
#else
    obterInfoCPUIDExt(infoCPU, tipoInfo, 0);
#endif    // #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
}


// Estrutura para armazenar uma única informação CPUID.
typedef struct tagInformacaoCPUID{
    uint32_t    funcaoID;    // ID da função. Parâmetro EAX da instrução CPUID.
    uint32_t    subfuncaoID;    // ID da subfunção. Parâmetro ECX da instrução CPUID.
    union{
        uint32_t    registros[4];    // Informação retornada.
        struct{
            uint32_t    _eax;
            uint32_t    _ebx;
            uint32_t    _ecx;
            uint32_t    _edx;
        };
    };
}InformacaoCPUID, *P_InformacaoCPUID;
typedef const InformacaoCPUID* PC_InformacaoCPUID;


////////////////////////////////////////
// CAMPO_CPUID: Esquema de numeração unificado para campos CPUID.
//
// http://www.cnblogs.com/zyl910/archive/2012/06/29/getcpuidfield.html (referência original)
////////////////////////////////////////

typedef uint32_t CAMPO_CPUID;

#define  CAMPO_CPUID_MASCARA_POSICAO    0x0000001F    // Deslocamento de bit. 0~31.
#define  CAMPO_CPUID_MASCARA_COMPRIMENTO    0x000003E0    // Comprimento de bit. 1~32
#define  CAMPO_CPUID_MASCARA_REGISTRADOR    0x00000C00    // Registrador. 0=EAX, 1=EBX, 2=ECX, 3=EDX.
#define  CAMPO_CPUID_MASCARA_SUBFUNCAO    0x000FF000    // ID da subfunção (8 bits baixos).
#define  CAMPO_CPUID_MASCARA_FUNCAO    0xFFF00000    // ID da função (4 bits mais significativos e 8 bits baixos).

#define CAMPO_CPUID_DESLOCAMENTO_POSICAO    0
#define CAMPO_CPUID_DESLOCAMENTO_COMPRIMENTO    5
#define CAMPO_CPUID_DESLOCAMENTO_REGISTRADOR    10
#define CAMPO_CPUID_DESLOCAMENTO_SUBFUNCAO    12
#define CAMPO_CPUID_DESLOCAMENTO_FUNCAO    20

#define CAMPO_CPUID_CRIAR(funcao,subfuncao,reg,pos,comp)    (((funcao)&0xF0000000U) \
    | ((funcao)<<CAMPO_CPUID_DESLOCAMENTO_FUNCAO & 0x0FF00000) \
    | ((subfuncao)<<CAMPO_CPUID_DESLOCAMENTO_SUBFUNCAO & CAMPO_CPUID_MASCARA_SUBFUNCAO) \
    | ((reg)<<CAMPO_CPUID_DESLOCAMENTO_REGISTRADOR & CAMPO_CPUID_MASCARA_REGISTRADOR) \
    | ((pos)<<CAMPO_CPUID_DESLOCAMENTO_POSICAO & CAMPO_CPUID_MASCARA_POSICAO) \
    | (((comp)-1)<<CAMPO_CPUID_DESLOCAMENTO_COMPRIMENTO & CAMPO_CPUID_MASCARA_COMPRIMENTO) \
    )
#define CAMPO_CPUID_OBTER_FUNCAO(campoCPUID)    ( ((uint32_t)(campoCPUID)&0xF0000000U) | (((uint32_t)(campoCPUID) & 0x0FF00000)>>CAMPO_CPUID_DESLOCAMENTO_FUNCAO) )
#define CAMPO_CPUID_OBTER_SUBFUNCAO(campoCPUID)    ( ((campoCPUID) & CAMPO_CPUID_MASCARA_SUBFUNCAO)>>CAMPO_CPUID_DESLOCAMENTO_SUBFUNCAO )
#define CAMPO_CPUID_OBTER_REGISTRADOR(campoCPUID)    ( ((campoCPUID) & CAMPO_CPUID_MASCARA_REGISTRADOR)>>CAMPO_CPUID_DESLOCAMENTO_REGISTRADOR )
#define CAMPO_CPUID_OBTER_POSICAO(campoCPUID)    ( ((campoCPUID) & CAMPO_CPUID_MASCARA_POSICAO)>>CAMPO_CPUID_DESLOCAMENTO_POSICAO )
#define CAMPO_CPUID_OBTER_COMPRIMENTO(campoCPUID)    ( (((campoCPUID) & CAMPO_CPUID_MASCARA_COMPRIMENTO)>>CAMPO_CPUID_DESLOCAMENTO_COMPRIMENTO) + 1 )

// Descrição de um campo CPUID.
typedef struct tagDescCampoCPUID{
    CAMPO_CPUID    cpuf;
    int    reservado;
    const char* nome;
    const char* descricao;
}DescCampoCPUID, *P_DescCampoCPUID;
typedef const DescCampoCPUID* PC_DescCampoCPUID;

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


// Obter campo de bits.
#ifndef __GETBITS32
#define __GETBITS32(fonte,pos,comp)    ( ((fonte)>>(pos)) & (((uint32_t)-1)>>(32-comp)) )
#endif

// Obter campo de um buffer baseado em CAMPO_CPUID.
INLINE uint32_t    obterCampoCPUID_buffer(const uint32_t buffer[4], CAMPO_CPUID cpuf)
{
    return __GETBITS32(buffer[CAMPO_CPUID_OBTER_REGISTRADOR(cpuf)], CAMPO_CPUID_OBTER_POSICAO(cpuf), CAMPO_CPUID_OBTER_COMPRIMENTO(cpuf));
}

// Obter campo CPUID.
INLINE uint32_t    obterCampoCPUID(CAMPO_CPUID cpuf)
{
    uint32_t buffer[4];
    obterInfoCPUIDExt(buffer, CAMPO_CPUID_OBTER_FUNCAO(cpuf), CAMPO_CPUID_OBTER_SUBFUNCAO(cpuf));
    return obterCampoCPUID_buffer(buffer, cpuf);
}

////////////////////////////////////////
// Funções de suporte.
////////////////////////////////////////

// Níveis de suporte para o conjunto de instruções SSE. Valor de retorno de `nivelSuporteSSE`.
#define SIMD_SSE_NENHUM    0    // Não suportado.
#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

// Níveis de suporte para o conjunto de instruções AVX. Valor de retorno de `nivelSuporteAVX`.
#define SIMD_AVX_NENHUM    0    // Não suportado
#define SIMD_AVX_1    1    // AVX
#define SIMD_AVX_2    2    // AVX2

// Obter nome do fabricante da CPU.
//
// Retorno: Comprimento da string em caso de sucesso (geralmente 12). 0 em caso de falha.
// nomeFornecedor: Buffer para a string do nome do fabricante. Mínimo de 13 bytes.
INLINE int obterNomeFabricanteCPU(char* nomeFornecedor)
{
    uint32_t infoCPU[4];
    if (NULL==nomeFornecedor)    return 0;
    // Função 0: ID do Fabricante e Maior Função Padrão
    obterInfoCPUID(infoCPU, 0);
    // Salvar em nomeFornecedor
    *(uint32_t *)&nomeFornecedor[0] = infoCPU[1];    // ebx: primeiros quatro caracteres.
    *(uint32_t *)&nomeFornecedor[4] = infoCPU[3];    // edx: quatro caracteres do meio.
    *(uint32_t *)&nomeFornecedor[8] = infoCPU[2];    // ecx: últimos quatro caracteres.
    nomeFornecedor[12] = '\0';
    return 12;
}

// Obter nome da marca da CPU.
//
// Retorno: Comprimento da string em caso de sucesso (geralmente 48). 0 em caso de falha.
// nomeMarca: Buffer para a string do nome da marca. Mínimo de 49 bytes.
INLINE int obterNomeMarcaCPU(char* nomeMarca)
{
    uint32_t infoCPU[4];
    if (NULL==nomeMarca)    return 0;
    // Função 0x80000000: Maior Número de Função Estendida
    obterInfoCPUID(infoCPU, 0x80000000U);
    if (infoCPU[0] < 0x80000004U)    return 0;
    // Funções 80000002h, 80000003h, 80000004h: String da Marca do Processador
    obterInfoCPUID((uint32_t *)&nomeMarca[0], 0x80000002U);    // Primeiros 16 caracteres.
    obterInfoCPUID((uint32_t *)&nomeMarca[16], 0x80000003U);    // 16 caracteres do meio.
    obterInfoCPUID((uint32_t *)&nomeMarca[32], 0x80000004U);    // Últimos 16 caracteres.
    nomeMarca[48] = '\0';
    return 48;
}

// Verifica se o conjunto de instruções MMX é suportado.
//
// Retorno: Nível de suporte do sistema operacional para MMX. Diferente de 0 indica suporte, 0 indica não suportado.
// ptrHardwareMMX: Nível de suporte do hardware para MMX. Diferente de 0 indica suporte, 0 indica não suportado.
INLINE int nivelSuporteMMX(int* ptrHardwareMMX)
{
    int    resultado = 0;    // Valor de retorno
    #ifdef CCPUID_X86
        const uint32_t    BIT_D_MMX = 0x00800000;    // bit 23
        uint32_t infoCPU[4];

        // Verificar suporte do processador
        obterInfoCPUID(infoCPU, 1);    // Função 1: Informações de Recurso
        if ( infoCPU[3] & BIT_D_MMX )    resultado=1;
        if (NULL!=ptrHardwareMMX)    *ptrHardwareMMX=resultado;

        // Verificar suporte do SO (ignorados em C puro devido à falta de tratamento de exceções estruturado)
        #if defined(__cplusplus)
            if ( resultado )
            {
                #if defined(_M_X64) && defined(_MSC_VER) && !defined(__INTEL_COMPILER)
                    // Compilador VC não suporta MMX em 64 bits.
                    resultado=0;
                #else
                    try
                    {
                        _mm_empty();    // Instrução MMX: emms
                    }
                    catch(...)
                    {
                        resultado=0;
                    }
                #endif    // #if defined(_M_X64) && defined(_MSC_VER)
            }
        #endif    // #if defined(__cplusplus)
    #else    // #ifdef CCPUID_X86
        if (NULL!=ptrHardwareMMX)    *ptrHardwareMMX=resultado;
    #endif    // #ifdef CCPUID_X86
    return resultado;
}

// Detecta o nível de suporte para o conjunto de instruções SSE.
//
// Retorno: Nível de suporte do sistema operacional para SSE. Consulte as constantes SIMD_SSE_.
// ptrHardwareSSE: Nível de suporte do hardware para SSE. Consulte as constantes SIMD_SSE_.
INLINE int nivelSuporteSSE(int* ptrHardwareSSE)
{
    int    resultado = SIMD_SSE_NENHUM;    // Valor de retorno
    #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 infoCPU[4];

        // Verificar suporte do processador
        obterInfoCPUID(infoCPU, 1);    // Função 1: Informações de Recurso
        if ( infoCPU[3] & BIT_D_SSE )
        {
            resultado = SIMD_SSE_1;
            if ( infoCPU[3] & BIT_D_SSE2 )
            {
                resultado = SIMD_SSE_2;
                if ( infoCPU[2] & BIT_C_SSE3 )
                {
                    resultado = SIMD_SSE_3;
                    if ( infoCPU[2] & BIT_C_SSSE3 )
                    {
                        resultado = SIMD_SSE_3S;
                        if ( infoCPU[2] & BIT_C_SSE41 )
                        {
                            resultado = SIMD_SSE_41;
                            if ( infoCPU[2] & BIT_C_SSE42 )
                            {
                                resultado = SIMD_SSE_42;
                            }
                        }
                    }
                }
            }
        }
        if (NULL!=ptrHardwareSSE)    *ptrHardwareSSE=resultado;

        // Verificar suporte do SO (ignorados em C puro)
        #if defined(__cplusplus)
            try
            {
                __m128 xmm1 = _mm_setzero_ps();    // Instrução SSE: xorps
                int* pxmm1 = (int*)&xmm1;    // Evitar aviso -Wstrict-aliasing do GCC.
                if (0!=*pxmm1)    resultado = SIMD_SSE_NENHUM;    // Evitar otimização do _mm_setzero_ps em modo Release.
            }
            catch(...)
            {
                resultado = SIMD_SSE_NENHUM;
            }
        #endif    // #if defined(__cplusplus)
    #else    // #ifdef CCPUID_X86
        if (NULL!=ptrHardwareSSE)    *ptrHardwareSSE=resultado;
    #endif    // #ifdef CCPUID_X86
    return resultado;
}

// Detecta o nível de suporte para o conjunto de instruções AVX.
//
// Retorno: Nível de suporte do sistema operacional para AVX. Consulte as constantes SIMD_AVX_.
// ptrHardwareAVX: Nível de suporte do hardware para AVX. Consulte as constantes SIMD_AVX_.
INLINE int nivelSuporteAVX(int* ptrHardwareAVX)
{
    int    resultado = SIMD_AVX_NENHUM;    // Valor de retorno
    #ifdef CCPUID_X86
        // Verificar suporte do processador
        if (0!=obterCampoCPUID(CPUF_AVX))
        {
            resultado = SIMD_AVX_1;
            if (0!=obterCampoCPUID(CPUF_AVX2))
            {
                resultado = SIMD_AVX_2;
            }
        }
        if (NULL!=ptrHardwareAVX)    *ptrHardwareAVX=resultado;

        // Verificar suporte do SO
        if (0!=obterCampoCPUID(CPUF_OSXSAVE))    // XGETBV habilitado para uso da aplicação.
        {
            uint32_t n = obterCampoCPUID(CPUF_XFeatureSupportedMaskLo);    // XCR0: Registrador XFeatureSupportedMask.
            if (6!=(n&6))    // XCR0[2:1] = ‘11b’ (estado XMM e YMM habilitados pelo SO).
            {
                resultado = SIMD_AVX_NENHUM;
            }
        }
    #else    // #ifdef CCPUID_X86
        if (NULL!=ptrHardwareAVX)    *ptrHardwareAVX=resultado;
    #endif    // #ifdef CCPUID_X86
    return resultado;
}

#if defined __cplusplus
};
#endif

#endif    // #ifndef __CCPUID_H_INCLUDED

2.2 testccpuidc.c: Teste do ccpuid.h (C Puro)

#include <stdio.h>

#include "ccpuid.h"

// Obter a largura do programa em bits (32 ou 64).
int obterBitsPrograma()
{
    return sizeof(int*) * 8;
}

int main(int argc, char* argv[])
{
    char bufferMarca[64];
    int hardwareMMXSuportado;    // Suporte de hardware para MMX.
    int mmxSuportadoPeloSO;    // Suporte do SO para MMX.
    int nivelHardwareSSE;    // Nível de suporte de hardware para SSE.
    int nivelSsePeloSO;    // Nível de suporte do SO para SSE.
    int nivelHardwareAVX;    // Nível de suporte de hardware para AVX.
    int nivelAvxPeloSO;    // Nível de suporte do SO para AVX.

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

    // Informações básicas
    obterNomeFabricanteCPU(bufferMarca);
    printf("Fabricante da CPU:\t%s\n", bufferMarca);
    obterNomeMarcaCPU(bufferMarca);
    printf("Marca da CPU:\t%s\n", bufferMarca);
    printf("Função Padrão Máxima:\t%.8Xh\n", obterCampoCPUID(CPUF_LFuncStd));
    printf("Função Estendida Máxima:\t%.8Xh\n", obterCampoCPUID(CPUF_LFuncExt));

    // MMX
    mmxSuportadoPeloSO = nivelSuporteMMX(&hardwareMMXSuportado);
    printf("MMX: %d\t// hw: %d\n", mmxSuportadoPeloSO, hardwareMMXSuportado);

    // SSE
    nivelSsePeloSO = nivelSuporteSSE(&nivelHardwareSSE);
    printf("SSE: %d\t// hw: %d\n", nivelSsePeloSO, nivelHardwareSSE);

    // AVX
    nivelAvxPeloSO = nivelSuporteAVX(&nivelHardwareAVX);
    printf("AVX: %d\t// hw: %d\n", nivelAvxPeloSO, nivelHardwareAVX);

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

    return 0;
}

2.3 ccpuid.hpp: Informações CPUID (Cabeçalho C++)

#ifndef __CCPUID_HPP_INCLUDED
#define __CCPUID_HPP_INCLUDED

#include "ccpuid.h"

////////////////////////////////////////
// Definição de estruturas
////////////////////////////////////////

#if defined __cplusplus
extern "C" {
#endif

#define MAX_INFOS_CPUID    0x100    // Número máximo de entradas de InformacaoCPUID na classe CCPUID.

#if defined __cplusplus
};
#endif


////////////////////////////////////////
// Definição da classe
////////////////////////////////////////

// Classe utilitária para CPUID.
class CCPUID{
public:
    enum {
        ComprimentoDescCPUF = 296    // Comprimento do array de descrições dos campos CPUIDFIELD.
    };
    static const DescCampoCPUID    DescCPUF[ComprimentoDescCPUF];    // Array de descrições dos campos CPUIDFIELD.
    static const char*    DescricoesCache[0x100];    // Array de descrições de cache.
    static const char*    NomesSSE[7];    // Nomes dos níveis SSE.
    static const char*    NomesAVX[3];    // Nomes dos níveis AVX.
    
    InformacaoCPUID    Informacoes[MAX_INFOS_CPUID+1];    // Array de informações CPUID.

    CCPUID();
    static CCPUID& instanciaAtual() { if(0==_instanciaAtual._contagemInfos){ _instanciaAtual.atualizarTudo(); } return _instanciaAtual; }    // Instância CCPUID do processador atual.
    int ContagemInfos() const { return _contagemInfos; }    // Número de itens válidos no array Informacoes.
    void atualizarInfos();    // Atualiza as informações.
    void atualizarPropriedades();    // Atualiza as propriedades.
    void atualizarTudo();    // Atualiza todas as informações e propriedades.
    PC_InformacaoCPUID obterInfo(uint32_t tipoInfo, uint32_t valorECX=0) const;    // Obtém uma informação.
    void obterDados(uint32_t infoCPU[4], uint32_t tipoInfo, uint32_t valorECX=0) const;    // Obtém os dados.
    uint32_t obterCampo(CAMPO_CPUID cpuf) const;    // Obtém o campo CPUID.
    // Propriedades
    uint32_t FuncaoPadraoMaxima() const { return _funcMaxPadrao; }    // Maior número de função padrão.
    uint32_t FuncaoEstendidaMaxima() const { return _funcMaxEstendida; }    // Maior número de função estendida.
    const char* Fabricante() const { return _nomeFornecedor; }    // Fabricante.
    const char* Marca() const { return _nomeMarca; }    // Marca.
    const char* MarcaFormatada() const { return _nomeMarcaFormatada; }    // Marca sem espaços iniciais.
    int suporteMMX() const { return _suporteMMX; }    // Suporte do sistema para MMX.
    int suporteHardwareMMX() const { return _suporteHardwareMMX; }    // Suporte de hardware para MMX.
    int suporteSSE() const { return _suporteSSE; }    // Suporte do sistema para SSE.
    int suporteHardwareSSE() const { return _suporteHardwareSSE; }    // Suporte de hardware para SSE.
    int suporteAVX() const { return _suporteAVX; }    // Suporte do sistema para AVX.
    int suporteHardwareAVX() const { return _suporteHardwareAVX; }    // Suporte de hardware para AVX.

private:
    static CCPUID _instanciaAtual;    // Instância CCPUID do processador atual. Para uso diário.

    int _contagemInfos;    // Número de itens válidos no array Informacoes.

    // Propriedades
    uint32_t _funcMaxPadrao;    // Maior número de função padrão.
    uint32_t _funcMaxEstendida;    // Maior número de função estendida.
    char _nomeFornecedor[13];    // Fabricante.
    char _nomeMarca[49];    // Marca.
    const char* _nomeMarcaFormatada;    // Marca sem espaços iniciais.
    int _suporteMMX;    // Suporte do sistema para MMX.
    int _suporteHardwareMMX;    // Suporte de hardware para MMX.
    int _suporteSSE;    // Suporte do sistema para SSE.
    int _suporteHardwareSSE;    // Suporte de hardware para SSE.
    int _suporteAVX;    // Suporte do sistema para AVX.
    int _suporteHardwareAVX;    // Suporte de hardware para AVX.

    void atualizarInfos_Adicionar(uint32_t fid, uint32_t fidsub, uint32_t infoCPU[4]);
    int    nivelSuporteMMX_Privado(int* ptrHardwareMMX) const;
    int    nivelSuporteSSE_Privado(int* ptrHardwareSSE) const;
    int    nivelSuporteAVX_Privado(int* ptrHardwareAVX) const;

};

#endif    // #ifndef __CCPUID_HPP_INCLUDED

2.4 ccpuid.cpp: Informações CPUID (Arquivo Fonte C++)

#include "ccpuid.hpp"

CCPUID CCPUID::_instanciaAtual;

const DescCampoCPUID CCPUID::DescCPUF[] = {
    {CPUF_LFuncStd, 0, "FuncaoPadraoMaxima", "Maior função padrão."}
    ,{CPUF_Stepping, 0, "Stepping", "Stepping do processador."}
    ,{CPUF_BaseModel, 0, "ModeloBase", "Modelo base do processador."}
    ,{CPUF_BaseFamily, 0, "FamiliaBase", "Família base do processador."}
    ,{CPUF_ProcessorType, 0, "TipoProcessador", "Tipo de processador."}
    ,{CPUF_ExtModel, 0, "ModeloEstendido", "Modelo estendido do processador."}
    ,{CPUF_ExtFamily, 0, "FamiliaEstendida", "Família estendida do processador."}
    ,{CPUF_BrandId8, 0, "BrandId8", "ID de marca de 8 bits."}
    ,{CPUF_CLFlush, 0, "CLFlush", "Tamanho da linha CLFLUSH. (*8)"}
    ,{CPUF_MaxApicId, 0, "MaxApicId", "Número máximo de IDs endereçáveis para processadores lógicos neste pacote físico."}
    ,{CPUF_ApicId, 0, "ApicId", "ID físico APIC local inicial (8 bits)."}
    ,{CPUF_SSE3, 0, "SSE3", "Streaming SIMD Extensions 3."}
    ,{CPUF_PCLMULQDQ, 0, "PCLMULQDQ", "Instrução PCLMULQDQ."}
    ,{CPUF_DTES64, 0, "DTES64", "Área DS de 64 bits."}
    ,{CPUF_MONITOR, 0, "MONITOR", "Instruções MONITOR/MWAIT."}
    ,{CPUF_DS_CPL, 0, "DS_CPL", "Debug Store qualificado por CPL."}
    ,{CPUF_VMX, 0, "VMX", "Virtual Machine Extensions."}
    ,{CPUF_SMX, 0, "SMX", "Safer Mode Extensions."}
    ,{CPUF_EIST, 0, "EIST", "Tecnologia Enhanced Intel SpeedStep."}
    ,{CPUF_TM2, 0, "TM2", "Thermal Monitor 2."}
    ,{CPUF_SSSE3, 0, "SSSE3", "Supplemental Streaming SIMD Extensions 3 (SSSE3)."}
    ,{CPUF_CNXT_ID, 0, "CNXT_ID", "ID de contexto L1."}
    ,{CPUF_FMA, 0, "FMA", "Suporta extensões FMA usando o estado YMM."}
    ,{CPUF_CX16, 0, "CX16", "Instrução CMPXCHG16B."}
    ,{CPUF_xTPR, 0, "xTPR", "Controle de atualização xTPR. Pode desativar o envio de mensagens de prioridade de tarefa."}
    ,{CPUF_PDCM, 0, "PDCM", "Capacidade de Perfmon e Debug."}
    ,{CPUF_PCID, 0, "PCID", "Identificadores de Contexto de Processo."}
    ,{CPUF_DCA, 0, "DCA", "Acesso Direto à Cache."}
    ,{CPUF_SSE41, 0, "SSE41", "Instruções SSE4.1."}
    ,{CPUF_SSE42, 0, "SSE42", "Instruções SSE4.2."}
    ,{CPUF_x2APIC, 0, "x2APIC", "Suporte xAPIC Estendido."}
    ,{CPUF_MOVBE, 0, "MOVBE", "Instrução MOVBE."}
    ,{CPUF_POPCNT, 0, "POPCNT", "Instrução POPCNT."}
    ,{CPUF_TSC_DEADLINE, 0, "TSC_DEADLINE", "O temporizador APIC local suporta operação de disparo único usando um valor de deadline TSC."}
    ,{CPUF_AES, 0, "AES", "Instruções de Padrão de Criptografia Avançado (AES)."}
    ,{CPUF_XSAVE, 0, "XSAVE", "As instruções XSAVE (e relacionadas) são suportadas por hardware."}
    ,{CPUF_OSXSAVE, 0, "OSXSAVE", "As instruções XSAVE (e relacionadas) estão habilitadas."}
    ,{CPUF_AVX, 0, "AVX", "Instruções AVX."}
    ,{CPUF_F16C, 0, "F16C", "Suporte a instruções de conversão de meia-precisão."}
    ,{CPUF_RDRAND, 0, "RDRAND", "Instrução RDRAND."}
    ,{CPUF_FPU, 0, "FPU", "Unidade de Ponto Flutuante On-Chip."}
    ,{CPUF_VME, 0, "VME", "Aprimoramentos do Modo Virtual 8086."}
    ,{CPUF_DE, 0, "DE", "Extensões de Depuração."}
    ,{CPUF_PSE, 0, "PSE", "Page Size Extension."}
    ,{CPUF_TSC, 0, "TSC", "Time Stamp Counter."}
    ,{CPUF_MSR, 0, "MSR", "Registradores Específicos do Modelo, Instruções RDMSR e WRMSR."}
    ,{CPUF_PAE, 0, "PAE", "Physical Address Extension."}
    ,{CPUF_MCE, 0, "MCE", "Machine Check Exception."}
    ,{CPUF_CX8, 0, "CX8", "Instrução CMPXCHG8B."}
    ,{CPUF_APIC, 0, "APIC", "APIC (Advanced Programmable Interrupt Controller) On-Chip."}
    ,{CPUF_SEP, 0, "SEP", "Instruções de Chamada de Sistema Rápida, SYSENTER e SYSEXIT."}
    ,{CPUF_MTRR, 0, "MTRR", "Registradores de Intervalo de Tipo de Memória."}
    ,{CPUF_PGE, 0, "PGE", "Page Global Enable."}
    ,{CPUF_MCA, 0, "MCA", "Machine-Check Architecture."}
    ,{CPUF_CMOV, 0, "CMOV", "Instruções de Movimento Condicional."}
    ,{CPUF_PAT, 0, "PAT", "Page Attribute Table."}
    ,{CPUF_PSE36, 0, "PSE36", "Page Size Extension de 36 bits."}
    ,{CPUF_PSN, 0, "PSN", "Número de Série do Processador."}
    ,{CPUF_CLFSH, 0, "CLFSH", "Instrução CLFLUSH."}
    ,{CPUF_DS, 0, "DS", "Debug Store."}
    ,{CPUF_ACPI, 0, "ACPI", "Monitor Térmico e Facilidades de Clock Controladas por Software."}
    ,{CPUF_MMX, 0, "MMX", "Instruções MMX."}
    ,{CPUF_FXSR, 0, "FXSR", "Instruções FXSAVE e FXRSTOR."}
    ,{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", "Campo reservado para IDs APIC Máximos é válido."}
    ,{CPUF_TM, 0, "TM", "Thermal Monitor."}
    ,{CPUF_PBE, 0, "PBE", "Pending Break Enable."}
    ,{CPUF_Cache_Type, 0, "TipoCache", "Tipo de Cache (0=Nulo, 1=Dados, 2=Instruções, 3=Unificado)."}
    ,{CPUF_Cache_Level, 0, "NivelCache", "Nível de Cache (Começa em 1)."}
    ,{CPUF_CACHE_SI, 0, "CACHE_SI", "Nível de cache auto inicializável."}
    ,{CPUF_CACHE_FA, 0, "CACHE_FA", "Cache totalmente associativo."}
    ,{CPUF_MaxApicIdShare, 0, "MaxApicIdCompartilhado", "Número máximo de IDs endereçáveis para processadores lógicos que compartilham esta cache (codificação +1)."}
    ,{CPUF_MaxApicIdCore, 0, "MaxApicIdCore", "Número máximo de IDs endereçáveis para núcleos de processador no pacote físico (codificação +1)."}
    ,{CPUF_Cache_LineSize, 0, "TamanhoLinhaCache", "Tamanho da Linha de Coerência do Sistema (codificação +1)."}
    ,{CPUF_Cache_Partitions, 0, "ParticoesCache", "Partições Físicas de Linha (codificação +1)."}
    ,{CPUF_Cache_Ways, 0, "ViasCache", "Vias de Associatividade (codificação +1)."}
    ,{CPUF_Cache_Sets, 0, "ConjuntosCache", "Número de Conjuntos (codificação +1)."}
    ,{CPUF_CACHE_INVD, 0, "CACHE_INVD", "Comportamento WBINVD/INVD em caches de nível inferior."}
    ,{CPUF_CACHE_INCLUSIVENESS, 0, "CACHE_INCLUSIVA", "Cache é inclusiva de níveis de cache inferiores."}
    ,{CPUF_CACHE_COMPLEXINDEX, 0, "CACHE_INDEXACAO_COMPLEXA", "Indexação de Cache Complexa."}
    ,{CPUF_MonLineSizeMin, 0, "MonTamanhoLinhaMin", "Menor tamanho de linha de monitoramento em bytes."}
    ,{CPUF_MonLineSizeMax, 0, "MonTamanhoLinhaMax", "Maior tamanho de linha de monitoramento em bytes."}
    ,{CPUF_EMX, 0, "EMX", "Enumerar extensões MONITOR/MWAIT."}
    ,{CPUF_IBE, 0, "IBE", "Interrupt Break-Event."}
    ,{CPUF_MWAIT_Number_C0, 0, "MWAIT_Num_C0", "Número de sub-estados C0 suportados usando MWAIT."}
    ,{CPUF_MWAIT_Number_C1, 0, "MWAIT_Num_C1", "Número de sub-estados C1 suportados usando MWAIT."}
    ,{CPUF_MWAIT_Number_C2, 0, "MWAIT_Num_C2", "Número de sub-estados C2 suportados usando MWAIT."}
    ,{CPUF_MWAIT_Number_C3, 0, "MWAIT_Num_C3", "Número de sub-estados C3 suportados usando MWAIT."}
    ,{CPUF_MWAIT_Number_C4, 0, "MWAIT_Num_C4", "Número de sub-estados C4 suportados usando MWAIT."}
    ,{CPUF_DTS, 0, "DTS", "Sensor Térmico Digital."}
    ,{CPUF_TURBO_BOOST, 0, "TURBO_BOOST", "Tecnologia Intel Turbo Boost."}
    ,{CPUF_ARAT, 0, "ARAT", "Temporizador APIC Sempre Ativo."}
    ,{CPUF_PLN, 0, "PLN", "Notificação de Limite de Energia."}
    ,{CPUF_ECMD, 0, "ECMD", "Ciclo de Modulação de Clock Estendido."}
    ,{CPUF_PTM, 0, "PTM", "Gerenciamento Térmico do Pacote."}
    ,{CPUF_DTS_ITs, 0, "DTS_ITs", "Número de Limiares de Interrupção no Sensor Térmico Digital."}
    ,{CPUF_PERF, 0, "PERF", "Capacidade de Feedback de Coordenação de Hardware."}
    ,{CPUF_ACNT2, 0, "ACNT2", "Capacidade ACNT2."}
    ,{CPUF_ENERGY_PERF_BIAS, 0, "ENERGY_PERF_BIAS", "Capacidade de Otimização de Desempenho-Energia."}
    ,{CPUF_Max07Subleaf, 0, "MaxSubfolha07", "Reporta o máximo de subfolhas da folha 7 suportadas."}
    ,{CPUF_FSGSBASE, 0, "FSGSBASE", "Suporta RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE."}
    ,{CPUF_TSC_ADJUST, 0, "TSC_ADJUST", "MSR IA32_TSC_ADJUST é suportado se 1."}
    ,{CPUF_BMI1, 0, "BMI1", "O primeiro grupo de extensões avançadas de manipulação de bits (ANDN, BEXTR, BLSI, BLSMK, BLSR, TZCNT)."}
    ,{CPUF_HLE, 0, "HLE", "Hardware Lock Elision."}
    ,{CPUF_AVX2, 0, "AVX2", "Instruções AVX2."}
    ,{CPUF_SMEP, 0, "SMEP", "Supervisor Mode Execution Protection."}
    ,{CPUF_BMI2, 0, "BMI2", "O segundo grupo de extensões avançadas de manipulação de bits (BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX)."}
    ,{CPUF_ERMS, 0, "ERMS", "Suporta Enhanced REP MOVSB/STOSB."}
    ,{CPUF_INVPCID, 0, "INVPCID", "Invalidar ID de Contexto do Processador."}
    ,{CPUF_RTM, 0, "RTM", "Restricted Transactional Memory."}
    ,{CPUF_RDSEED, 0, "RDSEED", "Instrução RDSEED."}
    ,{CPUF_ADX, 0, "ADX", "Instruções ADCX e ADOX."}
    ,{CPUF_SMAP, 0, "SMAP", "Supervisor Mode Access Prevention."}
    ,{CPUF_PLATFORM_DCA_CAP, 0, "PLATFORM_DCA_CAP", "Valor dos Bits MSR PLATFORM_DCA_CAP [31:0] (Offset 1F8h)."}
    ,{CPUF_APM_Version, 0, "APM_Versao", "ID de versão do monitoramento arquitetônico de desempenho."}
    ,{CPUF_APM_Counters, 0, "APM_Contadores", "Número de contadores de monitoramento de desempenho de propósito geral por processador lógico."}
    ,{CPUF_APM_Bits, 0, "APM_Bits", "Largura de bit dos contadores de monitoramento de desempenho de propósito geral."}
    ,{CPUF_APM_Length, 0, "APM_Comprimento", "Comprimento do vetor de bits EBX para enumerar eventos de monitoramento arquitetônico de desempenho."}
    ,{CPUF_APM_CC, 0, "APM_CC", "Evento de ciclo de núcleo não disponível se 1."}
    ,{CPUF_APM_IR, 0, "APM_IR", "Evento de instrução retirada não disponível se 1."}
    ,{CPUF_APM_RC, 0, "APM_RC", "Evento de ciclos de referência não disponível se 1."}
    ,{CPUF_APM_LLCR, 0, "APM_LLCR", "Evento de referência de cache de último nível não disponível se 1."}
    ,{CPUF_APM_LLCM, 0, "APM_LLCM", "Evento de falhas de cache de último nível não disponível se 1."}
    ,{CPUF_APM_BIR, 0, "APM_BIR", "Evento de instrução de desvio retirada não disponível se 1."}
    ,{CPUF_APM_BMR, 0, "APM_BMR", "Evento de desvio mal-predito retirado não disponível se 1."}
    ,{CPUF_APM_FC_Number, 0, "APM_FC_Numero", "Número de contadores de desempenho de função fixa."}
    ,{CPUF_APM_FC_Bits, 0, "APM_FC_Bits", "Largura de bit dos contadores de desempenho de função fixa."}
    ,{CPUF_Topology_Bits, 0, "Topologia_Bits", "Número de bits para deslocar à direita no ID x2APIC para obter um ID de topologia exclusivo do próximo tipo de nível."}
    ,{CPUF_Topology_Number, 0, "Topologia_Numero", "Número de processadores lógicos configurados de fábrica neste nível."}
    ,{CPUF_Topology_Level, 0, "Topologia_Nivel", "Número do nível. Mesmo valor na entrada ECX."}
    ,{CPUF_Topology_Type, 0, "Topologia_Tipo", "Tipo de Nível (0=Inválido, 1=Thread, 2=Core)."}
    ,{CPUF_X2APICID, 0, "X2APICID", "ID x2APIC."}
    ,{CPUF_XFeatureSupportedMaskLo, 0, "XFeatureMaskSuportadaLo", "Os 32 bits inferiores de XCR0 (registrador XFEATURE_ENABLED_MASK)."}
    ,{CPUF_XFeatureEnabledSizeMax, 0, "XFeatureTamHabilitadoMax", "Tamanho em bytes da área XSAVE/XRSTOR para os recursos atualmente habilitados em XCR0."}
    ,{CPUF_XFeatureSupportedSizeMax, 0, "XFeatureTamSuportadoMax", "Tamanho em bytes da área XSAVE/XRSTOR para todos os recursos que o núcleo suporta."}
    ,{CPUF_XFeatureSupportedMaskHi, 0, "XFeatureMaskSuportadaHi", "Os 32 bits superiores de XCR0 (registrador XFEATURE_ENABLED_MASK)."}
    ,{CPUF_XSAVEOPT, 0, "XSAVEOPT", "XSAVEOPT está disponível."}
    ,{CPUF_YmmSaveStateSize, 0, "TamanhoEstadoSalvoYmm", "Tamanho em bytes do estado salvo YMM."}
    ,{CPUF_YmmSaveStateOffset, 0, "OffsetEstadoSalvoYmm", "Offset em bytes do estado salvo YMM."}
    ,{CPUF_LwpSaveStateSize, 0, "TamanhoEstadoSalvoLwp", "Tamanho em bytes do estado salvo LWP."}
    ,{CPUF_LwpSaveStateOffset, 0, "OffsetEstadoSalvoLwp", "Offset em bytes do estado salvo LWP."}
    ,{CPUF_LFuncExt, 0, "FuncaoEstendidaMaxima", "Maior função estendida."}
    ,{CPUF_BrandId16, 0, "BrandId16", "ID de Marca de 16 bits."}
    ,{CPUF_PkgType, 0, "TipoPacote", "Tipo de pacote (Family[7:0] >= 10h)."}
    ,{CPUF_LahfSahf, 0, "LahfSahf", "Suporte a instruções LAHF e SAHF em modo de 64 bits."}
    ,{CPUF_CmpLegacy, 0, "CmpLegado", "Modo legado de multi-processamento de núcleo."}
    ,{CPUF_SVM, 0, "SVM", "Máquina virtual segura."}
    ,{CPUF_ExtApicSpace, 0, "EspacoApicExtendido", "Espaço APIC estendido."}
    ,{CPUF_AltMovCr8, 0, "AltMovCr8", "LOCK MOV CR0 significa MOV CR8."}
    ,{CPUF_ABM, 0, "ABM", "Manipulação avançada de bits (LZCNT)."}
    ,{CPUF_SSE4A, 0, "SSE4A", "Instruções SSE4A."}
    ,{CPUF_MisAlignSse, 0, "MisAlignSse", "Modo SSE desalinhado."}
    ,{CPUF_3DNowPrefetch, 0, "3DNowPrefetch", "Suporte a instruções PREFETCH e PREFETCHW."}
    ,{CPUF_OSVW, 0, "OSVW", "Solução visível pelo SO."}
    ,{CPUF_IBS, 0, "IBS", "Amostragem baseada em instrução."}
    ,{CPUF_XOP, 0, "XOP", "Suporte a operação estendida."}
    ,{CPUF_SKINIT, 0, "SKINIT", "SKINIT e STGI são suportados, independente do valor de MSRC000_0080[SVME]."}
    ,{CPUF_WDT, 0, "WDT", "Suporte a temporizador watchdog."}
    ,{CPUF_LWP, 0, "LWP", "Suporte a perfil de peso leve."}
    ,{CPUF_FMA4, 0, "FMA4", "Suporte a instruções FMA de 4 operandos."}
    ,{CPUF_BIT_NODEID, 0, "BIT_NODEID", "Indica suporte para MSRC001_100C[NodeId, NodesPerProcessor]."}
    ,{CPUF_TBM, 0, "TBM", "Suporte a instruções de manipulação de bits finais."}
    ,{CPUF_TopologyExtensions, 0, "ExtensoesTopologia", "Suporte a extensões de topologia."}
    ,{CPUF_SYSCALL, 0, "SYSCALL", "Instruções SYSCALL e SYSRET."}
    ,{CPUF_XD, 0, "XD", "Execution Disable Bit."}
    ,{CPUF_MmxExt, 0, "MmxExt", "Extensões AMD para instruções MMX."}
    ,{CPUF_FFXSR, 0, "FFXSR", "Otimizações das instruções FXSAVE e FXRSTOR."}
    ,{CPUF_Page1GB, 0, "Pagina1GB", "Suporte a páginas grandes de 1 GB."}
    ,{CPUF_RDTSCP, 0, "RDTSCP", "RDTSCP e TSC_AUX."}
    ,{CPUF_LM, 0, "LM", "Modo longo de 64 bits (x86-64)."}
    ,{CPUF_3DNowExt, 0, "3DNowExt", "Extensões AMD para instruções 3DNow!."}
    ,{CPUF_3DNow, 0, "3DNow", "Instruções 3DNow!."}
    ,{CPUF_L1ITlb2and4MSize, 0, "TamL1ITlb2e4M", "Número de entradas TLB de Instrução L1 para páginas de 2 MB e 4 MB."}
    ,{CPUF_L1ITlb2and4MAssoc, 0, "AssocL1ITlb2e4M", "Associatividade TLB de Instrução L1 para páginas de 2 MB e 4 MB."}
    ,{CPUF_L1DTlb2and4MSize, 0, "TamL1DTlb2e4M", "Número de entradas TLB de Dados L1 para páginas de 2 MB e 4 MB."}
    ,{CPUF_L1DTlb2and4MAssoc, 0, "AssocL1DTlb2e4M", "Associatividade TLB de Dados L1 para páginas de 2 MB e 4 MB."}
    ,{CPUF_L1ITlb4KSize, 0, "TamL1ITlb4K", "Número de entradas TLB de Instrução L1 para páginas de 4 KB."}
    ,{CPUF_L1ITlb4KAssoc, 0, "AssocL1ITlb4K", "Associatividade TLB de Instrução L1 para páginas de 4KB."}
    ,{CPUF_L1DTlb4KSize, 0, "TamL1DTlb4K", "Número de entradas TLB de Dados L1 para páginas de 4 KB."}
    ,{CPUF_L1DTlb4KAssoc, 0, "AssocL1DTlb4K", "Associatividade TLB de Dados L1 para páginas de 4 KB."}
    ,{CPUF_L1DcLineSize, 0, "TamLinhaL1Dc", "Tamanho da linha de cache de dados L1 em bytes."}
    ,{CPUF_L1DcLinesPerTag, 0, "LinhasL1DcPorTag", "Linhas de cache de dados L1 por tag."}
    ,{CPUF_L1DcAssoc, 0, "AssocL1Dc", "Associatividade da cache de dados L1."}
    ,{CPUF_L1DcSize, 0, "TamL1Dc", "Tamanho da cache de dados L1 em KB."}
    ,{CPUF_L1IcLineSize, 0, "TamLinhaL1Ic", "Tamanho da linha de cache de instruções L1 em bytes"}
    ,{CPUF_L1IcLinesPerTag, 0, "LinhasL1IcPorTag", "Linhas de cache de instruções L1 por tag."}
    ,{CPUF_L1IcAssoc, 0, "AssocL1Ic", "Associatividade da cache de instruções L1."}
    ,{CPUF_L1IcSize, 0, "TamL1Ic", "Tamanho da cache de instruções L1 em KB."}
    ,{CPUF_L2ITlb2and4MSize, 0, "TamL2ITlb2e4M", "Número de entradas TLB de Instrução L2 para páginas de 2 MB e 4 MB."}
    ,{CPUF_L2ITlb2and4MAssoc, 0, "AssocL2ITlb2e4M", "Associatividade TLB de Instrução L2 para páginas de 2 MB e 4 MB."}
    ,{CPUF_L2DTlb2and4MSize, 0, "TamL2DTlb2e4M", "Número de entradas TLB de Dados L2 para páginas de 2 MB e 4 MB."}
    ,{CPUF_L2DTlb2and4MAssoc, 0, "AssocL2DTlb2e4M", "Associatividade TLB de Dados L2 para páginas de 2 MB e 4 MB."}
    ,{CPUF_L2ITlb4KSize, 0, "TamL2ITlb4K", "Número de entradas TLB de Instrução L2 para páginas de 4 KB."}
    ,{CPUF_L2ITlb4KAssoc, 0, "AssocL2ITlb4K", "Associatividade TLB de Instrução L2 para páginas de 4 KB."}
    ,{CPUF_L2DTlb4KSize, 0, "TamL2DTlb4K", "Número de entradas TLB de Dados L2 para páginas de 4 KB."}
    ,{CPUF_L2DTlb4KAssoc, 0, "AssocL2DTlb4K", "Associatividade TLB de Dados L2 para páginas de 4 KB."}
    ,{CPUF_L2LineSize, 0, "TamLinhaL2", "Tamanho da linha de cache L2 em bytes."}
    ,{CPUF_L2LinesPerTag, 0, "LinhasL2PorTag", "Linhas de cache L2 por tag."}
    ,{CPUF_L2Assoc, 0, "AssocL2", "Associatividade da cache L2."}
    ,{CPUF_L2Size, 0, "TamL2", "Tamanho da cache L2 em KB."}
    ,{CPUF_L3LineSize, 0, "TamLinhaL3", "Tamanho da linha de cache L3 em bytes."}
    ,{CPUF_L3LinesPerTag, 0, "LinhasL3PorTag", "Linhas de cache L3 por tag."}
    ,{CPUF_L3Assoc, 0, "AssocL3", "Associatividade da cache L3."}
    ,{CPUF_L3Size, 0, "TamL3", "Tamanho da cache L3."}
    ,{CPUF_TS, 0, "TS", "Sensor de temperatura."}
    ,{CPUF_FID, 0, "FID", "Controle de ID de frequência."}
    ,{CPUF_VID, 0, "VID", "Controle de ID de tensão."}
    ,{CPUF_TTP, 0, "TTP", "THERMTRIP."}
    ,{CPUF_HTC, 0, "HTC", "TM: Controle térmico de hardware (HTC)."}
    ,{CPUF_100MHzSteps, 0, "Passos100MHz", "Controle de multiplicador de 100 MHz."}
    ,{CPUF_HwPstate, 0, "HwPstate", "Controle de P-state de hardware."}
    ,{CPUF_TscInvariant, 0, "TscInvariante", "TSC invariante."}
    ,{CPUF_CPB, 0, "CPB", "Impulso de desempenho do núcleo."}
    ,{CPUF_EffFreqRO, 0, "FrequenciaEfetivaSO", "Interface de frequência efetiva somente leitura."}
    ,{CPUF_PhysAddrSize, 0, "TamEnderecoFisico", "Tamanho máximo do endereço físico em bytes em bits."}
    ,{CPUF_LinAddrSize, 0, "TamEnderecoLinear", "Tamanho máximo do endereço linear em bytes em bits."}
    ,{CPUF_GuestPhysAddrSize, 0, "TamEnderecoFisicoConvidado", "Tamanho máximo do endereço físico de convidado em bytes em bits."}
    ,{CPUF_NC, 0, "NC", "Número de núcleos físicos - 1."}
    ,{CPUF_ApicIdCoreIdSize, 0, "TamIdApicCoreId", "Tamanho do ID APIC. O número de bits no valor inicial APIC20[ApicId] que indicam o ID do núcleo dentro de um processador."}
    ,{CPUF_SvmRev, 0, "SvmRev", "Revisão SVM."}
    ,{CPUF_NASID, 0, "NASID", "Número de identificadores de espaço de endereço (ASID)."}
    ,{CPUF_NP, 0, "NP", "Paginação aninhada."}
    ,{CPUF_LbrVirt, 0, "LbrVirt", "Virtualização LBR."}
    ,{CPUF_SVML, 0, "SVML", "Bloqueio SVM. Indica suporte para SVM-Lock."}
    ,{CPUF_NRIPS, 0, "NRIPS", "Salvar NRIP. Indica suporte para salvar NRIP em #VMEXIT."}
    ,{CPUF_TscRateMsr, 0, "TscRateMsr", "Controle de taxa TSC baseado em MSR."}
    ,{CPUF_VmcbClean, 0, "VmcbClean", "Bits limpos VMCB. Indica suporte para bits limpos VMCB."}
    ,{CPUF_FlushByAsid, 0, "FlushByAsid", "Descarga por ASID."}
    ,{CPUF_DecodeAssists, 0, "DecodeAssists", "Auxiliares de decodificação."}
    ,{CPUF_PauseFilter, 0, "FiltroPausa", "Filtro de intercepção de pausa."}
    ,{CPUF_PauseFilterThreshold, 0, "LimiarFiltroPausa", "Limiar do filtro PAUSE."}
    ,{CPUF_L1ITlb1GSize, 0, "TamL1ITlb1G", "Número de entradas TLB de Instrução L1 para páginas de 1 GB."}
    ,{CPUF_L1ITlb1GAssoc, 0, "AssocL1ITlb1G", "Associatividade TLB de Instrução L1 para páginas de 1 GB."}
    ,{CPUF_L1DTlb1GSize, 0, "TamL1DTlb1G", "Número de entradas TLB de Dados L1 para páginas de 1 GB."}
    ,{CPUF_L1DTlb1GAssoc, 0, "AssocL1DTlb1G", "Associatividade TLB de Dados L1 para páginas de 1 GB."}
    ,{CPUF_L2ITlb1GSize, 0, "TamL2ITlb1G", "Número de entradas TLB de Instrução L2 para páginas de 1 GB."}
    ,{CPUF_L2ITlb1GAssoc, 0, "AssocL2ITlb1G", "Associatividade TLB de Instrução L2 para páginas de 1 GB."}
    ,{CPUF_L2DTlb1GSize, 0, "TamL2DTlb1G", "Número de entradas TLB de Dados L2 para páginas de 1 GB."}
    ,{CPUF_L2DTlb1GAssoc, 0, "AssocL2DTlb1G", "Associatividade TLB de Dados L2 para páginas de 1 GB."}
    ,{CPUF_FP128, 0, "FP128", "Instruções SSE (multimídia) de 128 bits são executadas com operações e pipelines internos de largura total, em vez de decompô-las em suboperações internas de 64 bits."}
    ,{CPUF_MOVU, 0, "MOVU", "Instruções MOVU SSE (multimídia) são mais eficientes e devem ser preferidas a SSE (multimídia) MOVL/MOVH. MOVUPS é mais eficiente que MOVLPS/MOVHPS."}
    ,{CPUF_IBSFFV, 0, "IBSFFV", "Flags de recurso IBS válidos."}
    ,{CPUF_FetchSam, 0, "FetchSam", "Amostragem de fetch IBS suportada."}
    ,{CPUF_OpSam, 0, "OpSam", "Amostragem de execução IBS suportada."}
    ,{CPUF_RdWrOpCnt, 0, "ContOpRdWr", "Leitura e escrita de contador de operações suportada."}
    ,{CPUF_OpCnt, 0, "ContOp", "Modo de contagem de operações suportado."}
    ,{CPUF_BrnTrgt, 0, "AlvoDesvio", "Reporte de endereço de alvo de desvio suportado."}
    ,{CPUF_OpCntExt, 0, "ContOpExt", "IbsOpCurCnt e IbsOpMaxCnt estendidos em 7 bits."}
    ,{CPUF_RipInvalidChk, 0, "VerifRipInvalido", "Indicação de RIP inválido suportada."}
    ,{CPUF_LwpAvail, 0, "LwpDisponivel", "LWP disponível."}
    ,{CPUF_LwpVAL, 0, "LwpVAL", "Instrução LWPVAL disponível."}
    ,{CPUF_LwpIRE, 0, "LwpIRE", "Evento de instruções retiradas disponível."}
    ,{CPUF_LwpBRE, 0, "LwpBRE", "Evento de desvio retirado disponível."}
    ,{CPUF_LwpDME, 0, "LwpDME", "Evento de falha de DC disponível."}
    ,{CPUF_LwpCNH, 0, "LwpCNH", "Evento de clocks de núcleo não parados disponível."}
    ,{CPUF_LwpRNH, 0, "LwpRNH", "Evento de clocks de referência de núcleo não parados disponível."}
    ,{CPUF_LwpInt, 0, "LwpInt", "Interrupção por estouro de limiar disponível."}
    ,{CPUF_LwpCbSize, 0, "TamBlocoControleLwp", "Tamanho do bloco de controle. Tamanho em bytes do LWPCB."}
    ,{CPUF_LwpEventSize, 0, "TamRegistroEventoLwp", "Tamanho do registro de evento. Tamanho em bytes de um registro de evento no buffer circular de eventos LWP."}
    ,{CPUF_LwpMaxEvents, 0, "LwpMaxEventos", "ID de Evento máximo. Valor máximo de EventId suportado."}
    ,{CPUF_LwpEventOffset, 0, "OffsetEventoLwp", "Offset do início do LWPCB para o campo EventInterval1."}
    ,{CPUF_LwpLatencyMax, 0, "LatenciaMaxLwp", "Tamanho em bits dos contadores de latência de cache."}
    ,{CPUF_LwpDataAddress, 0, "EnderecoDadosLwp", "Endereço de falha de cache de dados válido."}
    ,{CPUF_LwpLatencyRnd, 0, "LatenciaArredondadaLwp", "Quantidade de arredondamento da latência de cache."}
    ,{CPUF_LwpVersion, 0, "VersaoLwp", "Versão da implementação LWP."}
    ,{CPUF_LwpMinBufferSize, 0, "TamBufferMinLwp", "Tamanho mínimo do buffer circular de eventos LWP, em unidades de 32 registros de eventos."}
    ,{CPUF_LwpBranchPrediction, 0, "LwpPrevisaoDesvio", "Filtragem de previsão de desvio suportada."}
    ,{CPUF_LwpIpFiltering, 0, "LwpFiltragemIP", "Filtragem de IP suportada."}
    ,{CPUF_LwpCacheLevels, 0, "LwpNiveisCache", "Filtragem de nível de cache suportada."}
    ,{CPUF_LwpCacheLatency, 0, "LwpLatenciaCache", "Filtragem de latência de cache suportada."}
    ,{CPUF_D_LwpAvail, 0, "D_LwpDisponivel", "Perfil de peso leve suportado."}
    ,{CPUF_D_LwpVAL, 0, "D_LwpVAL", "Instrução LWPVAL suportada."}
    ,{CPUF_D_LwpIRE, 0, "D_LwpIRE", "Evento de instruções retiradas suportado."}
    ,{CPUF_D_LwpBRE, 0, "D_LwpBRE", "Evento de desvio retirado suportado."}
    ,{CPUF_D_LwpDME, 0, "D_LwpDME", "Evento de falha de DC suportado."}
    ,{CPUF_D_LwpCNH, 0, "D_LwpCNH", "Evento de clocks de núcleo não parados suportado."}
    ,{CPUF_D_LwpRNH, 0, "D_LwpRNH", "Evento de clocks de referência de núcleo não parados suportado."}
    ,{CPUF_D_LwpInt, 0, "D_LwpInt", "Interrupção por estouro de limiar suportada."}
    ,{CPUF_CacheType, 0, "TipoCache", "Tipo de Cache (0=Nulo, 1=Dados, 2=Instruções, 3=Unificado)."}
    ,{CPUF_CacheLevel, 0, "NivelCache", "Nível de Cache (Começa em 1)."}
    ,{CPUF_SelfInitialization, 0, "AutoInicializacao", "Nível de cache auto inicializável."}
    ,{CPUF_FullyAssociative, 0, "TotalmenteAssociativo", "Cache totalmente associativo."}
    ,{CPUF_NumSharingCache, 0, "NumCompartilhamentoCache", "Número de núcleos compartilhando cache. O número de núcleos compartilhando esta cache é NumSharingCache+1."}
    ,{CPUF_CacheLineSize, 0, "TamLinhaCache", "Tamanho da linha de cache em bytes (codificação +1)."}
    ,{CPUF_CachePhysPartitions, 0, "ParticoesFisicasCache", "Partições de linha física de cache (codificação +1)."}
    ,{CPUF_CacheNumWays, 0, "NumViasCache", "Número de vias de cache (codificação +1)."}
    ,{CPUF_CacheNumSets, 0, "NumConjuntosCache", "Número de conjuntos de cache (codificação +1)."}
    ,{CPUF_WBINVD, 0, "WBINVD", "Write-Back Invalidate/Invalidate (WBINVD/INVD)."}
    ,{CPUF_CacheInclusive, 0, "CacheInclusiva", "Cache inclusiva."}
    ,{CPUF_ExtendedApicId, 0, "IdApicEstendido", "ID APIC estendido."}
    ,{CPUF_ComputeUnitId, 0, "IdUnidadeComputacao", "ID da unidade de computação. Identifica o ID da unidade de computação do processador."}
    ,{CPUF_CoresPerComputeUnit, 0, "CoresPorUnidadeComputacao", "Núcleos por unidade de computação. O número de núcleos por unidade de computação é CoresPerComputeUnit+1."}
    ,{CPUF_NodeId, 0, "IdNo", "Especifica o ID do nó."}
    ,{CPUF_NodesPerProcessor, 0, "NosPorProcessador", "Especifica o número de nós por processador."}
};

const char*    CCPUID::DescricoesCache[] = {
    "Descritor nulo, este byte não contém informações"
    ,"ITLB: Páginas de 4 KB, 4-way set associative, 32 entradas"
    ,"ITLB: Páginas de 4 MB, fully associative, 2 entradas"
    ,"DTLB: Páginas de 4 KB, 4-way set associative, 64 entradas"
    ,"DTLB: Páginas de 4 MB, 4-way set associative, 8 entradas"
    ,"DTLB1: Páginas de 4 MB, 4-way set associative, 32 entradas"
    ,"Cache de instruções de 1º nível: 8 KBytes, 4-way set associative, tamanho de linha de 32 bytes"
    ,""
    ,"Cache de instruções de 1º nível: 16 KBytes, 4-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de instruções de 1º nível: 32 KBytes, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de dados de 1º nível: 8 KBytes, 2-way set associative, tamanho de linha de 32 bytes"
    ,"ITLB: Páginas de 4 MB, 4-way set associative, 4 entradas"
    ,"Cache de dados de 1º nível: 16 KBytes, 4-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de dados de 1º nível: 16 KBytes, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de dados de 1º nível: 24 KBytes, 6-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Cache de 2º nível: 256 KBytes, 8-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 512 KBytes, 4-way set associative, tamanho de linha de 64 bytes, 2 linhas por setor"
    ,"Cache de 3º nível: 1 MBytes, 8-way set associative, tamanho de linha de 64 bytes, 2 linhas por setor"
    ,""
    ,"Cache de 3º nível: 2 MBytes, 8-way set associative, tamanho de linha de 64 bytes, 2 linhas por setor"
    ,""
    ,""
    ,""
    ,"Cache de 3º nível: 4 MBytes, 8-way set associative, tamanho de linha de 64 bytes, 2 linhas por setor"
    ,""
    ,""
    ,"Cache de dados de 1º nível: 32 KBytes, 8-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,"Cache de instruções de 1º nível: 32 KBytes, 8-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Nenhuma cache de 2º nível ou, se o processador contém uma cache de 2º nível válida, nenhuma cache de 3º nível"
    ,"Cache de 2º nível: 128 KBytes, 4-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 2º nível: 256 KBytes, 4-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 2º nível: 512 KBytes, 4-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 2º nível: 1 MByte, 4-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 2º nível: 2 MByte, 4-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 3º nível: 4 MByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 8 MByte, 8-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 2º nível: 3 MByte, 12-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 4 MB, 16-way set associative, tamanho de linha de 64 bytes (processador Intel Xeon MP, Família 0FH, Modelo 06H); Cache de 2º nível: 4 MByte, 16-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 6 MByte, 12-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 8 MByte, 16-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 12 MByte, 12-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 16 MByte, 16-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 2º nível: 6 MByte, 24-way set associative, tamanho de linha de 64 bytes"
    ,"ITLB: Páginas de 4 KB, 32 entradas"
    ,"ITLB: Páginas de 4 KB e 2-MByte ou 4-MByte, 64 entradas"
    ,"ITLB: Páginas de 4 KB e 2-MByte ou 4-MByte, 128 entradas"
    ,"ITLB: Páginas de 4 KB e 2-MByte ou 4-MByte, 256 entradas"
    ,""
    ,""
    ,"ITLB: Páginas de 2-MByte ou 4-MByte, fully associative, 7 entradas"
    ,"DTLB0: Páginas de 4 MByte, 4-way set associative, 16 entradas"
    ,"DTLB0: Páginas de 4 KByte, 4-way associative, 16 entradas"
    ,"DTLB0: Páginas de 4 KByte, fully associative, 16 entradas"
    ,"DTLB0: Páginas de 2-MByte ou 4 MByte, 4-way set associative, 32 entradas"
    ,"DTLB: Páginas de 4 KByte e 4 MByte, 64 entradas"
    ,"DTLB: Páginas de 4 KByte e 4 MByte, 128 entradas"
    ,"DTLB: Páginas de 4 KByte e 4 MByte, 256 entradas"
    ,""
    ,""
    ,""
    ,"Cache de dados de 1º nível: 16 KByte, 8-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Cache de dados de 1º nível: 8 KByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de dados de 1º nível: 16 KByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de dados de 1º nível: 32 KByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Cache de rastreamento: 12 K-μop, 8-way set associative"
    ,"Cache de rastreamento: 16 K-μop, 8-way set associative"
    ,"Cache de rastreamento: 32 K-μop, 8-way set associative"
    ,""
    ,""
    ,""
    ,"ITLB: Páginas de 2M/4M, fully associative, 8 entradas"
    ,""
    ,"Cache de 2º nível: 1 MByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 2º nível: 128 KByte, 8-way set associative, tamanho de linha de 64 bytes, 2 linhas por setor"
    ,"Cache de 2º nível: 256 KByte, 8-way set associative, tamanho de linha de 64 bytes, 2 linhas por setor"
    ,"Cache de 2º nível: 512 KByte, 8-way set associative, tamanho de linha de 64 bytes, 2 linhas por setor"
    ,"Cache de 2º nível: 1 MByte, 8-way set associative, tamanho de linha de 64 bytes, 2 linhas por setor"
    ,"Cache de 2º nível: 2 MByte, 8-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,"Cache de 2º nível: 512 KByte, 2-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 2º nível: 512 KByte, 8-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,"Cache de 2º nível: 256 KByte, 8-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 2º nível: 512 KByte, 8-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 2º nível: 1 MByte, 8-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 2º nível: 2 MByte, 8-way set associative, tamanho de linha de 32 bytes"
    ,"Cache de 2º nível: 512 KByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 2º nível: 1 MByte, 8-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"ITLB: Páginas de 4 KB, 4-way set associative, 128 entradas"
    ,"ITLB: Páginas de 2M, 4-way, 8 entradas ou páginas de 4M, 4-way, 4 entradas"
    ,"ITLB: Páginas de 4KByte, 4-way set associative, 64 entradas"
    ,"DTLB: Páginas de 4 KB, 4-way set associative, 128 entradas"
    ,"DTLB1: Páginas de 4 KB, 4-way associative, 256 entradas"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"DTLB1: Páginas de 4 KB, 4-way associative, 64 entradas"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"DTLB: Páginas de 4 KB e 4 MByte, 4-way associative, 8 entradas"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"TLB de 2º Nível Compartilhado: Páginas de 4 KB, 4-way associative, 512 entradas"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Cache de 3º nível: 512 KByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 1 MByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 2 MByte, 4-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,"Cache de 3º nível: 1 MByte, 8-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 2 MByte, 8-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 4 MByte, 8-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,"Cache de 3º nível: 1.5 MByte, 12-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 3 MByte, 12-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 6 MByte, 12-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,"Cache de 3º nível: 2 MByte, 16-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 4 MByte, 16-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 8 MByte, 16-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"Cache de 3º nível: 12 MByte, 24-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 18 MByte, 24-way set associative, tamanho de linha de 64 bytes"
    ,"Cache de 3º nível: 24 MByte, 24-way set associative, tamanho de linha de 64 bytes"
    ,""
    ,""
    ,""
    ,"Prefetch de 64 bytes"
    ,"Prefetch de 128 bytes"
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,""
    ,"A folha 2 do CPUID não reporta informações de descritor de cache, use a folha 4 do CPUID para consultar parâmetros de cache"
};

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

const char*    CCPUID::NomesAVX[] = {
    "Nenhum",
    "AVX",
    "AVX2"
};


////////////////////////////////////////////////////////////
// Implementação da classe CCPUID
////////////////////////////////////////////////////////////

// Construtor.
CCPUID::CCPUID()
    :_contagemInfos(0), _funcMaxPadrao(0), _funcMaxEstendida(0), _nomeMarcaFormatada(0)
{
    _nomeFornecedor[0] = '\0';
    _nomeMarca[0] = '\0';
}

// Atualiza as informações. Adiciona um item ao array Informacoes.
void CCPUID::atualizarInfos_Adicionar(uint32_t fid, uint32_t fidsub, uint32_t infoCPU[4])
{
    if (_contagemInfos>=MAX_INFOS_CPUID)    return;
    Informacoes[_contagemInfos].funcaoID = fid;
    Informacoes[_contagemInfos].subfuncaoID = fidsub;
    Informacoes[_contagemInfos].registros[0] = infoCPU[0];
    Informacoes[_contagemInfos].registros[1] = infoCPU[1];
    Informacoes[_contagemInfos].registros[2] = infoCPU[2];
    Informacoes[_contagemInfos].registros[3] = infoCPU[3];
    ++_contagemInfos;
}

// Atualiza as informações.
void CCPUID::atualizarInfos()
{
    uint32_t bufferCPU[4];
    uint32_t maxFuncao;
    uint32_t idx, subIdx;

    // == Salva informações CPUID no array Informacoes ==
    _contagemInfos = 0;

    // Funções padrão.
    obterInfoCPUID(bufferCPU, 0);
    atualizarInfos_Adicionar(0, 0, bufferCPU);
    maxFuncao = bufferCPU[0];    // CPUID(0).EAX[31:0]=FuncaoPadraoMaxima
    _funcMaxPadrao = maxFuncao;
    for(idx=1; idx<=maxFuncao; ++idx)
    {
        obterInfoCPUIDExt(bufferCPU, idx, 0);
        atualizarInfos_Adicionar(idx, 0, bufferCPU);
        // subfuncao
        if (0x4==idx)    // Parâmetros de Cache Determinísticos (Função 04h)
        {
            subIdx=1;
            while(true)
            {
                obterInfoCPUIDExt(bufferCPU, idx, subIdx);
                if (0==(bufferCPU[0]&0x1F))    break;    // EAX[4:0]=TipoCache
                atualizarInfos_Adicionar(idx, subIdx, bufferCPU);
                // próximo
                ++subIdx;
            }
        }
        else if (0xB==idx)    // Recursos x2APIC / Topologia do Processador (Função 0Bh)
        {
            subIdx=1;
            while(true)
            {
                obterInfoCPUIDExt(bufferCPU, idx, subIdx);
                if (0==bufferCPU[0] && 0==bufferCPU[1])    break;    // até EAX=0 e EBX=0
                atualizarInfos_Adicionar(idx, subIdx, bufferCPU);
                // próximo
                ++subIdx;
            }
        }
        else if (0xD==idx)    // Recursos XSAVE (Função 0Dh)
        {
            // subfuncao = 1
            subIdx=1;
            obterInfoCPUIDExt(bufferCPU, idx, subIdx);
            atualizarInfos_Adicionar(idx, subIdx, bufferCPU);
            // subfuncao >= 2
            for(subIdx=2; subIdx<=63; ++subIdx)
            {
                obterInfoCPUIDExt(bufferCPU, idx, subIdx);
                if (0!=bufferCPU[0]
                    || 0!=bufferCPU[1]
                    || 0!=bufferCPU[2]
                    || 0!=bufferCPU[3])
                {
                    atualizarInfos_Adicionar(idx, subIdx, bufferCPU);
                }
            }
        }
    }

    // Funções estendidas.
    obterInfoCPUID(bufferCPU, 0x80000000U);
    atualizarInfos_Adicionar(0x80000000U, 0, bufferCPU);
    maxFuncao = bufferCPU[0];    // CPUID(0x80000000).EAX[31:0]=FuncaoEstendidaMaxima
    _funcMaxEstendida = maxFuncao;
    if (maxFuncao!=0)
    {
        for(idx=0x80000001U; idx<=maxFuncao; ++idx)
        {
            obterInfoCPUIDExt(bufferCPU, idx, 0);
            atualizarInfos_Adicionar(idx, 0, bufferCPU);
            // subfuncao
            if (0x8000001DU==idx)    // Propriedades de Cache (Função 8000001Dh)
            {
                subIdx=1;
                while(true)
                {
                    obterInfoCPUIDExt(bufferCPU, idx, subIdx);
                    if (0==(bufferCPU[0]&0x1F))    break;    // EAX[4:0]=TipoCache
                    atualizarInfos_Adicionar(idx, subIdx, bufferCPU);
                    // próximo
                    ++subIdx;
                }
            }
        }
    }

}

// Atualiza as propriedades.
void CCPUID::atualizarPropriedades()
{
    uint32_t bufferCPU[4];

    // Fabricante
    obterDados(bufferCPU, 0);    // Função 0: ID do Fabricante e Maior Função Padrão
    uint32_t* ptrFabricante = (uint32_t *)_nomeFornecedor;    // Evitar aviso -Wstrict-aliasing do GCC.
    ptrFabricante[0] = bufferCPU[1];    // ebx: primeiros quatro caracteres.
    ptrFabricante[1] = bufferCPU[3];    // edx: quatro caracteres do meio.
    ptrFabricante[2] = bufferCPU[2];    // ecx: últimos quatro caracteres.
    _nomeFornecedor[12] = '\0';

    // Marca
    _nomeMarca[0] = '\0';
    if (_funcMaxEstendida >= 0x80000004)
    {
        // Funções 80000002h, 80000003h, 80000004h: String da Marca do Processador
        obterDados((uint32_t *)&_nomeMarca[0], 0x80000002);    // Primeiros 16 caracteres.
        obterDados((uint32_t *)&_nomeMarca[16], 0x80000003);    // 16 caracteres do meio.
        obterDados((uint32_t *)&_nomeMarca[32], 0x80000004);    // Últimos 16 caracteres.
        _nomeMarca[48] = '\0';
    }
    _nomeMarcaFormatada = &_nomeMarca[0];
    while('\0'!=*_nomeMarcaFormatada && ' '==*_nomeMarcaFormatada) ++_nomeMarcaFormatada;    // Remover espaços iniciais.

    // SIMD
    _suporteMMX = nivelSuporteMMX_Privado(&_suporteHardwareMMX);
    _suporteSSE = nivelSuporteSSE_Privado(&_suporteHardwareSSE);
    _suporteAVX = nivelSuporteAVX_Privado(&_suporteHardwareAVX);

}

// Atualiza tudo.
void CCPUID::atualizarTudo()
{
    atualizarInfos();
    atualizarPropriedades();
}

// Obtém uma informação.
//
// Retorno: Em caso de sucesso, retorna PC_InformacaoCPUID. Se falhar, retorna NULL.
// tipoInfo: ID da função. Parâmetro eax da instrução CPUID.
// valorECX: ID da subfunção. Parâmetro ecx da instrução CPUID.
PC_InformacaoCPUID CCPUID::obterInfo(uint32_t tipoInfo, uint32_t valorECX) const
{
    // Busca sequencial.
    for(int idx=0; idx<ContagemInfos(); ++idx)
    {
        const InformacaoCPUID& info = Informacoes[idx];
        if (tipoInfo==info.funcaoID && valorECX==info.subfuncaoID)
        {
            return &info;
        }
    }
    return NULL;
}

// Obtém os dados.
//
// infoCPU: Em caso de sucesso, retorna 4 DWORDS. Se falhar, retorna todos 0.
// tipoInfo: ID da função. Parâmetro eax da instrução CPUID.
// valorECX: ID da subfunção. Parâmetro ecx da instrução CPUID.
void CCPUID::obterDados(uint32_t infoCPU[4], uint32_t tipoInfo, uint32_t valorECX) const
{
    PC_InformacaoCPUID ptrInfo = obterInfo(tipoInfo, valorECX);
    if (NULL==ptrInfo)
    {
        infoCPU[0] = 0;
        infoCPU[1] = 0;
        infoCPU[2] = 0;
        infoCPU[3] = 0;
        return;
    }
    infoCPU[0] = ptrInfo->registros[0];
    infoCPU[1] = ptrInfo->registros[1];
    infoCPU[2] = ptrInfo->registros[2];
    infoCPU[3] = ptrInfo->registros[3];
}

// Obtém o campo CPUID
uint32_t CCPUID::obterCampo(CAMPO_CPUID cpuf) const
{
    PC_InformacaoCPUID ptrInfo = obterInfo(CAMPO_CPUID_OBTER_FUNCAO(cpuf), CAMPO_CPUID_OBTER_SUBFUNCAO(cpuf));
    if (NULL==ptrInfo)    return 0;
    return obterCampoCPUID_buffer(ptrInfo->registros, cpuf);
}

int    CCPUID::nivelSuporteMMX_Privado(int* ptrHardwareMMX) const
{
    int    resultado = 0;    // Valor de retorno
    #ifdef CCPUID_X86
        const uint32_t    BIT_D_MMX = 0x00800000;    // bit 23
        uint32_t bufferCPU[4];

        // Verificar suporte do processador
        obterDados(bufferCPU, 1);    // Função 1: Informações de Recurso
        if ( bufferCPU[3] & BIT_D_MMX )    resultado=1;
        if (NULL!=ptrHardwareMMX)    *ptrHardwareMMX=resultado;

        // Verificar suporte do SO
        if ( resultado )
        {
            #if defined(_M_X64) && defined(_MSC_VER) && !defined(__INTEL_COMPILER)
                // Compilador VC não suporta MMX em 64 bits.
                resultado=0;
            #else
                try
                {
                    _mm_empty();    // Instrução MMX: emms
                }
                catch(...)
                {
                    resultado=0;
                }
            #endif    // #if defined(_M_X64) && defined(_MSC_VER)
        }
    #else    // #ifdef CCPUID_X86
        if (NULL!=ptrHardwareMMX)    *ptrHardwareMMX=resultado;
    #endif    // #ifdef CCPUID_X86
    return resultado;
}

int    CCPUID::nivelSuporteSSE_Privado(int* ptrHardwareSSE) const
{
    int    resultado = SIMD_SSE_NENHUM;    // Valor de retorno
    #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 bufferCPU[4];

        // Verificar suporte do processador
        obterDados(bufferCPU, 1);    // Função 1: Informações de Recurso
        if ( bufferCPU[3] & BIT_D_SSE )
        {
            resultado = SIMD_SSE_1;
            if ( bufferCPU[3] & BIT_D_SSE2 )
            {
                resultado = SIMD_SSE_2;
                if ( bufferCPU[2] & BIT_C_SSE3 )
                {
                    resultado = SIMD_SSE_3;
                    if ( bufferCPU[2] & BIT_C_SSSE3 )
                    {
                        resultado = SIMD_SSE_3S;
                        if ( bufferCPU[2] & BIT_C_SSE41 )
                        {
                            resultado = SIMD_SSE_41;
                            if ( bufferCPU[2] & BIT_C_SSE42 )
                            {
                                resultado = SIMD_SSE_42;
                            }
                        }
                    }
                }
            }
        }
        if (NULL!=ptrHardwareSSE)    *ptrHardwareSSE=resultado;

        // Verificar suporte do SO
        try
        {
            __m128 xmm1 = _mm_setzero_ps();    // Instrução SSE: xorps
            int* pxmm1 = (int*)&xmm1;    // Evitar aviso -Wstrict-aliasing do GCC.
            if (0!=*pxmm1)    resultado = SIMD_SSE_NENHUM;    // Evitar otimização do _mm_setzero_ps em modo Release.
        }
        catch(...)
        {
            resultado = SIMD_SSE_NENHUM;
        }
    #else    // #ifdef CCPUID_X86
        if (NULL!=ptrHardwareSSE)    *ptrHardwareSSE=resultado;
    #endif    // #ifdef CCPUID_X86
    return resultado;
}

int    CCPUID::nivelSuporteAVX_Privado(int* ptrHardwareAVX) const
{
    int    resultado = SIMD_AVX_NENHUM;    // Valor de retorno
    #ifdef CCPUID_X86
        // Verificar suporte do processador
        if (0!=obterCampo(CPUF_AVX))
        {
            resultado = SIMD_AVX_1;
            if (0!=obterCampo(CPUF_AVX2))
            {
                resultado = SIMD_AVX_2;
            }
        }
        if (NULL!=ptrHardwareAVX)    *ptrHardwareAVX=resultado;

        // Verificar suporte do SO
        if (0!=obterCampo(CPUF_OSXSAVE))    // XGETBV habilitado para uso da aplicação.
        {
            uint32_t n = obterCampo(CPUF_XFeatureSupportedMaskLo);    // XCR0: Registrador XFeatureSupportedMask.
            if (6!=(n&6))    // XCR0[2:1] = ‘11b’ (estado XMM e YMM habilitados pelo SO).
            {
                resultado = SIMD_AVX_NENHUM;
            }
        }
    #else    // #ifdef CCPUID_X86
        if (NULL!=ptrHardwareAVX)    *ptrHardwareAVX=resultado;
    #endif    // #ifdef CCPUID_X86
    return resultado;
}

2.5 testccpuid.cpp: Teste do ccpuid.hpp (C++)

#include <stdio.h>

#include "ccpuid.hpp"

bool exibirDescricao = true;    // Exibir informações de descrição

// Obter a largura do programa em bits (32 ou 64).
int obterBitsPrograma()
{
    return sizeof(int*) * 8;
}

// Imprime um item de campo CPUID.
void imprimirItemCPUID(uint32_t fid, uint32_t fidsub, const uint32_t infoCPU[4])
{
    static const char* NomesReg[4] = { "EAX", "EBX", "ECX", "EDX" };
    uint32_t mascara = CAMPO_CPUID_MASCARA_FUNCAO | CAMPO_CPUID_MASCARA_SUBFUNCAO;
    uint32_t atual =  CAMPO_CPUID_CRIAR(fid, fidsub, 0, 0, 1) & mascara;
    int idx;
    for(idx=0; idx<CCPUID::ComprimentoDescCPUF; ++idx)
    {
        const DescCampoCPUID& item = CCPUID::DescCPUF[idx];
        if ((item.cpuf&mascara)==atual)
        {
            CAMPO_CPUID campo = item.cpuf;
            uint32_t bits = CAMPO_CPUID_OBTER_COMPRIMENTO(campo);
            uint32_t pos = CAMPO_CPUID_OBTER_POSICAO(campo);
            uint32_t reg = CAMPO_CPUID_OBTER_REGISTRADOR(campo);
            uint32_t val = obterCampoCPUID_buffer(infoCPU, campo);
            if (bits>1)
            {
                printf("\t%s[%2d:%2d]", NomesReg[reg], pos+bits-1, pos);
            }
            else
            {
                printf("\t%s[   %2d]", NomesReg[reg], pos);
            }
            printf("=%s:\t0x%X\t(%u)", item.nome, val, val);
            if (exibirDescricao)
            {
                printf("\t// %s", item.descricao);
            }
            printf("\n");

        }
    }
}

// Imprime as informações CPUID.
void imprimirCPUID(const CCPUID& ccid)
{
    int idx;
    for(idx=0; idx<ccid.ContagemInfos(); ++idx)
    {
        const InformacaoCPUID& info = ccid.Informacoes[idx];
        printf("0x%.8X[%d]:\t%.8X\t%.8X\t%.8X\t%.8X\n", info.funcaoID, info.subfuncaoID, info.registros[0], info.registros[1], info.registros[2], info.registros[3]);
        // Verificar subfuncao. Se for uma subfuncao padrão, defina-a como 0 intencionalmente
        // para que os campos da subfuncao 0 possam analisar as informações de cada subfuncao.
        uint32_t subfuncao = info.subfuncaoID;
        switch(info.funcaoID)
        {
        case 0x4: subfuncao=0; break;
        case 0xB: subfuncao=0; break;
        case 0x8000001D: subfuncao=0; break;
        default: break;
        }
        // item
        imprimirItemCPUID(info.funcaoID, subfuncao, info.registros);
        // Outros itens
        if (0==info.funcaoID)    // ID do Fabricante (Função 02h)
        {
            printf("\tFabricante:\t%s\n", ccid.Fabricante());
        }
        else if (0x80000004==info.funcaoID)    // String da Marca do Processador (Funções 80000002h, 80000003h, 80000004h)
        {
            printf("\tMarca:\t%s\n", ccid.Marca());
        }
        else if (0x2==info.funcaoID)    // Descritores de Cache (Função 02h)
        {
            for(int regIdx=0; regIdx<=3; ++regIdx)
            {
                uint32_t val = info.registros[regIdx];
                if (val>0)    // Bit mais significativo é 0, e não é tudo 0
                {
                    for(int byteIdx=0; byteIdx<=3; ++byteIdx)
                    {
                        if (regIdx>0 || byteIdx>0)    // Os 8 bits inferiores de EAX não são informações de cache
                        {
                            int byteVal = val & 0x00FF;
                            if (byteVal>0)
                            {
                                printf("\t0x%.2X:\t%s\n", byteVal, CCPUID::DescricoesCache[byteVal]);
                            }
                        }
                        val >>= 8;
                    }
                }
            }
        }
    }
}

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

    //CCPUID ccid;
    //ccid.atualizarTudo();
    CCPUID& ccid = CCPUID::instanciaAtual();

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

    // Informações básicas
    printf("CCPUID.Fabricante:\t%s\n", ccid.Fabricante());
    //printf("CCPUID.Marca:\t%s\n", ccid.Marca());
    printf("CCPUID.MarcaFormatada:\t%s\n", ccid.MarcaFormatada());
    printf("CCPUID.ContagemInfos:\t%d\n", ccid.ContagemInfos());
    printf("CCPUID.FuncaoPadraoMaxima:\t%.8Xh\n", ccid.FuncaoPadraoMaxima());
    printf("CCPUID.FuncaoEstendidaMaxima:\t%.8Xh\n", ccid.FuncaoEstendidaMaxima());

    // Informações SIMD
    printf("CCPUID.MMX:\t%d\t// hw: %d\n", ccid.suporteMMX(), ccid.suporteHardwareMMX());
    printf("CCPUID.SSE:\t%d\t// hw: %d\n", ccid.suporteSSE(), ccid.suporteHardwareSSE());
    for(idx=1; idx<(int)(sizeof(CCPUID::NomesSSE)/sizeof(CCPUID::NomesSSE[0])); ++idx)
    {
        if (ccid.suporteHardwareSSE()>=idx)    printf("\t%s\n", CCPUID::NomesSSE[idx]);
    }
    printf("SSE4A:\t%d\n", ccid.obterCampo(CPUF_SSE4A));
    printf("AES:\t%d\n", ccid.obterCampo(CPUF_AES));
    printf("PCLMULQDQ:\t%d\n", ccid.obterCampo(CPUF_PCLMULQDQ));
    printf("CCPUID.AVX:\t%d\t// hw: %d\n", ccid.suporteAVX(), ccid.suporteHardwareAVX());
    for(idx=1; idx<(int)(sizeof(CCPUID::NomesAVX)/sizeof(CCPUID::NomesAVX[0])); ++idx)
    {
        if (ccid.suporteHardwareAVX()>=idx)    printf("\t%s\n", CCPUID::NomesAVX[idx]);
    }
    printf("F16C:\t%d\n", ccid.obterCampo(CPUF_F16C));
    printf("FMA:\t%d\n", ccid.obterCampo(CPUF_FMA));
    printf("FMA4:\t%d\n", ccid.obterCampo(CPUF_FMA4));
    printf("XOP:\t%d\n", ccid.obterCampo(CPUF_XOP));

    // Informações de campo
    printf("== campos ==\n");
    imprimirCPUID(ccid);

    return 0;
}

2.6 makefile

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

# args
RELEASE =0
BITS =

# [args] Modo de geração. 0 para debug, 1 para release. Ex: make RELEASE=1.
ifeq ($(RELEASE),0)
    # debug
    CFLAGS += -g
else
    # release
    CFLAGS += -static -O3 -DNDEBUG
    LFLAGS += -static
endif

# [args] Largura do programa em bits. 32 para 32-bit, 64 para 64-bit, outro padrão. Ex: 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))

  1. Resultados do Teste

O módulo foi compilado e testado com sucesso nos seguintes ambientes:

  • VC6: Versão x86.
  • VC2003: Versão x86.
  • VC2005: Versão x86.
  • VC2010: Versões x86 e x64.
  • GCC 4.7.0 (Fedora 17 x64): Versões x86 e x64.
  • GCC 4.6.2 (MinGW (20120426)): Versão x86.
  • GCC 4.6.1 (TDM-GCC (MinGW-w64)): Versões x86 e x64.
  • llvm-gcc-4.2 (Mac OS X Lion 10.7.4, Xcode 4.4.1): Versões x86 e x64.

A execução do testccpuid em um sistema Mac OS X Lion 10.7.4 (em máquina virtual) para um processador Intel i3-2310M resultou na seguinte saída:

testccpuid v1.02 (64bit)

CCPUID.Fabricante:    GenuineIntel
CCPUID.MarcaFormatada:    Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz
CCPUID.ContagemInfos:    17
CCPUID.FuncaoPadraoMaxima:    00000005h
CCPUID.FuncaoEstendidaMaxima:    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
== campos ==
0x00000000[0]:    00000005    756E6547    6C65746E    49656E69
    EAX[31: 0]=FuncaoPadraoMaxima:    0x5    (5)    // Maior função padrão.
    Fabricante:    GenuineIntel
0x00000001[0]:    000206A7    01020800    00000201    178BFBFF
    EAX[ 3: 0]=Stepping:    0x7    (7)    // Stepping do processador.
    EAX[ 7: 4]=ModeloBase:    0xA    (10)    // Modelo base do processador.
    EAX[11: 8]=FamiliaBase:    0x6    (6)    // Família base do processador.
    EAX[13:12]=TipoProcessador:    0x0    (0)    // Tipo de processador.
    EAX[19:16]=ModeloEstendido:    0x2    (2)    // Modelo estendido do processador.
    EAX[27:20]=FamiliaEstendida:    0x0    (0)    // Família estendida do processador.
    EBX[ 7: 0]=BrandId8:    0x0    (0)    // ID de marca de 8 bits.
    EBX[15: 8]=CLFlush:    0x8    (8)    // Tamanho da linha CLFLUSH. (*8)
    EBX[23:16]=MaxApicId:    0x2    (2)    // Número máximo de IDs endereçáveis para processadores lógicos neste pacote físico.
    EBX[31:24]=ApicId:    0x1    (1)    // ID físico APIC local inicial (8 bits).
    ECX[    0]=SSE3:    0x1    (1)    // Streaming SIMD Extensions 3.
    ECX[    1]=PCLMULQDQ:    0x0    (0)    // Instrução PCLMULQDQ.
    ECX[    2]=DTES64:    0x0    (0)    // Área DS de 64 bits.
    ECX[    3]=MONITOR:    0x0    (0)    // Instruções MONITOR/MWAIT.
    ECX[    4]=DS_CPL:    0x0    (0)    // Debug Store qualificado por CPL.
    ECX[    5]=VMX:    0x0    (0)    // Virtual Machine Extensions.
    ECX[    6]=SMX:    0x0    (0)    // Safer Mode Extensions.
    ECX[    7]=EIST:    0x0    (0)    // Tecnologia Enhanced Intel SpeedStep.
    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)    // ID de contexto L1.
    ECX[   12]=FMA:    0x0    (0)    // Suporta extensões FMA usando o estado YMM.
    ECX[   13]=CX16:    0x0    (0)    // Instrução CMPXCHG16B.
    ECX[   14]=xTPR:    0x0    (0)    // Controle de atualização xTPR. Pode desativar o envio de mensagens de prioridade de tarefa.
    ECX[   15]=PDCM:    0x0    (0)    // Capacidade de Perfmon e Debug.
    ECX[   17]=PCID:    0x0    (0)    // Identificadores de Contexto de Processo.
    ECX[   18]=DCA:    0x0    (0)    // Acesso Direto à Cache.
    ECX[   19]=SSE41:    0x0    (0)    // Instruções SSE4.1.
    ECX[   20]=SSE42:    0x0    (0)    // Instruções SSE4.2.
    ECX[   21]=x2APIC:    0x0    (0)    // Suporte xAPIC Estendido.
    ECX[   22]=MOVBE:    0x0    (0)    // Instrução MOVBE.
    ECX[   23]=POPCNT:    0x0    (0)    // Instrução POPCNT.
    ECX[   24]=TSC_DEADLINE:    0x0    (0)    // O temporizador APIC local suporta operação de disparo único usando um valor de deadline TSC.
    ECX[   25]=AES:    0x0    (0)    // Instruções de Padrão de Criptografia Avançado (AES).
    ECX[   26]=XSAVE:    0x0    (0)    // As instruções XSAVE (e relacionadas) são suportadas por hardware.
    ECX[   27]=OSXSAVE:    0x0    (0)    // As instruções XSAVE (e relacionadas) estão habilitadas.
    ECX[   28]=AVX:    0x0    (0)    // Instruções AVX.
    ECX[   29]=F16C:    0x0    (0)    // Suporte a instruções de conversão de meia-precisão.
    ECX[   30]=RDRAND:    0x0    (0)    // Instrução RDRAND.
    EDX[    0]=FPU:    0x1    (1)    // Unidade de Ponto Flutuante On-Chip.
    EDX[    1]=VME:    0x1    (1)    // Aprimoramentos do Modo Virtual 8086.
    EDX[    2]=DE:    0x1    (1)    // Extensões de Depuração.
    EDX[    3]=PSE:    0x1    (1)    // Page Size Extension.
    EDX[    4]=TSC:    0x1    (1)    // Time Stamp Counter.
    EDX[    5]=MSR:    0x1    (1)    // Registradores Específicos do Modelo, Instruções RDMSR e WRMSR.
    EDX[    6]=PAE:    0x1    (1)    // Physical Address Extension.
    EDX[    7]=MCE:    0x1    (1)    // Machine Check Exception.
    EDX[    8]=CX8:    0x1    (1)    // Instrução CMPXCHG8B.
    EDX[    9]=APIC:    0x1    (1)    // APIC (Advanced Programmable Interrupt Controller) On-Chip.
    EDX[   11]=SEP:    0x1    (1)    // Instruções de Chamada de Sistema Rápida, SYSENTER e SYSEXIT.
    EDX[   12]=MTRR:    0x1    (1)    // Registradores de Intervalo de Tipo de Memória.
    EDX[   13]=PGE:    0x1    (1)    // Page Global Enable.
    EDX[   14]=MCA:    0x1    (1)    // Machine-Check Architecture.
    EDX[   15]=CMOV:    0x1    (1)    // Instruções de Movimento Condicional.
    EDX[   16]=PAT:    0x1    (1)    // Page Attribute Table.
    EDX[   17]=PSE36:    0x1    (1)    // Page Size Extension de 36 bits.
    EDX[   18]=PSN:    0x0    (0)    // Número de Série do Processador.
    EDX[   19]=CLFSH:    0x1    (1)    // Instrução CLFLUSH.
    EDX[   21]=DS:    0x0    (0)    // Debug Store.
    EDX[   22]=ACPI:    0x0    (0)    // Monitor Térmico e Facilidades de Clock Controladas por Software.
    EDX[   23]=MMX:    0x1    (1)    // Instruções MMX.
    EDX[   24]=FXSR:    0x1    (1)    // Instruções FXSAVE e FXRSTOR.
    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)    // Campo reservado para IDs APIC Máximos é válido.
    EDX[   29]=TM:    0x0    (0)    // Thermal Monitor.
    EDX[   31]=PBE:    0x0    (0)    // Pending Break Enable.
0x00000002[0]:    76035A01    00F0B2FF    00000000    00CA0000
    0x5A:    DTLB: Páginas de 4 KB e 4 MByte, 64 entradas
    0x03:    DTLB: Páginas de 4 KB, 4-way set associative, 64 entradas
    0x76:    ITLB: Páginas de 2M/4M, fully associative, 8 entradas
    0xFF:    A folha 2 do CPUID não reporta informações de descritor de cache, use a folha 4 do CPUID para consultar parâmetros de cache
    0xB2:    ITLB: Páginas de 4KByte, 4-way set associative, 64 entradas
    0xF0:    Prefetch de 64 bytes
    0xCA:    TLB de 2º Nível Compartilhado: Páginas de 4 KB, 4-way associative, 512 entradas
0x00000003[0]:    00000000    00000000    00000000    00000000
0x00000004[0]:    04000021    01C0003F    0000003F    00000000
    EAX[ 4: 0]=TipoCache:    0x1    (1)    // Tipo de Cache (0=Nulo, 1=Dados, 2=Instruções, 3=Unificado).
    EAX[ 7: 5]=NivelCache:    0x1    (1)    // Nível de Cache (Começa em 1).
    EAX[    8]=CACHE_SI:    0x0    (0)    // Nível de cache auto inicializável.
    EAX[    9]=CACHE_FA:    0x0    (0)    // Cache totalmente associativo.
    EAX[25:14]=MaxApicIdCompartilhado:    0x0    (0)    // Número máximo de IDs endereçáveis para processadores lógicos que compartilham esta cache (codificação +1).
    EAX[31:26]=MaxApicIdCore:    0x1    (1)    // Número máximo de IDs endereçáveis para núcleos de processador no pacote físico (codificação +1).
    EBX[11: 0]=TamanhoLinhaCache:    0x3F    (63)    // Tamanho da Linha de Coerência do Sistema (codificação +1).
    EBX[21:12]=ParticoesCache:    0x0    (0)    // Partições Físicas de Linha (codificação +1).
    EBX[31:22]=ViasCache:    0x7    (7)    // Vias de Associatividade (codificação +1).
    ECX[31: 0]=ConjuntosCache:    0x3F    (63)    // Número de Conjuntos (codificação +1).
    EDX[    0]=CACHE_INVD:    0x0    (0)    // Comportamento WBINVD/INVD em caches de nível inferior.
    EDX[    1]=CACHE_INCLUSIVA:    0x0    (0)    // Cache é inclusiva de níveis de cache inferiores.
    EDX[    2]=CACHE_INDEXACAO_COMPLEXA:    0x0    (0)    // Indexação de Cache Complexa.
0x00000004[1]:    04000021    01C0003F    0000003F    00000000
    EAX[ 4: 0]=TipoCache:    0x1    (1)    // Tipo de Cache (0=Nulo, 1=Dados, 2=Instruções, 3=Unificado).
    EAX[ 7: 5]=NivelCache:    0x1    (1)    // Nível de Cache (Começa em 1).
    EAX[    8]=CACHE_SI:    0x0    (0)    // Nível de cache auto inicializável.
    EAX[    9]=CACHE_FA:    0x0    (0)    // Cache totalmente associativo.
    EAX[25:14]=MaxApicIdCompartilhado:    0x0    (0)    // Número máximo de IDs endereçáveis para processadores lógicos que compartilham esta cache (codificação +1).
    EAX[31:26]=MaxApicIdCore:    0x1    (1)    // Número máximo de IDs endereçáveis para núcleos de processador no pacote físico (codificação +1).
    EBX[11: 0]=TamanhoLinhaCache:    0x3F    (63)    // Tamanho da Linha de Coerência do Sistema (codificação +1).
    EBX[21:12]=ParticoesCache:    0x0    (0)    // Partições Físicas de Linha (codificação +1).
    EBX[31:22]=ViasCache:    0x7    (7)    // Vias de Associatividade (codificação +1).
    ECX[31: 0]=ConjuntosCache:    0x3F    (63)    // Número de Conjuntos (codificação +1).
    EDX[    0]=CACHE_INVD:    0x0    (0)    // Comportamento WBINVD/INVD em caches de nível inferior.
    EDX[    1]=CACHE_INCLUSIVA:    0x0    (0)    // Cache é inclusiva de níveis de cache inferiores.
    EDX[    2]=CACHE_INDEXACAO_COMPLEXA:    0x0    (0)    // Indexação de Cache Complexa.
0x00000004[2]:    04004041    05C0003F    00000FFF    00000000
    EAX[ 4: 0]=TipoCache:    0x1    (1)    // Tipo de Cache (0=Nulo, 1=Dados, 2=Instruções, 3=Unificado).
    EAX[ 7: 5]=NivelCache:    0x2    (2)    // Nível de Cache (Começa em 1).
    EAX[    8]=CACHE_SI:    0x0    (0)    // Nível de cache auto inicializável.
    EAX[    9]=CACHE_FA:    0x0    (0)    // Cache totalmente associativo.
    EAX[25:14]=MaxApicIdCompartilhado:    0x1    (1)    // Número máximo de IDs endereçáveis para processadores lógicos que compartilham esta cache (codificação +1).
    EAX[31:26]=MaxApicIdCore:    0x1    (1)    // Número máximo de IDs endereçáveis para núcleos de processador no pacote físico (codificação +1).
    EBX[11: 0]=TamanhoLinhaCache:    0x3F    (63)    // Tamanho da Linha de Coerência do Sistema (codificação +1).
    EBX[21:12]=ParticoesCache:    0x0    (0)    // Partições Físicas de Linha (codificação +1).
    EBX[31:22]=ViasCache:    0x17    (23)    // Vias de Associatividade (codificação +1).
    ECX[31: 0]=ConjuntosCache:    0xFFF    (4095)    // Número de Conjuntos (codificação +1).
    EDX[    0]=CACHE_INVD:    0x0    (0)    // Comportamento WBINVD/INVD em caches de nível inferior.
    EDX[    1]=CACHE_INCLUSIVA:    0x0    (0)    // Cache é inclusiva de níveis de cache inferiores.
    EDX[    2]=CACHE_INDEXACAO_COMPLEXA:    0x0    (0)    // Indexação de Cache Complexa.
0x00000005[0]:    00000000    00000000    00000003    00000000
    EAX[15: 0]=MonTamanhoLinhaMin:    0x0    (0)    // Menor tamanho de linha de monitoramento em bytes.
    EBX[15: 0]=MonTamanhoLinhaMax:    0x0    (0)    // Maior tamanho de linha de monitoramento em bytes.
    ECX[    0]=EMX:    0x1    (1)    // Enumerar extensões MONITOR/MWAIT.
    ECX[    1]=IBE:    0x1    (1)    // Interrupt Break-Event.
    EDX[ 3: 0]=MWAIT_Num_C0:    0x0    (0)    // Número de sub-estados C0 suportados usando MWAIT.
    EDX[ 7: 4]=MWAIT_Num_C1:    0x0    (0)    // Número de sub-estados C1 suportados usando MWAIT.
    EDX[11: 8]=MWAIT_Num_C2:    0x0    (0)    // Número de sub-estados C2 suportados usando MWAIT.
    EDX[15:12]=MWAIT_Num_C3:    0x0    (0)    // Número de sub-estados C3 suportados usando MWAIT.
    EDX[19:16]=MWAIT_Num_C4:    0x0    (0)    // Número de sub-estados C4 suportados usando MWAIT.
0x80000000[0]:    80000008    00000000    00000000    00000000
    EAX[31: 0]=FuncaoEstendidaMaxima:    0x80000008    (2147483656)    // Maior função estendida.
0x80000001[0]:    00000000    00000000    00000001    20100800
    EBX[15: 0]=BrandId16:    0x0    (0)    // ID de Marca de 16 bits.
    EBX[31:28]=TipoPacote:    0x0    (0)    // Tipo de pacote (Family[7:0] >= 10h).
    ECX[    0]=LahfSahf:    0x1    (1)    // Suporte a instruções LAHF e SAHF em modo de 64 bits.
    ECX[    1]=CmpLegado:    0x0    (0)    // Modo legado de multi-processamento de núcleo.
    ECX[    2]=SVM:    0x0    (0)    // Máquina virtual segura.
    ECX[    3]=EspacoApicExtendido:    0x0    (0)    // Espaço APIC estendido.
    ECX[    4]=AltMovCr8:    0x0    (0)    // LOCK MOV CR0 significa MOV CR8.
    ECX[    5]=ABM:    0x0    (0)    // Manipulação avançada de bits (LZCNT).
    ECX[    6]=SSE4A:    0x0    (0)    // Instruções SSE4A.
    ECX[    7]=MisAlignSse:    0x0    (0)    // Modo SSE desalinhado.
    ECX[    8]=3DNowPrefetch:    0x0    (0)    // Suporte a instruções PREFETCH e PREFETCHW.
    ECX[    9]=OSVW:    0x0    (0)    // Solução visível pelo SO.
    ECX[   10]=IBS:    0x0    (0)    // Amostragem baseada em instrução.
    ECX[   11]=XOP:    0x0    (0)    // Suporte a operação estendida.
    ECX[   12]=SKINIT:    0x0    (0)    // SKINIT e STGI são suportados, independente do valor de MSRC000_0080[SVME].
    ECX[   13]=WDT:    0x0    (0)    // Suporte a temporizador watchdog.
    ECX[   15]=LWP:    0x0    (0)    // Suporte a perfil de peso leve.
    ECX[   16]=FMA4:    0x0    (0)    // Suporte a instruções FMA de 4 operandos.
    ECX[   19]=BIT_NODEID:    0x0    (0)    // Indica suporte para MSRC001_100C[NodeId, NodesPerProcessor].
    ECX[   21]=TBM:    0x0    (0)    // Suporte a instruções de manipulação de bits finais.
    ECX[   22]=ExtensoesTopologia:    0x0    (0)    // Suporte a extensões de topologia.
    EDX[   11]=SYSCALL:    0x1    (1)    // Instruções SYSCALL e SYSRET.
    EDX[   20]=XD:    0x1    (1)    // Execution Disable Bit.
    EDX[   22]=MmxExt:    0x0    (0)    // Extensões AMD para instruções MMX.
    EDX[   25]=FFXSR:    0x0    (0)    // Otimizações das instruções FXSAVE e FXRSTOR.
    EDX[   26]=Pagina1GB:    0x0    (0)    // Suporte a páginas grandes de 1 GB.
    EDX[   27]=RDTSCP:    0x0    (0)    // RDTSCP e TSC_AUX.
    EDX[   29]=LM:    0x1    (1)    // Modo longo de 64 bits (x86-64).
    EDX[   30]=3DNowExt:    0x0    (0)    // Extensões AMD para instruções 3DNow! .
    EDX[   31]=3DNow:    0x0    (0)    // Instruções 3DNow! .
0x80000002[0]:    20202020    49202020    6C65746E    20295228
0x80000003[0]:    65726F43    294D5428    2D336920    30313332
0x80000004[0]:    5043204D    20402055    30312E32    007A4847
    Marca:           Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz
0x80000005[0]:    00000000    00000000    00000000    00000000
    EAX[ 7: 0]=TamL1ITlb2e4M:    0x0    (0)    // Número de entradas TLB de Instrução L1 para páginas de 2 MB e 4 MB.
    EAX[15: 8]=AssocL1ITlb2e4M:    0x0    (0)    // Associatividade TLB de Instrução L1 para páginas de 2 MB e 4 MB.
    EAX[23:16]=TamL1DTlb2e4M:    0x0    (0)    // Número de entradas TLB de Dados L1 para páginas de 2 MB e 4 MB.
    EAX[31:24]=AssocL1DTlb2e4M:    0x0    (0)    // Associatividade TLB de Dados L1 para páginas de 2 MB e 4 MB.
    EBX[ 7: 0]=TamL1ITlb4K:    0x0    (0)    // Número de entradas TLB de Instrução L1 para páginas de 4 KB.
    EBX[15: 8]=AssocL1ITlb4K:    0x0    (0)    // Associatividade TLB de Instrução L1 para páginas de 4KB.
    EBX[23:16]=TamL1DTlb4K:    0x0    (0)    // Número de entradas TLB de Dados L1 para páginas de 4 KB.
    EBX[31:24]=AssocL1DTlb4K:    0x0    (0)    // Associatividade TLB de Dados L1 para páginas de 4 KB.
    ECX[ 7: 0]=TamLinhaL1Dc:    0x0    (0)    // Tamanho da linha de cache de dados L1 em bytes.
    ECX[15: 8]=LinhasL1DcPorTag:    0x0    (0)    // Linhas de cache de dados L1 por tag.
    ECX[23:16]=AssocL1Dc:    0x0    (0)    // Associatividade da cache de dados L1.
    ECX[31:24]=TamL1Dc:    0x0    (0)    // Tamanho da cache de dados L1 em KB.
    EDX[ 7: 0]=TamLinhaL1Ic:    0x0    (0)    // Tamanho da linha de cache de instruções L1 em bytes
    EDX[15: 8]=LinhasL1IcPorTag:    0x0    (0)    // Linhas de cache de instruções L1 por tag.
    EDX[23:16]=AssocL1Ic:    0x0    (0)    // Associatividade da cache de instruções L1.
    EDX[31:24]=TamL1Ic:    0x0    (0)    // Tamanho da cache de instruções L1 em KB.
0x80000006[0]:    00000000    00000000    01006040    00000000
    EAX[11: 0]=TamL2ITlb2e4M:    0x0    (0)    // Número de entradas TLB de Instrução L2 para páginas de 2 MB e 4 MB.
    EAX[15:12]=AssocL2ITlb2e4M:    0x0    (0)    // Associatividade TLB de Instrução L2 para páginas de 2 MB e 4 MB.
    EAX[27:16]=TamL2DTlb2e4M:    0x0    (0)    // Número de entradas TLB de Dados L2 para páginas de 2 MB e 4 MB.
    EAX[31:28]=AssocL2DTlb2e4M:    0x0    (0)    // Associatividade TLB de Dados L2 para páginas de 2 MB e 4 MB.
    EBX[11: 0]=TamL2ITlb4K:    0x0    (0)    // Número de entradas TLB de Instrução L2 para páginas de 4 KB.
    EBX[15:12]=AssocL2ITlb4K:    0x0    (0)    // Associatividade TLB de Instrução L2 para páginas de 4 KB.
    EBX[27:16]=TamL2DTlb4K:    0x0    (0)    // Número de entradas TLB de Dados L2 para páginas de 4 KB.
    EBX[31:28]=AssocL2DTlb4K:    0x0    (0)    // Associatividade TLB de Dados L2 para páginas de 4 KB.
    ECX[ 7: 0]=TamLinhaL2:    0x40    (64)    // Tamanho da linha de cache L2 em bytes.
    ECX[11: 8]=LinhasL2PorTag:    0x0    (0)    // Linhas de cache L2 por tag.
    ECX[15:12]=AssocL2:    0x6    (6)    // Associatividade da cache L2.
    ECX[31:16]=TamL2:    0x100    (256)    // Tamanho da cache L2 em KB.
    EDX[ 7: 0]=TamLinhaL3:    0x0    (0)    // Tamanho da linha de cache L3 em bytes.
    EDX[11: 8]=LinhasL3PorTag:    0x0    (0)    // Linhas de cache L3 por tag.
    EDX[15:12]=AssocL3:    0x0    (0)    // Associatividade da cache L3.
    EDX[31:18]=TamL3:    0x0    (0)    // Tamanho da cache L3.
0x80000007[0]:    00000000    00000000    00000000    00000000
    EDX[    0]=TS:    0x0    (0)    // Sensor de temperatura.
    EDX[    1]=FID:    0x0    (0)    // Controle de ID de frequência.
    EDX[    2]=VID:    0x0    (0)    // Controle de ID de tensão.
    EDX[    3]=TTP:    0x0    (0)    // THERMTRIP.
    EDX[    4]=HTC:    0x0    (0)    // TM: Controle térmico de hardware (HTC).
    EDX[    6]=Passos100MHz:    0x0    (0)    // Controle de multiplicador de 100 MHz.
    EDX[    7]=HwPstate:    0x0    (0)    // Controle de P-state de hardware.
    EDX[    8]=TscInvariante:    0x0    (0)    // TSC invariante.
    EDX[    9]=CPB:    0x0    (0)    // Impulso de desempenho do núcleo.
    EDX[   10]=FrequenciaEfetivaSO:    0x0    (0)    // Interface de frequência efetiva somente leitura.
0x80000008[0]:    00003024    00000000    00000000    00000000
    EAX[ 7: 0]=TamEnderecoFisico:    0x24    (36)    // Tamanho máximo do endereço físico em bytes em bits.
    EAX[15: 8]=TamEnderecoLinear:    0x30    (48)    // Tamanho máximo do endereço linear em bytes em bits.
    EAX[23:16]=TamEnderecoFisicoConvidado:    0x0    (0)    // Tamanho máximo do endereço físico de convidado em bytes em bits.
    ECX[ 7: 0]=NC:    0x0    (0)    // Número de núcleos físicos - 1.
    ECX[15:12]=TamIdApicCoreId:    0x0    (0)    // Tamanho do ID APIC. O número de bits no valor inicial APIC20[ApicId] que indicam o ID do núcleo dentro de um processador.

Tags: CPUID C C++ x86 Mac OS X

Publicado em 7-27 04:06