From 171e7f016dc9e132f9faf40a22f0312d45d356a5 Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Fri, 11 May 2018 01:42:27 +0100 Subject: [PATCH] common: Work around GCC8 _xgetbv bug clang and earlier GCC versions do not provide the _xgetbv intrinsic. GCC8 does, but unfortunately it's broken. (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85684). Re-use our _xgetbv implementation to avoid the bug, but rename it to avoid compilation errors as well. --- common/include/x86emitter/x86_intrin.h | 7 ++++--- common/src/x86emitter/cpudetect.cpp | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/common/include/x86emitter/x86_intrin.h b/common/include/x86emitter/x86_intrin.h index 573d752f66..0031096ddc 100644 --- a/common/include/x86emitter/x86_intrin.h +++ b/common/include/x86emitter/x86_intrin.h @@ -34,6 +34,7 @@ #define cpuid __cpuid #define cpuidex __cpuidex +#define xgetbv _xgetbv #else @@ -49,8 +50,9 @@ static __inline__ __attribute__((always_inline)) void cpuid(int CPUInfo[], const __cpuid(InfoType, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]); } -#if __GNUC__ < 8 -static __inline__ __attribute__((always_inline)) unsigned long long _xgetbv(unsigned int index) +// _xgetbv on gcc 8 is broken (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85684). +// It also isn't present on clang and earlier versions of gcc. +static __inline__ __attribute__((always_inline)) unsigned long long xgetbv(unsigned int index) { unsigned int eax, edx; __asm__ __volatile__("xgetbv" @@ -58,7 +60,6 @@ static __inline__ __attribute__((always_inline)) unsigned long long _xgetbv(unsi : "c"(index)); return ((unsigned long long)edx << 32) | eax; } -#endif #endif diff --git a/common/src/x86emitter/cpudetect.cpp b/common/src/x86emitter/cpudetect.cpp index 2854f6dd51..07aced0156 100644 --- a/common/src/x86emitter/cpudetect.cpp +++ b/common/src/x86emitter/cpudetect.cpp @@ -297,7 +297,7 @@ void x86capabilities::Identify() if ((Flags2 >> 27) & 1) // OSXSAVE { - if ((_xgetbv(0) & 6) == 6) // XFEATURE_ENABLED_MASK[2:1] = '11b' (XMM state and YMM state are enabled by OS). + if ((xgetbv(0) & 6) == 6) // XFEATURE_ENABLED_MASK[2:1] = '11b' (XMM state and YMM state are enabled by OS). { hasAVX = (Flags2 >> 28) & 1; //avx hasFMA = (Flags2 >> 12) & 1; //fma