diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index f53d540dd4..cc836a3a70 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -128,6 +128,7 @@ microVUt(void) mVUclear(u32 addr, u32 size) { microVUt(void) mVUclearProg(int progIndex) { microVU* mVU = mVUx; mVU->prog.prog[progIndex].used = 1; + mVU->prog.prog[progIndex].sFlagHack = 0; mVU->prog.prog[progIndex].x86ptr = mVU->prog.prog[progIndex].x86start; for (u32 i = 0; i < (mVU->progSize / 2); i++) { mVU->prog.prog[progIndex].block[i]->reset(); @@ -139,6 +140,7 @@ microVUt(void) mVUcacheProg(int progIndex) { microVU* mVU = mVUx; memcpy_fast(mVU->prog.prog[progIndex].data, mVU->regs->Micro, mVU->microSize); mVUdumpProg(progIndex); + mVUcheckSflag(progIndex); } // Finds the least used program, (if program list full clears and returns an old program; if not-full, returns free program) diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h index 19e23990fe..2137e9518c 100644 --- a/pcsx2/x86/microVU.h +++ b/pcsx2/x86/microVU.h @@ -68,6 +68,7 @@ template struct microProgram { u32 data[progSize/4]; u32 used; // Number of times its been used + u32 sFlagHack; // Optimize out Status Flag Updates if Program doesn't use Status Flags u8* x86ptr; // Pointer to program's recompilation code u8* x86start; // Start of program's rec-cache u8* x86end; // Limit of program's rec-cache diff --git a/pcsx2/x86/microVU_Alloc.h b/pcsx2/x86/microVU_Alloc.h index 8e50e24f73..dc4e81d867 100644 --- a/pcsx2/x86/microVU_Alloc.h +++ b/pcsx2/x86/microVU_Alloc.h @@ -75,7 +75,7 @@ struct microAllocInfo { u32 count; // Number of VU 64bit instructions ran (starts at 0 for each block) u32 curPC; // Current PC u32 startPC; // Start PC for Cur Block - u32 flagInfo; // Holds information to help with flag instances on block linking + u32 sFlagHack; // Optimize out all Status flag updates if microProgram doesn't use Status flags u32 info[pSize/8]; // Info for Instructions in current block u8 stall[pSize/8]; // Info on how much each instruction stalled (stores the max amount of cycles to stall for the current opcodes) }; diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index ace1301b7e..4d30137cf5 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -118,10 +118,12 @@ microVUt(void) mVUendProgram(int fStatus, int fMac, int fClip) { } // Save Flag Instances - getFlagReg(fStatus, fStatus); + if (!mVUflagHack) { + getFlagReg(fStatus, fStatus); + MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, fStatus); + } mVUallocMFLAGa(gprT1, fMac); mVUallocCFLAGa(gprT2, fClip); - MOV32RtoM((uptr)&mVU->regs->VI[REG_STATUS_FLAG].UL, fStatus); MOV32RtoM((uptr)&mVU->regs->VI[REG_MAC_FLAG].UL, gprT1); MOV32RtoM((uptr)&mVU->regs->VI[REG_CLIP_FLAG].UL, gprT2); diff --git a/pcsx2/x86/microVU_Flags.inl b/pcsx2/x86/microVU_Flags.inl index 20d1e8a81b..37a469a272 100644 --- a/pcsx2/x86/microVU_Flags.inl +++ b/pcsx2/x86/microVU_Flags.inl @@ -151,7 +151,7 @@ microVUt(int) mVUsetFlags(int* xStatus, int* xMac, int* xClip) { microVUt(void) mVUsetupFlags(int* xStatus, int* xMac, int* xClip, int cycles) { microVU* mVU = mVUx; - if (__Status) { + if (__Status && !mVUflagHack) { int bStatus[4]; sortFlag(xStatus, bStatus, cycles); PUSH32R(gprR); // Backup gprR diff --git a/pcsx2/x86/microVU_Lower.inl b/pcsx2/x86/microVU_Lower.inl index 615afeeb11..c829a0b964 100644 --- a/pcsx2/x86/microVU_Lower.inl +++ b/pcsx2/x86/microVU_Lower.inl @@ -551,7 +551,7 @@ microVUf(void) mVU_FSAND() { mVUallocVIb(gprT1, _It_); } pass3 { mVUlog("FSAND vi%02d, $%x", _Ft_, _Imm12_); } - pass4 { mVUflagInfo |= 0xf << (/*mVUcount +*/ 0); } + pass4 { mVUflagInfo |= 0xf << (/*mVUcount +*/ 0); mVUsFlagHack = 0; } } microVUf(void) mVU_FSEQ() { @@ -565,7 +565,7 @@ microVUf(void) mVU_FSEQ() { mVUallocVIb(gprT1, _It_); } pass3 { mVUlog("FSEQ vi%02d, $%x", _Ft_, _Imm12_); } - pass4 { mVUflagInfo |= 0xf << (/*mVUcount +*/ 0); } + pass4 { mVUflagInfo |= 0xf << (/*mVUcount +*/ 0); mVUsFlagHack = 0; } } microVUf(void) mVU_FSOR() { @@ -577,7 +577,7 @@ microVUf(void) mVU_FSOR() { mVUallocVIb(gprT1, _It_); } pass3 { mVUlog("FSOR vi%02d, $%x", _Ft_, _Imm12_); } - pass4 { mVUflagInfo |= 0xf << (/*mVUcount +*/ 0); SysPrintf("b\n"); } + pass4 { mVUflagInfo |= 0xf << (/*mVUcount +*/ 0); mVUsFlagHack = 0; } } microVUf(void) mVU_FSSET() { @@ -591,6 +591,7 @@ microVUf(void) mVU_FSSET() { OR16ItoR (flagReg1, (_Imm12_ & 0xfc0)); } pass3 { mVUlog("FSSET $%x", _Imm12_); } + pass4 { mVUsFlagHack = 0; } } //------------------------------------------------------------------ diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index 4e5df160a1..42f39247ee 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -160,7 +160,8 @@ declareAllVariables #define mVUregs mVUallocInfo.block.pState #define mVUregsTemp mVUallocInfo.regsTemp #define iPC mVUallocInfo.curPC -#define mVUflagInfo mVUregs.needExactMatch //mVUallocInfo.flagInfo +#define mVUflagInfo mVUregs.needExactMatch +#define mVUsFlagHack mVUallocInfo.sFlagHack #define mVUinfo mVUallocInfo.info[iPC / 2] #define mVUstall mVUallocInfo.stall[iPC / 2] #define mVUstartPC mVUallocInfo.startPC @@ -286,6 +287,10 @@ declareAllVariables #define mVUdumpProg 0&& #endif +// Status Flag Speed Hack +#define CHECK_VU_FLAGHACK 0 // Set to 1 to turn hack on +#define mVUflagHack (mVUcurProg.sFlagHack) + // Cache Limit Check #define mVUcacheCheck(ptr, start, limit) { \ uptr diff = ptr - start; \ diff --git a/pcsx2/x86/microVU_Misc.inl b/pcsx2/x86/microVU_Misc.inl index bae60ade93..8f0e53850e 100644 --- a/pcsx2/x86/microVU_Misc.inl +++ b/pcsx2/x86/microVU_Misc.inl @@ -299,4 +299,21 @@ microVUt(void) mVUrestoreRegs() { POP32R(gprR); // Restore EDX } + +microVUt(void) mVUcheckSflag(int progIndex) { + if (CHECK_VU_FLAGHACK) { + + microVU* mVU = mVUx; + mVUsFlagHack = 1; + for (u32 i = 0; i < mVU->progSize; i+=2) { + mVU->code = mVU->prog.prog[progIndex].data[i+1]; + mVUopU(); + mVU->code = mVU->prog.prog[progIndex].data[i]; + mVUopL(); + } + mVUflagInfo = 0; + mVU->prog.prog[progIndex].sFlagHack = mVUsFlagHack; + } +} + #endif //PCSX2_MICROVU diff --git a/pcsx2/x86/microVU_Upper.inl b/pcsx2/x86/microVU_Upper.inl index a6fe9f0f3b..c80718581e 100644 --- a/pcsx2/x86/microVU_Upper.inl +++ b/pcsx2/x86/microVU_Upper.inl @@ -35,6 +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 (!doFlags) return; if (!doMac) { regT1 = reg; } else { SSE2_PSHUFD_XMM_to_XMM(regT1, reg, 0x1B); } // Flip wzyx to xyzw