1 #include <stdbool.h>
2 #include <stdint.h>
3 #include <stddef.h>
4
5 #include <x86/cpuid.h>
6 #include <cpuinfo.h>
7
8
9 #if CPUINFO_ARCH_X86
10 #ifdef _MSC_VER
11 #pragma pack(push, 2)
12 #endif
13 struct fxsave_region {
14 uint16_t fpu_control_word;
15 uint16_t fpu_status_word;
16 uint16_t fpu_tag_word;
17 uint16_t fpu_opcode;
18 uint32_t fpu_instruction_pointer_offset;
19 uint32_t fpu_instruction_pointer_selector;
20 uint32_t fpu_operand_pointer_offset;
21 uint32_t fpu_operand_pointer_selector;
22 uint32_t mxcsr_state;
23 uint32_t mxcsr_mask;
24 uint64_t fpu_registers[8 * 2];
25 uint64_t xmm_registers[8 * 2];
26 uint64_t padding[28];
27 }
28 #ifndef _MSC_VER
29 __attribute__((__aligned__(16), __packed__))
30 #endif
31 ; /* end of fxsave_region structure */
32 #ifdef _MSC_VER
33 #pragma pack(pop, 2)
34 #endif
35 #endif
36
37
cpuinfo_x86_detect_isa(const struct cpuid_regs basic_info,const struct cpuid_regs extended_info,uint32_t max_base_index,uint32_t max_extended_index,enum cpuinfo_vendor vendor,enum cpuinfo_uarch uarch)38 struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
39 const struct cpuid_regs basic_info, const struct cpuid_regs extended_info,
40 uint32_t max_base_index, uint32_t max_extended_index,
41 enum cpuinfo_vendor vendor, enum cpuinfo_uarch uarch)
42 {
43 struct cpuinfo_x86_isa isa = { 0 };
44
45 const struct cpuid_regs structured_feature_info0 =
46 (max_base_index >= 7) ? cpuidex(7, 0) : (struct cpuid_regs) { 0, 0, 0, 0};
47 const struct cpuid_regs structured_feature_info1 =
48 (max_base_index >= 7) ? cpuidex(7, 1) : (struct cpuid_regs) { 0, 0, 0, 0};
49
50 const uint32_t processor_capacity_info_index = UINT32_C(0x80000008);
51 const struct cpuid_regs processor_capacity_info =
52 (max_extended_index >= processor_capacity_info_index) ?
53 cpuid(processor_capacity_info_index) : (struct cpuid_regs) { 0, 0, 0, 0 };
54
55 bool avx_regs = false, avx512_regs = false, mpx_regs = false;
56 /*
57 * OSXSAVE: Operating system enabled XSAVE instructions for application use:
58 * - Intel, AMD: ecx[bit 26] in basic info = XSAVE/XRSTOR instructions supported by a chip.
59 * - Intel, AMD: ecx[bit 27] in basic info = XSAVE/XRSTOR instructions enabled by OS.
60 */
61 const uint32_t osxsave_mask = UINT32_C(0x0C000000);
62 if ((basic_info.ecx & osxsave_mask) == osxsave_mask) {
63 uint64_t xcr0_valid_bits = 0;
64 if (max_base_index >= 0xD) {
65 const struct cpuid_regs regs = cpuidex(0xD, 0);
66 xcr0_valid_bits = ((uint64_t) regs.edx << 32) | regs.eax;
67 }
68
69 const uint64_t xfeature_enabled_mask = xgetbv(0);
70
71 /*
72 * AVX registers:
73 * - Intel, AMD: XFEATURE_ENABLED_MASK[bit 1] for low 128 bits of ymm registers
74 * - Intel, AMD: XFEATURE_ENABLED_MASK[bit 2] for high 128 bits of ymm registers
75 */
76 const uint64_t avx_regs_mask = UINT64_C(0x0000000000000006);
77 if ((xcr0_valid_bits & avx_regs_mask) == avx_regs_mask) {
78 avx_regs = (xfeature_enabled_mask & avx_regs_mask) == avx_regs_mask;
79 }
80
81 /*
82 * AVX512 registers:
83 * - Intel, AMD: XFEATURE_ENABLED_MASK[bit 1] for low 128 bits of zmm registers
84 * - Intel, AMD: XFEATURE_ENABLED_MASK[bit 2] for bits 128-255 of zmm registers
85 * - Intel: XFEATURE_ENABLED_MASK[bit 5] for 8 64-bit OpMask registers (k0-k7)
86 * - Intel: XFEATURE_ENABLED_MASK[bit 6] for the high 256 bits of the zmm registers zmm0-zmm15
87 * - Intel: XFEATURE_ENABLED_MASK[bit 7] for the 512-bit zmm registers zmm16-zmm31
88 */
89 const uint64_t avx512_regs_mask = UINT64_C(0x00000000000000E6);
90 if ((xcr0_valid_bits & avx512_regs_mask) == avx512_regs_mask) {
91 avx512_regs = (xfeature_enabled_mask & avx512_regs_mask) == avx512_regs_mask;
92 }
93
94 /*
95 * MPX registers:
96 * - Intel: XFEATURE_ENABLED_MASK[bit 3] for BNDREGS
97 * - Intel: XFEATURE_ENABLED_MASK[bit 4] for BNDCSR
98 */
99 const uint64_t mpx_regs_mask = UINT64_C(0x0000000000000018);
100 if ((xcr0_valid_bits & mpx_regs_mask) == mpx_regs_mask) {
101 mpx_regs = (xfeature_enabled_mask & mpx_regs_mask) == mpx_regs_mask;
102 }
103 }
104
105 #if CPUINFO_ARCH_X86
106 /*
107 * RDTSC instruction:
108 * - Intel, AMD: edx[bit 4] in basic info.
109 * - AMD: edx[bit 4] in extended info (reserved bit on Intel CPUs).
110 */
111 isa.rdtsc = !!((basic_info.edx | extended_info.edx) & UINT32_C(0x00000010));
112 #endif
113
114 /*
115 * SYSENTER/SYSEXIT instructions:
116 * - Intel, AMD: edx[bit 11] in basic info.
117 */
118 isa.sysenter = !!(basic_info.edx & UINT32_C(0x00000800));
119
120 #if CPUINFO_ARCH_X86
121 /*
122 * SYSCALL/SYSRET instructions:
123 * - Intel, AMD: edx[bit 11] in extended info.
124 */
125 isa.syscall = !!(extended_info.edx & UINT32_C(0x00000800));
126 #endif
127
128 /*
129 * RDMSR/WRMSR instructions:
130 * - Intel, AMD: edx[bit 5] in basic info.
131 * - AMD: edx[bit 5] in extended info (reserved bit on Intel CPUs).
132 */
133 isa.msr = !!((basic_info.edx | extended_info.edx) & UINT32_C(0x00000020));
134
135 /*
136 * CLZERO instruction:
137 * - AMD: ebx[bit 0] in processor capacity info (reserved bit on Intel CPUs).
138 */
139 isa.clzero = !!(processor_capacity_info.ebx & UINT32_C(0x00000001));
140
141 /*
142 * CLFLUSH instruction:
143 * - Intel, AMD: edx[bit 19] in basic info.
144 */
145 isa.clflush = !!(basic_info.edx & UINT32_C(0x00080000));
146
147 /*
148 * CLFLUSHOPT instruction:
149 * - Intel: ebx[bit 23] in structured feature info (ecx = 0).
150 */
151 isa.clflushopt = !!(structured_feature_info0.ebx & UINT32_C(0x00800000));
152
153 /*
154 * MWAIT/MONITOR instructions:
155 * - Intel, AMD: ecx[bit 3] in basic info.
156 */
157 isa.mwait = !!(basic_info.ecx & UINT32_C(0x00000008));
158
159 /*
160 * MWAITX/MONITORX instructions:
161 * - AMD: ecx[bit 29] in extended info.
162 */
163 isa.mwaitx = !!(extended_info.ecx & UINT32_C(0x20000000));
164
165 /*
166 * FXSAVE/FXRSTOR instructions:
167 * - Intel, AMD: edx[bit 24] in basic info.
168 * - AMD: edx[bit 24] in extended info (zero bit on Intel CPUs, EMMX bit on Cyrix CPUs).
169 */
170 switch (vendor) {
171 #if CPUINFO_ARCH_X86
172 case cpuinfo_vendor_cyrix:
173 case cpuinfo_vendor_nsc:
174 isa.emmx = !!(extended_info.edx & UINT32_C(0x01000000));
175 break;
176 #endif
177 default:
178 isa.fxsave = !!((basic_info.edx | extended_info.edx) & UINT32_C(0x01000000));
179 break;
180 }
181
182 /*
183 * XSAVE/XRSTOR instructions:
184 * - Intel, AMD: ecx[bit 26] in basic info.
185 */
186 isa.xsave = !!(basic_info.ecx & UINT32_C(0x04000000));
187
188 #if CPUINFO_ARCH_X86
189 /*
190 * x87 FPU instructions:
191 * - Intel, AMD: edx[bit 0] in basic info.
192 * - AMD: edx[bit 0] in extended info (reserved bit on Intel CPUs).
193 */
194 isa.fpu = !!((basic_info.edx | extended_info.edx) & UINT32_C(0x00000001));
195
196 /*
197 * MMX instructions:
198 * - Intel, AMD: edx[bit 23] in basic info.
199 * - AMD: edx[bit 23] in extended info (zero bit on Intel CPUs).
200 */
201 isa.mmx = !!((basic_info.edx | extended_info.edx) & UINT32_C(0x00800000));
202
203 /*
204 * MMX+/Integer SSE instructions:
205 * - Intel, AMD: edx[bit 25] in basic info (SSE feature flag).
206 * - Pre-SSE AMD: edx[bit 22] in extended info (zero bit on Intel CPUs).
207 */
208 isa.mmx_plus = !!((basic_info.edx & UINT32_C(0x02000000)) | (extended_info.edx & UINT32_C(0x00400000)));
209 #endif
210
211 /*
212 * 3dnow! instructions:
213 * - AMD: edx[bit 31] of extended info (zero bit on Intel CPUs).
214 */
215 isa.three_d_now = !!(extended_info.edx & UINT32_C(0x80000000));
216
217 /*
218 * 3dnow!+ instructions:
219 * - AMD: edx[bit 30] of extended info (zero bit on Intel CPUs).
220 */
221 isa.three_d_now_plus = !!(extended_info.edx & UINT32_C(0x40000000));
222
223 #if CPUINFO_ARCH_X86
224 /*
225 * 3dnow! Geode instructions:
226 * - No CPUID bit, detect as Geode microarchitecture + 3dnow!+ support
227 */
228 isa.three_d_now_geode = isa.three_d_now_plus && (uarch == cpuinfo_uarch_geode);
229 #endif
230
231 /*
232 * PREFETCH instruction:
233 * - AMD: ecx[bit 8] of extended info (one of 3dnow! prefetch instructions).
234 * On Intel this bit indicates PREFETCHW, but not PREFETCH support.
235 * - AMD: edx[bit 31] of extended info (implied by 3dnow! support). Reserved bit on Intel CPUs.
236 * - AMD: edx[bit 30] of extended info (implied by 3dnow!+ support). Reserved bit on Intel CPUs.
237 * - AMD: edx[bit 29] of extended info (x86-64 support). Does not imply PREFETCH support on non-AMD CPUs!!!
238 */
239 switch (vendor) {
240 case cpuinfo_vendor_intel:
241 /*
242 * Instruction is not documented in the manual,
243 * and the 3dnow! prefetch CPUID bit indicates PREFETCHW instruction.
244 */
245 break;
246 case cpuinfo_vendor_amd:
247 case cpuinfo_vendor_hygon:
248 isa.prefetch = !!((extended_info.ecx & UINT32_C(0x00000100)) | (extended_info.edx & UINT32_C(0xE0000000)));
249 break;
250 default:
251 /*
252 * Conservatively assume, that 3dnow!/3dnow!+ support implies PREFETCH support, but
253 * 3dnow! prefetch CPUID bit follows Intel spec (PREFETCHW, but not PREFETCH).
254 */
255 isa.prefetch = !!(extended_info.edx & UINT32_C(0xC0000000));
256 break;
257 }
258
259 /*
260 * PREFETCHW instruction:
261 * - AMD: ecx[bit 8] of extended info (one of 3dnow! prefetch instructions).
262 * - Intel: ecx[bit 8] of extended info (PREFETCHW instruction only).
263 * - AMD: edx[bit 31] of extended info (implied by 3dnow! support). Reserved bit on Intel CPUs.
264 * - AMD: edx[bit 30] of extended info (implied by 3dnow!+ support). Reserved bit on Intel CPUs.
265 * - AMD: edx[bit 29] of extended info (x86-64 support). Does not imply PREFETCHW support on non-AMD CPUs!!!
266 */
267 switch (vendor) {
268 case cpuinfo_vendor_amd:
269 case cpuinfo_vendor_hygon:
270 isa.prefetchw = !!((extended_info.ecx & UINT32_C(0x00000100)) | (extended_info.edx & UINT32_C(0xE0000000)));
271 break;
272 default:
273 /* Assume, that 3dnow!/3dnow!+ support implies PREFETCHW support, not implications from x86-64 support */
274 isa.prefetchw = !!((extended_info.ecx & UINT32_C(0x00000100)) | (extended_info.edx & UINT32_C(0xC0000000)));
275 break;
276 }
277
278 /*
279 * PREFETCHWT1 instruction:
280 * - Intel: ecx[bit 0] of structured feature info (ecx = 0). Reserved bit on AMD.
281 */
282 isa.prefetchwt1 = !!(structured_feature_info0.ecx & UINT32_C(0x00000001));
283
284 #if CPUINFO_ARCH_X86
285 /*
286 * SSE instructions:
287 * - Intel, AMD: edx[bit 25] in basic info.
288 */
289 isa.sse = !!(basic_info.edx & UINT32_C(0x02000000));
290
291 /*
292 * SSE2 instructions:
293 * - Intel, AMD: edx[bit 26] in basic info.
294 */
295 isa.sse2 = !!(basic_info.edx & UINT32_C(0x04000000));
296 #endif
297
298 /*
299 * SSE3 instructions:
300 * - Intel, AMD: ecx[bit 0] in basic info.
301 */
302 isa.sse3 = !!(basic_info.ecx & UINT32_C(0x00000001));
303
304 #if CPUINFO_ARCH_X86
305 /*
306 * CPUs with x86-64 or SSE3 always support DAZ (denormals-as-zero) mode.
307 * Only early Pentium 4 models may not support it.
308 */
309 if (isa.sse3) {
310 isa.daz = true;
311 } else {
312 /* Detect DAZ support from masked MXCSR bits */
313 if (isa.sse && isa.fxsave) {
314 struct fxsave_region region = { 0 };
315 #ifdef _MSC_VER
316 _fxsave(®ion);
317 #else
318 __asm__ __volatile__ ("fxsave %[region];" : [region] "+m" (region));
319 #endif
320
321 /*
322 * Denormals-as-zero (DAZ) flag:
323 * - Intel, AMD: MXCSR[bit 6]
324 */
325 isa.daz = !!(region.mxcsr_mask & UINT32_C(0x00000040));
326 }
327 }
328 #endif
329
330 /*
331 * SSSE3 instructions:
332 * - Intel, AMD: ecx[bit 9] in basic info.
333 */
334 isa.ssse3 = !!(basic_info.ecx & UINT32_C(0x0000200));
335
336
337 /*
338 * SSE4.1 instructions:
339 * - Intel, AMD: ecx[bit 19] in basic info.
340 */
341 isa.sse4_1 = !!(basic_info.ecx & UINT32_C(0x00080000));
342
343 /*
344 * SSE4.2 instructions:
345 * - Intel: ecx[bit 20] in basic info (reserved bit on AMD CPUs).
346 */
347 isa.sse4_2 = !!(basic_info.ecx & UINT32_C(0x00100000));
348
349 /*
350 * SSE4A instructions:
351 * - AMD: ecx[bit 6] in extended info (reserved bit on Intel CPUs).
352 */
353 isa.sse4a = !!(extended_info.ecx & UINT32_C(0x00000040));
354
355 /*
356 * Misaligned memory operands in SSE instructions:
357 * - AMD: ecx[bit 7] in extended info (reserved bit on Intel CPUs).
358 */
359 isa.misaligned_sse = !!(extended_info.ecx & UINT32_C(0x00000080));
360
361 /*
362 * AVX instructions:
363 * - Intel, AMD: ecx[bit 28] in basic info.
364 */
365 isa.avx = avx_regs && !!(basic_info.ecx & UINT32_C(0x10000000));
366
367 /*
368 * FMA3 instructions:
369 * - Intel: ecx[bit 12] in basic info (reserved bit on AMD CPUs).
370 */
371 isa.fma3 = avx_regs && !!(basic_info.ecx & UINT32_C(0x00001000));
372
373 /*
374 * FMA4 instructions:
375 * - AMD: ecx[bit 16] in extended info (reserved bit on Intel CPUs).
376 */
377 isa.fma4 = avx_regs && !!(extended_info.ecx & UINT32_C(0x00010000));
378
379 /*
380 * XOP instructions:
381 * - AMD: ecx[bit 11] in extended info (reserved bit on Intel CPUs).
382 */
383 isa.xop = avx_regs && !!(extended_info.ecx & UINT32_C(0x00000800));
384
385 /*
386 * F16C instructions:
387 * - Intel, AMD: ecx[bit 29] in basic info.
388 */
389 isa.f16c = avx_regs && !!(basic_info.ecx & UINT32_C(0x20000000));
390
391 /*
392 * AVX2 instructions:
393 * - Intel: ebx[bit 5] in structured feature info (ecx = 0).
394 */
395 isa.avx2 = avx_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00000020));
396
397 /*
398 * AVX512F instructions:
399 * - Intel: ebx[bit 16] in structured feature info (ecx = 0).
400 */
401 isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000));
402
403 /*
404 * AVX512PF instructions:
405 * - Intel: ebx[bit 26] in structured feature info (ecx = 0).
406 */
407 isa.avx512pf = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x04000000));
408
409 /*
410 * AVX512ER instructions:
411 * - Intel: ebx[bit 27] in structured feature info (ecx = 0).
412 */
413 isa.avx512er = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x08000000));
414
415 /*
416 * AVX512CD instructions:
417 * - Intel: ebx[bit 28] in structured feature info (ecx = 0).
418 */
419 isa.avx512cd = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x10000000));
420
421 /*
422 * AVX512DQ instructions:
423 * - Intel: ebx[bit 17] in structured feature info (ecx = 0).
424 */
425 isa.avx512dq = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00020000));
426
427 /*
428 * AVX512BW instructions:
429 * - Intel: ebx[bit 30] in structured feature info (ecx = 0).
430 */
431 isa.avx512bw = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x40000000));
432
433 /*
434 * AVX512VL instructions:
435 * - Intel: ebx[bit 31] in structured feature info (ecx = 0).
436 */
437 isa.avx512vl = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x80000000));
438
439 /*
440 * AVX512IFMA instructions:
441 * - Intel: ebx[bit 21] in structured feature info (ecx = 0).
442 */
443 isa.avx512ifma = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00200000));
444
445 /*
446 * AVX512VBMI instructions:
447 * - Intel: ecx[bit 1] in structured feature info (ecx = 0).
448 */
449 isa.avx512vbmi = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000002));
450
451 /*
452 * AVX512VBMI2 instructions:
453 * - Intel: ecx[bit 6] in structured feature info (ecx = 0).
454 */
455 isa.avx512vbmi2 = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000040));
456
457 /*
458 * AVX512BITALG instructions:
459 * - Intel: ecx[bit 12] in structured feature info (ecx = 0).
460 */
461 isa.avx512bitalg = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00001000));
462
463 /*
464 * AVX512VPOPCNTDQ instructions:
465 * - Intel: ecx[bit 14] in structured feature info (ecx = 0).
466 */
467 isa.avx512vpopcntdq = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00004000));
468
469 /*
470 * AVX512VNNI instructions:
471 * - Intel: ecx[bit 11] in structured feature info (ecx = 0).
472 */
473 isa.avx512vnni = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000800));
474
475 /*
476 * AVX512_4VNNIW instructions:
477 * - Intel: edx[bit 2] in structured feature info (ecx = 0).
478 */
479 isa.avx512_4vnniw = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000004));
480
481 /*
482 * AVX512_4FMAPS instructions:
483 * - Intel: edx[bit 3] in structured feature info (ecx = 0).
484 */
485 isa.avx512_4fmaps = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000008));
486
487 /*
488 * AVX512_VP2INTERSECT instructions:
489 * - Intel: edx[bit 8] in structured feature info (ecx = 0).
490 */
491 isa.avx512vp2intersect = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000100));
492
493 /*
494 * AVX512_BF16 instructions:
495 * - Intel: eax[bit 5] in structured feature info (ecx = 1).
496 */
497 isa.avx512bf16 = avx512_regs && !!(structured_feature_info1.eax & UINT32_C(0x00000020));
498
499 /*
500 * HLE instructions:
501 * - Intel: ebx[bit 4] in structured feature info (ecx = 0).
502 */
503 isa.hle = !!(structured_feature_info0.ebx & UINT32_C(0x00000010));
504
505 /*
506 * RTM instructions:
507 * - Intel: ebx[bit 11] in structured feature info (ecx = 0).
508 */
509 isa.rtm = !!(structured_feature_info0.ebx & UINT32_C(0x00000800));
510
511 /*
512 * XTEST instruction:
513 * - Intel: either HLE or RTM is supported
514 */
515 isa.xtest = isa.hle || isa.rtm;
516
517 /*
518 * MPX registers and instructions:
519 * - Intel: ebx[bit 14] in structured feature info (ecx = 0).
520 */
521 isa.mpx = mpx_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00004000));
522
523 #if CPUINFO_ARCH_X86
524 /*
525 * CMOV instructions:
526 * - Intel, AMD: edx[bit 15] in basic info.
527 * - AMD: edx[bit 15] in extended info (zero bit on Intel CPUs).
528 */
529 isa.cmov = !!((basic_info.edx | extended_info.edx) & UINT32_C(0x00008000));
530
531 /*
532 * CMPXCHG8B instruction:
533 * - Intel, AMD: edx[bit 8] in basic info.
534 * - AMD: edx[bit 8] in extended info (reserved bit on Intel CPUs).
535 */
536 isa.cmpxchg8b = !!((basic_info.edx | extended_info.edx) & UINT32_C(0x00000100));
537 #endif
538
539 /*
540 * CMPXCHG16B instruction:
541 * - Intel, AMD: ecx[bit 13] in basic info.
542 */
543 isa.cmpxchg16b = !!(basic_info.ecx & UINT32_C(0x00002000));
544
545 /*
546 * CLWB instruction:
547 * - Intel: ebx[bit 24] in structured feature info (ecx = 0).
548 */
549 isa.clwb = !!(structured_feature_info0.ebx & UINT32_C(0x01000000));
550
551 /*
552 * MOVBE instruction:
553 * - Intel: ecx[bit 22] in basic info.
554 */
555 isa.movbe = !!(basic_info.ecx & UINT32_C(0x00400000));
556
557 #if CPUINFO_ARCH_X86_64
558 /*
559 * Some early x86-64 CPUs lack LAHF & SAHF instructions.
560 * A special CPU feature bit must be checked to ensure their availability:
561 * - Intel, AMD: ecx[bit 0] in extended info.
562 */
563 isa.lahf_sahf = !!(extended_info.ecx & UINT32_C(0x00000001));
564 #endif
565
566 /*
567 * RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE instructions.
568 * - Intel: ebx[bit 0] in structured feature info (ecx = 0).
569 */
570 isa.fs_gs_base = !!(structured_feature_info0.ebx & UINT32_C(0x00000001));
571
572 /*
573 * LZCNT instruction:
574 * - Intel, AMD: ecx[bit 5] in extended info.
575 */
576 isa.lzcnt = !!(extended_info.ecx & UINT32_C(0x00000020));
577
578 /*
579 * POPCNT instruction:
580 * - Intel, AMD: ecx[bit 23] in basic info.
581 */
582 isa.popcnt = !!(basic_info.ecx & UINT32_C(0x00800000));
583
584 /*
585 * TBM instructions:
586 * - AMD: ecx[bit 21] in extended info (reserved bit on Intel CPUs).
587 */
588 isa.tbm = !!(extended_info.ecx & UINT32_C(0x00200000));
589
590 /*
591 * BMI instructions:
592 * - Intel, AMD: ebx[bit 3] in structured feature info (ecx = 0).
593 */
594 isa.bmi = !!(structured_feature_info0.ebx & UINT32_C(0x00000008));
595
596 /*
597 * BMI2 instructions:
598 * - Intel: ebx[bit 8] in structured feature info (ecx = 0).
599 */
600 isa.bmi2 = !!(structured_feature_info0.ebx & UINT32_C(0x00000100));
601
602 /*
603 * ADCX/ADOX instructions:
604 * - Intel: ebx[bit 19] in structured feature info (ecx = 0).
605 */
606 isa.adx = !!(structured_feature_info0.ebx & UINT32_C(0x00080000));
607
608 /*
609 * AES instructions:
610 * - Intel: ecx[bit 25] in basic info (reserved bit on AMD CPUs).
611 */
612 isa.aes = !!(basic_info.ecx & UINT32_C(0x02000000));
613
614 /*
615 * VAES instructions:
616 * - Intel: ecx[bit 9] in structured feature info (ecx = 0).
617 */
618 isa.vaes = !!(structured_feature_info0.ecx & UINT32_C(0x00000200));
619
620 /*
621 * PCLMULQDQ instruction:
622 * - Intel: ecx[bit 1] in basic info (reserved bit on AMD CPUs).
623 */
624 isa.pclmulqdq = !!(basic_info.ecx & UINT32_C(0x00000002));
625
626 /*
627 * VPCLMULQDQ instruction:
628 * - Intel: ecx[bit 10] in structured feature info (ecx = 0).
629 */
630 isa.vpclmulqdq = !!(structured_feature_info0.ecx & UINT32_C(0x00000400));
631
632 /*
633 * GFNI instructions:
634 * - Intel: ecx[bit 8] in structured feature info (ecx = 0).
635 */
636 isa.gfni = !!(structured_feature_info0.ecx & UINT32_C(0x00000100));
637
638 /*
639 * RDRAND instruction:
640 * - Intel: ecx[bit 30] in basic info (reserved bit on AMD CPUs).
641 */
642 isa.rdrand = !!(basic_info.ecx & UINT32_C(0x40000000));
643
644 /*
645 * RDSEED instruction:
646 * - Intel: ebx[bit 18] in structured feature info (ecx = 0).
647 */
648 isa.rdseed = !!(structured_feature_info0.ebx & UINT32_C(0x00040000));
649
650 /*
651 * SHA instructions:
652 * - Intel: ebx[bit 29] in structured feature info (ecx = 0).
653 */
654 isa.sha = !!(structured_feature_info0.ebx & UINT32_C(0x20000000));
655
656 if (vendor == cpuinfo_vendor_via) {
657 const struct cpuid_regs padlock_meta_info = cpuid(UINT32_C(0xC0000000));
658 const uint32_t max_padlock_index = padlock_meta_info.eax;
659 const uint32_t padlock_info_index = UINT32_C(0xC0000001);
660 if (max_padlock_index >= padlock_info_index) {
661 const struct cpuid_regs padlock_info = cpuid(padlock_info_index);
662
663 /*
664 * Padlock RNG extension:
665 * - VIA: edx[bit 2] in padlock info = RNG exists on chip flag.
666 * - VIA: edx[bit 3] in padlock info = RNG enabled by OS.
667 */
668 const uint32_t padlock_rng_mask = UINT32_C(0x0000000C);
669 isa.rng = (padlock_info.edx & padlock_rng_mask) == padlock_rng_mask;
670
671 /*
672 * Padlock ACE extension:
673 * - VIA: edx[bit 6] in padlock info = ACE exists on chip flag.
674 * - VIA: edx[bit 7] in padlock info = ACE enabled by OS.
675 */
676 const uint32_t padlock_ace_mask = UINT32_C(0x000000C0);
677 isa.ace = (padlock_info.edx & padlock_ace_mask) == padlock_ace_mask;
678
679 /*
680 * Padlock ACE 2 extension:
681 * - VIA: edx[bit 8] in padlock info = ACE2 exists on chip flag.
682 * - VIA: edx[bit 9] in padlock info = ACE 2 enabled by OS.
683 */
684 const uint32_t padlock_ace2_mask = UINT32_C(0x00000300);
685 isa.ace2 = (padlock_info.edx & padlock_ace2_mask) == padlock_ace2_mask;
686
687 /*
688 * Padlock PHE extension:
689 * - VIA: edx[bit 10] in padlock info = PHE exists on chip flag.
690 * - VIA: edx[bit 11] in padlock info = PHE enabled by OS.
691 */
692 const uint32_t padlock_phe_mask = UINT32_C(0x00000C00);
693 isa.phe = (padlock_info.edx & padlock_phe_mask) == padlock_phe_mask;
694
695 /*
696 * Padlock PMM extension:
697 * - VIA: edx[bit 12] in padlock info = PMM exists on chip flag.
698 * - VIA: edx[bit 13] in padlock info = PMM enabled by OS.
699 */
700 const uint32_t padlock_pmm_mask = UINT32_C(0x00003000);
701 isa.pmm = (padlock_info.edx & padlock_pmm_mask) == padlock_pmm_mask;
702 }
703 }
704
705 /*
706 * LWP instructions:
707 * - AMD: ecx[bit 15] in extended info (reserved bit on Intel CPUs).
708 */
709 isa.lwp = !!(extended_info.ecx & UINT32_C(0x00008000));
710
711 /*
712 * RDTSCP instruction:
713 * - Intel, AMD: edx[bit 27] in extended info.
714 */
715 isa.rdtscp = !!(extended_info.edx & UINT32_C(0x08000000));
716
717 /*
718 * RDPID instruction:
719 * - Intel: ecx[bit 22] in structured feature info (ecx = 0).
720 */
721 isa.rdpid = !!(structured_feature_info0.ecx & UINT32_C(0x00400000));
722
723 return isa;
724 }
725