mirror of https://github.com/PCSX2/pcsx2.git
x86emitter: always use fxsave intrinsic/asm
This commit is contained in:
parent
d5efd6eacb
commit
02186d5a54
|
@ -28,13 +28,6 @@ void x86capabilities::CountLogicalCores()
|
||||||
LogicalCores = wxThread::GetCPUCount();
|
LogicalCores = wxThread::GetCPUCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanEmitShit()
|
|
||||||
{
|
|
||||||
// In Linux I'm pretty sure TLS always works, none of the funny business that Windows
|
|
||||||
// has involving DLLs. >_<
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not implemented yet for linux (see cpudetect_internal.h for details)
|
// Not implemented yet for linux (see cpudetect_internal.h for details)
|
||||||
SingleCoreAffinity::SingleCoreAffinity() {}
|
SingleCoreAffinity::SingleCoreAffinity() {}
|
||||||
SingleCoreAffinity::~SingleCoreAffinity() throw() {}
|
SingleCoreAffinity::~SingleCoreAffinity() throw() {}
|
||||||
|
|
|
@ -39,21 +39,6 @@ void x86capabilities::CountLogicalCores()
|
||||||
LogicalCores = CPUs;
|
LogicalCores = CPUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanEmitShit()
|
|
||||||
{
|
|
||||||
// Under Windows, pre 0.9.6 versions of PCSX2 may not initialize the TLS
|
|
||||||
// register (FS register), so plugins (DLLs) using our x86emitter in multithreaded
|
|
||||||
// mode will just crash/fail if it tries to do the instruction set tests.
|
|
||||||
|
|
||||||
#if x86EMIT_MULTITHREADED
|
|
||||||
static __threadlocal int tls_failcheck;
|
|
||||||
__try { tls_failcheck = 1; }
|
|
||||||
__except(EXCEPTION_EXECUTE_HANDLER) { return false; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SingleCoreAffinity::SingleCoreAffinity()
|
SingleCoreAffinity::SingleCoreAffinity()
|
||||||
{
|
{
|
||||||
s_threadId = NULL;
|
s_threadId = NULL;
|
||||||
|
|
|
@ -22,7 +22,6 @@ using namespace x86Emitter;
|
||||||
__aligned16 x86capabilities x86caps;
|
__aligned16 x86capabilities x86caps;
|
||||||
|
|
||||||
// Recompiled code buffer for SSE and MXCSR feature testing.
|
// Recompiled code buffer for SSE and MXCSR feature testing.
|
||||||
static __pagealigned u8 recSSE[__pagesize];
|
|
||||||
static __pagealigned u8 targetFXSAVE[512];
|
static __pagealigned u8 targetFXSAVE[512];
|
||||||
|
|
||||||
static const char* bool_to_char( bool testcond )
|
static const char* bool_to_char( bool testcond )
|
||||||
|
@ -34,6 +33,7 @@ static const char* bool_to_char( bool testcond )
|
||||||
// MSVC PGO builds. The problem was fixed when I moved the MXCSR code to this function, and
|
// MSVC PGO builds. The problem was fixed when I moved the MXCSR code to this function, and
|
||||||
// moved the recSSE[] array to a global static (it was local to cpudetectInit). Commented
|
// moved the recSSE[] array to a global static (it was local to cpudetectInit). Commented
|
||||||
// here in case the nutty crash ever re-surfaces. >_<
|
// here in case the nutty crash ever re-surfaces. >_<
|
||||||
|
// Note: recSSE was deleted
|
||||||
void x86capabilities::SIMD_EstablishMXCSRmask()
|
void x86capabilities::SIMD_EstablishMXCSRmask()
|
||||||
{
|
{
|
||||||
if( !hasStreamingSIMDExtensions ) return;
|
if( !hasStreamingSIMDExtensions ) return;
|
||||||
|
@ -48,32 +48,9 @@ void x86capabilities::SIMD_EstablishMXCSRmask()
|
||||||
|
|
||||||
MXCSR_Mask.bitmask = 0xFFFF; // SSE2 features added
|
MXCSR_Mask.bitmask = 0xFFFF; // SSE2 features added
|
||||||
}
|
}
|
||||||
#ifdef _M_X86_64
|
|
||||||
#ifdef _MSC_VER
|
// Work for recent enough GCC/CLANG/MSVC 2012
|
||||||
// Use the intrinsic that is provided with MSVC 2012
|
|
||||||
_fxsave(&targetFXSAVE);
|
_fxsave(&targetFXSAVE);
|
||||||
#else
|
|
||||||
// GCC path is supported since GCC 4.6.x
|
|
||||||
__asm __volatile ("fxsave %0" : "+m" (targetFXSAVE));
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
// Grab the MXCSR mask the x86_32 way.
|
|
||||||
//
|
|
||||||
// the fxsave buffer must be 16-byte aligned to avoid GPF. I just save it to an
|
|
||||||
// unused portion of recSSE, since it has plenty of room to spare.
|
|
||||||
|
|
||||||
if( !CanEmitShit() ) return;
|
|
||||||
|
|
||||||
HostSys::MemProtectStatic( recSSE, PageAccess_ReadWrite() );
|
|
||||||
|
|
||||||
xSetPtr( recSSE );
|
|
||||||
xFXSAVE( ptr[&targetFXSAVE] );
|
|
||||||
xRET();
|
|
||||||
|
|
||||||
HostSys::MemProtectStatic( recSSE, PageAccess_ExecOnly() );
|
|
||||||
|
|
||||||
CallAddress( recSSE );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u32 result = (u32&)targetFXSAVE[28]; // bytes 28->32 are the MXCSR_Mask.
|
u32 result = (u32&)targetFXSAVE[28]; // bytes 28->32 are the MXCSR_Mask.
|
||||||
if( result != 0 )
|
if( result != 0 )
|
||||||
|
|
|
@ -37,18 +37,3 @@ public:
|
||||||
SingleCoreAffinity();
|
SingleCoreAffinity();
|
||||||
virtual ~SingleCoreAffinity() throw();
|
virtual ~SingleCoreAffinity() throw();
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// SIMD "Manual" Detection, using Invalid Instruction Checks
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Note: This API doesn't support GCC/Linux. Looking online it seems the only
|
|
||||||
// way to simulate the Microsoft SEH model is to use unix signals, and the 'sigaction'
|
|
||||||
// function specifically. A linux coder could implement this using sigaction at a later
|
|
||||||
// date, however its not really a big deal: CPUID should be 99-100% accurate, as no modern
|
|
||||||
// software would work on the CPU if it mis-reported capabilities. However there are known
|
|
||||||
// cases of a CPU failing to report supporting instruction sets it does in fact support.
|
|
||||||
// This secondary test fixes such cases (although apparently a CMOS reset does as well).
|
|
||||||
//
|
|
||||||
|
|
||||||
extern bool CanEmitShit();
|
|
||||||
|
|
Loading…
Reference in New Issue