- Added a new status-flag speedhack after learning how evil sVU is with status flags (mVU with both flag-speedhacks ON is less evil than sVU's default setting which does something even hackier)
- Minor Changes

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1246 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-05-23 12:40:01 +00:00
parent ecfed766cd
commit 342da0e2a8
5 changed files with 21 additions and 17 deletions

View File

@ -291,6 +291,7 @@ microVUt(void) mVUanalyzeSflag(int It) {
if (!It) { mVUinfo |= _isNOP; }
else {
mVUinfo |= _swapOps;
mVUsFlagHack = 0; // Don't Optimize Out Status Flags for this block
if (mVUcount < 4) { mVUpBlock->pState.needExactMatch |= 0xf /*<< mVUcount*/; }
if (mVUcount >= 1) { incPC2(-2); mVUinfo |= _isSflag; incPC2(2); }
// Note: _isSflag is used for status flag optimizations.

View File

@ -237,6 +237,7 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
mVUpBlock = pBlock;
mVUregs.flags = 0;
mVUflagInfo = 0;
mVUsFlagHack = CHECK_VU_FLAGHACK2 | mVUflagHack;
bool eBitBranch = 0; // E-bit Set on Branch
for (int branch = 0; mVUcount < (vuIndex ? (0x3fff/8) : (0xfff/8)); ) {
@ -252,7 +253,6 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
mVUsetCycles<vuIndex>();
if (mVU->p) { mVUinfo |= _readP; }
if (mVU->q) { mVUinfo |= _readQ; }
else { mVUinfo |= _writeQ; }
if (branch >= 2) { mVUinfo |= _isEOB | ((branch == 3) ? _isBdelay : 0); mVUcount++; branchWarning(); break; }
else if (branch == 1) { branch = 2; }
if (mVUbranch) { mVUsetFlagInfo<vuIndex>(); branchEbit(); branch = 3; mVUbranch = 0; mVUinfo |= _isBranch; }

View File

@ -72,6 +72,8 @@ void sortFlag(int* fFlag, int* bFlag, int cycles) {
}
}
#define sFlagCond ((doStatus && !mVUsFlagHack) || isFSSET || doDivFlag)
// Note: Flag handling is 'very' complex, it requires full knowledge of how microVU recs work, so don't touch!
microVUt(int) mVUsetFlags(int* xStatus, int* xMac, int* xClip) {
microVU* mVU = mVUx;
@ -132,9 +134,9 @@ microVUt(int) mVUsetFlags(int* xStatus, int* xMac, int* xClip) {
mVUinfo |= xM << 10; // _fmInstance
mVUinfo |= xC << 14; // _fcInstance
if (doStatus || isFSSET || doDivFlag) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; }
if (doMac) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; }
if (doClip) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; }
if (sFlagCond) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; }
if (doMac) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; }
if (doClip) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; }
cycles++;
incPC2(2);
@ -183,7 +185,7 @@ microVUt(void) mVUsetupFlags(int* xStatus, int* xMac, int* xClip, int cycles) {
}
}
microVUt(void) mVUpass4(int startPC) {
microVUt(void) mVUflagPass(int startPC) {
microVU* mVU = mVUx;
int oldPC = iPC;
@ -195,7 +197,7 @@ microVUt(void) mVUpass4(int startPC) {
for (int branch = 0; mVUcount < 4; mVUcount++) {
incPC(1);
if ( curI & _Ebit_ ) { branch = 1; }
if ( curI & _MDTbit_ ) { branch = 2; }
if ( curI & _MDTbit_ ) { branch = 4; }
if (!(curI & _Ibit_) ) { incPC(-1); mVUopL<vuIndex, 3>(); incPC(1); }
if (branch >= 2) { break; }
else if (branch == 1) { branch = 2; }
@ -215,15 +217,15 @@ microVUt(void) mVUpass4(int startPC) {
microVUt(void) mVUsetFlagInfo() {
microVU* mVU = mVUx;
branchType1 { incPC(-1); mVUpass4<vuIndex>(branchAddr); incPC(1); }
branchType1 { incPC(-1); mVUflagPass<vuIndex>(branchAddr); incPC(1); }
branchType2 { mVUflagInfo |= 0xfff; }
branchType3 {
incPC(-1);
mVUpass4<vuIndex>(branchAddr);
mVUflagPass<vuIndex>(branchAddr);
int backupFlagInfo = mVUflagInfo;
mVUflagInfo = 0;
incPC(4); // Branch Not Taken
mVUpass4<vuIndex>(xPC);
mVUflagPass<vuIndex>(xPC);
incPC(-3);
mVUflagInfo |= backupFlagInfo;
}

View File

@ -189,8 +189,8 @@ declareAllVariables
#define _isEOB (1<<2) // End of Block
#define _isBdelay (1<<3) // Cur Instruction in Branch Delay slot
#define _isSflag (1<<4) // Cur Instruction uses status flag
#define _writeQ (1<<5)
#define _readQ (1<<6)
#define _writeQ (1<<6)
#define _readQ (1<<6) // same as writeQ
#define _writeP (1<<7)
#define _readP (1<<7) // same as writeP
#define _doFlags (3<<8)
@ -220,10 +220,10 @@ declareAllVariables
#define isEOB (mVUinfo & (1<<2))
#define isBdelay (mVUinfo & (1<<3))
#define isSflag (mVUinfo & (1<<4))
#define writeQ ((mVUinfo >> 5) & 1)
#define readQ ((mVUinfo >> 6) & 1)
#define writeP (((mVUinfo >> 7) + 1) & 1)
#define readQ ((mVUinfo >> 6) & 1) // same as writeQ
#define readP ((mVUinfo >> 7) & 1) // same as writeP
#define writeQ (((mVUinfo >> 6) + 1) & 1)
#define writeP (((mVUinfo >> 7) + 1) & 1)
#define doFlags (mVUinfo & (3<<8))
#define doMac (mVUinfo & (1<<8))
#define doStatus (mVUinfo & (1<<9))
@ -289,8 +289,9 @@ declareAllVariables
#endif
// Speed Hacks (Set to 1 to turn On)
#define CHECK_VU_FLAGHACK 0 // Status Flag Speed Hack
#define CHECK_VU_MINMAXHACK 0 // Min/Max Speed Hack
#define CHECK_VU_FLAGHACK 0 // Status Flag Speed Hack (Very-Compatible)
#define CHECK_VU_FLAGHACK2 0 // Status Flag Speed Hack (More-Hacky)
#define CHECK_VU_MINMAXHACK 0 // Min/Max Speed Hack (Semi-Compatible)
// Cache Limit Check
#define mVUcacheCheck(ptr, start, limit) { \

View File

@ -35,7 +35,7 @@ microVUt(void) mVUupdateFlags(int reg, int regT1, int regT2, int xyzw, bool modX
static const u16 flipMask[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15};
//SysPrintf("doStatus = %d; doMac = %d\n", doStatus>>9, doMac>>8);
if (mVUflagHack) { mVUinfo &= ~_doStatus; }
if (mVUsFlagHack) { mVUinfo &= ~_doStatus; }
if (!doFlags) return;
if (!doMac || (_XYZW_SS && modXYZW)) { regT1 = reg; }
else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw