- Implemented some bizarre behavior where conditional branches will read old VI-reg values if the previous instructions continuously read+write to the VI reg.

example from zerorec's comments:
SQI vi5++
SQI vi5++
IBNE vi4, vi5

vi5's value in the branch should be the value before all the SQI's...
more examples in iVUzerorec.cpp

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1304 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-06-02 00:50:37 +00:00
parent a8266a48d8
commit 8c5b6ae749
2 changed files with 34 additions and 32 deletions

View File

@ -29,6 +29,7 @@
#define aReg(x) mVUregs.VF[x]
#define bReg(x, y) mVUregsTemp.VFreg[y] = x; mVUregsTemp.VF[y]
#define aMax(x, y) ((x > y) ? x : y)
#define aMin(x, y) ((x < y) ? x : y)
// Read a VF reg by upper op
#define analyzeReg1(xReg, vfRead) { \
@ -128,18 +129,6 @@
// Writing to a VI reg
#define analyzeVIreg2(xReg, viWrite, aCycles) { \
if (xReg) { \
mVUregsTemp.VIreg = xReg; \
mVUregsTemp.VI = aCycles; \
mVUlow.writesVI = 1; \
mVU->VIbackup[0] = xReg; \
viWrite.reg = xReg; \
viWrite.used = aCycles; \
} \
}
// Writing to a VI reg (FSxxx, FMxxx, FCxxx opcodes)
#define analyzeVIreg3(xReg, viWrite, aCycles) { \
if (xReg) { \
mVUregsTemp.VIreg = xReg; \
mVUregsTemp.VI = aCycles; \
@ -319,16 +308,13 @@ microVUt(void) mVUanalyzeSflag(mV, int It) {
// Do to stalls, it can only be set one instruction prior to the status flag read instruction
// if we were guaranteed no-stalls were to happen, it could be set 4 instruction prior.
}
analyzeVIreg3(It, mVUlow.VI_write, 1);
mVUlow.readFlags = 1;
analyzeVIreg2(It, mVUlow.VI_write, 1);
}
microVUt(void) mVUanalyzeFSSET(mV) {
mVUlow.isFSSET = 1;
// mVUinfo &= ~_doStatus;
// Note: I'm not entirely sure if the non-sticky flags
// should be taken from the current upper instruction
// or if they should be taken from the previous instruction
// Uncomment the above line if the latter-case is true
mVUlow.readFlags = 1;
}
//------------------------------------------------------------------
@ -347,8 +333,9 @@ microVUt(void) mVUanalyzeMflag(mV, int Is, int It) {
}
iPC = curPC;
}
mVUlow.readFlags = 1;
analyzeVIreg1(Is, mVUlow.VI_read[0]);
analyzeVIreg3(It, mVUlow.VI_write, 1);
analyzeVIreg2(It, mVUlow.VI_write, 1);
}
//------------------------------------------------------------------
@ -357,8 +344,9 @@ microVUt(void) mVUanalyzeMflag(mV, int Is, int It) {
microVUt(void) mVUanalyzeCflag(mV, int It) {
mVUinfo.swapOps = 1;
mVUlow.readFlags = 1;
if (mVUcount < 4) { mVUpBlock->pState.needExactMatch |= 0xf << (/*mVUcount +*/ 8); }
analyzeVIreg3(It, mVUlow.VI_write, 1);
analyzeVIreg2(It, mVUlow.VI_write, 1);
}
//------------------------------------------------------------------
@ -381,17 +369,30 @@ microVUt(void) mVUanalyzeXGkick(mV, int Fs, int xCycles) {
// Branches - Branch Opcodes
//------------------------------------------------------------------
#define analyzeBranchVI(reg, infoVar) { \
/* First ensure branch is not first opcode in block */ \
if (reg && (mVUcount > 0)) { \
incPC2(-2); \
/* Check if prev Op modified VI reg */ \
if (mVUlow.writesVI && (reg == mVU->VIbackup[0])) { \
mVUlow.backupVI = 1; \
#define analyzeBranchVI(xReg, infoVar) { \
if (xReg) { \
int i; \
int iEnd = aMin(4, mVUcount); \
int bPC = iPC; \
for (i = 0; i < iEnd; i++) { \
incPC2(-2) \
if ((mVUlow.VI_write.reg == xReg) && mVUlow.VI_write.used) { \
if (mVUlow.readFlags) break; \
if (i == 0) continue; \
if (((mVUlow.VI_read[0].reg == xReg) && (mVUlow.VI_read[0].used)) \
|| ((mVUlow.VI_read[1].reg == xReg) && (mVUlow.VI_read[1].used))) \
{ continue; } \
} \
break; \
} \
if (i) { \
DevCon::Status("microVU%d: Branch VI-Delay (%d)", params getIndex, i); \
incPC2(2); \
mVUlow.backupVI = 1; \
iPC = bPC; \
infoVar = 1; \
} \
else { incPC2(2); } \
iPC = bPC; \
} \
}

View File

@ -99,6 +99,7 @@ struct microLowerOp {
bool memReadIs; // Read Is (VI reg) from memory (used by branches)
bool memReadIt; // Read If (VI reg) from memory (used by branches)
bool writesVI; // Current Instruction writes to VI (used by branches; note that flag-modifying opcodes shouldn't set this)
bool readFlags; // Current Instruction reads Status, Mac, or Clip flags
};
struct microFlagInst {