4 * Feature detection for x86 processors.
9 * The author dedicates this file to the public domain.
10 * You can do whatever you want with this file.
13 #include "wimlib/x86_cpu_features.h"
15 #if defined(__i386__) || defined(__x86_64__)
23 u32 _x86_cpu_features = 0;
25 /* Execute the CPUID instruction. */
27 cpuid(u32 leaf, u32 subleaf, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
30 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
31 : "a" (leaf), "c" (subleaf));
34 /* Read an extended control register. */
40 __asm__ ("xgetbv" : "=d" (edx), "=a" (eax) : "c" (index));
42 return ((u64)edx << 32) | eax;
45 #define IS_SET(reg, bit) ((reg) & ((u32)1 << (bit)))
47 /* Initialize _x86_cpu_features with bits for interesting processor features. */
49 x86_setup_cpu_features(void)
52 u32 dummy1, dummy2, dummy3, dummy4;
54 u32 features_1, features_2, features_3, features_4;
55 bool os_saves_ymm_regs = false;
57 /* Get maximum supported function */
58 cpuid(0, 0, &max_function, &dummy2, &dummy3, &dummy4);
62 /* Standard feature flags */
63 cpuid(1, 0, &dummy1, &dummy2, &features_2, &features_1);
65 if (IS_SET(features_1, 25))
66 features |= X86_CPU_FEATURE_SSE;
68 if (IS_SET(features_1, 26))
69 features |= X86_CPU_FEATURE_SSE2;
71 if (IS_SET(features_2, 0))
72 features |= X86_CPU_FEATURE_SSE3;
74 if (IS_SET(features_2, 9))
75 features |= X86_CPU_FEATURE_SSSE3;
77 if (IS_SET(features_2, 19))
78 features |= X86_CPU_FEATURE_SSE4_1;
80 if (IS_SET(features_2, 20))
81 features |= X86_CPU_FEATURE_SSE4_2;
83 if (IS_SET(features_2, 27)) /* OSXSAVE set? */
84 if ((read_xcr(0) & 0x6) == 0x6)
85 os_saves_ymm_regs = true;
87 if (os_saves_ymm_regs && IS_SET(features_2, 28))
88 features |= X86_CPU_FEATURE_AVX;
93 /* Extended feature flags */
94 cpuid(7, 0, &dummy1, &features_3, &features_4, &dummy4);
96 if (IS_SET(features_3, 3))
97 features |= X86_CPU_FEATURE_BMI;
99 if (os_saves_ymm_regs && IS_SET(features_3, 5))
100 features |= X86_CPU_FEATURE_AVX2;
102 if (IS_SET(features_3, 8))
103 features |= X86_CPU_FEATURE_BMI2;
108 printf("Detected x86 CPU features: ");
109 if (features & X86_CPU_FEATURE_SSE)
111 if (features & X86_CPU_FEATURE_SSE2)
113 if (features & X86_CPU_FEATURE_SSE3)
115 if (features & X86_CPU_FEATURE_SSSE3)
117 if (features & X86_CPU_FEATURE_SSE4_1)
119 if (features & X86_CPU_FEATURE_SSE4_2)
121 if (features & X86_CPU_FEATURE_BMI)
123 if (features & X86_CPU_FEATURE_AVX)
125 if (features & X86_CPU_FEATURE_BMI2)
127 if (features & X86_CPU_FEATURE_AVX2)
132 _x86_cpu_features = features | X86_CPU_FEATURES_KNOWN;
135 #endif /* __i386__ || __x86_64__ */