- 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);
declareAllVariables // Declares All Global Variables :D
//------------------------------------------------------------------
// Micro VU - Main Functions
//------------------------------------------------------------------
@ -117,7 +118,6 @@ microVUt(void) mVUclose() {
// Clears Block Data in specified range
microVUt(void) mVUclear(u32 addr, u32 size) {
microVU* mVU = mVUx;
if (!mVU->prog.cleared) {
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].x86ptr = mVU->prog.prog[progIndex].x86start;
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();
}
}
@ -170,11 +170,9 @@ microVUt(int) mVUfindLeastUsedProg() {
int smallidx = startidx;
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;
if (smallval > used)
{
if (smallval > used) {
smallval = used;
smallidx = i;
}
@ -195,7 +193,6 @@ microVUt(int) mVUfindLeastUsedProg() {
// 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
// or prev frame. if it's 0, the program hasn't been used for a while.
//
microVUt(void) __mVUvsyncUpdate() {
microVU* mVU = mVUx;
@ -247,10 +244,6 @@ microVUt(int) mVUsearchProg() {
if (mVUcmpProg<vuIndex>(i, !mVU->prog.prog[i].used, 0, 0))
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.cleared = 0;
mVU->prog.isSame = 1;
@ -260,27 +253,7 @@ microVUt(int) mVUsearchProg() {
mVU->prog.prog[mVU->prog.cur].last_used = 3;
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
//------------------------------------------------------------------

View File

@ -18,7 +18,7 @@
#pragma once
//#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 "VU.h"
@ -27,24 +27,26 @@
#include "microVU_Alloc.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 {
private:
static const int MaxBlocks = mMaxBlocks - 1;
int listSize; // Total Items - 1
int listI; // Index to Add new block
microBlock blockList[mMaxBlocks];
public:
microBlockManager() { reset(); }
~microBlockManager() {}
void reset() { listSize = -1; };
void reset() { listSize = -1; listI = -1; };
microBlock* add(microBlock* pBlock) {
microBlock* thisBlock = search(&pBlock->pState);
if (!thisBlock) {
listSize++;
if (listSize > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listSize = 0; }
memcpy_fast(&blockList[listSize], pBlock, sizeof(microBlock));
thisBlock = &blockList[listSize];
listI++;
if (listSize < MaxBlocks) { listSize++; }
if (listI > MaxBlocks) { Console::Error("microVU Warning: Block List Overflow"); listI = 0; }
memcpy_fast(&blockList[listI], pBlock, sizeof(microBlock));
thisBlock = &blockList[listI];
}
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) {
microVU* mVU = mVUx;
mVUinfo |= _doStatus;
@ -136,6 +149,13 @@ microVUt(void) mVUanalyzeIALU2(int Is, int It) {
if (_Y) { mVUstall = aMax(mVUstall, aReg(reg).z); } \
if (_Z) { mVUstall = aMax(mVUstall, aReg(reg).w); } \
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 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) {
microVU* mVU = mVUx;
mVUprint("microVU: EFU Opcode");
analyzeReg1(Fs);
analyzeReg1b(Fs);
analyzePreg(xCycles);
}
@ -207,8 +234,7 @@ microVUt(void) mVUanalyzeMFP(int Ft) {
microVUt(void) mVUanalyzeMOVE(int Fs, int Ft) {
microVU* mVU = mVUx;
if (!Ft || (Ft == Fs)) { mVUinfo |= _isNOP; }
if (mVUregsTemp.VFreg[0] == Fs) { mVUinfo |= _swapOps; }
analyzeReg1(Fs);
analyzeReg1b(Fs);
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) {
microVU* mVU = mVUx;
analyzeReg1(Fs);
analyzeReg1b(Fs);
analyzeVIreg1(It);
if (writeIt) { analyzeVIreg2(It, 1); }
if (mVUregsTemp.VFreg[0] == Fs) { mVUinfo |= _swapOps; }
}
//------------------------------------------------------------------

View File

@ -45,6 +45,36 @@
// 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
microVUt(void) mVUsetupBranch(int* xStatus, int* xMac, int* xClip, int xCycles) {
microVU* mVU = mVUx;
@ -150,34 +180,6 @@ microVUt(void) mVUtestCycles() {
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
//------------------------------------------------------------------
@ -276,7 +278,7 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
incPC(-3); // Go back to branch opcode (to get branch imm addr)
mVUsetupBranch<vuIndex>(xStatus, xMac, xClip, xCycles);
if( mVUblocks[branchAddr/8] == NULL )
if (mVUblocks[branchAddr/8] == NULL)
mVUblocks[branchAddr/8] = new microBlockManager();
// Check if branch-block has already been compiled
@ -293,7 +295,6 @@ microVUt(void*) __fastcall mVUcompile(u32 startPC, uptr pState) {
mVUbackupRegs<vuIndex>();
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)
if (!vuIndex) CALLFunc((uptr)mVUcompileVU0); //(u32 startPC, uptr pState)

View File

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

View File

@ -295,5 +295,8 @@ declareAllVariables
// Cache Limit Check
#define mVUcacheCheck(ptr, start, limit) { \
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
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<vuIndex, 3>();
mVU->code = mVU->prog.prog[progIndex].data[i];
mVUopL<vuIndex, 3>();
}