#include <stdio.h>
// Function to execute cpuid instruction and get the results in the provided registers
void cpuid(int code, unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d) {
__asm__ volatile ("cpuid"
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
: "a" (code));
}
void cpuidex(int code, int subleaf, unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d) {
__asm__ volatile ("cpuid"
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
: "a" (code), "c" (subleaf));
}
void print_feature_flags() {
unsigned int eax, ebx, ecx, edx;
// Call cpuid with eax = 1 to get the main feature flags
cpuid(1, &eax, &ebx, &ecx, &edx);
printf("Feature flags from cpuid(1):\n");
printf("EDX: ");
if (edx & (1 << 0)) printf("FPU ");
if (edx & (1 << 1)) printf("VME ");
if (edx & (1 << 2)) printf("DE ");
if (edx & (1 << 3)) printf("PSE ");
if (edx & (1 << 4)) printf("TSC ");
if (edx & (1 << 5)) printf("MSR ");
if (edx & (1 << 6)) printf("PAE ");
if (edx & (1 << 7)) printf("MCE ");
if (edx & (1 << 8)) printf("CX8 ");
if (edx & (1 << 9)) printf("APIC ");
if (edx & (1 << 11)) printf("SEP ");
if (edx & (1 << 12)) printf("MTRR ");
if (edx & (1 << 13)) printf("PGE ");
if (edx & (1 << 14)) printf("MCA ");
if (edx & (1 << 15)) printf("CMOV ");
if (edx & (1 << 16)) printf("PAT ");
if (edx & (1 << 17)) printf("PSE36 ");
if (edx & (1 << 18)) printf("PSN ");
if (edx & (1 << 19)) printf("CLFLUSH ");
if (edx & (1 << 23)) printf("MMX ");
if (edx & (1 << 24)) printf("FXSR ");
if (edx & (1 << 25)) printf("SSE ");
if (edx & (1 << 26)) printf("SSE2 ");
if (edx & (1 << 27)) printf("SS ");
if (edx & (1 << 28)) printf("HTT ");
if (edx & (1 << 29)) printf("TM ");
if (edx & (1 << 30)) printf("IA64 ");
if (edx & (1 << 31)) printf("PBE ");
printf("\n");
printf("ECX: ");
if (ecx & (1 << 0)) printf("SSE3 ");
if (ecx & (1 << 1)) printf("PCLMULQDQ ");
if (ecx & (1 << 2)) printf("DTES64 ");
if (ecx & (1 << 3)) printf("MONITOR ");
if (ecx & (1 << 4)) printf("DS_CPL ");
if (ecx & (1 << 5)) printf("VMX ");
if (ecx & (1 << 6)) printf("SMX ");
if (ecx & (1 << 7)) printf("EST ");
if (ecx & (1 << 8)) printf("TM2 ");
if (ecx & (1 << 9)) printf("SSSE3 ");
if (ecx & (1 << 10)) printf("CNXT_ID ");
if (ecx & (1 << 11)) printf("SDBG ");
if (ecx & (1 << 12)) printf("FMA ");
if (ecx & (1 << 13)) printf("CX16 ");
if (ecx & (1 << 14)) printf("XTPR ");
if (ecx & (1 << 15)) printf("PDCM ");
if (ecx & (1 << 17)) printf("PCID ");
if (ecx & (1 << 18)) printf("DCA ");
if (ecx & (1 << 19)) printf("SSE4_1 ");
if (ecx & (1 << 20)) printf("SSE4_2 ");
if (ecx & (1 << 21)) printf("X2APIC ");
if (ecx & (1 << 22)) printf("MOVBE ");
if (ecx & (1 << 23)) printf("POPCNT ");
if (ecx & (1 << 24)) printf("TSC_DEADLINE ");
if (ecx & (1 << 25)) printf("AES ");
if (ecx & (1 << 26)) printf("XSAVE ");
if (ecx & (1 << 27)) printf("OSXSAVE ");
if (ecx & (1 << 28)) printf("AVX ");
if (ecx & (1 << 29)) printf("F16C ");
if (ecx & (1 << 30)) printf("RDRAND ");
if (ecx & (1 << 31)) printf("HYPERVISOR ");
printf("\n");
// Call cpuid with eax = 7 and ecx = 0 to get extended feature flags
cpuidex(7, 0, &eax, &ebx, &ecx, &edx);
printf("Extended feature flags from cpuid(7, 0):\n");
printf("EBX: ");
if (ebx & (1 << 0)) printf("FSGSBASE ");
if (ebx & (1 << 1)) printf("IA32_TSC_ADJUST ");
if (ebx & (1 << 2)) printf("SGX ");
if (ebx & (1 << 3)) printf("BMI1 ");
if (ebx & (1 << 4)) printf("HLE ");
if (ebx & (1 << 5)) printf("AVX2 ");
if (ebx & (1 << 6)) printf("FDP_EXCPTN_ONLY ");
if (ebx & (1 << 7)) printf("SMEP ");
if (ebx & (1 << 8)) printf("BMI2 ");
if (ebx & (1 << 9)) printf("ERMS ");
if (ebx & (1 << 10)) printf("INVPCID ");
if (ebx & (1 << 11)) printf("RTM ");
if (ebx & (1 << 12)) printf("PQM ");
if (ebx & (1 << 13)) printf("FPU_CS_DS ");
if (ebx & (1 << 14)) printf("MPX ");
if (ebx & (1 << 15)) printf("PQE ");
if (ebx & (1 << 16)) printf("AVX512F ");
if (ebx & (1 << 17)) printf("AVX512DQ ");
if (ebx & (1 << 18)) printf("RDSEED ");
if (ebx & (1 << 19)) printf("ADX ");
if (ebx & (1 << 20)) printf("SMAP ");
if (ebx & (1 << 21)) printf("AVX512IFMA ");
if (ebx & (1 << 22)) printf("PCOMMIT ");
if (ebx & (1 << 23)) printf("CLFLUSHOPT ");
if (ebx & (1 << 24)) printf("CLWB ");
if (ebx & (1 << 25)) printf("INTEL_PT ");
if (ebx & (1 << 26)) printf("AVX512PF ");
if (ebx & (1 << 27)) printf("AVX512ER ");
if (ebx & (1 << 28)) printf("AVX512CD ");
if (ebx & (1 << 29)) printf("SHA ");
if (ebx & (1 << 30)) printf("AVX512BW ");
if (ebx & (1 << 31)) printf("AVX512VL ");
printf("\n");
printf("ECX: ");
if (ecx & (1 << 1)) printf("AVX512VBMI ");
if (ecx & (1 << 3)) printf("UMIP ");
if (ecx & (1 << 4)) printf("PKU ");
if (ecx & (1 << 5)) printf("OSPKE ");
if (ecx & (1 << 6)) printf("WAITPKG ");
if (ecx & (1 << 8)) printf("AVX512VBMI2 ");
if (ecx & (1 << 9)) printf("CET_SS ");
if (ecx & (1 << 10)) printf("GFNI ");
if (ecx & (1 << 11)) printf("VAES ");
if (ecx & (1 << 12)) printf("VPCLMULQDQ ");
if (ecx & (1 << 14)) printf("AVX512VNNI ");
if (ecx & (1 << 16)) printf("AVX512BITALG ");
if (ecx & (1 << 17)) printf("TME ");
if (ecx & (1 << 18)) printf("AVX512VPOPCNTDQ ");
if (ecx & (1 << 22)) printf("RDPID ");
if (ecx & (1 << 30)) printf("SGX_LC ");
printf("\n");
printf("EDX: ");
if (edx & (1 << 2)) printf("AVX512_4VNNIW ");
if (edx & (1 << 3)) printf("AVX512_4FMAPS ");
if (edx & (1 << 8)) printf("AVX512_VP2INTERSECT ");
if (edx & (1 << 14)) printf("MD_CLEAR ");
if (edx & (1 << 18)) printf("IBT ");
printf("\n");
}
int main() {
print_feature_flags();
return 0;
}