x64/x86 dynarecs: fast-math fcmp/eq implementation

Fixes Shin Nihon Pro Wrestling - Toukon Retsuden 4
Fixes Project Justice (Issue #38)
This commit is contained in:
Flyinghead 2021-03-07 16:59:17 +01:00
parent 0e20d5976b
commit 31e0b3ab51
4 changed files with 32 additions and 11 deletions

View File

@ -131,12 +131,15 @@ static INLINE f32 fixNaN(f32 f)
{ {
#ifdef STRICT_MODE #ifdef STRICT_MODE
u32& hex = *(u32 *)&f; u32& hex = *(u32 *)&f;
#ifdef __FAST_MATH__
// fast-math
if ((hex & 0x7fffffff) > 0x7f800000)
hex = 0x7fbfffff;
#else
// no fast-math // no fast-math
if (f != f) if (f != f)
hex = 0x7fbfffff; hex = 0x7fbfffff;
// // fast-math #endif
// if ((hex & 0x7fffffff) > 0x7f800000)
// hex = 0x7fbfffff;
#endif #endif
return f; return f;
} }
@ -144,12 +147,16 @@ static INLINE f32 fixNaN(f32 f)
static INLINE f64 fixNaN64(f64 f) static INLINE f64 fixNaN64(f64 f)
{ {
#ifdef STRICT_MODE #ifdef STRICT_MODE
// no fast-math
u64& hex = *(u64 *)&f; u64& hex = *(u64 *)&f;
#ifdef __FAST_MATH__
// fast-math
if ((hex & 0x7fffffffffffffffll) > 0x7ff0000000000000ll)
hex = 0x7ff7ffffffffffffll;
#else
// no fast-math
if (f != f) if (f != f)
hex = 0x7ff7ffffffffffffll; hex = 0x7ff7ffffffffffffll;
// fast-math #endif
// return (*(u64 *)&f & 0x7fffffffffffffffll) <= 0x7f80000000000000ll ? f : 0x7ff7ffffffffffffll;
#endif #endif
return f; return f;
} }

View File

@ -335,6 +335,12 @@ public:
} }
break; break;
case shop_jcond:
case shop_jdyn:
case shop_mov32:
genBaseOpcode(op);
break;
#ifndef CANONICAL_TEST #ifndef CANONICAL_TEST
case shop_sync_sr: case shop_sync_sr:
GenCall(UpdateSR); GenCall(UpdateSR);

View File

@ -566,11 +566,13 @@ protected:
} }
else else
{ {
//special case #ifdef __FAST_MATH__
//We want to take in account the 'unordered' case on the fpu sete(al);
lahf(); #else
test(ah, 0x44); mov(edx, 0);
setnp(al); setnp(al); // Parity means unordered (NaN), ZF is set too
cmovne(eax, edx);
#endif
} }
movzx(mapRegister(op.rd), al); movzx(mapRegister(op.rd), al);
break; break;

View File

@ -349,6 +349,12 @@ void X86Compiler::genOpcode(RuntimeBlockInfo* block, bool optimise, shil_opcode&
} }
break; break;
case shop_jcond:
case shop_jdyn:
case shop_mov32:
genBaseOpcode(op);
break;
#ifndef CANONICAL_TEST #ifndef CANONICAL_TEST
case shop_sync_sr: case shop_sync_sr:
genCallCdecl(UpdateSR); genCallCdecl(UpdateSR);