r339: improved SIMD detection
old code does not check AVX2
This commit is contained in:
parent
46e8b6a4f9
commit
8b9f2aaf04
|
|
@ -5,30 +5,48 @@
|
||||||
#define SIMD_SSE 0x1
|
#define SIMD_SSE 0x1
|
||||||
#define SIMD_SSE2 0x2
|
#define SIMD_SSE2 0x2
|
||||||
#define SIMD_SSE3 0x4
|
#define SIMD_SSE3 0x4
|
||||||
#define SIMD_SSE4_1 0x8
|
#define SIMD_SSSE3 0x8
|
||||||
#define SIMD_SSE4_2 0x10
|
#define SIMD_SSE4_1 0x10
|
||||||
#define SIMD_AVX 0x20
|
#define SIMD_SSE4_2 0x20
|
||||||
#define SIMD_AVX2 0x40
|
#define SIMD_AVX 0x40
|
||||||
#define SIMD_AVX512F 0x80
|
#define SIMD_AVX2 0x80
|
||||||
|
#define SIMD_AVX512F 0x100
|
||||||
|
|
||||||
unsigned x86_simd(void)
|
#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)
|
||||||
{
|
{
|
||||||
unsigned eax, ebx, ecx, edx, flag = 0;
|
#if defined(__x86_64__)
|
||||||
#ifdef _MSC_VER
|
asm volatile ("cpuid"
|
||||||
int cpuid[4];
|
: "=a" (cpuid[0]), "=b" (cpuid[1]), "=c" (cpuid[2]), "=d" (cpuid[3])
|
||||||
__cpuid(cpuid, 1);
|
: "0" (func_id), "2" (subfunc_id));
|
||||||
eax = cpuid[0], ebx = cpuid[1], ecx = cpuid[2], edx = cpuid[3];
|
#else // on 32bit, ebx can NOT be used as PIC code
|
||||||
#else
|
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
|
||||||
asm volatile("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (1));
|
: "=a" (cpuid[0]), "=r" (cpuid[1]), "=c" (cpuid[2]), "=d" (cpuid[3])
|
||||||
|
: "0" (func_id), "2" (subfunc_id));
|
||||||
#endif
|
#endif
|
||||||
if (edx>>25&1) flag |= SIMD_SSE;
|
}
|
||||||
if (edx>>26&1) flag |= SIMD_SSE2;
|
#endif
|
||||||
if (ecx>>0 &1) flag |= SIMD_SSE3;
|
|
||||||
if (ecx>>19&1) flag |= SIMD_SSE4_1;
|
int x86_simd(void)
|
||||||
if (ecx>>20&1) flag |= SIMD_SSE4_2;
|
{
|
||||||
if (ecx>>28&1) flag |= SIMD_AVX;
|
int flag = 0, cpuid[4], max_id;
|
||||||
if (ebx>>5 &1) flag |= SIMD_AVX2;
|
__cpuidex(cpuid, 0, 0);
|
||||||
if (ebx>>16&1) flag |= SIMD_AVX512F;
|
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;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue