mirror of https://github.com/PCSX2/pcsx2.git
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
This commit is contained in:
parent
ecfed766cd
commit
342da0e2a8
|
@ -291,6 +291,7 @@ microVUt(void) mVUanalyzeSflag(int It) {
|
||||||
if (!It) { mVUinfo |= _isNOP; }
|
if (!It) { mVUinfo |= _isNOP; }
|
||||||
else {
|
else {
|
||||||
mVUinfo |= _swapOps;
|
mVUinfo |= _swapOps;
|
||||||
|
mVUsFlagHack = 0; // Don't Optimize Out Status Flags for this block
|
||||||
if (mVUcount < 4) { mVUpBlock->pState.needExactMatch |= 0xf /*<< mVUcount*/; }
|
if (mVUcount < 4) { mVUpBlock->pState.needExactMatch |= 0xf /*<< mVUcount*/; }
|
||||||
if (mVUcount >= 1) { incPC2(-2); mVUinfo |= _isSflag; incPC2(2); }
|
if (mVUcount >= 1) { incPC2(-2); mVUinfo |= _isSflag; incPC2(2); }
|
||||||
// Note: _isSflag is used for status flag optimizations.
|
// Note: _isSflag is used for status flag optimizations.
|
||||||
|
|
|
@ -237,6 +237,7 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
|
||||||
mVUpBlock = pBlock;
|
mVUpBlock = pBlock;
|
||||||
mVUregs.flags = 0;
|
mVUregs.flags = 0;
|
||||||
mVUflagInfo = 0;
|
mVUflagInfo = 0;
|
||||||
|
mVUsFlagHack = CHECK_VU_FLAGHACK2 | mVUflagHack;
|
||||||
bool eBitBranch = 0; // E-bit Set on Branch
|
bool eBitBranch = 0; // E-bit Set on Branch
|
||||||
|
|
||||||
for (int branch = 0; mVUcount < (vuIndex ? (0x3fff/8) : (0xfff/8)); ) {
|
for (int branch = 0; mVUcount < (vuIndex ? (0x3fff/8) : (0xfff/8)); ) {
|
||||||
|
@ -252,7 +253,6 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
|
||||||
mVUsetCycles<vuIndex>();
|
mVUsetCycles<vuIndex>();
|
||||||
if (mVU->p) { mVUinfo |= _readP; }
|
if (mVU->p) { mVUinfo |= _readP; }
|
||||||
if (mVU->q) { mVUinfo |= _readQ; }
|
if (mVU->q) { mVUinfo |= _readQ; }
|
||||||
else { mVUinfo |= _writeQ; }
|
|
||||||
if (branch >= 2) { mVUinfo |= _isEOB | ((branch == 3) ? _isBdelay : 0); mVUcount++; branchWarning(); break; }
|
if (branch >= 2) { mVUinfo |= _isEOB | ((branch == 3) ? _isBdelay : 0); mVUcount++; branchWarning(); break; }
|
||||||
else if (branch == 1) { branch = 2; }
|
else if (branch == 1) { branch = 2; }
|
||||||
if (mVUbranch) { mVUsetFlagInfo<vuIndex>(); branchEbit(); branch = 3; mVUbranch = 0; mVUinfo |= _isBranch; }
|
if (mVUbranch) { mVUsetFlagInfo<vuIndex>(); branchEbit(); branch = 3; mVUbranch = 0; mVUinfo |= _isBranch; }
|
||||||
|
|
|
@ -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!
|
// 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) {
|
microVUt(int) mVUsetFlags(int* xStatus, int* xMac, int* xClip) {
|
||||||
microVU* mVU = mVUx;
|
microVU* mVU = mVUx;
|
||||||
|
@ -132,9 +134,9 @@ microVUt(int) mVUsetFlags(int* xStatus, int* xMac, int* xClip) {
|
||||||
mVUinfo |= xM << 10; // _fmInstance
|
mVUinfo |= xM << 10; // _fmInstance
|
||||||
mVUinfo |= xC << 14; // _fcInstance
|
mVUinfo |= xC << 14; // _fcInstance
|
||||||
|
|
||||||
if (doStatus || isFSSET || doDivFlag) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; }
|
if (sFlagCond) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; }
|
||||||
if (doMac) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; }
|
if (doMac) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; }
|
||||||
if (doClip) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; }
|
if (doClip) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; }
|
||||||
|
|
||||||
cycles++;
|
cycles++;
|
||||||
incPC2(2);
|
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;
|
microVU* mVU = mVUx;
|
||||||
int oldPC = iPC;
|
int oldPC = iPC;
|
||||||
|
@ -195,7 +197,7 @@ microVUt(void) mVUpass4(int startPC) {
|
||||||
for (int branch = 0; mVUcount < 4; mVUcount++) {
|
for (int branch = 0; mVUcount < 4; mVUcount++) {
|
||||||
incPC(1);
|
incPC(1);
|
||||||
if ( curI & _Ebit_ ) { branch = 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 (!(curI & _Ibit_) ) { incPC(-1); mVUopL<vuIndex, 3>(); incPC(1); }
|
||||||
if (branch >= 2) { break; }
|
if (branch >= 2) { break; }
|
||||||
else if (branch == 1) { branch = 2; }
|
else if (branch == 1) { branch = 2; }
|
||||||
|
@ -215,15 +217,15 @@ microVUt(void) mVUpass4(int startPC) {
|
||||||
|
|
||||||
microVUt(void) mVUsetFlagInfo() {
|
microVUt(void) mVUsetFlagInfo() {
|
||||||
microVU* mVU = mVUx;
|
microVU* mVU = mVUx;
|
||||||
branchType1 { incPC(-1); mVUpass4<vuIndex>(branchAddr); incPC(1); }
|
branchType1 { incPC(-1); mVUflagPass<vuIndex>(branchAddr); incPC(1); }
|
||||||
branchType2 { mVUflagInfo |= 0xfff; }
|
branchType2 { mVUflagInfo |= 0xfff; }
|
||||||
branchType3 {
|
branchType3 {
|
||||||
incPC(-1);
|
incPC(-1);
|
||||||
mVUpass4<vuIndex>(branchAddr);
|
mVUflagPass<vuIndex>(branchAddr);
|
||||||
int backupFlagInfo = mVUflagInfo;
|
int backupFlagInfo = mVUflagInfo;
|
||||||
mVUflagInfo = 0;
|
mVUflagInfo = 0;
|
||||||
incPC(4); // Branch Not Taken
|
incPC(4); // Branch Not Taken
|
||||||
mVUpass4<vuIndex>(xPC);
|
mVUflagPass<vuIndex>(xPC);
|
||||||
incPC(-3);
|
incPC(-3);
|
||||||
mVUflagInfo |= backupFlagInfo;
|
mVUflagInfo |= backupFlagInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,8 +189,8 @@ declareAllVariables
|
||||||
#define _isEOB (1<<2) // End of Block
|
#define _isEOB (1<<2) // End of Block
|
||||||
#define _isBdelay (1<<3) // Cur Instruction in Branch Delay slot
|
#define _isBdelay (1<<3) // Cur Instruction in Branch Delay slot
|
||||||
#define _isSflag (1<<4) // Cur Instruction uses status flag
|
#define _isSflag (1<<4) // Cur Instruction uses status flag
|
||||||
#define _writeQ (1<<5)
|
#define _writeQ (1<<6)
|
||||||
#define _readQ (1<<6)
|
#define _readQ (1<<6) // same as writeQ
|
||||||
#define _writeP (1<<7)
|
#define _writeP (1<<7)
|
||||||
#define _readP (1<<7) // same as writeP
|
#define _readP (1<<7) // same as writeP
|
||||||
#define _doFlags (3<<8)
|
#define _doFlags (3<<8)
|
||||||
|
@ -220,10 +220,10 @@ declareAllVariables
|
||||||
#define isEOB (mVUinfo & (1<<2))
|
#define isEOB (mVUinfo & (1<<2))
|
||||||
#define isBdelay (mVUinfo & (1<<3))
|
#define isBdelay (mVUinfo & (1<<3))
|
||||||
#define isSflag (mVUinfo & (1<<4))
|
#define isSflag (mVUinfo & (1<<4))
|
||||||
#define writeQ ((mVUinfo >> 5) & 1)
|
#define readQ ((mVUinfo >> 6) & 1) // same as writeQ
|
||||||
#define readQ ((mVUinfo >> 6) & 1)
|
|
||||||
#define writeP (((mVUinfo >> 7) + 1) & 1)
|
|
||||||
#define readP ((mVUinfo >> 7) & 1) // same as writeP
|
#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 doFlags (mVUinfo & (3<<8))
|
||||||
#define doMac (mVUinfo & (1<<8))
|
#define doMac (mVUinfo & (1<<8))
|
||||||
#define doStatus (mVUinfo & (1<<9))
|
#define doStatus (mVUinfo & (1<<9))
|
||||||
|
@ -289,8 +289,9 @@ declareAllVariables
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Speed Hacks (Set to 1 to turn On)
|
// Speed Hacks (Set to 1 to turn On)
|
||||||
#define CHECK_VU_FLAGHACK 0 // Status Flag Speed Hack
|
#define CHECK_VU_FLAGHACK 0 // Status Flag Speed Hack (Very-Compatible)
|
||||||
#define CHECK_VU_MINMAXHACK 0 // Min/Max Speed Hack
|
#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
|
// Cache Limit Check
|
||||||
#define mVUcacheCheck(ptr, start, limit) { \
|
#define mVUcacheCheck(ptr, start, limit) { \
|
||||||
|
|
|
@ -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};
|
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);
|
//SysPrintf("doStatus = %d; doMac = %d\n", doStatus>>9, doMac>>8);
|
||||||
if (mVUflagHack) { mVUinfo &= ~_doStatus; }
|
if (mVUsFlagHack) { mVUinfo &= ~_doStatus; }
|
||||||
if (!doFlags) return;
|
if (!doFlags) return;
|
||||||
if (!doMac || (_XYZW_SS && modXYZW)) { regT1 = reg; }
|
if (!doMac || (_XYZW_SS && modXYZW)) { regT1 = reg; }
|
||||||
else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw
|
else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw
|
||||||
|
|
Loading…
Reference in New Issue