X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fcpuid%2Fcpuid.c;h=d64f2cf57bb7afaacdf95fc393ed20957e12d0c6;hp=d27441022d2bad386d4361a2ee5fbdff7113a402;hb=6977745243a4bdd351e1565f2749872bb927709e;hpb=339178b2247516362d8e0abb263089052c79eb69 diff --git a/ccan/cpuid/cpuid.c b/ccan/cpuid/cpuid.c index d2744102..d64f2cf5 100644 --- a/ccan/cpuid/cpuid.c +++ b/ccan/cpuid/cpuid.c @@ -151,49 +151,80 @@ bool cpuid_test_feature(cpuid_t feature) return (feature <= cpuid_highest_ext_func_supported()); } -bool cpuid_has_ecxfeature(int feature) -{ - static uint32_t _ecx; - if (_ecx == 0) { #if defined(__GNUC__) || defined(__clang__) +static uint32_t fetch_ecx(uint32_t what) +{ + static uint32_t ecx; + if (ecx == 0) { asm volatile( "cpuid\n\t" - : "=c" (_ecx) - : "a" (CPUID_PROCINFO_AND_FEATUREBITS) + : "=c" (ecx) + : "a" (what) ); -#elif defined _MSC_VER + } + + return ecx; +} + +static uint32_t fetch_edx(uint32_t what) +{ + static uint32_t edx; + if (edx == 0) { + asm volatile( + "cpuid\n\t" + : "=d" (edx) + : "a" (what) + ); + } + + return edx; +} +#elif defined(_MSC_VER) +static uint32_t fetch_ecx(uint32_t what) +{ + static uint32_t _ecx; + if (_ecx == 0) { __asm { - mov eax, CPUID_PROCINFO_AND_FEATUREBITS + mov eax, what cpuid mov _ecx, ecx }; -#endif } - return (_ecx & feature) == feature; + return _ecx; } -bool cpuid_has_edxfeature(int feature) +static uint32_t fetch_edx(uint32_t what) { static uint32_t _edx; if (_edx == 0) { -#if defined(__GNUC__) || defined(__clang__) - asm volatile( - "cpuid\n\t" - : "=d" (_edx) - : "a" (CPUID_PROCINFO_AND_FEATUREBITS) - ); -#elif defined _MSC_VER __asm { - mov eax, CPUID_PROCINFO_AND_FEATUREBITS + mov eax, what cpuid mov _edx, edx }; -#endif } - return (_edx & feature) == feature; + return _edx; } +#endif + +#define DEFINE_FEATURE_FUNC(NAME, REGISTER, TYPE) \ + bool cpuid_has_##NAME(int feature) \ + { \ + static uint32_t REGISTER; \ + if (REGISTER == 0) \ + REGISTER = fetch_##REGISTER(TYPE); \ + return (REGISTER & feature) == feature; \ + } + +DEFINE_FEATURE_FUNC(ecxfeature, ecx, CPUID_PROCINFO_AND_FEATUREBITS) +DEFINE_FEATURE_FUNC(edxfeature, edx, CPUID_PROCINFO_AND_FEATUREBITS) + +DEFINE_FEATURE_FUNC(ecxfeature_ext, ecx, CPUID_EXTENDED_PROC_INFO_FEATURE_BITS) +DEFINE_FEATURE_FUNC(edxfeature_ext, edx, CPUID_EXTENDED_PROC_INFO_FEATURE_BITS) + +#undef DEFINE_FEATURE_FUNC static const char *const cpuids[] = { "Nooooooooone",