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