xref: /aosp_15_r20/external/cpuinfo/src/x86/cpuid.h (revision 2b54f0db79fd8303838913b20ff3780cddaa909f)
1*2b54f0dbSXin Li #pragma once
2*2b54f0dbSXin Li #include <stdint.h>
3*2b54f0dbSXin Li 
4*2b54f0dbSXin Li #if defined(__GNUC__)
5*2b54f0dbSXin Li 	#include <cpuid.h>
6*2b54f0dbSXin Li #elif defined(_MSC_VER)
7*2b54f0dbSXin Li 	#include <intrin.h>
8*2b54f0dbSXin Li #endif
9*2b54f0dbSXin Li 
10*2b54f0dbSXin Li #if CPUINFO_MOCK
11*2b54f0dbSXin Li 	#include <cpuinfo-mock.h>
12*2b54f0dbSXin Li #endif
13*2b54f0dbSXin Li #include <x86/api.h>
14*2b54f0dbSXin Li 
15*2b54f0dbSXin Li 
16*2b54f0dbSXin Li #if defined(__GNUC__) || defined(_MSC_VER)
cpuid(uint32_t eax)17*2b54f0dbSXin Li 	static inline struct cpuid_regs cpuid(uint32_t eax) {
18*2b54f0dbSXin Li 		#if CPUINFO_MOCK
19*2b54f0dbSXin Li 			uint32_t regs_array[4];
20*2b54f0dbSXin Li 			cpuinfo_mock_get_cpuid(eax, regs_array);
21*2b54f0dbSXin Li 			return (struct cpuid_regs) {
22*2b54f0dbSXin Li 				.eax = regs_array[0],
23*2b54f0dbSXin Li 				.ebx = regs_array[1],
24*2b54f0dbSXin Li 				.ecx = regs_array[2],
25*2b54f0dbSXin Li 				.edx = regs_array[3],
26*2b54f0dbSXin Li 			};
27*2b54f0dbSXin Li 		#else
28*2b54f0dbSXin Li 			struct cpuid_regs regs;
29*2b54f0dbSXin Li 			#if defined(__GNUC__)
30*2b54f0dbSXin Li 				__cpuid(eax, regs.eax, regs.ebx, regs.ecx, regs.edx);
31*2b54f0dbSXin Li 			#else
32*2b54f0dbSXin Li 				int regs_array[4];
33*2b54f0dbSXin Li 				__cpuid(regs_array, (int) eax);
34*2b54f0dbSXin Li 				regs.eax = regs_array[0];
35*2b54f0dbSXin Li 				regs.ebx = regs_array[1];
36*2b54f0dbSXin Li 				regs.ecx = regs_array[2];
37*2b54f0dbSXin Li 				regs.edx = regs_array[3];
38*2b54f0dbSXin Li 			#endif
39*2b54f0dbSXin Li 			return regs;
40*2b54f0dbSXin Li 		#endif
41*2b54f0dbSXin Li 	}
42*2b54f0dbSXin Li 
cpuidex(uint32_t eax,uint32_t ecx)43*2b54f0dbSXin Li 	static inline struct cpuid_regs cpuidex(uint32_t eax, uint32_t ecx) {
44*2b54f0dbSXin Li 		#if CPUINFO_MOCK
45*2b54f0dbSXin Li 			uint32_t regs_array[4];
46*2b54f0dbSXin Li 			cpuinfo_mock_get_cpuidex(eax, ecx, regs_array);
47*2b54f0dbSXin Li 			return (struct cpuid_regs) {
48*2b54f0dbSXin Li 				.eax = regs_array[0],
49*2b54f0dbSXin Li 				.ebx = regs_array[1],
50*2b54f0dbSXin Li 				.ecx = regs_array[2],
51*2b54f0dbSXin Li 				.edx = regs_array[3],
52*2b54f0dbSXin Li 			};
53*2b54f0dbSXin Li 		#else
54*2b54f0dbSXin Li 			struct cpuid_regs regs;
55*2b54f0dbSXin Li 			#if defined(__GNUC__)
56*2b54f0dbSXin Li 				__cpuid_count(eax, ecx, regs.eax, regs.ebx, regs.ecx, regs.edx);
57*2b54f0dbSXin Li 			#else
58*2b54f0dbSXin Li 				int regs_array[4];
59*2b54f0dbSXin Li 				__cpuidex(regs_array, (int) eax, (int) ecx);
60*2b54f0dbSXin Li 				regs.eax = regs_array[0];
61*2b54f0dbSXin Li 				regs.ebx = regs_array[1];
62*2b54f0dbSXin Li 				regs.ecx = regs_array[2];
63*2b54f0dbSXin Li 				regs.edx = regs_array[3];
64*2b54f0dbSXin Li 			#endif
65*2b54f0dbSXin Li 			return regs;
66*2b54f0dbSXin Li 		#endif
67*2b54f0dbSXin Li 	}
68*2b54f0dbSXin Li #endif
69*2b54f0dbSXin Li 
xgetbv(uint32_t ext_ctrl_reg)70*2b54f0dbSXin Li static inline uint64_t xgetbv(uint32_t ext_ctrl_reg) {
71*2b54f0dbSXin Li 	#ifdef _MSC_VER
72*2b54f0dbSXin Li 		return (uint64_t)_xgetbv((unsigned int)ext_ctrl_reg);
73*2b54f0dbSXin Li 	#else
74*2b54f0dbSXin Li 		uint32_t lo, hi;
75*2b54f0dbSXin Li 		__asm__(".byte 0x0F, 0x01, 0xD0" : "=a" (lo), "=d" (hi) : "c" (ext_ctrl_reg));
76*2b54f0dbSXin Li 		return ((uint64_t) hi << 32) | (uint64_t) lo;
77*2b54f0dbSXin Li 	#endif
78*2b54f0dbSXin Li }
79*2b54f0dbSXin Li 
80