microVU: If the vi reg is modified directly before the branch, then the value read by the branch is always the result of the 5th or greater instruction...

Thanks to genter for helping me figure this out.
See this:
http://forums.pcsx2.net/Thread-blog-PS2-VU-Vector-Unit-Documentation-Part-1?pid=103928#pid103928


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3091 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2010-05-28 02:25:56 +00:00
parent de13bdf8d7
commit 1addaf5c69
3 changed files with 47 additions and 3 deletions

View File

@ -347,6 +347,49 @@ _f void mVUanalyzeXGkick(mV, int Fs, int xCycles) {
// Branches - Branch Opcodes // Branches - Branch Opcodes
//------------------------------------------------------------------ //------------------------------------------------------------------
_f void analyzeBranchVI(mV, int xReg, bool &infoVar) {
if (!xReg) return;
int i, j = 0;
int iEnd = 4;
int bPC = iPC;
incPC2(-2);
for (i = 0; i < iEnd; i++) {
if (i == mVUcount) {
bool warn = 0;
if (i == 1) warn = 1;
if (mVUpBlock->pState.viBackUp == xReg) {
if (i == 0) warn = 1;
infoVar = 1;
j = i; i++;
}
if (warn) DevCon.Warning("microVU%d: Warning Branch VI-Delay with small block (%d) [%04x]", getIndex, i, xPC);
break; // if (warn), we don't have enough information to always guarantee the correct result.
}
if ((mVUlow.VI_write.reg == xReg) && mVUlow.VI_write.used) {
if (mVUlow.readFlags) {
if (i) DevCon.Warning("microVU%d: Warning Branch VI-Delay with Read Flags Set (%d) [%04x]", getIndex, i, xPC);
break; // Not sure if on the above "if (i)" case, if we need to "continue" or if we should "break"
}
j = i;
}
elif (i == 0) break;
incPC2(-2);
}
if (i) {
if (!infoVar) {
iPC = bPC;
incPC2(-2*(j+1));
mVUlow.backupVI = 1;
infoVar = 1;
}
iPC = bPC;
Console.WriteLn(Color_Green, "microVU%d: Branch VI-Delay (%d) [%04x]", getIndex, j+1, xPC);
}
else iPC = bPC;
}
/*
// Dead Code... the old version of analyzeBranchVI()
_f void analyzeBranchVI(mV, int xReg, bool &infoVar) { _f void analyzeBranchVI(mV, int xReg, bool &infoVar) {
if (!xReg) return; if (!xReg) return;
int i; int i;
@ -381,6 +424,7 @@ _f void analyzeBranchVI(mV, int xReg, bool &infoVar) {
} }
else iPC = bPC; else iPC = bPC;
} }
*/
// Branch in Branch Delay-Slots // Branch in Branch Delay-Slots
_f int mVUbranchCheck(mV) { _f int mVUbranchCheck(mV) {

View File

@ -36,7 +36,7 @@ struct __aligned16 microRegInfo { // Ordered for Faster Compares
u8 p; u8 p;
u8 r; u8 r;
u8 xgkick; u8 xgkick;
u8 viBackUp; u8 viBackUp; // VI reg number that was written to on branch-delay slot
u8 VI[16]; u8 VI[16];
regInfo VF[32]; regInfo VF[32];
u8 flags; // clip x2 :: status x2 u8 flags; // clip x2 :: status x2

View File

@ -185,8 +185,8 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
#define xPC ((iPC / 2) * 8) #define xPC ((iPC / 2) * 8)
#define curI ((u32*)mVU->regs->Micro)[iPC] //mVUcurProg.data[iPC] #define curI ((u32*)mVU->regs->Micro)[iPC] //mVUcurProg.data[iPC]
#define setCode() { mVU->code = curI; } #define setCode() { mVU->code = curI; }
#define incPC(x) { iPC = ((iPC + x) & (mVU->progSize-1)); setCode(); } #define incPC(x) { iPC = ((iPC + (x)) & (mVU->progSize-1)); setCode(); }
#define incPC2(x) { iPC = ((iPC + x) & (mVU->progSize-1)); } #define incPC2(x) { iPC = ((iPC + (x)) & (mVU->progSize-1)); }
#define bSaveAddr (((xPC + 16) & (mVU->microMemSize-8)) / 8) #define bSaveAddr (((xPC + 16) & (mVU->microMemSize-8)) / 8)
#define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & (mVU->microMemSize-8)) #define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & (mVU->microMemSize-8))
#define branchAddrN ((xPC + 16 + (_Imm11_ * 8)) & (mVU->microMemSize-8)) #define branchAddrN ((xPC + 16 + (_Imm11_ * 8)) & (mVU->microMemSize-8))