client: Add missing code to properly detect AVX on Windows. It'll go into affect when we fully convert over to VS2010.

This commit is contained in:
Rom Walton 2013-09-09 11:54:42 -04:00
parent 612fb64b96
commit 74e12f6bcc
1 changed files with 52 additions and 8 deletions

View File

@ -1025,6 +1025,45 @@ int get_processor_cache(int& cache) {
}
// Returns true if the AVX instruction set is supported with the current
// combination of OS and CPU.
// see: http://insufficientlycomplicated.wordpress.com/2011/11/07/detecting-intel-advanced-vector-extensions-avx-in-visual-studio/
bool is_avx_supported() {
bool supported = false;
// If Visual Studio 2010 SP1 or later
#if (_MSC_FULL_VER >= 160040219)
// Checking for AVX requires 3 things:
// 1) CPUID indicates that the OS uses XSAVE and XRSTORE
// instructions (allowing saving YMM registers on context
// switch)
// 2) CPUID indicates support for AVX
// 3) XGETBV indicates the AVX registers will be saved and
// restored on context switch
//
// Note that XGETBV is only available on 686 or later CPUs, so
// the instruction needs to be conditionally run.
int cpuInfo[4];
__cpuid(cpuInfo, 1);
bool osUsesXSAVE_XRSTORE = cpuInfo[2] & (1 << 27) || false;
bool cpuAVXSuport = cpuInfo[2] & (1 << 28) || false;
if (osUsesXSAVE_XRSTORE && cpuAVXSuport)
{
// Check if the OS will save the YMM registers
unsigned long long xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
supported = (xcrFeatureMask & 0x6) || false;
}
#endif
return supported;
}
// Returns the features supported by the processor, use the
// Linux CPU processor feature mnemonics.
// see: http://msdn.microsoft.com/en-us/library/hskdteyh.aspx
@ -1115,7 +1154,6 @@ int get_processor_features(char* vendor, char* features, int features_size) {
FEATURE_TEST(std_supported, (std_ecx & (1 << 22)), "movebe ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 23)), "popcnt ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 25)), "aes ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 28)), "avx ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 29)), "f16c ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 30)), "rdrand");
@ -1123,14 +1161,9 @@ int get_processor_features(char* vendor, char* features, int features_size) {
FEATURE_TEST(ext_supported, (ext_edx & (1 << 20)), "nx ");
FEATURE_TEST(ext_supported, (ext_edx & (1 << 29)), "lm ");
if (intel_supported) {
// Intel only features
FEATURE_TEST(std_supported, (std_ecx & (1 << 5)), "vmx ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 6)), "smx ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 8)), "tm2 ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 18)), "dca ");
FEATURE_TEST(std_supported, (std_edx & (1 << 31)), "pbe ");
if (is_avx_supported()) {
FEATURE_TEST(std_supported, (std_ecx & (1 << 28)), "avx ");
}
@ -1147,6 +1180,17 @@ int get_processor_features(char* vendor, char* features, int features_size) {
}
if (intel_supported) {
// Intel only features
FEATURE_TEST(std_supported, (std_ecx & (1 << 5)), "vmx ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 6)), "smx ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 8)), "tm2 ");
FEATURE_TEST(std_supported, (std_ecx & (1 << 18)), "dca ");
FEATURE_TEST(std_supported, (std_edx & (1 << 31)), "pbe ");
}
if (amd_supported) {
// AMD only features
FEATURE_TEST(ext_supported, (ext_ecx & (1 << 2)), "svm ");