From 932945d4808e37ba0ca1a953571187f445e24f41 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Thu, 6 Mar 2014 14:38:10 -0800 Subject: [PATCH] Implement workaround for Windows versions which do not support XSAVE. Fixes CRT math routines using FMA instructions from causing illegal instructions. --- Source/Core/Common/Common.vcxproj | 1 + Source/Core/Common/Common.vcxproj.filters | 1 + Source/Core/Common/XSaveWorkaround.cpp | 40 +++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 Source/Core/Common/XSaveWorkaround.cpp diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 48cbcdfe3c..2aa69ba1b7 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -125,6 +125,7 @@ + diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters index f2b194c007..d932b32be5 100644 --- a/Source/Core/Common/Common.vcxproj.filters +++ b/Source/Core/Common/Common.vcxproj.filters @@ -103,6 +103,7 @@ Logging + diff --git a/Source/Core/Common/XSaveWorkaround.cpp b/Source/Core/Common/XSaveWorkaround.cpp new file mode 100644 index 0000000000..30a2a42b2b --- /dev/null +++ b/Source/Core/Common/XSaveWorkaround.cpp @@ -0,0 +1,40 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#if defined(_WIN32) && defined(_ARCH_64) + +#include +#include + +// This puts the rest of this translation unit into a segment which is +// initialized by the CRT *before* any of the other code (including C++ +// static initializers). +#pragma warning(disable : 4075) +#pragma init_seg(".CRT$XCB") + +struct EnableXSaveWorkaround +{ + EnableXSaveWorkaround() + { + // Some Windows environments may have hardware support for AVX/FMA, + // but the OS does not support it. The CRT math library does not support + // this scenario, so we have to manually tell it not to use FMA3 + // instructions. + + // The API name is somewhat misleading - we're testing for OS support + // here. + if (!IsProcessorFeaturePresent(PF_XSAVE_ENABLED)) + { + _set_FMA3_enable(0); + } + } +}; + +static EnableXSaveWorkaround enableXSaveWorkaround; + +// N.B. Any code after this will still be in the .CRT$XCB segment. Please just +// do not append any code here unless it is intended to be executed before +// static initializers. + +#endif