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