Bug 1590624 - mingw-clang cannot use _xgetbv without -mavx, work around it r=lsalzman,froydnj
authorTom Ritter <tom@mozilla.com>
Thu, 12 Dec 2019 06:38:39 +0000
changeset 506625 df32eb1fdc8d5aa6c75cbf9a23d92b80507a83c2
parent 506624 79bf2b523d94d5558206d14ff7077b32d431e8af
child 506626 c2cffffd5ca6a115cc114bdd8a2a6c695c0ef087
push id36910
push usercsabou@mozilla.com
push dateThu, 12 Dec 2019 21:50:40 +0000
treeherdermozilla-central@0f6958f49842 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman, froydnj
bugs1590624
milestone73.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1590624 - mingw-clang cannot use _xgetbv without -mavx, work around it r=lsalzman,froydnj Differential Revision: https://phabricator.services.mozilla.com/D54531
gfx/skia/skia/src/core/SkCpu.cpp
mozglue/build/SSE.cpp
mozglue/build/SSE.h
widget/windows/GfxInfo.cpp
--- a/gfx/skia/skia/src/core/SkCpu.cpp
+++ b/gfx/skia/skia/src/core/SkCpu.cpp
@@ -6,17 +6,17 @@
  */
 
 #include "include/core/SkStream.h"
 #include "include/core/SkString.h"
 #include "include/private/SkOnce.h"
 #include "src/core/SkCpu.h"
 
 #if defined(SK_CPU_X86)
-    #if defined(SK_BUILD_FOR_WIN)
+    #if defined(SK_BUILD_FOR_WIN) && !defined(__MINGW32__)
         #include <intrin.h>
         static void cpuid (uint32_t abcd[4]) { __cpuid  ((int*)abcd, 1);    }
         static void cpuid7(uint32_t abcd[4]) { __cpuidex((int*)abcd, 7, 0); }
         static uint64_t xgetbv(uint32_t xcr) { return _xgetbv(xcr); }
     #else
         #include <cpuid.h>
         #if !defined(__cpuid_count)  // Old Mac Clang doesn't have this defined.
             #define  __cpuid_count(eax, ecx, a, b, c, d) \
--- a/mozglue/build/SSE.cpp
+++ b/mozglue/build/SSE.cpp
@@ -35,24 +35,16 @@ static bool has_cpuid_bits(unsigned int 
   __cpuid_count(level, 0, eax, ebx, ecx, edx);
   regs[0] = eax;
   regs[1] = ebx;
   regs[2] = ecx;
   regs[3] = edx;
   return (regs[reg] & bits) == bits;
 }
 
-#  if !defined(MOZILLA_PRESUME_AVX)
-static uint64_t xgetbv(uint32_t xcr) {
-  uint32_t eax, edx;
-  __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr));
-  return (uint64_t)(edx) << 32 | eax;
-}
-#  endif
-
 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64))
 
 enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
 
 static bool has_cpuid_bits(unsigned int level, CPUIDRegister reg,
                            unsigned int bits) {
   // Check that the level in question is supported.
   int regs[4];
@@ -60,20 +52,16 @@ static bool has_cpuid_bits(unsigned int 
   if (unsigned(regs[0]) < level) return false;
 
   // "The __cpuid intrinsic clears the ECX register before calling the cpuid
   // instruction."
   __cpuid(regs, level);
   return (unsigned(regs[reg]) & bits) == bits;
 }
 
-#  if !defined(MOZILLA_PRESUME_AVX)
-static uint64_t xgetbv(uint32_t xcr) { return _xgetbv(xcr); }
-#  endif
-
 #elif (defined(__GNUC__) || defined(__SUNPRO_CC)) && \
     (defined(__i386) || defined(__x86_64__))
 
 enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 };
 
 #  ifdef __i386
 static void moz_cpuid(int CPUInfo[4], int InfoType) {
   asm("xchg %esi, %ebx\n"
@@ -189,9 +177,20 @@ bool avx2_enabled = has_avx() && has_cpu
 
 #  if !defined(MOZILLA_PRESUME_AES)
 bool aes_enabled = has_cpuid_bits(1u, ecx, (1u << 25));
 #  endif
 
 #endif
 
 }  // namespace sse_private
+
+#ifdef HAVE_CPUID_H
+
+uint64_t xgetbv(uint32_t xcr) {
+  uint32_t eax, edx;
+  __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr));
+  return (uint64_t)(edx) << 32 | eax;
+}
+
+#endif
+
 }  // namespace mozilla
--- a/mozglue/build/SSE.h
+++ b/mozglue/build/SSE.h
@@ -222,16 +222,20 @@ extern bool MFBT_DATA avx2_enabled;
 #  endif
 #  if !defined(MOZILLA_PRESUME_AES)
 extern bool MFBT_DATA aes_enabled;
 #  endif
 
 #endif
 }  // namespace sse_private
 
+#ifdef HAVE_CPUID_H
+MOZ_EXPORT uint64_t xgetbv(uint32_t xcr);
+#endif
+
 #if defined(MOZILLA_PRESUME_MMX)
 #  define MOZILLA_MAY_SUPPORT_MMX 1
 inline bool supports_mmx() { return true; }
 #elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION)
 #  if !(defined(_MSC_VER) && defined(_M_AMD64))
 // Define MOZILLA_MAY_SUPPORT_MMX only if we're not on MSVC for
 // AMD64, since that compiler doesn't support MMX.
 #    define MOZILLA_MAY_SUPPORT_MMX 1
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -12,33 +12,32 @@
 #include "GfxInfo.h"
 #include "nsUnicharUtils.h"
 #include "prenv.h"
 #include "prprf.h"
 #include "GfxDriverInfo.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/gfx/DeviceManagerDx.h"
 #include "mozilla/gfx/Logging.h"
+#include "mozilla/SSE.h"
 #include "nsExceptionHandler.h"
 #include "nsPrintfCString.h"
 #include "jsapi.h"
 #include <intrin.h>
 
 #define NS_CRASHREPORTER_CONTRACTID "@mozilla.org/toolkit/crash-reporter;1"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::widget;
 
 #ifdef DEBUG
 NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
 #endif
 
-static const uint32_t allWindowsVersions = 0xffffffff;
-
 GfxInfo::GfxInfo()
     : mWindowsVersion(0), mActiveGPUIndex(0), mHasDualGPU(false) {}
 
 /* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after
  * gfxPlatform initialization has occurred because they depend on it for
  * information. (See bug 591561) */
 nsresult GfxInfo::GetD2DEnabled(bool* aEnabled) {
   // Telemetry queries this during XPCOM initialization, and there's no
@@ -1093,17 +1092,17 @@ static inline bool DetectBrokenAVX() {
   const unsigned OSXSAVE = 1u << 27;
   if ((regs[2] & OSXSAVE) != OSXSAVE) {
     // AVX is supported, but the OS didn't enable it.
     // This can be forced via bcdedit /set xsavedisable 1.
     return true;
   }
 
   const unsigned AVX_CTRL_BITS = (1 << 1) | (1 << 2);
-  return (_xgetbv(0) & AVX_CTRL_BITS) != AVX_CTRL_BITS;
+  return (xgetbv(0) & AVX_CTRL_BITS) != AVX_CTRL_BITS;
 }
 #endif
 
 const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() {
   if (!sDriverInfo->Length()) {
     /*
      * It should be noted here that more specialized rules on certain features
      * should be inserted -before- more generalized restriction. As the first