diff --git a/pcsx2/VUmicro.h b/pcsx2/VUmicro.h index 922d74328a..2a88d9ce4d 100644 --- a/pcsx2/VUmicro.h +++ b/pcsx2/VUmicro.h @@ -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. diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index d6198eebee..829ddd0803 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -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(smallidx); // Clear old data if overwriting old program mVUcacheProg(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(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); +} + diff --git a/pcsx2/x86/microVU.h b/pcsx2/x86/microVU.h index d7256904c3..3ebd1d94ef 100644 --- a/pcsx2/x86/microVU.h +++ b/pcsx2/x86/microVU.h @@ -85,15 +85,15 @@ public: template // progSize = VU program memory size / 4 struct microProgram { - u32 data[progSize]; + PCSX2_ALIGNED16(u32 data[progSize]); + microBlockManager* block[progSize/2]; + microIR 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 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 diff --git a/pcsx2/x86/microVU_Execute.inl b/pcsx2/x86/microVU_Execute.inl index 1ca593aac8..3017e0636a 100644 --- a/pcsx2/x86/microVU_Execute.inl +++ b/pcsx2/x86/microVU_Execute.inl @@ -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>(); } diff --git a/pcsx2/x86/microVU_Misc.h b/pcsx2/x86/microVU_Misc.h index b91f9e74a9..cfb3a54258 100644 --- a/pcsx2/x86/microVU_Misc.h +++ b/pcsx2/x86/microVU_Misc.h @@ -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