1 #include <stdio.h>
2 #define XBYAK_NO_OP_NAMES
3 #include "xbyak/xbyak_util.h"
4 
5 #define NUM_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
6 
7 struct PopCountTest : public Xbyak::CodeGenerator {
PopCountTestPopCountTest8 	PopCountTest(int n)
9 	{
10 		mov(eax, n);
11 		popcnt(eax, eax);
12 		ret();
13 	}
14 };
15 
putCPUinfo()16 void putCPUinfo()
17 {
18 	using namespace Xbyak::util;
19 	Cpu cpu;
20 	printf("vendor %s\n", cpu.has(Cpu::tINTEL) ? "intel" : "amd");
21 	static const struct {
22 		Cpu::Type type;
23 		const char *str;
24 	} tbl[] = {
25 		{ Cpu::tMMX, "mmx" },
26 		{ Cpu::tMMX2, "mmx2" },
27 		{ Cpu::tCMOV, "cmov" },
28 		{ Cpu::tSSE, "sse" },
29 		{ Cpu::tSSE2, "sse2" },
30 		{ Cpu::tSSE3, "sse3" },
31 		{ Cpu::tSSSE3, "ssse3" },
32 		{ Cpu::tSSE41, "sse41" },
33 		{ Cpu::tSSE42, "sse42" },
34 		{ Cpu::tPOPCNT, "popcnt" },
35 		{ Cpu::t3DN, "3dn" },
36 		{ Cpu::tE3DN, "e3dn" },
37 		{ Cpu::tSSE4a, "sse4a" },
38 		{ Cpu::tSSE5, "sse5" },
39 		{ Cpu::tAESNI, "aesni" },
40 		{ Cpu::tRDTSCP, "rdtscp" },
41 		{ Cpu::tOSXSAVE, "osxsave(xgetvb)" },
42 		{ Cpu::tPCLMULQDQ, "pclmulqdq" },
43 		{ Cpu::tAVX, "avx" },
44 		{ Cpu::tFMA, "fma" },
45 		{ Cpu::tAVX2, "avx2" },
46 		{ Cpu::tBMI1, "bmi1" },
47 		{ Cpu::tBMI2, "bmi2" },
48 		{ Cpu::tLZCNT, "lzcnt" },
49 		{ Cpu::tPREFETCHW, "prefetchw" },
50 		{ Cpu::tENHANCED_REP, "enh_rep" },
51 		{ Cpu::tRDRAND, "rdrand" },
52 		{ Cpu::tADX, "adx" },
53 		{ Cpu::tRDSEED, "rdseed" },
54 		{ Cpu::tSMAP, "smap" },
55 		{ Cpu::tHLE, "hle" },
56 		{ Cpu::tRTM, "rtm" },
57 		{ Cpu::tMPX, "mpx" },
58 		{ Cpu::tSHA, "sha" },
59 		{ Cpu::tPREFETCHWT1, "prefetchwt1" },
60 		{ Cpu::tF16C, "f16c" },
61 		{ Cpu::tMOVBE, "movbe" },
62 		{ Cpu::tAVX512F, "avx512f" },
63 		{ Cpu::tAVX512DQ, "avx512dq" },
64 		{ Cpu::tAVX512IFMA, "avx512_ifma" },
65 		{ Cpu::tAVX512PF, "avx512pf" },
66 		{ Cpu::tAVX512ER, "avx512er" },
67 		{ Cpu::tAVX512CD, "avx512cd" },
68 		{ Cpu::tAVX512BW, "avx512bw" },
69 		{ Cpu::tAVX512VL, "avx512vl" },
70 		{ Cpu::tAVX512VBMI, "avx512_vbmi" },
71 		{ Cpu::tAVX512_4VNNIW, "avx512_4vnniw" },
72 		{ Cpu::tAVX512_4FMAPS, "avx512_4fmaps" },
73 
74 		{ Cpu::tAVX512_VBMI2, "avx512_vbmi2" },
75 		{ Cpu::tGFNI, "gfni" },
76 		{ Cpu::tVAES, "vaes" },
77 		{ Cpu::tVPCLMULQDQ, "vpclmulqdq" },
78 		{ Cpu::tAVX512_VNNI, "avx512_vnni" },
79 		{ Cpu::tAVX512_BITALG, "avx512_bitalg" },
80 		{ Cpu::tAVX512_VPOPCNTDQ, "avx512_vpopcntdq" },
81 	};
82 	for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
83 		if (cpu.has(tbl[i].type)) printf(" %s", tbl[i].str);
84 	}
85 	printf("\n");
86 	if (cpu.has(Cpu::tPOPCNT)) {
87 		const int n = 0x12345678; // bitcount = 13
88 		const int ok = 13;
89 		int r = PopCountTest(n).getCode<int (*)()>()();
90 		if (r == ok) {
91 			puts("popcnt ok");
92 		} else {
93 			printf("popcnt ng %d %d\n", r, ok);
94 		}
95 	}
96 	/*
97 		                displayFamily displayModel
98 		Opteron 2376        10            4
99 		Core2 Duo T7100      6            F
100 		Core i3-2120T        6           2A
101 		Core i7-2600         6           2A
102 		Xeon X5650           6           2C
103 		Core i7-3517         6           3A
104 		Core i7-3930K        6           2D
105 	*/
106 	cpu.putFamily();
107 	if (!cpu.has(Cpu::tINTEL)) return;
108 	for (unsigned int i = 0; i < cpu.getDataCacheLevels(); i++) {
109 		printf("cache level=%u data cache size=%u cores sharing data cache=%u\n", i, cpu.getDataCacheSize(i), cpu.getCoresSharingDataCache(i));
110 	}
111 	printf("SmtLevel =%u\n", cpu.getNumCores(Xbyak::util::SmtLevel));
112 	printf("CoreLevel=%u\n", cpu.getNumCores(Xbyak::util::CoreLevel));
113 }
114 
main()115 int main()
116 {
117 #ifdef XBYAK32
118 	puts("32bit");
119 #else
120 	puts("64bit");
121 #endif
122 	putCPUinfo();
123 }
124