12 #ifndef hifi_CPUDetect_h
13 #define hifi_CPUDetect_h
19 #define MASK_SSE3 (1 << 0)
20 #define MASK_SSSE3 (1 << 9)
21 #define MASK_SSE41 (1 << 19)
22 #define MASK_SSE42 ((1 << 20) | (1 << 23))
23 #define MASK_OSXSAVE (1 << 27)
24 #define MASK_AVX ((1 << 27) | (1 << 28))
25 #define MASK_AVX2 (1 << 5)
27 #define MASK_AVX512 ((1 << 16) | (1 << 17) | (1 << 28) | (1 << 30) | (1 << 31))
29 #define MASK_XCR0_YMM ((1 << 1) | (1 << 2))
30 #define MASK_XCR0_ZMM ((1 << 1) | (1 << 2) | (7 << 5))
32 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
36 #if defined(ARCH_X86) && defined(_MSC_VER)
41 #define cpuidex(info, eax, ecx) __cpuidex(info, eax, ecx)
42 #define xgetbv(ecx) _xgetbv(ecx)
44 #elif defined(ARCH_X86) && defined(__GNUC__)
49 static inline void cpuidex(
int info[4],
int eax,
int ecx) {
50 __cpuid_count(eax, ecx, info[0], info[1], info[2], info[3]);
53 static inline unsigned long long xgetbv(
unsigned int ecx){
54 unsigned int eax, edx;
55 __asm__(
"xgetbv" :
"=a"(eax),
"=d"(edx) :
"c"(ecx));
56 return ((
unsigned long long)edx << 32) | eax;
61 static inline void cpuidex(
int info[4],
int eax,
int ecx) {
68 static inline unsigned long long xgetbv(
unsigned int ecx){
74 static inline bool cpuSupportsSSE3() {
77 cpuidex(info, 0x1, 0);
79 return ((info[2] & MASK_SSE3) == MASK_SSE3);
82 static inline bool cpuSupportsSSSE3() {
85 cpuidex(info, 0x1, 0);
87 return ((info[2] & MASK_SSSE3) == MASK_SSSE3);
90 static inline bool cpuSupportsSSE41() {
93 cpuidex(info, 0x1, 0);
95 return ((info[2] & MASK_SSE41) == MASK_SSE41);
98 static inline bool cpuSupportsSSE42() {
101 cpuidex(info, 0x1, 0);
103 return ((info[2] & MASK_SSE42) == MASK_SSE42);
106 static inline bool cpuSupportsAVX() {
109 cpuidex(info, 0x1, 0);
112 if ((info[2] & MASK_AVX) == MASK_AVX) {
115 if ((xgetbv(0) & MASK_XCR0_YMM) == MASK_XCR0_YMM) {
122 static inline bool cpuSupportsAVX2() {
126 if (cpuSupportsAVX()) {
128 cpuidex(info, 0x7, 0);
130 if ((info[1] & MASK_AVX2) == MASK_AVX2) {
137 static inline bool cpuSupportsAVX512() {
140 cpuidex(info, 0x1, 0);
143 if ((info[2] & MASK_OSXSAVE) == MASK_OSXSAVE) {
146 if ((xgetbv(0) & MASK_XCR0_ZMM) == MASK_XCR0_ZMM) {
148 cpuidex(info, 0x7, 0);
150 if ((info[1] & MASK_AVX512) == MASK_AVX512) {