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-152d48957efa
master
elm 2013-02-15 18:11:22 +00:00
parent 327f637b83
commit e6fd0a544b
2 changed files with 77 additions and 18 deletions

44
intel_cpu_capabilities.h Normal file
View File

@ -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);
}
}

View File

@ -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");
}