Merge pull request #498 from magumagu/remove-daz

Don't set DAZ on x86 in non-IEEE mode.
This commit is contained in:
Tony Wasserka 2014-06-19 16:53:21 +02:00
commit 0e0238eccf
5 changed files with 4 additions and 46 deletions

View File

@ -281,8 +281,3 @@ std::string CPUInfo::Summarize()
return sum; return sum;
} }
bool CPUInfo::IsUnsafe()
{
return false;
}

View File

@ -77,7 +77,6 @@ struct CPUInfo
// Turn the cpu info into a string we can show // Turn the cpu info into a string we can show
std::string Summarize(); std::string Summarize();
bool IsUnsafe();
private: private:
// Detects the various cpu features // Detects the various cpu features

View File

@ -162,32 +162,10 @@ void CPUInfo::Detect()
if ((cpu_id[2] >> 22) & 1) bMOVBE = true; if ((cpu_id[2] >> 22) & 1) bMOVBE = true;
if ((cpu_id[2] >> 25) & 1) bAES = true; if ((cpu_id[2] >> 25) & 1) bAES = true;
// To check DAZ support, we first need to check FXSAVE support.
if ((cpu_id[3] >> 24) & 1) if ((cpu_id[3] >> 24) & 1)
{ {
// We can use FXSAVE. // We can use FXSAVE.
bFXSR = true; bFXSR = true;
GC_ALIGNED16(u8 fx_state[512]);
memset(fx_state, 0, sizeof(fx_state));
#ifdef _WIN32
#if _M_X86_32
_fxsave(fx_state);
#elif _M_X86_64
_fxsave64(fx_state);
#endif
#else
__asm__("fxsave %0" : "=m" (fx_state));
#endif
// lowest byte of MXCSR_MASK
if ((fx_state[0x1C] >> 6) & 1)
{
// On x86, the FTZ field (supported since SSE1) only flushes denormal _outputs_ to zero,
// now that we checked DAZ support (flushing denormal _inputs_ to zero),
// we can set our generic flag.
bFlushToZero = true;
}
} }
// AVX support requires 3 separate checks: // AVX support requires 3 separate checks:
@ -204,6 +182,9 @@ void CPUInfo::Detect()
} }
} }
} }
bFlushToZero = bSSE;
if (max_ex_fn >= 0x80000004) { if (max_ex_fn >= 0x80000004) {
// Extract brand string // Extract brand string
__cpuid(cpu_id, 0x80000002); __cpuid(cpu_id, 0x80000002);
@ -269,7 +250,3 @@ std::string CPUInfo::Summarize()
return sum; return sum;
} }
bool CPUInfo::IsUnsafe()
{
return !bFlushToZero;
}

View File

@ -62,8 +62,6 @@ namespace FPURoundMode
{ {
// OR-mask for disabling FPU exceptions (bits 7-12 in the MXCSR register) // OR-mask for disabling FPU exceptions (bits 7-12 in the MXCSR register)
const u32 EXCEPTION_MASK = 0x1F80; const u32 EXCEPTION_MASK = 0x1F80;
// Denormals-Are-Zero (non-IEEE mode: denormal inputs are set to +/- 0)
const u32 DAZ = 0x40;
// Flush-To-Zero (non-IEEE mode: denormal outputs are set to +/- 0) // Flush-To-Zero (non-IEEE mode: denormal outputs are set to +/- 0)
const u32 FTZ = 0x8000; const u32 FTZ = 0x8000;
// lookup table for FPSCR.RN-to-MXCSR.RC translation // lookup table for FPSCR.RN-to-MXCSR.RC translation
@ -76,16 +74,9 @@ namespace FPURoundMode
}; };
u32 csr = simd_rounding_table[rounding_mode]; u32 csr = simd_rounding_table[rounding_mode];
// Some initial steppings of Pentium 4 CPUs support FTZ but not DAZ.
// They will not flush input operands but flushing outputs only is better than nothing.
static const u32 denormalLUT[2] =
{
FTZ, // flush-to-zero only
FTZ | DAZ, // flush-to-zero and denormals-are-zero (may not be supported)
};
if (non_ieee_mode) if (non_ieee_mode)
{ {
csr |= denormalLUT[cpu_info.bFlushToZero]; csr |= FTZ;
} }
_mm_setcsr(csr); _mm_setcsr(csr);
} }

View File

@ -374,10 +374,6 @@ void EmuThread()
DisplayMessage(cpu_info.brand_string, 8000); DisplayMessage(cpu_info.brand_string, 8000);
DisplayMessage(cpu_info.Summarize(), 8000); DisplayMessage(cpu_info.Summarize(), 8000);
DisplayMessage(_CoreParameter.m_strFilename, 3000); DisplayMessage(_CoreParameter.m_strFilename, 3000);
if (cpu_info.IsUnsafe() && (NetPlay::IsNetPlayRunning() || Movie::IsRecordingInput() || Movie::IsPlayingInput()))
{
PanicAlertT("Warning: Netplay/movies will desync because your CPU does not support DAZ and Dolphin does not emulate it anymore.");
}
Movie::Init(); Movie::Init();