13
0

improved solution for xgetbv() on windows and linux with all compilers

This commit is contained in:
Paul Davis 2015-08-11 17:45:41 -04:00
parent 53bc2ba2c1
commit bb5c969ac0

View File

@ -37,22 +37,6 @@
using namespace PBD;
using namespace std;
/* This function is provided by MSVC are part of the compiler instrinsics. We
* don't care about this on OS X (though perhaps we should), but we need to
* test AVX support on Linux also. This doesn't work on OS X because
* the compiler is different there.
*/
#if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4
static inline unsigned long long _xgetbv(unsigned int index){
unsigned int eax, edx;
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
return ((unsigned long long)edx << 32) | eax;
}
#else
#define _xgetbv() 0
#endif
FPU::FPU ()
{
unsigned long cpuflags = 0;
@ -126,8 +110,15 @@ FPU::FPU ()
* the 2nd and 3rd bits, indicating correct register save/restore.
*/
uint64_t xcrFeatureMask = _xgetbv (0);
uint64_t xcrFeatureMask = 0;
#if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4
unsigned int eax, edx, index = 0;
asm volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
xcrFeatureMask = ((unsigned long long)edx << 32) | eax;
#elif defined (COMPILER_MSVC)
xcrFeatureMask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
#endif
if (xcrFeatureMask & 0x6) {
std::cerr << "Definitely AVX\n";
_flags = Flags (_flags | (HasAVX) );