From 342da0e2a850ed5b3a40e53aba294f685504c1eb Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Sat, 23 May 2009 12:40:01 +0000 Subject: [PATCH] microVU: - 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 --- pcsx2/x86/microVU_Analyze.inl | 1 + pcsx2/x86/microVU_Compile.inl | 2 +- pcsx2/x86/microVU_Flags.inl | 18 ++++++++++-------- pcsx2/x86/microVU_Misc.h | 15 ++++++++------- pcsx2/x86/microVU_Upper.inl | 2 +- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/pcsx2/x86/microVU_Analyze.inl b/pcsx2/x86/microVU_Analyze.inl index 0301d2a476..214f3fe440 100644 --- a/pcsx2/x86/microVU_Analyze.inl +++ b/pcsx2/x86/microVU_Analyze.inl @@ -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. diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index 0857fd144a..db6a44131e 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -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(); 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(); branchEbit(); branch = 3; mVUbranch = 0; mVUinfo |= _isBranch; } diff --git a/pcsx2/x86/microVU_Flags.inl b/pcsx2/x86/microVU_Flags.inl index b513f8f89c..95f4527efb 100644 --- a/pcsx2/x86/microVU_Flags.inl +++ b/pcsx2/x86/microVU_Flags.inl @@ -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(); 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(branchAddr); incPC(1); } + branchType1 { incPC(-1); mVUflagPass(branchAddr); incPC(1); } branchType2 { mVUflagInfo |= 0xfff; } branchType3 { incPC(-1); - mVUpass4(branchAddr); + mVUflagPass(branchAddr); int backupFlagInfo = mVUflagInfo; mVUflagInfo = 0; incPC(4); // Branch Not Taken - mVUpass4(xPC); + mVUflagPass(xPC); incPC(-3); mVUflagInfo |= backupFlagInfo; } diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index f5a2e60174..306e9d5686 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -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) { \ diff --git a/pcsx2/x86/microVU_Upper.inl b/pcsx2/x86/microVU_Upper.inl index 37a92f8442..3ecdb57fb7 100644 --- a/pcsx2/x86/microVU_Upper.inl +++ b/pcsx2/x86/microVU_Upper.inl @@ -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