From d857799002be14f7e063fa27d2bf8f83d4d62f7a Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Sun, 25 Mar 2018 00:20:42 +0100 Subject: [PATCH] Basic support for advanced instructions --- 01h.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 01h.h | 8 ++++ Makefile | 4 +- main.c | 6 +++ 4 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 01h.c create mode 100644 01h.h diff --git a/01h.c b/01h.c new file mode 100644 index 0000000..13a1e99 --- /dev/null +++ b/01h.c @@ -0,0 +1,131 @@ +#include +#include +#include "01h.h" +#include "cpuid.h" + +#define BOOLEAN_TRUE 1 +#define BOOLEAN_FALSE 0 + +/*** + + MASTER PAGE + http://www.sandpile.org/x86/cpuid.htm + +***/ + +struct cpuInfo { + /* (256 bits) */ + int AVX; + int AVX2; + + /* (512 bits) */ + int AVX512; + + /* (128 bits) */ + int SSE; + int SSE2; + int SSE3; + int SSSE3; + int SSE4a; + int SSE4_1; + int SSE4_2; + + int FMA3; + int FMA4; + + int AES; + int SHA; + + int maxLevels; + int maxExtendedLevels; +}; + +void initializeCpuInfo(struct cpuInfo* cpu) { + cpu->AVX = BOOLEAN_FALSE; + cpu->AVX2 = BOOLEAN_FALSE; + cpu->AVX512 = BOOLEAN_FALSE; + cpu->SSE = BOOLEAN_FALSE; + cpu->SSE2 = BOOLEAN_FALSE; + cpu->SSE3 = BOOLEAN_FALSE; + cpu->SSSE3 = BOOLEAN_FALSE; + cpu->SSE4a = BOOLEAN_FALSE; + cpu->SSE4_1 = BOOLEAN_FALSE; + cpu->SSE4_2 = BOOLEAN_FALSE; + cpu->FMA3 = BOOLEAN_FALSE; + cpu->FMA4 = BOOLEAN_FALSE; + cpu->AES = BOOLEAN_FALSE; + cpu->SHA = BOOLEAN_FALSE; +} + +struct cpuInfo* getCPUInfo() { + struct cpuInfo* cpu = malloc(sizeof(struct cpuInfo)); + initializeCpuInfo(cpu); + + unsigned eax, ebx, ecx, edx; + eax = 0x0000000; + cpuid(&eax, &ebx, &ecx, &edx); + cpu->maxLevels = eax; + + cpuid(&eax, &ebx, &ecx, &edx); + cpu->maxExtendedLevels = eax; + + //Always check we can fetch data + if (cpu->maxLevels >= 0x00000001){ + eax = 0x00000001; + cpuid(&eax, &ebx, &ecx, &edx); + cpu->SSE = (edx & ((int)1 << 25)) != 0; + cpu->SSE2 = (edx & ((int)1 << 26)) != 0; + cpu->SSE3 = (ecx & ((int)1 << 0)) != 0; + + cpu->SSSE3 = (ecx & ((int)1 << 9)) != 0; + cpu->SSE4_1 = (ecx & ((int)1 << 19)) != 0; + cpu->SSE4_2 = (ecx & ((int)1 << 20)) != 0; + + cpu->AES = (ecx & ((int)1 << 25)) != 0; + + cpu->AVX = (ecx & ((int)1 << 28)) != 0; + cpu->FMA3 = (ecx & ((int)1 << 12)) != 0; + } + if (cpu->maxLevels >= 0x00000007){ + eax = 0x00000007; + cpuid(&eax, &ebx, &ecx, &edx); + cpu->AVX2 = (ebx & ((int)1 << 5)) != 0; + cpu->SHA = (ebx & ((int)1 << 29)) != 0; + cpu->AVX512 = (((ebx & ((int)1 << 16)) != 0) || + ((ebx & ((int)1 << 28)) != 0) || + ((ebx & ((int)1 << 26)) != 0) || + ((ebx & ((int)1 << 27)) != 0) || + ((ebx & ((int)1 << 31)) != 0) || + ((ebx & ((int)1 << 30)) != 0) || + ((ebx & ((int)1 << 17)) != 0) || + ((ebx & ((int)1 << 21)) != 0)); + } + if (cpu->maxExtendedLevels >= 0x80000001){ + eax = 0x80000001; + cpuid(&eax, &ebx, &ecx, &edx); + cpu->SSE4a = (ecx & ((int)1 << 6)) != 0; + cpu->FMA4 = (ecx & ((int)1 << 16)) != 0; + } + + return cpu; +} + +void debugCpuInfo(struct cpuInfo* cpu) { + printf("AVX=%s\n", cpu->AVX ? "true" : "false"); + printf("AVX2=%s\n", cpu->AVX2 ? "true" : "false"); + printf("AVX512=%s\n\n", cpu->AVX512 ? "true" : "false"); + + printf("SSE=%s\n", cpu->SSE ? "true" : "false"); + printf("SSE2=%s\n", cpu->SSE2 ? "true" : "false"); + printf("SSE3=%s\n", cpu->SSE3 ? "true" : "false"); + printf("SSSE3=%s\n", cpu->SSSE3 ? "true" : "false"); + printf("SSE4a=%s\n", cpu->SSE4a ? "true" : "false"); + printf("SSE4_1=%s\n", cpu->SSE4_1 ? "true" : "false"); + printf("SSE4_2=%s\n\n", cpu->SSE4_2 ? "true" : "false"); + + printf("FMA3=%s\n", cpu->FMA3 ? "true" : "false"); + printf("FMA4=%s\n\n", cpu->FMA4 ? "true" : "false"); + + printf("AES=%s\n", cpu->AES ? "true" : "false"); + printf("SHA=%s\n", cpu->SHA ? "true" : "false"); +} diff --git a/01h.h b/01h.h new file mode 100644 index 0000000..9d5fbd2 --- /dev/null +++ b/01h.h @@ -0,0 +1,8 @@ +#ifndef __01h__ +#define __01h__ + +struct cpuInfo; +struct cpuInfo* getCPUInfo(); +void debugCpuInfo(struct cpuInfo* cpu); + +#endif diff --git a/Makefile b/Makefile index e95737a..776dbed 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ CXX=gcc CXXFLAGS=-g -SOURCE=main.c 02h.c extended.c cpuid.c -HEADERS=02h.h extended.h cpuid.h +SOURCE=main.c 01h.c 02h.c extended.c cpuid.c +HEADERS=01h.c 02h.h extended.h cpuid.h OUTPUT=cpufetch diff --git a/main.c b/main.c index 7f542c6..719a632 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,6 @@ #include #include +#include "01h.h" #include "02h.h" #include "extended.h" @@ -26,5 +27,10 @@ int main() { struct level2* level2 = fillLevel2(level2); debugLevel2(level2); freeLevel2(level2); + + struct cpuInfo* cpu = getCPUInfo(cpu); + debugCpuInfo(cpu); + free(cpu); + printf("%s\n",getCPUName()); }