summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authornitsuja <nitsuja-@hotmail.com>2012-01-07 22:19:45 -0800
committernitsuja <nitsuja-@hotmail.com>2012-01-07 22:23:59 -0800
commit1603bbb5f44f3046667dabdbcb60cb09b970f979 (patch)
treef45b200ddcd36588a5cc5b95190851c278628844 /Source/Core
parent2368d88c654d691b8c60179b505113c87a4d72a6 (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.cpp2
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_FloatingPoint.cpp63
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();
}