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