Features["movbe"] = (ECX >> 22) & 1;
Features["popcnt"] = (ECX >> 23) & 1;
Features["aes"] = (ECX >> 25) & 1;
- Features["xsave"] = (ECX >> 26) & 1;
Features["rdrnd"] = (ECX >> 30) & 1;
// If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
// indicates that the AVX registers will be saved and restored on context
// switch, then we have full AVX support.
- bool HasAVX = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
- !GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
- Features["avx"] = HasAVX;
- Features["fma"] = HasAVX && (ECX >> 12) & 1;
- Features["f16c"] = HasAVX && (ECX >> 29) & 1;
+ bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
+ !GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
+ Features["avx"] = HasAVXSave;
+ Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
+ Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;
+
+ // Only enable XSAVE if OS has enabled support for saving YMM state.
+ Features["xsave"] = HasAVXSave && (ECX >> 26) & 1;
// AVX512 requires additional context to be saved by the OS.
- bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
+ bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
unsigned MaxExtLevel;
GetX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
- Features["xop"] = HasAVX && HasExtLeaf1 && ((ECX >> 11) & 1);
- Features["fma4"] = HasAVX && HasExtLeaf1 && ((ECX >> 16) & 1);
+ Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
+ Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);
bool HasLeaf7 = MaxLevel >= 7 &&
!GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
// AVX2 is only supported if we have the OS save support from AVX.
- Features["avx2"] = HasAVX && HasLeaf7 && (EBX >> 5) & 1;
+ Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);
Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
-
bool HasLeafD = MaxLevel >= 0xd &&
!GetX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
- Features["xsaveopt"] = Features["xsave"] && HasLeafD && ((EAX >> 0) & 1);
- Features["xsavec"] = Features["xsave"] && HasLeafD && ((EAX >> 1) & 1);
- Features["xsaves"] = Features["xsave"] && HasLeafD && ((EAX >> 3) & 1);
+ // Only enable XSAVE if OS has enabled support for saving YMM state.
+ Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
+ Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
+ Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);
return true;
}