From 1603bbb5f44f3046667dabdbcb60cb09b970f979 Mon Sep 17 00:00:00 2001 From: nitsuja Date: Sat, 7 Jan 2012 22:19:45 -0800 Subject: [PATCH] fixed and reenabled and slightly optimized the JIT version of fcmpo/fcmpu. --- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 2 +- .../Src/PowerPC/Jit64/Jit_FloatingPoint.cpp | 63 ++++++++++++------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 0d31893b53..2a2f3c36b0 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -193,7 +193,7 @@ void Jit64::Init() jo.enableFastMem = false; #endif jo.assumeFPLoadFromMem = Core::g_CoreStartupParameter.bUseFastMem; - jo.fpAccurateFcmp = true; // Fallback to Interpreter + jo.fpAccurateFcmp = Core::g_CoreStartupParameter.bEnableFPRF; jo.optimizeGatherPipe = true; jo.fastInterrupts = false; jo.accurateSinglePrecision = true; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp index a325e3a150..5fcd2f9e29 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp @@ -229,8 +229,6 @@ void Jit64::fmrx(UGeckoInstruction inst) void Jit64::fcmpx(UGeckoInstruction inst) { - // TODO : This still causes crashes in Nights, and broken graphics - // in Paper Mario, Super Paper Mario as well as SoulCalibur 2 prolly others too.. :( INSTRUCTION_START JITDISABLE(FloatingPoint) if (jo.fpAccurateFcmp) { @@ -243,36 +241,59 @@ void Jit64::fcmpx(UGeckoInstruction inst) int crf = inst.CRFD; fpr.Lock(a,b); - if (a != b) fpr.BindToRegister(a, true); + fpr.BindToRegister(b, true); // Are we masking sNaN invalid floating point exceptions? If not this could crash if we don't handle the exception? - UCOMISD(fpr.R(a).GetSimpleReg(), fpr.R(b)); + UCOMISD(fpr.R(b).GetSimpleReg(), fpr.R(a)); - FixupBranch pNaN = J_CC(CC_P); - FixupBranch pLesser = J_CC(CC_B); - FixupBranch pGreater = J_CC(CC_A); + FixupBranch pNaN, pLesser, pGreater; + FixupBranch continue1, continue2, continue3; + + if (a != b) + { + // if B > A, goto Lesser's jump target + pLesser = J_CC(CC_A); + } + + // if (B != B) or (A != A), goto NaN's jump target + pNaN = J_CC(CC_P); + + if (a != b) + { + // if B < A, goto Greater's jump target + // JB can't precede the NaN check because it doesn't test ZF + pGreater = J_CC(CC_B); + } // Equal MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x2)); - FixupBranch continue1 = J(); - - // Greater Than - SetJumpTarget(pGreater); - MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x4)); - FixupBranch continue2 = J(); - - // Less Than - SetJumpTarget(pLesser); - MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x8)); - FixupBranch continue3 = J(); - + continue1 = J(); + // NAN SetJumpTarget(pNaN); MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x1)); + + if (a != b) + { + continue2 = J(); + + // Greater Than + SetJumpTarget(pGreater); + MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x4)); + continue3 = J(); + + // Less Than + SetJumpTarget(pLesser); + MOV(8, M(&PowerPC::ppcState.cr_fast[crf]), Imm8(0x8)); + } SetJumpTarget(continue1); - SetJumpTarget(continue2); - SetJumpTarget(continue3); + if (a != b) + { + SetJumpTarget(continue2); + SetJumpTarget(continue3); + } + fpr.UnlockAll(); }