mirror of https://github.com/PCSX2/pcsx2.git
mVU: Rework multiple branch chaining
This commit is contained in:
parent
4ab9d1a493
commit
59ab303c5c
|
@ -243,6 +243,7 @@ struct microVU
|
|||
u32 branch; // Holds branch compare result (IBxx) OR Holds address to Jump to (JALR/JR)
|
||||
u32 badBranch; // For Branches in Branch Delay Slots, holds Address the first Branch went to + 8
|
||||
u32 evilBranch; // For Branches in Branch Delay Slots, holds Address to Jump to
|
||||
u32 evilevilBranch;// For Branches in Branch Delay Slots (chained), holds Address to Jump to
|
||||
u32 p; // Holds current P instance index
|
||||
u32 q; // Holds current Q instance index
|
||||
u32 totalCycles; // Total Cycles that mVU is expected to run for
|
||||
|
|
|
@ -584,9 +584,30 @@ static void analyzeBranchVI(mV, int xReg, bool& infoVar)
|
|||
// Branch in Branch Delay-Slots
|
||||
__ri int mVUbranchCheck(mV)
|
||||
{
|
||||
if (!mVUcount)
|
||||
if (!mVUcount && !isEvilBlock)
|
||||
return 0;
|
||||
|
||||
// This means we have jumped from an evil branch situation, so this is another branch in delay slot
|
||||
if (isEvilBlock)
|
||||
{
|
||||
mVUlow.evilBranch = true;
|
||||
mVUregs.blockType = 2;
|
||||
mVUregs.needExactMatch |= 7; // This might not be necessary, but w/e...
|
||||
mVUregs.flagInfo = 0;
|
||||
|
||||
if (mVUlow.branch == 2 || mVUlow.branch == 10)
|
||||
{
|
||||
Console.Error("microVU%d: %s in branch, branch delay slot requires link [%04x] - If game broken report to PCSX2 Team", mVU.index,
|
||||
branchSTR[mVUlow.branch & 0xf], xPC);
|
||||
}
|
||||
else
|
||||
{
|
||||
DevCon.Warning("microVU%d: %s in branch, branch delay slot! [%04x] - If game broken report to PCSX2 Team", mVU.index,
|
||||
branchSTR[mVUlow.branch & 0xf], xPC);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
incPC(-2);
|
||||
|
||||
if (mVUlow.branch)
|
||||
|
|
|
@ -304,7 +304,11 @@ void normJumpCompile(mV, microFlagCycles& mFC, bool isEvilJump)
|
|||
}
|
||||
|
||||
if (isEvilJump)
|
||||
{
|
||||
xMOV(arg1regd, ptr32[&mVU.evilBranch]);
|
||||
xMOV(gprT1, ptr32[&mVU.evilevilBranch]);
|
||||
xMOV(ptr32[&mVU.evilBranch], gprT1);
|
||||
}
|
||||
else
|
||||
xMOV(arg1regd, ptr32[&mVU.branch]);
|
||||
if (doJumpCaching)
|
||||
|
|
|
@ -903,13 +903,13 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
|
|||
mVU_XGKICK_DELAY(mVU);
|
||||
}
|
||||
|
||||
if (isEvilBlock && !isConditional)
|
||||
if (isEvilBlock)
|
||||
{
|
||||
mVUsetupRange(mVU, xPC + 8, false);
|
||||
normJumpCompile(mVU, mFC, true);
|
||||
goto perf_and_return;
|
||||
}
|
||||
else if (!mVUinfo.isBdelay && !isEvilBlock)
|
||||
else if (!mVUinfo.isBdelay)
|
||||
{
|
||||
// Handle range wrapping
|
||||
if ((xPC + 8) == mVU.microMemSize)
|
||||
|
|
|
@ -1756,16 +1756,30 @@ void condEvilBranch(mV, int JMPcc)
|
|||
cJMP.SetTarget();
|
||||
return;
|
||||
}
|
||||
xMOV(ptr32[&mVU.evilBranch], branchAddr(mVU));
|
||||
xCMP(gprT1b, 0);
|
||||
xForwardJump8 cJMP((JccComparisonType)JMPcc);
|
||||
if (isEvilBlock)
|
||||
{
|
||||
xMOV(ptr32[&mVU.evilevilBranch], branchAddr(mVU));
|
||||
xCMP(gprT1b, 0);
|
||||
xForwardJump8 cJMP((JccComparisonType)JMPcc);
|
||||
xMOV(gprT1, ptr32[&mVU.evilBranch]); // Branch Not Taken
|
||||
xADD(gprT1, 8); // We have already executed 1 instruction from the original branch
|
||||
xMOV(ptr32[&mVU.evilevilBranch], gprT1);
|
||||
cJMP.SetTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
xMOV(ptr32[&mVU.evilBranch], branchAddr(mVU));
|
||||
xCMP(gprT1b, 0);
|
||||
xForwardJump8 cJMP((JccComparisonType)JMPcc);
|
||||
xMOV(gprT1, ptr32[&mVU.badBranch]); // Branch Not Taken
|
||||
//xADD(gprT1, 8); // We have already executed 1 instruction from the original branch
|
||||
xMOV(ptr32[&mVU.evilBranch], gprT1);
|
||||
cJMP.SetTarget();
|
||||
incPC(-2);
|
||||
if (mVUlow.branch >= 9)
|
||||
DevCon.Warning("Conditional in JALR/JR delay slot - If game broken report to PCSX2 Team");
|
||||
incPC(2);
|
||||
cJMP.SetTarget();
|
||||
incPC(-2);
|
||||
if (mVUlow.branch >= 9)
|
||||
DevCon.Warning("Conditional in JALR/JR delay slot - If game broken report to PCSX2 Team");
|
||||
incPC(2);
|
||||
}
|
||||
}
|
||||
|
||||
mVUop(mVU_B)
|
||||
|
@ -1774,8 +1788,8 @@ mVUop(mVU_B)
|
|||
pass1 { mVUanalyzeNormBranch(mVU, 0, false); }
|
||||
pass2
|
||||
{
|
||||
if (mVUlow.badBranch) { xMOV(ptr32[&mVU.badBranch], branchAddrN(mVU)); }
|
||||
if (mVUlow.evilBranch) { xMOV(ptr32[&mVU.evilBranch], branchAddr(mVU)); }
|
||||
if (mVUlow.badBranch) { xMOV(ptr32[&mVU.badBranch], branchAddr(mVU)); }
|
||||
if (mVUlow.evilBranch) { if(isEvilBlock) xMOV(ptr32[&mVU.evilevilBranch], branchAddr(mVU)); else xMOV(ptr32[&mVU.evilBranch], branchAddr(mVU)); }
|
||||
mVU.profiler.EmitOp(opB);
|
||||
}
|
||||
pass3 { mVUlog("B [<a href=\"#addr%04x\">%04x</a>]", branchAddr(mVU), branchAddr(mVU)); }
|
||||
|
@ -1792,9 +1806,23 @@ mVUop(mVU_BAL)
|
|||
xMOV(gprT1, bSaveAddr);
|
||||
mVUallocVIb(mVU, gprT1, _It_);
|
||||
}
|
||||
else
|
||||
{
|
||||
incPC(-2);
|
||||
DevCon.Warning("Linking BAL from %s branch taken/nottaken target! - If game broken report to PCSX2 Team", branchSTR[mVUlow.branch & 0xf]);
|
||||
incPC(2);
|
||||
if (isEvilBlock)
|
||||
xMOV(gprT1, ptr32[&mVU.evilBranch]);
|
||||
else
|
||||
xMOV(gprT1, ptr32[&mVU.badBranch]);
|
||||
|
||||
if (mVUlow.badBranch) { xMOV(ptr32[&mVU.badBranch], branchAddrN(mVU)); }
|
||||
if (mVUlow.evilBranch) { xMOV(ptr32[&mVU.evilBranch], branchAddr(mVU));}
|
||||
xADD(gprT1, 8);
|
||||
xSHR(gprT1, 3);
|
||||
mVUallocVIb(mVU, gprT1, _It_);
|
||||
}
|
||||
|
||||
if (mVUlow.badBranch) { xMOV(ptr32[&mVU.badBranch], branchAddr(mVU)); }
|
||||
if (mVUlow.evilBranch) { if (isEvilBlock) xMOV(ptr32[&mVU.evilevilBranch], branchAddr(mVU)); else xMOV(ptr32[&mVU.evilBranch], branchAddr(mVU)); }
|
||||
mVU.profiler.EmitOp(opBAL);
|
||||
}
|
||||
pass3 { mVUlog("BAL vi%02d [<a href=\"#addr%04x\">%04x</a>]", _Ft_, branchAddr(mVU), branchAddr(mVU)); }
|
||||
|
@ -1946,7 +1974,10 @@ void normJumpPass2(mV)
|
|||
}
|
||||
else
|
||||
{
|
||||
xMOV(ptr32[&mVU.evilBranch], gprT1);
|
||||
if(isEvilBlock)
|
||||
xMOV(ptr32[&mVU.evilevilBranch], gprT1);
|
||||
else
|
||||
xMOV(ptr32[&mVU.evilBranch], gprT1);
|
||||
}
|
||||
//If delay slot is conditional, it uses badBranch to go to its target
|
||||
if (mVUlow.badBranch)
|
||||
|
@ -1983,18 +2014,35 @@ mVUop(mVU_JALR)
|
|||
}
|
||||
if (mVUlow.evilBranch)
|
||||
{
|
||||
incPC(-2);
|
||||
if (mVUlow.branch >= 9) // Previous branch is a jump of some type so we need to take the branch address from the register it uses.
|
||||
if (isEvilBlock)
|
||||
{
|
||||
DevCon.Warning("Linking JALR from JALR/JR branch target! - If game broken report to PCSX2 Team");
|
||||
mVUallocVIa(mVU, gprT1, _Is_);
|
||||
xMOV(gprT1, ptr32[&mVU.evilBranch]);
|
||||
xADD(gprT1, 8);
|
||||
xSHR(gprT1, 3);
|
||||
incPC(2);
|
||||
mVUallocVIb(mVU, gprT1, _It_);
|
||||
}
|
||||
else
|
||||
incPC(2);
|
||||
{
|
||||
incPC(-2);
|
||||
if (mVUlow.branch >= 9) // Previous branch is a jump of some type so we need to take the branch address from the register it uses.
|
||||
{
|
||||
DevCon.Warning("Linking JALR from JALR/JR branch target! - If game broken report to PCSX2 Team");
|
||||
mVUallocVIa(mVU, gprT1, _Is_);
|
||||
xADD(gprT1, 8);
|
||||
xSHR(gprT1, 3);
|
||||
incPC(2);
|
||||
mVUallocVIb(mVU, gprT1, _It_);
|
||||
}
|
||||
else // Else we take the branch target of the previous branch
|
||||
{
|
||||
DevCon.Warning("Linking JALR from %d branch taken/nottaken target! - If game broken report to PCSX2 Team", branchSTR[mVUlow.branch & 0xf]);
|
||||
xMOV(gprT1, ptr32[&mVU.badBranch]);
|
||||
xADD(gprT1, 8);
|
||||
xSHR(gprT1, 3);
|
||||
incPC(2);
|
||||
mVUallocVIb(mVU, gprT1, _It_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mVU.profiler.EmitOp(opJALR);
|
||||
|
|
|
@ -229,13 +229,6 @@ static void __fc mVUEBit()
|
|||
vu1Thread.mtvuInterrupts.fetch_or(VU_Thread::InterruptFlagVUEBit, std::memory_order_release);
|
||||
}
|
||||
|
||||
static inline u32 branchAddrN(const mV)
|
||||
{
|
||||
pxAssumeDev(islowerOP, "MicroVU: Expected Lower OP code for valid branch addr.");
|
||||
return ((((iPC + 4) + (_Imm11_ * 2)) & mVU.progMemMask) * 4);
|
||||
}
|
||||
|
||||
|
||||
static inline u32 branchAddr(const mV)
|
||||
{
|
||||
pxAssumeDev(islowerOP, "MicroVU: Expected Lower OP code for valid branch addr.");
|
||||
|
|
Loading…
Reference in New Issue