1
2
3
4
5
6
7
8
9
10
11#ifndef ZSTD_COMMON_CPU_H
12#define ZSTD_COMMON_CPU_H
13
14
15
16
17
18
19#include "mem.h"
20
21
22typedef struct {
23 U32 f1c;
24 U32 f1d;
25 U32 f7b;
26 U32 f7c;
27} ZSTD_cpuid_t;
28
29MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
30 U32 f1c = 0;
31 U32 f1d = 0;
32 U32 f7b = 0;
33 U32 f7c = 0;
34#if defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
35
36
37
38
39 U32 n;
40 __asm__(
41 "pushl %%ebx\n\t"
42 "cpuid\n\t"
43 "popl %%ebx\n\t"
44 : "=a"(n)
45 : "a"(0)
46 : "ecx", "edx");
47 if (n >= 1) {
48 U32 f1a;
49 __asm__(
50 "pushl %%ebx\n\t"
51 "cpuid\n\t"
52 "popl %%ebx\n\t"
53 : "=a"(f1a), "=c"(f1c), "=d"(f1d)
54 : "a"(1));
55 }
56 if (n >= 7) {
57 __asm__(
58 "pushl %%ebx\n\t"
59 "cpuid\n\t"
60 "movl %%ebx, %%eax\n\t"
61 "popl %%ebx"
62 : "=a"(f7b), "=c"(f7c)
63 : "a"(7), "c"(0)
64 : "edx");
65 }
66#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__)
67 U32 n;
68 __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx");
69 if (n >= 1) {
70 U32 f1a;
71 __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx");
72 }
73 if (n >= 7) {
74 U32 f7a;
75 __asm__("cpuid"
76 : "=a"(f7a), "=b"(f7b), "=c"(f7c)
77 : "a"(7), "c"(0)
78 : "edx");
79 }
80#endif
81 {
82 ZSTD_cpuid_t cpuid;
83 cpuid.f1c = f1c;
84 cpuid.f1d = f1d;
85 cpuid.f7b = f7b;
86 cpuid.f7c = f7c;
87 return cpuid;
88 }
89}
90
91#define X(name, r, bit) \
92 MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \
93 return ((cpuid.r) & (1U << bit)) != 0; \
94 }
95
96
97#define C(name, bit) X(name, f1c, bit)
98 C(sse3, 0)
99 C(pclmuldq, 1)
100 C(dtes64, 2)
101 C(monitor, 3)
102 C(dscpl, 4)
103 C(vmx, 5)
104 C(smx, 6)
105 C(eist, 7)
106 C(tm2, 8)
107 C(ssse3, 9)
108 C(cnxtid, 10)
109 C(fma, 12)
110 C(cx16, 13)
111 C(xtpr, 14)
112 C(pdcm, 15)
113 C(pcid, 17)
114 C(dca, 18)
115 C(sse41, 19)
116 C(sse42, 20)
117 C(x2apic, 21)
118 C(movbe, 22)
119 C(popcnt, 23)
120 C(tscdeadline, 24)
121 C(aes, 25)
122 C(xsave, 26)
123 C(osxsave, 27)
124 C(avx, 28)
125 C(f16c, 29)
126 C(rdrand, 30)
127#undef C
128#define D(name, bit) X(name, f1d, bit)
129 D(fpu, 0)
130 D(vme, 1)
131 D(de, 2)
132 D(pse, 3)
133 D(tsc, 4)
134 D(msr, 5)
135 D(pae, 6)
136 D(mce, 7)
137 D(cx8, 8)
138 D(apic, 9)
139 D(sep, 11)
140 D(mtrr, 12)
141 D(pge, 13)
142 D(mca, 14)
143 D(cmov, 15)
144 D(pat, 16)
145 D(pse36, 17)
146 D(psn, 18)
147 D(clfsh, 19)
148 D(ds, 21)
149 D(acpi, 22)
150 D(mmx, 23)
151 D(fxsr, 24)
152 D(sse, 25)
153 D(sse2, 26)
154 D(ss, 27)
155 D(htt, 28)
156 D(tm, 29)
157 D(pbe, 31)
158#undef D
159
160
161#define B(name, bit) X(name, f7b, bit)
162 B(bmi1, 3)
163 B(hle, 4)
164 B(avx2, 5)
165 B(smep, 7)
166 B(bmi2, 8)
167 B(erms, 9)
168 B(invpcid, 10)
169 B(rtm, 11)
170 B(mpx, 14)
171 B(avx512f, 16)
172 B(avx512dq, 17)
173 B(rdseed, 18)
174 B(adx, 19)
175 B(smap, 20)
176 B(avx512ifma, 21)
177 B(pcommit, 22)
178 B(clflushopt, 23)
179 B(clwb, 24)
180 B(avx512pf, 26)
181 B(avx512er, 27)
182 B(avx512cd, 28)
183 B(sha, 29)
184 B(avx512bw, 30)
185 B(avx512vl, 31)
186#undef B
187#define C(name, bit) X(name, f7c, bit)
188 C(prefetchwt1, 0)
189 C(avx512vbmi, 1)
190#undef C
191
192#undef X
193
194#endif
195