JitArm64: Partially fallback on bcctrx

No need to assert, fallbacks on branching instructions now works fine.
This commit is contained in:
degasus 2015-06-28 20:27:50 +02:00
parent 0054c4e0d9
commit 245a639e2c
1 changed files with 23 additions and 28 deletions

View File

@ -179,39 +179,34 @@ void JitArm64::bcctrx(UGeckoInstruction inst)
INSTRUCTION_START INSTRUCTION_START
JITDISABLE(bJITBranchOff); JITDISABLE(bJITBranchOff);
// Rare condition seen in (just some versions of?) Nintendo's NES Emulator
// BO_2 == 001zy -> b if false
// BO_2 == 011zy -> b if true
FALLBACK_IF(!(inst.BO_2 & BO_DONT_CHECK_CONDITION));
// bcctrx doesn't decrement and/or test CTR // bcctrx doesn't decrement and/or test CTR
_assert_msg_(DYNA_REC, inst.BO_2 & BO_DONT_DECREMENT_FLAG, "bcctrx with decrement and test CTR option is invalid!"); _assert_msg_(DYNA_REC, inst.BO_2 & BO_DONT_DECREMENT_FLAG, "bcctrx with decrement and test CTR option is invalid!");
if (inst.BO_2 & BO_DONT_CHECK_CONDITION) // BO_2 == 1z1zz -> b always
//NPC = CTR & 0xfffffffc;
gpr.Flush(FlushMode::FLUSH_ALL);
fpr.Flush(FlushMode::FLUSH_ALL);
if (inst.LK_3)
{ {
// BO_2 == 1z1zz -> b always ARM64Reg WB = gpr.GetReg();
u32 Jumpto = js.compilerPC + 4;
//NPC = CTR & 0xfffffffc; MOVI2R(WB, Jumpto);
gpr.Flush(FlushMode::FLUSH_ALL); STR(INDEX_UNSIGNED, WB, X29, PPCSTATE_OFF(spr[SPR_LR]));
fpr.Flush(FlushMode::FLUSH_ALL); gpr.Unlock(WB);
if (inst.LK_3)
{
ARM64Reg WB = gpr.GetReg();
u32 Jumpto = js.compilerPC + 4;
MOVI2R(WB, Jumpto);
STR(INDEX_UNSIGNED, WB, X29, PPCSTATE_OFF(spr[SPR_LR]));
gpr.Unlock(WB);
}
ARM64Reg WA = gpr.GetReg();
LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(spr[SPR_CTR]));
AND(WA, WA, 30, 29); // Wipe the bottom 2 bits.
WriteExitDestInR(WA);
}
else
{
// Rare condition seen in (just some versions of?) Nintendo's NES Emulator
// BO_2 == 001zy -> b if false
// BO_2 == 011zy -> b if true
_assert_msg_(DYNA_REC, false, "Haven't implemented rare form of bcctrx yet");
} }
ARM64Reg WA = gpr.GetReg();
LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(spr[SPR_CTR]));
AND(WA, WA, 30, 29); // Wipe the bottom 2 bits.
WriteExitDestInR(WA);
} }
void JitArm64::bclrx(UGeckoInstruction inst) void JitArm64::bclrx(UGeckoInstruction inst)