diff options
| author | nitsuja <nitsuja-@hotmail.com> | 2012-01-07 22:19:45 -0800 |
|---|---|---|
| committer | nitsuja <nitsuja-@hotmail.com> | 2012-01-07 22:23:59 -0800 |
| commit | 1603bbb5f44f3046667dabdbcb60cb09b970f979 (patch) | |
| tree | f45b200ddcd36588a5cc5b95190851c278628844 /Source/Core | |
| parent | 2368d88c654d691b8c60179b505113c87a4d72a6 (diff) | |
fixed and reenabled and slightly optimized the JIT version of fcmpo/fcmpu.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/Core/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(); } |
