some microVU work

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@466 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2009-02-10 09:18:57 +00:00
parent 68afc71ba8
commit 0f0cf9d84d
2 changed files with 82 additions and 69 deletions

View File

@ -34,8 +34,9 @@ microVU microVU1;
//------------------------------------------------------------------
// Only run this once! ;)
__forceinline void mVUinit(microVU* mVU, VURegs* vuRegsPtr, const int vuIndex) {
microVUt(void) mVUinit(VURegs* vuRegsPtr) {
microVU* mVU = mVUx;
mVU->regs = vuRegsPtr;
mVU->index = vuIndex;
mVU->microSize = (vuIndex ? 0x4000 : 0x1000);
@ -43,13 +44,14 @@ __forceinline void mVUinit(microVU* mVU, VURegs* vuRegsPtr, const int vuIndex) {
mVU->cacheAddr = 0xC0000000 + (vuIndex ? mVU->cacheSize : 0);
mVU->cache = NULL;
mVUreset(mVU);
mVUreset<vuIndex>();
}
// Will Optimize later
__forceinline void mVUreset(microVU* mVU) {
microVUt(void) mVUreset() {
mVUclose(mVU); // Close
microVU* mVU = mVUx;
mVUclose<vuIndex>(); // Close
// Create Block Managers
for (int i; i <= mVU->prog.max; i++) {
@ -71,7 +73,9 @@ __forceinline void mVUreset(microVU* mVU) {
}
// Free Allocated Resources
__forceinline void mVUclose(microVU* mVU) {
microVUt(void) mVUclose() {
microVU* mVU = mVUx;
if ( mVU->cache ) { SysMunmap( mVU->cache, mVU->cacheSize ); mVU->cache = NULL; }
@ -83,16 +87,16 @@ __forceinline void mVUclose(microVU* mVU) {
}
}
// Clears Block Data in specified range (Caches current microProgram if a difference has been found)
__forceinline void mVUclear(microVU* mVU, u32 addr, u32 size) {
// Clears Block Data in specified range
microVUt(void) mVUclear(u32 addr, u32 size) {
microVU* mVU = mVUx;
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() ) {
mVUcacheProg(mVU);
mVU->prog.cleared = 1;
i++;
break;
@ -105,8 +109,9 @@ __forceinline void mVUclear(microVU* mVU, u32 addr, u32 size) {
}
// Executes for number of cycles
void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles) {
/* Pseudocode: (ToDo: implement # of cycles)
microVUt(void*) __fastcall mVUexecute(u32 startPC, u32 cycles) {
/*
Pseudocode: (ToDo: implement # of cycles)
1) Search for existing program
2) If program not found, goto 5
3) Search for recompiled block
@ -114,38 +119,44 @@ void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles) {
5) Recompile as much blocks as possible
6) Return start execution address of block
*/
if ( mVUsearchProg(&microVU0) ) { // Found Program
microBlock* block = microVU0.prog.prog[microVU0.prog.cur].block[startPC]->search(microVU0.prog.lastPipelineState);
microVU* mVU = mVUx;
if ( mVUsearchProg(mVU) ) { // Found Program
microBlock* block = mVU->prog.prog[mVU->prog.cur].block[startPC]->search(mVU->prog.lastPipelineState);
if (block) return block->x86ptrStart;
}
// Recompile code
return NULL;
}
void* __fastcall mVUexecuteVU0(u32 startPC, u32 cycles) {
return mVUexecute<0>(startPC, cycles);
}
void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles) {
return NULL;
return mVUexecute<1>(startPC, cycles);
}
/*
// Executes till finished
void* mVUexecuteF(microVU* mVU, u32 startPC) {
//if (!mProg.finished) {
// runMicroProgram(startPC);
//}
//if (mProg.cleared && !mProg.finished) {
//}
return NULL;
}
*/
//------------------------------------------------------------------
// Micro VU - Private Functions
//------------------------------------------------------------------
// Finds the least used program
// Clears program data (Sets used to 1 because calling this function implies the program will be used at least once)
__forceinline void mVUclearProg(microVU* mVU, int progIndex) {
mVU->prog.prog[progIndex].used = 1;
for (u32 i = 0; i < mVU->progSize; i++) {
mVU->prog.prog[progIndex].block[i]->reset();
}
}
// Caches Micro Program
__forceinline void mVUcacheProg(microVU* mVU, int progIndex) {
memcpy_fast(mVU->prog.prog[progIndex].data, mVU->regs->Micro, mVU->microSize);
}
// Finds the least used program, (if program list full clears and returns an old program; if not-full, returns free program)
__forceinline int mVUfindLeastUsedProg(microVU* mVU) {
if (mVU->prog.total < mVU->prog.max) {
mVU->prog.total++;
mVUcacheProg(mVU, mVU->prog.total); // Cache Micro Program
return mVU->prog.total;
}
else {
@ -157,35 +168,30 @@ __forceinline int mVUfindLeastUsedProg(microVU* mVU) {
j = i;
}
}
mVUclearProg(mVU, j); // Clear old data if overwriting old program
mVUcacheProg(mVU, j); // Cache Micro Program
return j;
}
}
// Caches Micro Program if appropriate
__forceinline void mVUcacheProg(microVU* mVU) {
if (!mVU->prog.prog[mVU->prog.cur].cached) { // If uncached, then cache
memcpy_fast(mVU->prog.prog[mVU->prog.cur].data, mVU->regs->Micro, mVU->microSize);
mVU->prog.prog[mVU->prog.cur].cached = 1;
}
}
// Searches for Cached Micro Program and sets prog.cur to it (returns 1 if program found, else returns 0)
__forceinline int mVUsearchProg(microVU* mVU) {
if (mVU->prog.cleared) { // If cleared, we need to search for new program
for (int i = 0; i <= mVU->prog.total; i++) {
if (i == mVU->prog.cur) continue; // We can skip the current program.
if (mVU->prog.prog[i].cached) {
if (!memcmp_mmx(mVU->prog.prog[i].data, mVU->regs->Micro, mVU->microSize)) {
mVU->prog.cur = i;
return 1;
}
if (!memcmp_mmx(mVU->prog.prog[i].data, mVU->regs->Micro, mVU->microSize)) {
mVU->prog.cur = i;
mVU->prog.cleared = 0;
mVU->prog.prog[i].used++;
return 1;
}
}
mVU->prog.cur = mVUfindLeastUsedProg(mVU); // If cleared and program not cached, make a new program instance
// ToDo: Clear old data if overwriting old program
mVU->prog.cur = mVUfindLeastUsedProg(mVU); // If cleared and program not found, make a new program instance
mVU->prog.cleared = 0;
return 0;
}
else return 1; // If !cleared, then we're still on the same program as last-time ;)
mVU->prog.prog[mVU->prog.cur].used++;
return 1; // If !cleared, then we're still on the same program as last-time ;)
}
//------------------------------------------------------------------
@ -249,29 +255,29 @@ __declspec(naked) void __fastcall endVU0(u32 startPC, u32 cycles) {
// Wrapper Functions - Called by other parts of the Emu
//------------------------------------------------------------------
__forceinline void initVUrec(VURegs* vuRegs, int vuIndex) {
if (!vuIndex) mVUinit(&microVU0, vuRegs, 0);
else mVUinit(&microVU1, vuRegs, 1);
__forceinline void initVUrec(VURegs* vuRegs, const int vuIndex) {
if (!vuIndex) mVUinit<0>(vuRegs);
else mVUinit<1>(vuRegs);
}
__forceinline void closeVUrec(int vuIndex) {
if (!vuIndex) mVUclose(&microVU0);
else mVUclose(&microVU1);
__forceinline void closeVUrec(const int vuIndex) {
if (!vuIndex) mVUclose<0>();
else mVUclose<1>();
}
__forceinline void resetVUrec(int vuIndex) {
if (!vuIndex) mVUreset(&microVU0);
else mVUreset(&microVU1);
__forceinline void resetVUrec(const int vuIndex) {
if (!vuIndex) mVUreset<0>();
else mVUreset<1>();
}
__forceinline void clearVUrec(u32 addr, u32 size, int vuIndex) {
if (!vuIndex) mVUclear(&microVU0, addr, size);
else mVUclear(&microVU1, addr, size);
__forceinline void clearVUrec(u32 addr, u32 size, const int vuIndex) {
if (!vuIndex) mVUclear<0>(addr, size);
else mVUclear<1>(addr, size);
}
__forceinline void runVUrec(u32 startPC, u32 cycles, int vuIndex) {
if (!vuIndex) startVU0(startPC, cycles);
else startVU1(startPC, cycles);
__forceinline void runVUrec(u32 startPC, u32 cycles, const int vuIndex) {
if (!vuIndex) startVU0(startPC, cycles);
else startVU1(startPC, cycles);
}
#endif // PCSX2_MICROVU

View File

@ -47,8 +47,10 @@ public:
void init() {
listSize = -1;
callerSize = -1;
ZeroMemory(&blockList, sizeof(blockList)); // Can be Omitted?
//ZeroMemory(&blockList, sizeof(blockList)); // Can be Omitted?
//ZeroMemory(&blockList, sizeof(callersList)); // Can be Omitted?
}
void reset() { init(); };
void close() {}; // Can be Omitted?
void add(u32 pipelineState, u8* x86ptrStart) {
if (!search(pipelineState)) {
@ -67,7 +69,7 @@ public:
void clearFast() {
listSize = -1;
for ( ; callerSize >= 0; callerSize--) {
//callerList[callerSize]. // Implement Branch Link Removal Code
//callerList[callerSize]. // ToDo: Implement Branch Link Removal Code
}
}
int clear() {
@ -80,7 +82,7 @@ template<u32 progSize>
struct microProgram {
u8 data[progSize];
u32 used; // Number of times its been used
int cached; // Has been Cached?
//int cached; // Has been Cached? (can be omitted because every new program will be cached?)
microBlockManager* block[progSize];
};
@ -92,7 +94,7 @@ struct microProgManager {
int cur; // Index to Current MicroProgram thats running (-1 = uncached)
int total; // Total Number of valid MicroPrograms minus 1
int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one)
int finished; // Completed MicroProgram to E-bit Termination
int finished; // Completed MicroProgram by E-bit Termination
u32 lastPipelineState; // Pipeline state from where it left off (useful for continuing execution)
};
@ -119,18 +121,23 @@ struct microVU {
microProgManager<0x800> prog; // Micro Program Data
};
// Template Stuff
#define mVUx (vuIndex ? &microVU1 : &microVU0)
#define microVUt(aType) template<int vuIndex> __forceinline aType
// Opcode Tables
extern void (*mVU_UPPER_OPCODE[64])( VURegs* VU, s32 info );
extern void (*mVU_LOWER_OPCODE[128])( VURegs* VU, s32 info );
//void invalidateBlocks(u32 addr, u32 size); // Invalidates Blocks in the range [addr, addr+size)
__forceinline void mVUinit(microVU* mVU, VURegs* vuRegsPtr, const int vuIndex);
__forceinline void mVUreset(microVU* mVU);
__forceinline void mVUclose(microVU* mVU);
__forceinline void mVUclear(microVU* mVU, u32 addr, u32 size); // Clears part of a Micro Program (must use before modifying micro program!)
//__forceinline void mVUinit(microVU* mVU, VURegs* vuRegsPtr, const int vuIndex);
//__forceinline void mVUreset(microVU* mVU);
//__forceinline void mVUclose(microVU* mVU);
//__forceinline void mVUclear(microVU* mVU, u32 addr, u32 size); // Clears part of a Micro Program (must use before modifying micro program!)
//void* mVUexecute(microVU* mVU, u32 startPC, u32 cycles); // Recompiles/Executes code for the number of cycles indicated (will always run for >= 'cycles' amount unless 'finished')
//void* mVUexecuteF(microVU* mVU, u32 startPC); // Recompiles/Executes code till finished
__forceinline int mVUfindLeastUsedProg(microVU* mVU);
__forceinline int mVUsearchProg(microVU* mVU);
__forceinline void mVUcacheProg(microVU* mVU);
__forceinline void mVUclearProg(microVU* mVU, int progIndex);
__forceinline int mVUfindLeastUsedProg(microVU* mVU);
__forceinline int mVUsearchProg(microVU* mVU);
__forceinline void mVUcacheProg(microVU* mVU, int progIndex);