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