microVU: minor changes...

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1414 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-06-21 07:01:41 +00:00
parent fffe95bc4b
commit 9d091450b1
5 changed files with 36 additions and 35 deletions

View File

@ -76,9 +76,9 @@ void vuMicroCpuReset();
extern void initVUrec(VURegs* vuRegs, const int vuIndex);
extern void closeVUrec(const int vuIndex);
extern void resetVUrec(const int vuIndex);
extern void clearVUrec(u32 addr, u32 size, const int vuIndex);
extern void runVUrec(u32 startPC, u32 cycles, const int vuIndex);
extern void vsyncVUrec(const int vuIndex);
extern void __fastcall clearVUrec(u32 addr, u32 size, const int vuIndex);
extern void __fastcall runVUrec(u32 startPC, u32 cycles, const int vuIndex);
/////////////////////////////////////////////////////////////////
// Everything else does stuff on a per-VU basis.

View File

@ -49,8 +49,8 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) {
mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init");
mVU->cache = SysMmapEx((vuIndex ? 0x5f240000 : 0x5e240000), mVU->cacheSize + 0x1000, 0, (vuIndex ? "Micro VU1" : "Micro VU0"));
if ( mVU->cache == NULL ) throw Exception::OutOfMemory(fmt_string( "microVU Error: Failed to allocate recompiler memory! (addr: 0x%x)", (u32)mVU->cache));
if (!mVU->cache) throw Exception::OutOfMemory(fmt_string("microVU Error: Failed to allocate recompiler memory!"));
mVUemitSearch();
mVUreset(mVU);
}
@ -117,10 +117,10 @@ microVUt(void) mVUclose(mV) {
// Clears Block Data in specified range
microVUt(void) mVUclear(mV, u32 addr, u32 size) {
if (!mVU->prog.cleared) {
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
//if (!mVU->prog.cleared) {
//memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
mVU->prog.cleared = 1; // Next execution searches/creates a new microprogram
}
//}
}
//------------------------------------------------------------------
@ -161,22 +161,20 @@ microVUf(int) mVUfindLeastUsedProg() {
}
else {
int startidx = (mVU->prog.cur + 1) & mVU->prog.max;
int endidx = mVU->prog.cur;
int smallidx = startidx;
u32 smallval = mVU->prog.prog[startidx].used;
const int pMax = mVU->prog.max;
int smallidx = (mVU->prog.cur+1)&pMax;
u32 smallval = mVU->prog.prog[smallidx].used;
for (int i = startidx; i != endidx; i = (i+1)&mVU->prog.max) {
u32 used = mVU->prog.prog[i].used;
if (smallval > used) {
smallval = used;
smallidx = i;
for (int i = 1, j = (smallidx+1)&pMax; i <= pMax; i++, j=(j+1)&pMax) {
if (smallval > mVU->prog.prog[j].used) {
smallval = mVU->prog.prog[j].used;
smallidx = j;
}
}
mVUclearProg<vuIndex>(smallidx); // Clear old data if overwriting old program
mVUcacheProg<vuIndex>(smallidx); // Cache Micro Program
//Console::Notice("microVU%d: Overwriting existing program in slot %d [%d times used]", params vuIndex, smallidx, smallval );
//Console::Notice("microVU%d: Overwriting existing program in slot %d [%d times used]", params vuIndex, smallidx, smallval);
return smallidx;
}
}
@ -187,13 +185,13 @@ microVUf(int) mVUfindLeastUsedProg() {
//
// To fix the program cache to more efficiently dispose of "obsolete" programs, we need to use a
// 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.
microVUt(void) mVUvsyncUpdate(mV) {
if (mVU->prog.total < mVU->prog.max) return;
for (int i = 0; i <= mVU->prog.total; i++) {
for (int i = 0; i <= mVU->prog.max; i++) {
if (mVU->prog.prog[i].last_used != 0) {
if (mVU->prog.prog[i].last_used >= 3) {
@ -212,7 +210,7 @@ microVUf(int) mVUcmpProg(int progIndex, bool progUsed, bool needOverflowCheck, b
if (progUsed) {
if (cmpWholeProg && (!memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize)) ||
(!cmpWholeProg && (!memcmp_mmx((u8*)mVUprogI.data + mVUprogI.range[0], (u8*)mVU->regs->Micro + mVUprogI.range[0], ((mVUprogI.range[1] + 8) - mVUprogI.range[0]))))) {
(!cmpWholeProg && (!memcmp_mmx(cmpOffset(mVUprogI.data), cmpOffset(mVU->regs->Micro), ((mVUprogI.range[1] + 8) - mVUprogI.range[0]))))) {
mVU->prog.cur = progIndex;
mVU->prog.cleared = 0;
mVU->prog.isSame = cmpWholeProg ? 1 : -1;
@ -229,7 +227,7 @@ microVUf(int) mVUcmpProg(int progIndex, bool progUsed, bool needOverflowCheck, b
// Searches for Cached Micro Program and sets prog.cur to it (returns 1 if program found, else returns 0)
microVUf(int) mVUsearchProg() {
microVU* mVU = mVUx;
if (mVU->prog.cleared) { // If cleared, we need to search for new program
for (int i = 0; i <= mVU->prog.total; i++) {
if (mVUcmpProg<vuIndex>(i, !!mVU->prog.prog[i].used, 1, 0))
@ -253,13 +251,17 @@ microVUf(int) mVUsearchProg() {
// Wrapper Functions - Called by other parts of the Emu
//------------------------------------------------------------------
void initVUrec (VURegs* vuRegs, const int vuIndex) { mVUinit(vuRegs, vuIndex); }
void closeVUrec(const int vuIndex) { mVUclose(mVUx); }
void resetVUrec(const int vuIndex) { mVUreset(mVUx); }
void vsyncVUrec(const int vuIndex) { mVUvsyncUpdate(mVUx); }
void clearVUrec(u32 addr, u32 size, const int vuIndex) { mVUclear(mVUx, addr, size); }
void initVUrec (VURegs* vuRegs, const int vuIndex) { mVUinit(vuRegs, vuIndex); }
void closeVUrec(const int vuIndex) { mVUclose(mVUx); }
void resetVUrec(const int vuIndex) { mVUreset(mVUx); }
void vsyncVUrec(const int vuIndex) { mVUvsyncUpdate(mVUx); }
void runVUrec(u32 startPC, u32 cycles, const int vuIndex) {
if (!vuIndex) startVU0(startPC, cycles);
else startVU1(startPC, cycles);
void __fastcall clearVUrec(u32 addr, u32 size, const int vuIndex) {
mVUclear(mVUx, addr, size);
}
void __fastcall runVUrec(u32 startPC, u32 cycles, const int vuIndex) {
if (!vuIndex) ((mVUrecCall)microVU0.startFunct)(startPC, cycles);
else ((mVUrecCall)microVU1.startFunct)(startPC, cycles);
}

View File

@ -85,15 +85,15 @@ public:
template<u32 progSize> // progSize = VU program memory size / 4
struct microProgram {
u32 data[progSize];
PCSX2_ALIGNED16(u32 data[progSize]);
microBlockManager* block[progSize/2];
microIR<progSize> allocInfo;
u32 used; // Number of times its been used
u32 last_used; // Counters # of frames since last use (starts at 3 and counts backwards to 0 for each 30fps vSync)
s32 range[2]; // The range of microMemory that has already been recompiled for the current program
u8* x86ptr; // Pointer to program's recompilation code
u8* x86start; // Start of program's rec-cache
u8* x86end; // Limit of program's rec-cache
microBlockManager* block[progSize/2];
microIR<progSize> allocInfo;
};
#define mMaxProg 32 // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...)
@ -128,7 +128,7 @@ struct microVU {
VURegs* regs; // VU Regs Struct
u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to)
u8* startFunct; // Ptr Function to the Start code for recompiled programs
u8* exitFunct; // Ptr Function to the Exit code for recompiled programs
u8* exitFunct; // Ptr Function to the Exit code for recompiled programs
u32 code; // Contains the current Instruction
u32 divFlag; // 1 instance of I/D flags
u32 VIbackup; // Holds a backup of a VI reg if modified before a branch

View File

@ -151,8 +151,6 @@ microVUx(void) mVUcleanUp() {
// Caller Functions
//------------------------------------------------------------------
void __fastcall startVU0(u32 startPC, u32 cycles) { ((mVUrecCall)microVU0.startFunct)(startPC, cycles); }
void __fastcall startVU1(u32 startPC, u32 cycles) { ((mVUrecCall)microVU1.startFunct)(startPC, cycles); }
void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles) { return mVUexecute<0>(startPC, cycles); }
void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles) { return mVUexecute<1>(startPC, cycles); }
void __fastcall mVUcleanUpVU0() { mVUcleanUp<0>(); }

View File

@ -206,6 +206,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
#define bSaveAddr (((xPC + (2 * 8)) & ((isVU1) ? 0x3ff8:0xff8)) / 8)
#define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & (mVU->microMemSize-8))
#define shufflePQ (((mVU->p) ? 0xb0 : 0xe0) | ((mVU->q) ? 0x01 : 0x04))
#define cmpOffset(x) (&(((u8*)x)[mVUprogI.range[0]]))
#define Rmem (uptr)&mVU->regs->VI[REG_R].UL
#define Roffset (uptr)&mVU->regs->VI[9].UL