2 * Copyright (c) 2013 Ahmed Samy <f.fallen45@gmail.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * This file has been written with some help from wikipedia:
23 * http://en.wikipedia.org/wiki/CPUID
26 /* Only compile this file if we're on a x86 machine. */
27 #if defined(__i386__) || defined(__i386) || defined(__x86_64) \
28 || defined(_M_AMD64) || defined(__M_X64)
35 CPUID_PROC_BRAND_STRING_INTERNAL0 = 0x80000003,
36 CPUID_PROC_BRAND_STRING_INTERNAL1 = 0x80000004
40 static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
43 "xchg %%ebx, %%edi\n\t" /* 32bit PIC: Don't clobber ebx. */
45 "xchg %%ebx, %%edi\n\t"
46 : "=a"(*eax), "=D"(*ebx), "=c"(*ecx), "=d"(*edx)
53 static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
55 uint32_t registers[4];
56 __cpuid(registers, info);
65 bool cpuid_is_supported(void)
68 #if defined(__GNUC__) || defined(__clang__)
69 /* The following assembly code uses EAX as the return value,
70 * but we store the value of EAX into ret since GCC uses EAX
71 * as the return register for every C function. That's a double
72 * operation, but there's no other way to do this unless doing this
73 * function entirely in assembly.
75 * The following assembly code has been shamelessly stolen from:
76 * http://wiki.osdev.org/CPUID
77 * and converted to work with AT&T syntax.
79 * This check is to make sure that the compiler is actually compiling
82 * The compiler can be 32-bit and the system 64-bit so the
83 * following would be true:
84 * #if defined(__x86_64) ...
87 #if UINTPTR_MAX == 0xffffffffffffffff
88 #define ASM_PUSHF "pushfq\n\t"
89 #define ASM_POPF "popfq\n\t"
90 #define ASM_PUSHEAX "pushq %%rax\n\t"
91 #define ASM_POPEAX "popq %%rax\n\t"
92 #define ASM_PUSHECX "pushq %%rcx\n\t"
93 #elif UINTPTR_MAX == 0xffffffff
94 #define ASM_PUSHF "pushfl\n\t"
95 #define ASM_POPF "popfl\n\t"
96 #define ASM_PUSHEAX "pushl %%eax\n\t"
97 #define ASM_POPEAX "popl %%eax\n\t"
98 #define ASM_PUSHECX "pushl %%ecx\n\t"
104 "movl %%eax, %%ecx\n\t"
105 "xorl $0x200000, %%eax\n\t"
110 "xorl %%ecx, %%eax\n\t"
111 "shrl $21, %%eax\n\t"
123 #elif defined _MSC_VER
146 bool cpuid_test_feature(cpuid_t feature)
148 if (feature > CPUID_VIRT_PHYS_ADDR_SIZES || feature < CPUID_EXTENDED_PROC_INFO_FEATURE_BITS)
151 return (feature <= cpuid_highest_ext_func_supported());
154 #if defined(__GNUC__) || defined(__clang__)
155 static uint32_t fetch_ecx(uint32_t what)
169 static uint32_t fetch_edx(uint32_t what)
182 #elif defined(_MSC_VER)
183 static uint32_t fetch_ecx(uint32_t what)
185 static uint32_t _ecx;
197 static uint32_t fetch_edx(uint32_t what)
199 static uint32_t _edx;
212 #define DEFINE_FEATURE_FUNC(NAME, REGISTER, TYPE) \
213 bool cpuid_has_##NAME(int feature) \
215 static uint32_t REGISTER; \
217 REGISTER = fetch_##REGISTER(TYPE); \
218 return !!(REGISTER & feature); \
221 DEFINE_FEATURE_FUNC(ecxfeature, ecx, CPUID_PROCINFO_AND_FEATUREBITS)
222 DEFINE_FEATURE_FUNC(edxfeature, edx, CPUID_PROCINFO_AND_FEATUREBITS)
224 DEFINE_FEATURE_FUNC(ecxfeature_ext, ecx, CPUID_EXTENDED_PROC_INFO_FEATURE_BITS)
225 DEFINE_FEATURE_FUNC(edxfeature_ext, edx, CPUID_EXTENDED_PROC_INFO_FEATURE_BITS)
227 #undef DEFINE_FEATURE_FUNC
229 cputype_t cpuid_get_cpu_type(void)
231 static cputype_t cputype;
232 if (cputype == CT_NONE) {
239 ___cpuid(CPUID_VENDORID, &i, &u.bufu32[0], &u.bufu32[2], &u.bufu32[1]);
240 for (i = 0; i < sizeof(c_cpunames) / sizeof(c_cpunames); ++i) {
241 if (strncmp(c_cpunames[i], u.buf, sizeof(c_cpunames[0])) == 0) {
242 cputype = (cputype_t)i;
251 uint32_t cpuid_highest_ext_func_supported(void)
253 static uint32_t highest;
256 #if defined(__GNUC__) || defined(__clang__)
260 : "a" (CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED)
262 #elif defined _MSC_VER
264 mov eax, CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
274 void cpuid(cpuid_t request, uint32_t *buf)
276 /* Sanity checks, make sure we're not trying to do something
277 * invalid or we are trying to get information that isn't supported
279 if (request > CPUID_VIRT_PHYS_ADDR_SIZES || (request > CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
280 && !cpuid_test_feature(request)))
283 if (request == CPUID_PROC_BRAND_STRING) {
284 static char cached[48] = { 0 };
285 if (cached[0] == '\0') {
286 ___cpuid(CPUID_PROC_BRAND_STRING, &buf[0], &buf[1], &buf[2], &buf[3] );
287 ___cpuid(CPUID_PROC_BRAND_STRING_INTERNAL0, &buf[4], &buf[5], &buf[6], &buf[7] );
288 ___cpuid(CPUID_PROC_BRAND_STRING_INTERNAL1, &buf[8], &buf[9], &buf[10], &buf[11]);
290 memcpy(cached, buf, sizeof cached);
292 buf = (uint32_t *)cached;
295 } else if (request == CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED) {
296 *buf = cpuid_highest_ext_func_supported();
300 uint32_t eax, ebx, ecx, edx;
301 ___cpuid(request, &eax, &ebx, &ecx, &edx);
309 case CPUID_PROCINFO_AND_FEATUREBITS:
310 buf[0] = (eax & 0x0F); /* Stepping */
311 buf[1] = (eax >> 4) & 0x0F; /* Model */
312 buf[2] = (eax >> 8) & 0x0F; /* Family */
313 buf[3] = (eax >> 16) & 0x0F; /* Extended Model. */
314 buf[4] = (eax >> 24) & 0x0F; /* Extended Family. */
316 /* Additional Feature information. */
318 buf[6] = (ebx >> 8) & 0xFF;
319 buf[7] = (ebx >> 16) & 0xFF;
322 case CPUID_CACHE_AND_TLBD_INFO:
328 case CPUID_EXTENDED_PROC_INFO_FEATURE_BITS:
332 case CPUID_L1_CACHE_AND_TLB_IDS:
334 buf[1] = (eax >> 8) & 0xFF;
335 buf[2] = (eax >> 16) & 0xFF;
339 buf[5] = (ebx >> 8) & 0xFF;
340 buf[6] = (ebx >> 16) & 0xFF;
344 buf[9] = (ecx >> 8) & 0xFF;
345 buf[10] = (ecx >> 16) & 0xFF;
348 buf[12] = edx & 0xFF;
349 buf[13] = (edx >> 8) & 0xFF;
350 buf[14] = (edx >> 16) & 0xFF;
353 case CPUID_EXTENDED_L2_CACHE_FEATURES:
354 buf[0] = ecx & 0xFF; /* Line size. */
355 buf[1] = (ecx >> 12) & 0xFF; /* Associativity. */
356 buf[2] = ecx >> 16; /* Cache size. */
358 case CPUID_ADV_POWER_MGT_INFO:
361 case CPUID_VIRT_PHYS_ADDR_SIZES:
362 buf[0] = eax & 0xFF; /* physical. */
363 buf[1] = (eax >> 8) & 0xFF; /* virtual. */
371 bool cpuid_write_info(uint32_t info, uint32_t featureset, const char *outfile)
375 char cpu_information[64];
377 if (!cpuid_sprintf_cputype(cpuid_get_cpu_type(), cpu_information))
381 cpuid(CPUID_PROC_BRAND_STRING, (uint32_t *)brand);
383 cpu_information[12] = '_';
384 memcpy(&cpu_information[13], brand, sizeof brand);
387 strncpy(filename, cpu_information, sizeof cpu_information);
389 strncpy(filename, outfile, sizeof filename);
391 file = fopen(filename, "w");
395 fprintf(file, "-- CPU Information for CPU: %s --\n\n", cpu_information);
397 if (info & CPUID_HIGHEST_EXTENDED_FUNCTION_SUPPORTED)
398 fprintf(file, "Highest extended function supported: %#010x\n\n", cpuid_highest_ext_func_supported());
400 if (info & CPUID_EXTENDED_L2_CACHE_FEATURES) {
402 cpuid(CPUID_EXTENDED_L2_CACHE_FEATURES, l2c);
404 fprintf(file, "-- Extended L2 Cache features --\nL2 Line size: %u bytes\nAssociativity: %02xh\nCache Size: %u KB\n\n",
405 l2c[0], l2c[1], l2c[2]);
408 if (info & CPUID_VIRT_PHYS_ADDR_SIZES) {
409 uint32_t phys_virt[2];
410 cpuid(CPUID_VIRT_PHYS_ADDR_SIZES, phys_virt);
412 fprintf(file, "-- Virtual and Physical address sizes --\n"
413 "Physical address size: %d\nVirtual address size: %d\n\n", phys_virt[0], phys_virt[1]);
416 if (info & CPUID_PROCINFO_AND_FEATUREBITS) {
417 uint32_t procinfo[9];
418 cpuid(CPUID_PROCINFO_AND_FEATUREBITS, procinfo);
420 fputs("-- Processor information and feature bits --\n", file );
421 fprintf(file, "Stepping: %d\nModel: 0x%X\nFamily: %d\nExtended model: %d\nExtended family: %d\n",
422 procinfo[0], procinfo[1], procinfo[2], procinfo[3], procinfo[4]);
423 fprintf(file, "\nBrand Index: %d\nCL Flush Line Size: %d\nLogical Processors: %d\nInitial APICID: %d\n\n",
424 procinfo[5], procinfo[6], procinfo[7], procinfo[8]);
428 fputs("-- CPU FEATURES --\n\n", file);
431 sse3 = cpuid_has_ecxfeature(CPUID_FEAT_ECX_SSE3),
432 pclmul = cpuid_has_ecxfeature(CPUID_FEAT_ECX_PCLMUL),
433 dtes64 = cpuid_has_ecxfeature(CPUID_FEAT_ECX_DTES64),
434 monitor = cpuid_has_ecxfeature(CPUID_FEAT_ECX_MONITOR),
435 ds_cpl = cpuid_has_ecxfeature(CPUID_FEAT_ECX_DS_CPL),
436 vmx = cpuid_has_ecxfeature(CPUID_FEAT_ECX_VMX),
437 smx = cpuid_has_ecxfeature(CPUID_FEAT_ECX_SMX),
438 est = cpuid_has_ecxfeature(CPUID_FEAT_ECX_EST),
439 tm2 = cpuid_has_ecxfeature(CPUID_FEAT_ECX_TM2),
440 ssse3 = cpuid_has_ecxfeature(CPUID_FEAT_ECX_SSSE3),
441 cid = cpuid_has_ecxfeature(CPUID_FEAT_ECX_CID),
442 fma = cpuid_has_ecxfeature(CPUID_FEAT_ECX_FMA),
443 cx16 = cpuid_has_ecxfeature(CPUID_FEAT_ECX_CX16),
444 etprd = cpuid_has_ecxfeature(CPUID_FEAT_ECX_ETPRD),
445 pdcm = cpuid_has_ecxfeature(CPUID_FEAT_ECX_PDCM),
446 dca = cpuid_has_ecxfeature(CPUID_FEAT_ECX_DCA),
447 sse4_1 = cpuid_has_ecxfeature(CPUID_FEAT_ECX_SSE4_1),
448 sse4_2 = cpuid_has_ecxfeature(CPUID_FEAT_ECX_SSE4_2),
449 x2_apic = cpuid_has_ecxfeature(CPUID_FEAT_ECX_x2APIC),
450 movbe = cpuid_has_ecxfeature(CPUID_FEAT_ECX_MOVBE),
451 popcnt = cpuid_has_ecxfeature(CPUID_FEAT_ECX_POPCNT),
452 aes = cpuid_has_ecxfeature(CPUID_FEAT_ECX_AES),
453 xsave = cpuid_has_ecxfeature(CPUID_FEAT_ECX_XSAVE),
454 osxsave = cpuid_has_ecxfeature(CPUID_FEAT_ECX_OSXSAVE),
455 avx = cpuid_has_ecxfeature(CPUID_FEAT_ECX_AVX);
457 #define YON(v) (v) ? "Yes" : "No"
458 if (featureset & CPUID_FEAT_ECX_ALL) {
459 fputs("-- ECX Features --\n", file);
460 fprintf(file, "SSE3: %s\n"
485 YON(sse3), YON(pclmul), YON(dtes64), YON(monitor), YON(ds_cpl),
486 YON(vmx), YON(smx), YON(est), YON(tm2), YON(ssse3), YON(cid),
487 YON(fma), YON(cx16), YON(etprd), YON(pdcm), YON(dca), YON(sse4_1),
488 YON(sse4_2), YON(x2_apic), YON(movbe), YON(popcnt), YON(aes),
489 YON(xsave), YON(osxsave), YON(avx)
492 if (featureset & CPUID_FEAT_ECX_SSE3)
493 fprintf(file, "SSE3: %s\n", YON(sse3));
494 if (featureset & CPUID_FEAT_ECX_PCLMUL)
495 fprintf(file, "PCLMUL: %s\n", YON(pclmul));
496 if (featureset & CPUID_FEAT_ECX_DTES64)
497 fprintf(file, "DTES64: %s\n", YON(dtes64));
498 if (featureset & CPUID_FEAT_ECX_MONITOR)
499 fprintf(file, "Monitor: %s\n", YON(monitor));
500 if (featureset & CPUID_FEAT_ECX_DS_CPL)
501 fprintf(file, "DS CPL: %s\n", YON(ds_cpl));
502 if (featureset & CPUID_FEAT_ECX_VMX)
503 fprintf(file, "VMX: %s\n", YON(vmx));
504 if (featureset & CPUID_FEAT_ECX_SMX)
505 fprintf(file, "SMX: %s\n", YON(smx));
506 if (featureset & CPUID_FEAT_ECX_EST)
507 fprintf(file, "EST: %s\n", YON(est));
508 if (featureset & CPUID_FEAT_ECX_TM2)
509 fprintf(file, "TM2: %s\n", YON(tm2));
510 if (featureset & CPUID_FEAT_ECX_SSSE3)
511 fprintf(file, "SSSE3: %s\n", YON(ssse3));
512 if (featureset & CPUID_FEAT_ECX_CID)
513 fprintf(file, "CID: %s\n", YON(cid));
514 if (featureset & CPUID_FEAT_ECX_FMA)
515 fprintf(file, "FMA: %s\n", YON(fma));
516 if (featureset & CPUID_FEAT_ECX_CX16)
517 fprintf(file, "CX16: %s\n", YON(cx16));
518 if (featureset & CPUID_FEAT_ECX_ETPRD)
519 fprintf(file, "ETPRD: %s\n", YON(etprd));
520 if (featureset & CPUID_FEAT_ECX_PDCM)
521 fprintf(file, "PDCM: %s\n", YON(pdcm));
522 if (featureset & CPUID_FEAT_ECX_DCA)
523 fprintf(file, "DCA: %s\n", YON(dca));
524 if (featureset & CPUID_FEAT_ECX_SSE4_1)
525 fprintf(file, "SSE4_1: %s\n", YON(sse4_1));
526 if (featureset & CPUID_FEAT_ECX_SSE4_2)
527 fprintf(file, "SSE4_2: %s\n", YON(sse4_2));
528 if (featureset & CPUID_FEAT_ECX_x2APIC)
529 fprintf(file, "x2APIC: %s\n", YON(x2_apic));
530 if (featureset & CPUID_FEAT_ECX_MOVBE)
531 fprintf(file, "MOVBE: %s\n", YON(movbe));
532 if (featureset & CPUID_FEAT_ECX_POPCNT)
533 fprintf(file, "POPCNT: %s\n", YON(popcnt));
534 if (featureset & CPUID_FEAT_ECX_AES)
535 fprintf(file, "AES: %s\n", YON(aes));
536 if (featureset & CPUID_FEAT_ECX_XSAVE)
537 fprintf(file, "XSAVE: %s\n", YON(xsave));
538 if (featureset & CPUID_FEAT_ECX_OSXSAVE)
539 fprintf(file, "OSXSAVE: %s\n", YON(osxsave));
540 if (featureset & CPUID_FEAT_ECX_AVX)
541 fprintf(file, "AVX: %s\n", YON(avx));
545 fpu = cpuid_has_edxfeature(CPUID_FEAT_EDX_FPU),
546 vme = cpuid_has_edxfeature(CPUID_FEAT_EDX_VME),
547 de = cpuid_has_edxfeature(CPUID_FEAT_EDX_DE),
548 pse = cpuid_has_edxfeature(CPUID_FEAT_EDX_PSE),
549 tsc = cpuid_has_edxfeature(CPUID_FEAT_EDX_TSC),
550 msr = cpuid_has_edxfeature(CPUID_FEAT_EDX_MSR),
551 pae = cpuid_has_edxfeature(CPUID_FEAT_EDX_PAE),
552 mce = cpuid_has_edxfeature(CPUID_FEAT_EDX_MCE),
553 cx8 = cpuid_has_edxfeature(CPUID_FEAT_EDX_CX8),
554 apic = cpuid_has_edxfeature(CPUID_FEAT_EDX_APIC),
555 sep = cpuid_has_edxfeature(CPUID_FEAT_EDX_SEP),
556 mtrr = cpuid_has_edxfeature(CPUID_FEAT_EDX_MTRR),
557 pge = cpuid_has_edxfeature(CPUID_FEAT_EDX_PGE),
558 mca = cpuid_has_edxfeature(CPUID_FEAT_EDX_MCA),
559 cmov = cpuid_has_edxfeature(CPUID_FEAT_EDX_CMOV),
560 pat = cpuid_has_edxfeature(CPUID_FEAT_EDX_PAT),
561 pse36 = cpuid_has_edxfeature(CPUID_FEAT_EDX_PSE36),
562 psn = cpuid_has_edxfeature(CPUID_FEAT_EDX_PSN),
563 clf = cpuid_has_edxfeature(CPUID_FEAT_EDX_CLF),
564 dtes = cpuid_has_edxfeature(CPUID_FEAT_EDX_DTES),
565 acpi = cpuid_has_edxfeature(CPUID_FEAT_EDX_ACPI),
566 mmx = cpuid_has_edxfeature(CPUID_FEAT_EDX_MMX),
567 fxsr = cpuid_has_edxfeature(CPUID_FEAT_EDX_FXSR),
568 sse = cpuid_has_edxfeature(CPUID_FEAT_EDX_SSE),
569 sse2 = cpuid_has_edxfeature(CPUID_FEAT_EDX_SSE2),
570 ss = cpuid_has_edxfeature(CPUID_FEAT_EDX_SS),
571 htt = cpuid_has_edxfeature(CPUID_FEAT_EDX_HTT),
572 tm1 = cpuid_has_edxfeature(CPUID_FEAT_EDX_TM1),
573 ia64 = cpuid_has_edxfeature(CPUID_FEAT_EDX_IA64),
574 pbe = cpuid_has_edxfeature(CPUID_FEAT_EDX_PBE);
576 if (featureset & CPUID_FEAT_EDX_ALL) {
577 fputs("-- EDX FEATURES --\n", file);
578 fprintf(file, "FPU: %s\n"
608 YON(fpu), YON(vme), YON(de), YON(pse), YON(tsc), YON(msr),
609 YON(pae), YON(mce), YON(cx8), YON(apic), YON(sep), YON(mtrr),
610 YON(pge), YON(mca), YON(cmov), YON(pat), YON(pse36), YON(psn),
611 YON(clf), YON(dtes), YON(acpi), YON(mmx), YON(fxsr), YON(sse),
612 YON(sse2), YON(ss), YON(htt), YON(tm1), YON(ia64), YON(pbe)
615 if (featureset & CPUID_FEAT_EDX_FPU)
616 fprintf(file, "FPU: %s\n", YON(fpu));
617 if (featureset & CPUID_FEAT_EDX_VME)
618 fprintf(file, "VME: %s\n", YON(vme));
619 if (featureset & CPUID_FEAT_EDX_DE)
620 fprintf(file, "DE: %s\n", YON(de));
621 if (featureset & CPUID_FEAT_EDX_PSE)
622 fprintf(file, "PSE: %s\n", YON(pse));
623 if (featureset & CPUID_FEAT_EDX_TSC)
624 fprintf(file, "TSC: %s\n", YON(tsc));
625 if (featureset & CPUID_FEAT_EDX_MSR)
626 fprintf(file, "MSR: %s\n", YON(msr));
627 if (featureset & CPUID_FEAT_EDX_PAE)
628 fprintf(file, "PAE: %s\n", YON(pae));
629 if (featureset & CPUID_FEAT_EDX_MCE)
630 fprintf(file, "MCE: %s\n", YON(mce));
631 if (featureset & CPUID_FEAT_EDX_CX8)
632 fprintf(file, "CX8: %s\n", YON(cx8));
633 if (featureset & CPUID_FEAT_EDX_APIC)
634 fprintf(file, "APIC: %s\n", YON(apic));
635 if (featureset & CPUID_FEAT_EDX_SEP)
636 fprintf(file, "SEP: %s\n", YON(sep));
637 if (featureset & CPUID_FEAT_EDX_MTRR)
638 fprintf(file, "MTRR: %s\n", YON(mtrr));
639 if (featureset & CPUID_FEAT_EDX_PGE)
640 fprintf(file, "PGE: %s\n", YON(pge));
641 if (featureset & CPUID_FEAT_EDX_MCA)
642 fprintf(file, "MCA: %s\n", YON(mca));
643 if (featureset & CPUID_FEAT_EDX_CMOV)
644 fprintf(file, "CMOV: %s\n", YON(cmov));
645 if (featureset & CPUID_FEAT_EDX_PAT)
646 fprintf(file, "PAT: %s\n", YON(pat));
647 if (featureset & CPUID_FEAT_EDX_PSE36)
648 fprintf(file, "PSE36: %s\n", YON(pse36));
649 if (featureset & CPUID_FEAT_EDX_PSN)
650 fprintf(file, "PSN: %s\n", YON(psn));
651 if (featureset & CPUID_FEAT_EDX_CLF)
652 fprintf(file, "CLF: %s\n", YON(clf));
653 if (featureset & CPUID_FEAT_EDX_DTES)
654 fprintf(file, "DTES:%s\n", YON(dtes));
655 if (featureset & CPUID_FEAT_EDX_ACPI)
656 fprintf(file, "ACPI: %s\n", YON(acpi));
657 if (featureset & CPUID_FEAT_EDX_MMX)
658 fprintf(file, "MMX: %s\n", YON(mmx));
659 if (featureset & CPUID_FEAT_EDX_FXSR)
660 fprintf(file, "FXSR: %s\n", YON(fxsr));
661 if (featureset & CPUID_FEAT_EDX_SSE)
662 fprintf(file, "SSE: %s\n", YON(sse));
663 if (featureset & CPUID_FEAT_EDX_SSE2)
664 fprintf(file, "SSE2: %s\n", YON(sse2));
665 if (featureset & CPUID_FEAT_EDX_SS)
666 fprintf(file, "SS: %s\n", YON(ss));
667 if (featureset & CPUID_FEAT_EDX_HTT)
668 fprintf(file, "HTT: %s\n", YON(htt));
669 if (featureset & CPUID_FEAT_EDX_TM1)
670 fprintf(file, "TM1: %s\n", YON(tm1));
671 if (featureset & CPUID_FEAT_EDX_IA64)
672 fprintf(file, "IA64: %s\n", YON(ia64));
673 if (featureset & CPUID_FEAT_EDX_PBE)
674 fprintf(file, "PBE: %s\n", YON(pbe));