Merge pull request #1073 from phire/save_jitil2

Fix Idle Skipping in JitIL.
This commit is contained in:
Dolphin Bot 2014-09-13 18:40:57 +02:00
commit d72f61d62f
4 changed files with 33 additions and 19 deletions

View File

@ -909,7 +909,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
regMarkUse(RI, I, getOp1(I), 1);
break;
case IdleBranch:
regMarkUse(RI, I, getOp1(getOp1(I)), 1);
regMarkUse(RI, I, getOp1(I), 1);
break;
case BranchCond:
{
@ -2088,9 +2088,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
case IdleBranch:
{
Jit->CMP(32, regLocForInst(RI, getOp1(getOp1(I))),
Imm32(RI.Build->GetImmValue(getOp2(getOp1(I)))));
FixupBranch cont = Jit->J_CC(CC_NE);
// If value is 0, we don't need to call out to the idle function.
OpArg value = regLocForInst(RI, getOp1(I));
Jit->TEST(32, value, value);
FixupBranch noidle = Jit->J_CC(CC_NZ);
RI.Jit->Cleanup(); // is it needed?
Jit->ABI_CallFunction((void *)&PowerPC::OnIdleIL);
@ -2098,9 +2099,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
Jit->MOV(32, PPCSTATE(pc), Imm32(ibuild->GetImmValue( getOp2(I) )));
Jit->WriteExceptionExit();
Jit->SetJumpTarget(cont);
Jit->SetJumpTarget(noidle);
if (RI.IInfo[I - RI.FirstI] & 4)
regClearInst(RI, getOp1(getOp1(I)));
regClearInst(RI, getOp1(I));
if (RI.IInfo[I - RI.FirstI] & 8)
regClearInst(RI, getOp2(I));
break;

View File

@ -1083,11 +1083,6 @@ InstLoc IRBuilder::FoldBranchCond(InstLoc Op1, InstLoc Op2)
return EmitBiOp(BranchCond, Op1, Op2);
}
InstLoc IRBuilder::FoldIdleBranch(InstLoc Op1, InstLoc Op2)
{
return EmitBiOp(IdleBranch, EmitICmpEq(getOp1(getOp1(Op1)), getOp2(getOp1(Op1))), Op2);
}
InstLoc IRBuilder::FoldICmp(unsigned Opcode, InstLoc Op1, InstLoc Op2)
{
if (isImm(*Op1))
@ -1245,8 +1240,6 @@ InstLoc IRBuilder::FoldBiOp(unsigned Opcode, InstLoc Op1, InstLoc Op2, unsigned
return FoldRol(Op1, Op2);
case BranchCond:
return FoldBranchCond(Op1, Op2);
case IdleBranch:
return FoldIdleBranch(Op1, Op2);
case ICmpEq: case ICmpNe:
case ICmpUgt: case ICmpUlt: case ICmpUge: case ICmpUle:
case ICmpSgt: case ICmpSlt: case ICmpSge: case ICmpSle:

View File

@ -138,14 +138,18 @@ void JitILBase::bcx(UGeckoInstruction inst)
else
destination = js.compilerPC + SignExt16(inst.BD << 2);
// Idle skipping:
// The main Idle skipping is done in the LoadStore code, but there is an optimization here.
// If idle skipping is enabled, then this branch will only be reached when the branch is not
// taken.
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle &&
inst.hex == 0x4182fff8 &&
(Memory::ReadUnchecked_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 &&
(Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x28000000 ||
(SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x2C000000))
)
inst.hex == 0x4182fff8 &&
(Memory::ReadUnchecked_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 &&
(Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x28000000 ||
(SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x2C000000))
)
{
ibuild.EmitIdleBranch(Test, ibuild.EmitIntConst(destination));
// Uh, Do nothing.
}
else
{

View File

@ -33,6 +33,22 @@ void JitILBase::lXz(UGeckoInstruction inst)
ibuild.EmitStoreGReg(addr, inst.RA);
IREmitter::InstLoc val;
// Idle Skipping. This really should be done somewhere else.
// Either lower in the IR or higher in PPCAnalyist
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle &&
inst.OPCD == 32 && // Lwx
(inst.hex & 0xFFFF0000) == 0x800D0000 &&
(Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 ||
(SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) &&
Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8)
{
val = ibuild.EmitLoad32(addr);
ibuild.EmitIdleBranch(val, ibuild.EmitIntConst(js.compilerPC));
ibuild.EmitStoreGReg(val, inst.RD);
return;
}
switch (inst.OPCD & ~0x1)
{
case 32: // lwz