microVU: minor changes

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4395 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2011-03-07 02:35:57 +00:00
parent a61c657717
commit bfc4ab8e7d
2 changed files with 75 additions and 22 deletions

View File

@ -240,6 +240,40 @@ _mVUt __fi void mVUcacheProg(microProgram& prog) {
mVUdumpProg(prog);
}
// Generate Hash for partial program based on compiled ranges...
_mVUt __fi u64 mVUrangesHash(microProgram& prog) {
microVU* mVU = mVUx;
u32 hash[2] = {0, 0};
deque<microRange>::const_iterator it(prog.ranges->begin());
for ( ; it != prog.ranges->end(); ++it) {
if((it[0].start<0)||(it[0].end<0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU->index, it[0].start, it[0].end); }
for(int i = it[0].start/4; i < it[0].end/4; i++) {
hash[0] -= prog.data[i];
hash[1] ^= prog.data[i];
}
}
return *(u64*)hash;
}
// Prints the ratio of unique programs to total programs
_mVUt __fi void mVUprintUniqueRatio() {
microVU* mVU = mVUx;
vector<u64> v;
for(u32 pc = 0; pc < mProgSize/2; pc++) {
microProgramList* list = mVU->prog.prog[pc];
if (!list) continue;
deque<microProgram*>::iterator it(list->begin());
for ( ; it != list->end(); ++it) {
v.push_back(mVUrangesHash<vuIndex>(*it[0]));
}
}
u32 total = v.size();
sortVector(v);
makeUnique(v);
if (!total) return;
DevCon.WriteLn("%d / %d [%3.1f%%]", v.size(), total, 100.-(double)v.size()/(double)total*100.);
}
// Compare partial program by only checking compiled ranges...
_mVUt __fi bool mVUcmpPartial(microProgram& prog) {
microVU* mVU = mVUx;
@ -291,6 +325,7 @@ _mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) {
quick.block = mVU->prog.cur->block[startPC/8];
quick.prog = mVU->prog.cur;
list->push_front(mVU->prog.cur);
//mVUprintUniqueRatio<vuIndex>();
return entryPoint;
}
// If list.quick, then we've already found and recompiled the program ;)
@ -361,22 +396,18 @@ void recMicroVU1::Clear(u32 addr, u32 size) {
mVUclear(&microVU1, addr, size);
}
uint recMicroVU0::GetCacheReserve() const
{
uint recMicroVU0::GetCacheReserve() const {
return microVU0.cacheSize;
}
uint recMicroVU1::GetCacheReserve() const
{
uint recMicroVU1::GetCacheReserve() const {
return microVU1.cacheSize;
}
void recMicroVU0::SetCacheReserve( uint reserveInMegs ) const
{
void recMicroVU0::SetCacheReserve( uint reserveInMegs ) const {
DevCon.WriteLn("microVU0: Upping cache size [%dmb]", reserveInMegs);
microVU0.cacheSize = min(reserveInMegs, mVUcacheMaxReserve);
}
void recMicroVU1::SetCacheReserve( uint reserveInMegs ) const
{
void recMicroVU1::SetCacheReserve( uint reserveInMegs ) const {
DevCon.WriteLn("microVU1: Upping cache size [%dmb]", reserveInMegs);
microVU1.cacheSize = min(reserveInMegs, mVUcacheMaxReserve);
}

View File

@ -38,31 +38,43 @@ struct microBlockLink {
class microBlockManager {
private:
microBlockLink* blockList;
microBlockLink* blockEnd;
int listI;
microBlockLink* qBlockList, *qBlockEnd; // Quick Search
microBlockLink* fBlockList, *fBlockEnd; // Full Search
int qListI, fListI;
public:
microBlockManager() {
listI = 0;
blockEnd = blockList = NULL;
qListI = fListI = 0;
qBlockEnd = qBlockList = NULL;
fBlockEnd = fBlockList = NULL;
}
~microBlockManager() { reset(); }
void reset() {
for(microBlockLink* linkI = blockList; linkI != NULL; ) {
for(microBlockLink* linkI = qBlockList; linkI != NULL; ) {
microBlockLink* freeI = linkI;
safe_delete_array(linkI->block.jumpCache);
linkI = linkI->next;
_aligned_free(freeI);
}
listI = 0;
blockEnd = blockList = NULL;
for(microBlockLink* linkI = fBlockList; linkI != NULL; ) {
microBlockLink* freeI = linkI;
safe_delete_array(linkI->block.jumpCache);
linkI = linkI->next;
_aligned_free(freeI);
}
qListI = fListI = 0;
qBlockEnd = qBlockList = NULL;
fBlockEnd = fBlockList = NULL;
};
microBlock* add(microBlock* pBlock) {
microBlock* thisBlock = search(&pBlock->pState);
if (!thisBlock) {
listI++;
microBlockLink* newBlock = (microBlockLink*)_aligned_malloc(sizeof(microBlockLink), 16);
u8 fullCmp = pBlock->pState.needExactMatch;
if (fullCmp) fListI++; else qListI++;
microBlockLink*& blockList = fullCmp ? fBlockList : qBlockList;
microBlockLink*& blockEnd = fullCmp ? fBlockEnd : qBlockEnd;
microBlockLink* newBlock = (microBlockLink*)_aligned_malloc(sizeof(microBlockLink), 16);
newBlock->block.jumpCache = NULL;
newBlock->next = NULL;
@ -81,13 +93,13 @@ public:
}
__ri microBlock* search(microRegInfo* pState) {
if (pState->needExactMatch) { // Needs Detailed Search (Exact Match of Pipeline State)
for (microBlockLink* linkI = blockList; linkI != NULL; linkI = linkI->next) {
for(microBlockLink* linkI = fBlockList; linkI != NULL; linkI = linkI->next) {
if (mVUquickSearch((void*)pState, (void*)&linkI->block.pState, sizeof(microRegInfo)))
return &linkI->block;
}
}
else { // Can do Simple Search (Only Matches the Important Pipeline Stuff)
for (microBlockLink* linkI = blockList; linkI != NULL; linkI = linkI->next) {
for(microBlockLink* linkI = qBlockList; linkI != NULL; linkI = linkI->next) {
if (doConstProp && (linkI->block.pState.vi15 != pState->vi15)) continue;
if (linkI->block.pState.quick32[0] != pState->quick32[0]) continue;
if (linkI->block.pState.quick32[1] != pState->quick32[1]) continue;
@ -96,9 +108,10 @@ public:
}
return NULL;
}
void printInfo(int pc) {
void printInfo(int pc, bool printQuick) {
int listI = printQuick ? qListI : fListI;
if (listI < 7) return;
microBlockLink* linkI = blockList;
microBlockLink* linkI = printQuick ? qBlockList : fBlockList;
for (int i = 0; i <= listI; i++) {
u32 viCRC = 0, vfCRC = 0, crc = 0, z = sizeof(microRegInfo)/4;
for (u32 j = 0; j < 4; j++) viCRC -= ((u32*)linkI->block.pState.VI)[j];
@ -269,3 +282,12 @@ extern void* __fastcall mVUexecuteVU1(u32 startPC, u32 cycles);
// recCall Function Pointer
typedef void (__fastcall *mVUrecCall)(u32, u32);
template<typename T>
void makeUnique(T& v) { // Removes Duplicates
v.erase(unique(v.begin(), v.end()), v.end());
}
template<typename T>
void sortVector(T& v) {
sort(v.begin(), v.end());
}