Merge pull request #1073 from phire/save_jitil2
Fix Idle Skipping in JitIL.
This commit is contained in:
commit
d72f61d62f
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue