• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&region);
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