- Crashes when "microVU Error: Program went over its cache limit" message occurs should be fixed.
- Miscellaneous code changes and cleanups.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1211 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-05-17 11:34:00 +00:00
parent 0391b76015
commit 942e7e9231
7 changed files with 84 additions and 84 deletions

View File

@ -30,6 +30,7 @@ PCSX2_ALIGNED16(microVU microVU0);
PCSX2_ALIGNED16(microVU microVU1); PCSX2_ALIGNED16(microVU microVU1);
declareAllVariables // Declares All Global Variables :D declareAllVariables // Declares All Global Variables :D
//------------------------------------------------------------------ //------------------------------------------------------------------
// Micro VU - Main Functions // Micro VU - Main Functions
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -117,7 +118,6 @@ microVUt(void) mVUclose() {
// Clears Block Data in specified range // Clears Block Data in specified range
microVUt(void) mVUclear(u32 addr, u32 size) { microVUt(void) mVUclear(u32 addr, u32 size) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!mVU->prog.cleared) { if (!mVU->prog.cleared) {
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState)); memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
@ -139,7 +139,7 @@ microVUt(void) mVUclearProg(int progIndex) {
mVU->prog.prog[progIndex].range[1] = -1; mVU->prog.prog[progIndex].range[1] = -1;
mVU->prog.prog[progIndex].x86ptr = mVU->prog.prog[progIndex].x86start; mVU->prog.prog[progIndex].x86ptr = mVU->prog.prog[progIndex].x86start;
for (u32 i = 0; i < (mVU->progSize / 2); i++) { for (u32 i = 0; i < (mVU->progSize / 2); i++) {
if( mVU->prog.prog[progIndex].block[i] ) if (mVU->prog.prog[progIndex].block[i])
mVU->prog.prog[progIndex].block[i]->reset(); mVU->prog.prog[progIndex].block[i]->reset();
} }
} }
@ -170,11 +170,9 @@ microVUt(int) mVUfindLeastUsedProg() {
int smallidx = startidx; int smallidx = startidx;
u32 smallval = mVU->prog.prog[startidx].used; u32 smallval = mVU->prog.prog[startidx].used;
for (int i = startidx; i != endidx; i = (i+1)&mVU->prog.max) for (int i = startidx; i != endidx; i = (i+1)&mVU->prog.max) {
{
u32 used = mVU->prog.prog[i].used; u32 used = mVU->prog.prog[i].used;
if (smallval > used) if (smallval > used) {
{
smallval = used; smallval = used;
smallidx = i; smallidx = i;
} }
@ -195,7 +193,6 @@ microVUt(int) mVUfindLeastUsedProg() {
// frame-based decrementing system in combination with a program-execution-based incrementing // frame-based decrementing system in combination with a program-execution-based incrementing
// system. In english: if last_used >= 2 it means the program has been used for the current // system. In english: if last_used >= 2 it means the program has been used for the current
// or prev frame. if it's 0, the program hasn't been used for a while. // or prev frame. if it's 0, the program hasn't been used for a while.
//
microVUt(void) __mVUvsyncUpdate() { microVUt(void) __mVUvsyncUpdate() {
microVU* mVU = mVUx; microVU* mVU = mVUx;
@ -246,11 +243,7 @@ microVUt(int) mVUsearchProg() {
for (int i = 0; i <= mVU->prog.total; i++) { for (int i = 0; i <= mVU->prog.total; i++) {
if (mVUcmpProg<vuIndex>(i, !mVU->prog.prog[i].used, 0, 0)) if (mVUcmpProg<vuIndex>(i, !mVU->prog.prog[i].used, 0, 0))
return 1; // Check Older Programs return 1; // Check Older Programs
} }
/*for (int i = 0; i <= mVU->prog.total; i++) {
if (mVUcmpProg<vuIndex>(i, 1, 1, 0))
return 1; // Check Partial Program
}*/
mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance
mVU->prog.cleared = 0; mVU->prog.cleared = 0;
mVU->prog.isSame = 1; mVU->prog.isSame = 1;
@ -260,27 +253,7 @@ microVUt(int) mVUsearchProg() {
mVU->prog.prog[mVU->prog.cur].last_used = 3; mVU->prog.prog[mVU->prog.cur].last_used = 3;
return 1; // If !cleared, then we're still on the same program as last-time ;) return 1; // If !cleared, then we're still on the same program as last-time ;)
} }
/*
// Block Invalidation
__forceinline void mVUinvalidateBlock(microVU* mVU, u32 addr, u32 size) {
int i = addr/8;
int end = i+((size+(8-(size&7)))/8); // ToDo: Can be simplified to addr+size if Size is always a multiple of 8
if (!mVU->prog.cleared) {
for ( ; i < end; i++) {
if ( mVU->prog.prog[mVU->prog.cur].block[i]->clear() ) {
mVU->prog.cleared = 1;
i++;
break;
}
}
}
for ( ; i < end; i++) {
mVU->prog.prog[mVU->prog.cur].block[i]->clearFast();
}
}
*/
//------------------------------------------------------------------ //------------------------------------------------------------------
// Wrapper Functions - Called by other parts of the Emu // Wrapper Functions - Called by other parts of the Emu
//------------------------------------------------------------------ //------------------------------------------------------------------

View File

@ -17,8 +17,8 @@
*/ */
#pragma once #pragma once
//#define mVUdebug // Prints Extra Info to Console //#define mVUdebug // Prints Extra Info to Console
//#define mVUlogProg // Dumps MicroPrograms into microVU0.txt/microVU1.txt //#define mVUlogProg // Dumps MicroPrograms to \logs\*.html
#include "Common.h" #include "Common.h"
#include "VU.h" #include "VU.h"
@ -27,24 +27,26 @@
#include "microVU_Alloc.h" #include "microVU_Alloc.h"
#include "microVU_Misc.h" #include "microVU_Misc.h"
#define mMaxBlocks 32 // Max Blocks With Different Pipeline States #define mMaxBlocks 32 // Max Blocks With Different Pipeline States (For n = 1, 2, 4, 8, 16, etc...)
class microBlockManager { class microBlockManager {
private: private:
static const int MaxBlocks = mMaxBlocks - 1; static const int MaxBlocks = mMaxBlocks - 1;
int listSize; // Total Items - 1 int listSize; // Total Items - 1
int listI; // Index to Add new block
microBlock blockList[mMaxBlocks]; microBlock blockList[mMaxBlocks];
public: public:
microBlockManager() { reset(); } microBlockManager() { reset(); }
~microBlockManager() {} ~microBlockManager() {}
void reset() { listSize = -1; }; void reset() { listSize = -1; listI = -1; };
microBlock* add(microBlock* pBlock) { microBlock* add(microBlock* pBlock) {
microBlock* thisBlock = search(&pBlock->pState); microBlock* thisBlock = search(&pBlock->pState);
if (!thisBlock) { if (!thisBlock) {
listSize++; listI++;
if (listSize > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listSize = 0; } if (listSize < MaxBlocks) { listSize++; }
memcpy_fast(&blockList[listSize], pBlock, sizeof(microBlock)); if (listI > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listI = 0; }
thisBlock = &blockList[listSize]; memcpy_fast(&blockList[listI], pBlock, sizeof(microBlock));
thisBlock = &blockList[listI];
} }
return thisBlock; return thisBlock;
} }

View File

@ -49,6 +49,19 @@
} \ } \
} }
#define analyzeReg1b(reg) { \
if (reg) { \
analyzeReg1(reg); \
if (mVUregsTemp.VFreg[0] == reg) { \
if ((mVUregsTemp.VF[0].x && _X) \
|| (mVUregsTemp.VF[0].y && _Y) \
|| (mVUregsTemp.VF[0].z && _Z) \
|| (mVUregsTemp.VF[0].w && _W)) \
{ mVUinfo |= _swapOps; } \
} \
} \
}
microVUt(void) mVUanalyzeFMAC1(int Fd, int Fs, int Ft) { microVUt(void) mVUanalyzeFMAC1(int Fd, int Fs, int Ft) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
mVUinfo |= _doStatus; mVUinfo |= _doStatus;
@ -136,6 +149,13 @@ microVUt(void) mVUanalyzeIALU2(int Is, int It) {
if (_Y) { mVUstall = aMax(mVUstall, aReg(reg).z); } \ if (_Y) { mVUstall = aMax(mVUstall, aReg(reg).z); } \
if (_Z) { mVUstall = aMax(mVUstall, aReg(reg).w); } \ if (_Z) { mVUstall = aMax(mVUstall, aReg(reg).w); } \
if (_W) { mVUstall = aMax(mVUstall, aReg(reg).x); } \ if (_W) { mVUstall = aMax(mVUstall, aReg(reg).x); } \
if (mVUregsTemp.VFreg[0] == reg) { \
if ((mVUregsTemp.VF[0].y && _X) \
|| (mVUregsTemp.VF[0].z && _Y) \
|| (mVUregsTemp.VF[0].w && _Z) \
|| (mVUregsTemp.VF[0].x && _W)) \
{ mVUinfo |= _swapOps; } \
} \
} \ } \
} }
@ -158,6 +178,13 @@ microVUt(void) mVUanalyzeMR32(int Fs, int Ft) {
case 2: mVUstall = aMax(mVUstall, aReg(reg).z); break; \ case 2: mVUstall = aMax(mVUstall, aReg(reg).z); break; \
case 3: mVUstall = aMax(mVUstall, aReg(reg).w); break; \ case 3: mVUstall = aMax(mVUstall, aReg(reg).w); break; \
} \ } \
if (mVUregsTemp.VFreg[0] == reg) { \
if ((mVUregsTemp.VF[0].x && (fxf == 0)) \
|| (mVUregsTemp.VF[0].y && (fxf == 1)) \
|| (mVUregsTemp.VF[0].z && (fxf == 2)) \
|| (mVUregsTemp.VF[0].w && (fxf == 3))) \
{ mVUinfo |= _swapOps; } \
} \
} \ } \
} }
@ -186,7 +213,7 @@ microVUt(void) mVUanalyzeEFU1(int Fs, int Fsf, u8 xCycles) {
microVUt(void) mVUanalyzeEFU2(int Fs, u8 xCycles) { microVUt(void) mVUanalyzeEFU2(int Fs, u8 xCycles) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
mVUprint("microVU: EFU Opcode"); mVUprint("microVU: EFU Opcode");
analyzeReg1(Fs); analyzeReg1b(Fs);
analyzePreg(xCycles); analyzePreg(xCycles);
} }
@ -207,8 +234,7 @@ microVUt(void) mVUanalyzeMFP(int Ft) {
microVUt(void) mVUanalyzeMOVE(int Fs, int Ft) { microVUt(void) mVUanalyzeMOVE(int Fs, int Ft) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
if (!Ft || (Ft == Fs)) { mVUinfo |= _isNOP; } if (!Ft || (Ft == Fs)) { mVUinfo |= _isNOP; }
if (mVUregsTemp.VFreg[0] == Fs) { mVUinfo |= _swapOps; } analyzeReg1b(Fs);
analyzeReg1(Fs);
analyzeReg2(Ft, 1); analyzeReg2(Ft, 1);
} }
@ -231,10 +257,9 @@ microVUt(void) mVUanalyzeLQ(int Ft, int Is, bool writeIs) {
microVUt(void) mVUanalyzeSQ(int Fs, int It, bool writeIt) { microVUt(void) mVUanalyzeSQ(int Fs, int It, bool writeIt) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
analyzeReg1(Fs); analyzeReg1b(Fs);
analyzeVIreg1(It); analyzeVIreg1(It);
if (writeIt) { analyzeVIreg2(It, 1); } if (writeIt) { analyzeVIreg2(It, 1); }
if (mVUregsTemp.VFreg[0] == Fs) { mVUinfo |= _swapOps; }
} }
//------------------------------------------------------------------ //------------------------------------------------------------------

View File

@ -45,6 +45,36 @@
// Helper Functions // Helper Functions
//------------------------------------------------------------------ //------------------------------------------------------------------
// Used by mVUsetupRange
microVUt(void) mVUcheckIsSame() {
microVU* mVU = mVUx;
if (mVU->prog.isSame == -1) {
mVU->prog.isSame = !!memcmp_mmx(mVU->prog.prog[mVU->prog.cur].data, mVU->regs->Micro, mVU->microSize);
}
if (mVU->prog.isSame == 0) {
mVUcacheProg<vuIndex>(mVU->prog.cur);
}
}
// Sets up microProgram PC ranges based on whats been recompiled
microVUt(void) mVUsetupRange(u32 pc) {
microVU* mVU = mVUx;
if (mVUcurProg.range[0] == -1) {
mVUcurProg.range[0] = (s32)pc;
mVUcurProg.range[1] = (s32)pc;
}
else if (mVUcurProg.range[0] > (s32)pc) {
mVUcurProg.range[0] = (s32)pc;
mVUcheckIsSame<vuIndex>();
}
else if (mVUcurProg.range[1] < (s32)pc) {
mVUcurProg.range[1] = (s32)pc;
mVUcheckIsSame<vuIndex>();
}
}
// Recompiles Code for Proper Flags and Q/P regs on Block Linkings // Recompiles Code for Proper Flags and Q/P regs on Block Linkings
microVUt(void) mVUsetupBranch(int* xStatus, int* xMac, int* xClip, int xCycles) { microVUt(void) mVUsetupBranch(int* xStatus, int* xMac, int* xClip, int xCycles) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
@ -150,34 +180,6 @@ microVUt(void) mVUtestCycles() {
SUB32ItoM((uptr)&mVU->cycles, mVUcycles); SUB32ItoM((uptr)&mVU->cycles, mVUcycles);
} }
microVUt(void) mVUcheckIsSame() {
microVU* mVU = mVUx;
if (mVU->prog.isSame == -1) {
mVU->prog.isSame = !!memcmp_mmx(mVU->prog.prog[mVU->prog.cur].data, mVU->regs->Micro, mVU->microSize);
}
if (mVU->prog.isSame == 0) {
mVUcacheProg<vuIndex>(mVU->prog.cur);
}
}
microVUt(void) mVUsetupRange(u32 pc) {
microVU* mVU = mVUx;
if (mVUcurProg.range[0] == -1) {
mVUcurProg.range[0] = (s32)pc;
mVUcurProg.range[1] = (s32)pc;
}
else if (mVUcurProg.range[0] > (s32)pc) {
mVUcurProg.range[0] = (s32)pc;
mVUcheckIsSame<vuIndex>();
}
else if (mVUcurProg.range[1] < (s32)pc) {
mVUcurProg.range[1] = (s32)pc;
mVUcheckIsSame<vuIndex>();
}
}
//------------------------------------------------------------------ //------------------------------------------------------------------
// Recompiler // Recompiler
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -276,7 +278,7 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
incPC(-3); // Go back to branch opcode (to get branch imm addr) incPC(-3); // Go back to branch opcode (to get branch imm addr)
mVUsetupBranch<vuIndex>(xStatus, xMac, xClip, xCycles); mVUsetupBranch<vuIndex>(xStatus, xMac, xClip, xCycles);
if( mVUblocks[branchAddr/8] == NULL ) if (mVUblocks[branchAddr/8] == NULL)
mVUblocks[branchAddr/8] = new microBlockManager(); mVUblocks[branchAddr/8] = new microBlockManager();
// Check if branch-block has already been compiled // Check if branch-block has already been compiled
@ -293,7 +295,6 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
mVUbackupRegs<vuIndex>(); mVUbackupRegs<vuIndex>();
MOV32MtoR(gprT2, (uptr)&mVU->branch); // Get startPC (ECX first argument for __fastcall) MOV32MtoR(gprT2, (uptr)&mVU->branch); // Get startPC (ECX first argument for __fastcall)
//AND32ItoR(gprT2, (vuIndex)?0x3ff8:0xff8); // Ensure valid jump address
MOV32ItoR(gprR, (u32)&pBlock->pStateEnd); // Get pState (EDX second argument for __fastcall) MOV32ItoR(gprR, (u32)&pBlock->pStateEnd); // Get pState (EDX second argument for __fastcall)
if (!vuIndex) CALLFunc((uptr)mVUcompileVU0); //(u32 startPC, uptr pState) if (!vuIndex) CALLFunc((uptr)mVUcompileVU0); //(u32 startPC, uptr pState)

View File

@ -26,7 +26,7 @@ microVUt(void) mVUdivSet() {
if (doDivFlag) { if (doDivFlag) {
getFlagReg(flagReg1, fsInstance); getFlagReg(flagReg1, fsInstance);
if (!doStatus) { getFlagReg(flagReg2, fpsInstance); MOV32RtoR(flagReg1, flagReg2); } if (!doStatus) { getFlagReg(flagReg2, fpsInstance); MOV32RtoR(flagReg1, flagReg2); }
AND16ItoR(flagReg1, 0x0fcf); AND32ItoR(flagReg1, 0x0fcf);
OR32MtoR (flagReg1, (uptr)&mVU->divFlag); OR32MtoR (flagReg1, (uptr)&mVU->divFlag);
} }
} }
@ -223,8 +223,7 @@ microVUt(void) mVUsetFlagInfo() {
mVUflagInfo = 0; mVUflagInfo = 0;
incPC(4); // Branch Not Taken incPC(4); // Branch Not Taken
mVUpass4<vuIndex>(xPC); mVUpass4<vuIndex>(xPC);
incPC(-3); incPC(-3);
//if (mVUflagInfo != backupFlagInfo) { mVUflagInfo |= __NeedExact; }
mVUflagInfo |= backupFlagInfo; mVUflagInfo |= backupFlagInfo;
} }
} }

View File

@ -293,7 +293,10 @@ declareAllVariables
#define CHECK_VU_MINMAXHACK 0 // Min/Max Speed Hack #define CHECK_VU_MINMAXHACK 0 // Min/Max Speed Hack
// Cache Limit Check // Cache Limit Check
#define mVUcacheCheck(ptr, start, limit) { \ #define mVUcacheCheck(ptr, start, limit) { \
uptr diff = ptr - start; \ uptr diff = ptr - start; \
if (diff >= limit) { Console::Error("microVU Error: Program went over its cache limit. Size = 0x%x", params diff); } \ if (diff >= limit) { \
Console::Error("microVU Error: Program went over its cache limit. Size = 0x%x", params diff); \
mVUreset<vuIndex>(); \
} \
} }

View File

@ -302,12 +302,9 @@ microVUt(void) mVUrestoreRegs() {
// Reads entire microProgram and finds out if Status Flag is Used // Reads entire microProgram and finds out if Status Flag is Used
microVUt(void) mVUcheckSflag(int progIndex) { microVUt(void) mVUcheckSflag(int progIndex) {
if (CHECK_VU_FLAGHACK) { if (CHECK_VU_FLAGHACK) {
microVU* mVU = mVUx; microVU* mVU = mVUx;
mVUsFlagHack = 1; mVUsFlagHack = 1;
for (u32 i = 0; i < mVU->progSize; i+=2) { for (u32 i = 0; i < mVU->progSize; i+=2) {
mVU->code = mVU->prog.prog[progIndex].data[i+1];
mVUopU<vuIndex, 3>();
mVU->code = mVU->prog.prog[progIndex].data[i]; mVU->code = mVU->prog.prog[progIndex].data[i];
mVUopL<vuIndex, 3>(); mVUopL<vuIndex, 3>();
} }