Updated the way we track CPU features. Much more stable now.
git-svn-id: svn://mamba.eecs.utk.edu/home/plank/svn/Galois-Library@100 36f187d4-5712-4624-889c-152d48957efamaster
parent
327f637b83
commit
e6fd0a544b
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Routines to figure out what an Intel CPU's capabilities are.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Words in CPE_INFO */
|
||||
#define CPU_CPE_INFO 0x1000
|
||||
#define CPU_CAP_MMX (CPU_CPE_INFO | 23)
|
||||
#define CPU_CAP_SSE (CPU_CPE_INFO | 25)
|
||||
#define CPU_CAP_SSE2 (CPU_CPE_INFO | 26)
|
||||
|
||||
/* Words in CPSSE */
|
||||
#define CPU_CPSSE 0x2000
|
||||
#define CPU_CAP_SSE3 (CPU_CPSSE | 0)
|
||||
#define CPU_CAP_PCLMULQDQ (CPU_CPSSE | 1)
|
||||
#define CPU_CAP_SSSE3 (CPU_CPSSE | 10)
|
||||
#define CPU_CAP_SSE41 (CPU_CPSSE | 19)
|
||||
#define CPU_CAP_SSE42 (CPU_CPSSE | 20)
|
||||
#define CPU_CAP_AVX (CPU_CPSSE | 28)
|
||||
|
||||
#define cpuid(func,ax,bx,cx,dx)\
|
||||
__asm__ __volatile__ ("cpuid":\
|
||||
"=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));
|
||||
|
||||
inline
|
||||
int
|
||||
cpu_has_feature (unsigned which)
|
||||
{
|
||||
uint32_t cpeinfo;
|
||||
uint32_t cpsse;
|
||||
uint32_t a, b;
|
||||
|
||||
cpuid(1, a, b, cpsse, cpeinfo);
|
||||
if (which & CPU_CPE_INFO) {
|
||||
return (!! ((cpeinfo >> (which & 0xff)) & 0x1) );
|
||||
} else if (which & CPU_CPSSE) {
|
||||
return (!! ((cpsse >> (which & 0xff)) & 0x1) );
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
|
@ -4,25 +4,40 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "intel_cpu_capabilities.h"
|
||||
|
||||
struct {
|
||||
unsigned feature_code;
|
||||
const char * feature_name;
|
||||
} features[] = {
|
||||
{CPU_CAP_MMX, "MMX"},
|
||||
{CPU_CAP_SSE, "SSE"},
|
||||
{CPU_CAP_SSE2, "SSE2"},
|
||||
{CPU_CAP_SSE3, "SSE3"},
|
||||
{CPU_CAP_SSSE3, "SSSE3"},
|
||||
{CPU_CAP_SSE41, "SSE4.1"},
|
||||
{CPU_CAP_SSE42, "SSE4.2"},
|
||||
{CPU_CAP_PCLMULQDQ, "PCLMULQDQ"},
|
||||
{CPU_CAP_AVX, "AVX"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned int cpeinfo;
|
||||
unsigned int cpsse;
|
||||
asm (
|
||||
"mov $0x1, %%eax\n\t"
|
||||
"cpuid\n\t"
|
||||
"mov %%edx, %0\n\t"
|
||||
"mov %%ecx, %1\n" : "=m" (cpeinfo), "=m" (cpsse)
|
||||
);
|
||||
unsigned i;
|
||||
|
||||
printf("1 - Instruction set is supported by CPU\n");
|
||||
printf("0 - Instruction set not supported\n");
|
||||
printf("--------------------------------\n");
|
||||
printf("MMX: %d\n", ((cpeinfo >> 23) & 0x1 ));
|
||||
printf("SSE: %d\n", ((cpeinfo >> 25) & 0x1 ));
|
||||
printf("SSE2: %d\n", ((cpeinfo >> 26) & 0x1 ));
|
||||
printf("SSE3: %d\n", ((cpsse ) & 0x1 ));
|
||||
printf("SSE4.1: %d\n", ((cpsse >> 19) & 0x1 ));
|
||||
printf("SSE4.2: %d\n", ((cpsse >> 20) & 0x1 ));
|
||||
printf("SSEAVX: %d\n", ((cpsse >> 28) & 0x1 ));
|
||||
printf ("CPU has the following instruction set features enabled: " );
|
||||
for (i = 0; features[i].feature_name != NULL; ++i) {
|
||||
if (cpu_has_feature (features[i].feature_code)) {
|
||||
printf ("%s ", features[i].feature_name);
|
||||
}
|
||||
}
|
||||
printf ("\nCPU is missing the following instruction set features: ");
|
||||
for (i = 0; features[i].feature_name != NULL; ++i) {
|
||||
if (! cpu_has_feature (features[i].feature_code)) {
|
||||
printf ("%s ", features[i].feature_name);
|
||||
}
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue