mirror of https://github.com/PCSX2/pcsx2.git
microVU: minor changes...
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1414 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
fffe95bc4b
commit
9d091450b1
|
@ -76,9 +76,9 @@ void vuMicroCpuReset();
|
||||||
extern void initVUrec(VURegs* vuRegs, const int vuIndex);
|
extern void initVUrec(VURegs* vuRegs, const int vuIndex);
|
||||||
extern void closeVUrec(const int vuIndex);
|
extern void closeVUrec(const int vuIndex);
|
||||||
extern void resetVUrec(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 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.
|
// Everything else does stuff on a per-VU basis.
|
||||||
|
|
|
@ -49,8 +49,8 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) {
|
||||||
mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init");
|
mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init");
|
||||||
|
|
||||||
mVU->cache = SysMmapEx((vuIndex ? 0x5f240000 : 0x5e240000), mVU->cacheSize + 0x1000, 0, (vuIndex ? "Micro VU1" : "Micro VU0"));
|
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();
|
mVUemitSearch();
|
||||||
mVUreset(mVU);
|
mVUreset(mVU);
|
||||||
}
|
}
|
||||||
|
@ -117,10 +117,10 @@ microVUt(void) mVUclose(mV) {
|
||||||
|
|
||||||
// Clears Block Data in specified range
|
// Clears Block Data in specified range
|
||||||
microVUt(void) mVUclear(mV, u32 addr, u32 size) {
|
microVUt(void) mVUclear(mV, u32 addr, u32 size) {
|
||||||
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));
|
||||||
mVU->prog.cleared = 1; // Next execution searches/creates a new microprogram
|
mVU->prog.cleared = 1; // Next execution searches/creates a new microprogram
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
@ -161,22 +161,20 @@ microVUf(int) mVUfindLeastUsedProg() {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
int startidx = (mVU->prog.cur + 1) & mVU->prog.max;
|
const int pMax = mVU->prog.max;
|
||||||
int endidx = mVU->prog.cur;
|
int smallidx = (mVU->prog.cur+1)&pMax;
|
||||||
int smallidx = startidx;
|
u32 smallval = mVU->prog.prog[smallidx].used;
|
||||||
u32 smallval = mVU->prog.prog[startidx].used;
|
|
||||||
|
|
||||||
for (int i = startidx; i != endidx; i = (i+1)&mVU->prog.max) {
|
for (int i = 1, j = (smallidx+1)&pMax; i <= pMax; i++, j=(j+1)&pMax) {
|
||||||
u32 used = mVU->prog.prog[i].used;
|
if (smallval > mVU->prog.prog[j].used) {
|
||||||
if (smallval > used) {
|
smallval = mVU->prog.prog[j].used;
|
||||||
smallval = used;
|
smallidx = j;
|
||||||
smallidx = i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mVUclearProg<vuIndex>(smallidx); // Clear old data if overwriting old program
|
mVUclearProg<vuIndex>(smallidx); // Clear old data if overwriting old program
|
||||||
mVUcacheProg<vuIndex>(smallidx); // Cache Micro 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;
|
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
|
// 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
|
// 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(mV) {
|
microVUt(void) mVUvsyncUpdate(mV) {
|
||||||
|
|
||||||
if (mVU->prog.total < mVU->prog.max) return;
|
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 != 0) {
|
||||||
if (mVU->prog.prog[i].last_used >= 3) {
|
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 (progUsed) {
|
||||||
if (cmpWholeProg && (!memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize)) ||
|
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.cur = progIndex;
|
||||||
mVU->prog.cleared = 0;
|
mVU->prog.cleared = 0;
|
||||||
mVU->prog.isSame = cmpWholeProg ? 1 : -1;
|
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)
|
// Searches for Cached Micro Program and sets prog.cur to it (returns 1 if program found, else returns 0)
|
||||||
microVUf(int) mVUsearchProg() {
|
microVUf(int) mVUsearchProg() {
|
||||||
microVU* mVU = mVUx;
|
microVU* mVU = mVUx;
|
||||||
|
|
||||||
if (mVU->prog.cleared) { // If cleared, we need to search for new program
|
if (mVU->prog.cleared) { // If cleared, we need to search for new program
|
||||||
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, 1, 0))
|
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
|
// Wrapper Functions - Called by other parts of the Emu
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
void initVUrec (VURegs* vuRegs, const int vuIndex) { mVUinit(vuRegs, vuIndex); }
|
void initVUrec (VURegs* vuRegs, const int vuIndex) { mVUinit(vuRegs, vuIndex); }
|
||||||
void closeVUrec(const int vuIndex) { mVUclose(mVUx); }
|
void closeVUrec(const int vuIndex) { mVUclose(mVUx); }
|
||||||
void resetVUrec(const int vuIndex) { mVUreset(mVUx); }
|
void resetVUrec(const int vuIndex) { mVUreset(mVUx); }
|
||||||
void vsyncVUrec(const int vuIndex) { mVUvsyncUpdate(mVUx); }
|
void vsyncVUrec(const int vuIndex) { mVUvsyncUpdate(mVUx); }
|
||||||
void clearVUrec(u32 addr, u32 size, const int vuIndex) { mVUclear(mVUx, addr, size); }
|
|
||||||
|
|
||||||
void runVUrec(u32 startPC, u32 cycles, const int vuIndex) {
|
void __fastcall clearVUrec(u32 addr, u32 size, const int vuIndex) {
|
||||||
if (!vuIndex) startVU0(startPC, cycles);
|
mVUclear(mVUx, addr, size);
|
||||||
else startVU1(startPC, cycles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __fastcall runVUrec(u32 startPC, u32 cycles, const int vuIndex) {
|
||||||
|
if (!vuIndex) ((mVUrecCall)microVU0.startFunct)(startPC, cycles);
|
||||||
|
else ((mVUrecCall)microVU1.startFunct)(startPC, cycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,15 +85,15 @@ public:
|
||||||
|
|
||||||
template<u32 progSize> // progSize = VU program memory size / 4
|
template<u32 progSize> // progSize = VU program memory size / 4
|
||||||
struct microProgram {
|
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 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)
|
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
|
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* x86ptr; // Pointer to program's recompilation code
|
||||||
u8* x86start; // Start of program's rec-cache
|
u8* x86start; // Start of program's rec-cache
|
||||||
u8* x86end; // Limit 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...)
|
#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
|
VURegs* regs; // VU Regs Struct
|
||||||
u8* cache; // Dynarec Cache Start (where we will start writing the recompiled code to)
|
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* 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 code; // Contains the current Instruction
|
||||||
u32 divFlag; // 1 instance of I/D flags
|
u32 divFlag; // 1 instance of I/D flags
|
||||||
u32 VIbackup; // Holds a backup of a VI reg if modified before a branch
|
u32 VIbackup; // Holds a backup of a VI reg if modified before a branch
|
||||||
|
|
|
@ -151,8 +151,6 @@ microVUx(void) mVUcleanUp() {
|
||||||
// Caller Functions
|
// 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 mVUexecuteVU0(u32 startPC, u32 cycles) { return mVUexecute<0>(startPC, cycles); }
|
||||||
void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles) { return mVUexecute<1>(startPC, cycles); }
|
void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles) { return mVUexecute<1>(startPC, cycles); }
|
||||||
void __fastcall mVUcleanUpVU0() { mVUcleanUp<0>(); }
|
void __fastcall mVUcleanUpVU0() { mVUcleanUp<0>(); }
|
||||||
|
|
|
@ -206,6 +206,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
|
||||||
#define bSaveAddr (((xPC + (2 * 8)) & ((isVU1) ? 0x3ff8:0xff8)) / 8)
|
#define bSaveAddr (((xPC + (2 * 8)) & ((isVU1) ? 0x3ff8:0xff8)) / 8)
|
||||||
#define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & (mVU->microMemSize-8))
|
#define branchAddr ((xPC + 8 + (_Imm11_ * 8)) & (mVU->microMemSize-8))
|
||||||
#define shufflePQ (((mVU->p) ? 0xb0 : 0xe0) | ((mVU->q) ? 0x01 : 0x04))
|
#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 Rmem (uptr)&mVU->regs->VI[REG_R].UL
|
||||||
#define Roffset (uptr)&mVU->regs->VI[9].UL
|
#define Roffset (uptr)&mVU->regs->VI[9].UL
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue