void CPUFeatures::Detect() { QString str = "[CPUFeatures::Detect] " + Logger::tr("CPU features") + ":"; // CPUID exists in i586 ('pentium 1') and higher, older processors are not supported. // The meaning of ecx/edx bits are listed in table 3-20 and 3-21 ('Feature Information Returned in the ECX/EDX Register') // from the Intel reference manual (page 589), or in AMD's CPUID reference (they are compatible). unsigned int eax, ebx, ecx, edx; __cpuid(0, eax, ebx, ecx, edx); unsigned int cpuid_max = eax; if(cpuid_max >= 1) { __cpuid(1, eax, ebx, ecx, edx); if(edx & (1 << 23)) { s_mmx = true; str += " mmx"; } if(edx & (1 << 25)) { s_sse = true; str += " sse"; } if(edx & (1 << 26)) { s_sse2 = true; str += " sse2"; } if(ecx & (1 << 0)) { s_sse3 = true; str += " sse3"; } if(ecx & (1 << 9)) { s_ssse3 = true; str += " ssse3"; } if(ecx & (1 << 19)) { s_sse41 = true; str += " sse4_1"; } if(ecx & (1 << 20)) { s_sse42 = true; str += " sse4_2"; } if(ecx & (1 << 28)) { s_avx = true; str += " avx"; } } if(cpuid_max >= 7) { __cpuid_count(7, 0, eax, ebx, ecx, edx); if(ebx & (1 << 5)) { s_avx2 = true; str += " avx2"; } if(ebx & (1 << 3)) { s_bmi1 = true; str += " bmi1"; } if(ebx & (1 << 8)) { s_bmi2 = true; str += " bmi2"; } } Logger::LogInfo(str); }
static void FetchCpuInfoOnce(void){ const _MCFCRT_OnceResult result = _MCFCRT_WaitForOnceFlagForever(&g_once); if(result == _MCFCRT_kOnceResultFinished){ return; } _MCFCRT_ASSERT(result == _MCFCRT_kOnceResultInitial); // Reference: // Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2 (2A, 2B & 2C): // Table 3-17. Information Returned by CPUID Instruction // Iterate from cache level 1, until there are no more levels. unsigned level = 1; do { unsigned eax, ebx, ecx, edx; __cpuid_count(0x04, level, eax, ebx, ecx, edx); if((eax & 0x1F) == 0){ // No more cache levels. Stop. break; } const unsigned ways = ((ebx >> 22) & 0x3FF) + 1; const unsigned partitions = ((ebx >> 12) & 0x3FF) + 1; const unsigned line_size = (ebx & 0xFFF) + 1; const unsigned sets = ecx + 1; g_cache_sizes[level] = ways * partitions * line_size * sets; } while(++level < _MCFCRT_kCpuCacheLevelMax); // Set up boundary values. g_cache_sizes[_MCFCRT_kCpuCacheLevelMin] = g_cache_sizes[_MCFCRT_kCpuCacheLevel1]; g_cache_sizes[_MCFCRT_kCpuCacheLevelMax] = g_cache_sizes[level - 1]; _MCFCRT_SignalOnceFlagAsFinished(&g_once); }
JNIEXPORT jboolean JNICALL Java_javartm_Transaction_rtmAvailable(JNIEnv *env, jclass cls) { unsigned int eax, ebx, ecx, edx; if (__get_cpuid_max(0, NULL) >= 7) { __cpuid_count(7, 0, eax, ebx, ecx, edx); if (ebx & bit_RTM) return 1; } return 0; }
static inline void get_cpuid2(int *array, int info_type, int ecx) { #if defined(_MSC_VER) __cpuidex(array, info_type, ecx); #else __cpuid_count(info_type, ecx, array[0], array[1], array[2], array[3]); #endif }
static int get_cpuid_count (unsigned int leaf, unsigned int subleaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { __cpuid_count(leaf, subleaf, *eax, *ebx, *ecx, *edx); return 1; }
inline void cpuidex(register_type pRegisters[4], int function, int subfunction) { #if defined(BOOST_SIMD_CPUID_HEADER) __cpuid_count ( function, subfunction , pRegisters[eax], pRegisters[ebx], pRegisters[ecx], pRegisters[edx] ); #else __cpuidex(pRegisters, function, subfunction); #endif }
static bool avx2_support(void) { int a, b, c, d; if (__get_cpuid_max(0, NULL) < 7) { return false; } __cpuid_count(7, 0, a, b, c, d); return b & bit_AVX2; }
static bool internal_cpuid(int32_t out[4], int32_t x) { #if defined __GNUC__ __cpuid_count(x, 0, out[0], out[1], out[2], out[3]); return true; #endif #if defined _MSC_VER __cpuidex(out, x, 0); return true; #endif return false; }
void fe_hw_x86_cpuidex(uint32_t leaf, uint32_t subleaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { #if (defined(__GNUC__) || defined(__clang__)) __cpuid_count(leaf, subleaf, eax, ebx, ecx, edx); #elif defined(_MSC_VER) int regs[4]; __cpuidex(regs, leaf, subleaf); *eax = regs[0]; *ebx = regs[1]; *ecx = regs[2]; *edx = regs[3]; #else #error "No cpuid intrinsic for this target !" #endif }
static void detect () { #if defined (__x86__) unsigned int sig, eax, ebx, ecx, edx; int max = __get_cpuid_max (0, &sig); if (max < 1) return; if (sig == signature_INTEL_ebx || sig == signature_AMD_ebx) { __cpuid (1, eax, ebx, ecx, edx); if (ecx & bit_RDRND) __cpu_rng = RNG_RDRAND; if (max > 7) { __cpuid_count (7, 0, eax, ebx, ecx, edx); if (ebx & bit_RDSEED) __cpu_rng = RNG_RDSEED; } } #endif }
unsigned int NOINLINE have_mpx (void) { unsigned int eax, ebx, ecx, edx; if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; if ((ecx & bit_OSXSAVE) == bit_OSXSAVE) { if (__get_cpuid_max (0, NULL) < 7) return 0; __cpuid_count (7, 0, eax, ebx, ecx, edx); if ((ebx & bit_MPX) == bit_MPX) return 1; else return 0; } return 0; }
static int codec_choose_x86 (struct codec *codec) { #if (__x86_64__ || __i386__) && (HAVE_AVX2 || HAVE_SSSE3) unsigned int eax, ebx = 0, ecx = 0, edx; unsigned int max_level = __get_cpuid_max(0, NULL); #if HAVE_AVX2 /* Check for AVX2 support: */ if (max_level >= 7) { __cpuid_count(7, 0, eax, ebx, ecx, edx); if (ebx & bit_AVX2) { codec->enc = base64_stream_encode_avx2; codec->dec = base64_stream_decode_avx2; return 1; } } #endif #if HAVE_SSSE3 /* Check for SSSE3 support: */ if (max_level >= 1) { __cpuid(1, eax, ebx, ecx, edx); if (ecx & bit_SSSE3) { codec->enc = base64_stream_encode_ssse3; codec->dec = base64_stream_decode_ssse3; return 1; } } #endif #else (void)codec; #endif return 0; }
static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) { __cpuid_count(func, subfunc, cpuinfo->eax, cpuinfo->ebx, cpuinfo->ecx, cpuinfo->edx); }
static void cpuid(unsigned int op, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { __cpuid_count(op, 0, *eax, *ebx, *ecx, *edx); }
InstructionSet_Internal() : nIds_{ 0 }, nExIds_{ 0 }, isIntel_{ false }, isAMD_{ false }, f_1_ECX_{ 0 }, f_1_EDX_{ 0 }, f_7_EBX_{ 0 }, f_7_ECX_{ 0 }, f_81_ECX_{ 0 }, f_81_EDX_{ 0 }, data_{}, extdata_{} { //int cpuInfo[4] = {-1}; std::array<int, 4> cpui; // Calling __cpuid with 0x0 as the function_id argument // gets the number of the highest valid function ID. #if defined(_MSC_VER) && !defined(__clang__) __cpuid(cpui.data(), 0); nIds_ = cpui[0]; #else nIds_ = __get_cpuid_max(0, NULL); #endif for (int i = 0; i <= nIds_; ++i) { #if defined(_MSC_VER) && !defined(__clang__) __cpuidex(cpui.data(), i, 0); #else int *data = cpui.data(); __cpuid_count(i, 0, data[0], data[1], data[2], data[3]); #endif data_.push_back(cpui); } // Capture vendor string char vendor[0x20]; memset(vendor, 0, sizeof(vendor)); *reinterpret_cast<int*>(vendor) = data_[0][1]; *reinterpret_cast<int*>(vendor + 4) = data_[0][3]; *reinterpret_cast<int*>(vendor + 8) = data_[0][2]; vendor_ = vendor; if (vendor_ == "GenuineIntel") { isIntel_ = true; } else if (vendor_ == "AuthenticAMD") { isAMD_ = true; } // load bitset with flags for function 0x00000001 if (nIds_ >= 1) { f_1_ECX_ = data_[1][2]; f_1_EDX_ = data_[1][3]; } // load bitset with flags for function 0x00000007 if (nIds_ >= 7) { f_7_EBX_ = data_[7][1]; f_7_ECX_ = data_[7][2]; } // Calling __cpuid with 0x80000000 as the function_id argument // gets the number of the highest valid extended ID. #if defined(_MSC_VER) && !defined(__clang__) __cpuid(cpui.data(), 0x80000000); nExIds_ = cpui[0]; #else nExIds_ = __get_cpuid_max(0x80000000, NULL); #endif char brand[0x40]; memset(brand, 0, sizeof(brand)); for (unsigned i = 0x80000000; i <= nExIds_; ++i) { #if defined(_MSC_VER) && !defined(__clang__) __cpuidex(cpui.data(), i, 0); #else int *data = cpui.data(); __cpuid_count(i, 0, data[0], data[1], data[2], data[3]); #endif extdata_.push_back(cpui); } // load bitset with flags for function 0x80000001 if (nExIds_ >= 0x80000001) { f_81_ECX_ = extdata_[1][2]; f_81_EDX_ = extdata_[1][3]; } // Interpret CPU brand string if reported if (nExIds_ >= 0x80000004) { memcpy(brand, extdata_[2].data(), sizeof(cpui)); memcpy(brand + 16, extdata_[3].data(), sizeof(cpui)); memcpy(brand + 32, extdata_[4].data(), sizeof(cpui)); brand_ = brand; } };
static inline void cpuid(unsigned func, unsigned subfunc, unsigned cpuinfo[4]) { __cpuid_count(func, subfunc, cpuinfo[EAX_IDX], cpuinfo[EBX_IDX], cpuinfo[ECX_IDX], cpuinfo[EDX_IDX]); }