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:
- Um cabeçalho
ccpuid.hcontendo funções e estruturas compatíveis com C. Funções globais foram movidas para este cabeçalho e marcadas comoinlinepara facilitar a compilação. - Um cabeçalho
ccpuid.hpp, que fornece a interface da classe C++CCPUID, e um arrquivo de implementaçãoccpuid.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 MSRIA32_TSC_ADJUST.CPUID.(EAX=07H, ECX=0H):EBX.RDSEED(bit 18): Indica suporte à instruçãoRDSEED.CPUID.(EAX=07H, ECX=0H):EBX.ADX(bit 19): Indica suporte às instruçõesADCXeADOX.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_IX86ou_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.
- 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))
- 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.