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 { Cpu::tAVX512_BF16, "avx512_bf16" },
82 { Cpu::tAVX512_VP2INTERSECT, "avx512_vp2intersect" },
83 };
84 for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
85 if (cpu.has(tbl[i].type)) printf(" %s", tbl[i].str);
86 }
87 printf("\n");
88 if (cpu.has(Cpu::tPOPCNT)) {
89 const int n = 0x12345678; // bitcount = 13
90 const int ok = 13;
91 int r = PopCountTest(n).getCode<int (*)()>()();
92 if (r == ok) {
93 puts("popcnt ok");
94 } else {
95 printf("popcnt ng %d %d\n", r, ok);
96 }
97 }
98 /*
99 displayFamily displayModel
100 Opteron 2376 10 4
101 Core2 Duo T7100 6 F
102 Core i3-2120T 6 2A
103 Core i7-2600 6 2A
104 Xeon X5650 6 2C
105 Core i7-3517 6 3A
106 Core i7-3930K 6 2D
107 */
108 cpu.putFamily();
109 if (!cpu.has(Cpu::tINTEL)) return;
110 for (unsigned int i = 0; i < cpu.getDataCacheLevels(); i++) {
111 printf("cache level=%u data cache size=%u cores sharing data cache=%u\n", i, cpu.getDataCacheSize(i), cpu.getCoresSharingDataCache(i));
112 }
113 printf("SmtLevel =%u\n", cpu.getNumCores(Xbyak::util::SmtLevel));
114 printf("CoreLevel=%u\n", cpu.getNumCores(Xbyak::util::CoreLevel));
115 }
116
main()117 int main()
118 {
119 #ifdef XBYAK32
120 puts("32bit");
121 #else
122 puts("64bit");
123 #endif
124 putCPUinfo();
125 }
126