Created
September 5, 2017 17:06
-
-
Save lh3/3fd977099883e866857b9d3718a680b1 to your computer and use it in GitHub Desktop.
Get supported SIMD instruction sets (x86 only)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#define SIMD_SSE 0x1 | |
#define SIMD_SSE2 0x2 | |
#define SIMD_SSE3 0x4 | |
#define SIMD_SSSE3 0x8 | |
#define SIMD_SSE4_1 0x10 | |
#define SIMD_SSE4_2 0x20 | |
#define SIMD_AVX 0x40 | |
#define SIMD_AVX2 0x80 | |
#define SIMD_AVX512F 0x100 | |
#ifndef _MSC_VER | |
// adapted from https://github.com/01org/linux-sgx/blob/master/common/inc/internal/linux/cpuid_gnu.h | |
void __cpuidex(int cpuid[4], int func_id, int subfunc_id) | |
{ | |
#if defined(__x86_64__) | |
asm volatile ("cpuid" | |
: "=a" (cpuid[0]), "=b" (cpuid[1]), "=c" (cpuid[2]), "=d" (cpuid[3]) | |
: "0" (func_id), "2" (subfunc_id)); | |
#else // on 32bit, ebx can NOT be used as PIC code | |
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" | |
: "=a" (cpuid[0]), "=r" (cpuid[1]), "=c" (cpuid[2]), "=d" (cpuid[3]) | |
: "0" (func_id), "2" (subfunc_id)); | |
#endif | |
} | |
#endif | |
int x86_simd(void) | |
{ | |
int flag = 0, cpuid[4], max_id; | |
__cpuidex(cpuid, 0, 0); | |
max_id = cpuid[0]; | |
if (max_id == 0) return 0; | |
__cpuidex(cpuid, 1, 0); | |
if (cpuid[3]>>25&1) flag |= SIMD_SSE; | |
if (cpuid[3]>>26&1) flag |= SIMD_SSE2; | |
if (cpuid[2]>>0 &1) flag |= SIMD_SSE3; | |
if (cpuid[2]>>9 &1) flag |= SIMD_SSSE3; | |
if (cpuid[2]>>19&1) flag |= SIMD_SSE4_1; | |
if (cpuid[2]>>20&1) flag |= SIMD_SSE4_2; | |
if (cpuid[2]>>28&1) flag |= SIMD_AVX; | |
if (max_id >= 7) { | |
__cpuidex(cpuid, 7, 0); | |
if (cpuid[1]>>5 &1) flag |= SIMD_AVX2; | |
if (cpuid[1]>>16&1) flag |= SIMD_AVX512F; | |
} | |
return flag; | |
} | |
const char *simd_name[9] = { "sse", "sse2", "sse3", "ssse3", "sse4.1", "sse4.2", "avx", "avx2", "avx512f" }; | |
int main() | |
{ | |
unsigned i, simd_flag; | |
simd_flag = x86_simd(); | |
for (i = 0; i < 8; ++i) | |
if (simd_flag>>i&1) puts(simd_name[i]); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment