mirror of https://github.com/PCSX2/pcsx2.git
microVU: minor changes
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4395 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
a61c657717
commit
bfc4ab8e7d
|
@ -240,6 +240,40 @@ _mVUt __fi void mVUcacheProg(microProgram& prog) {
|
||||||
mVUdumpProg(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...
|
// Compare partial program by only checking compiled ranges...
|
||||||
_mVUt __fi bool mVUcmpPartial(microProgram& prog) {
|
_mVUt __fi bool mVUcmpPartial(microProgram& prog) {
|
||||||
microVU* mVU = mVUx;
|
microVU* mVU = mVUx;
|
||||||
|
@ -291,6 +325,7 @@ _mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) {
|
||||||
quick.block = mVU->prog.cur->block[startPC/8];
|
quick.block = mVU->prog.cur->block[startPC/8];
|
||||||
quick.prog = mVU->prog.cur;
|
quick.prog = mVU->prog.cur;
|
||||||
list->push_front(mVU->prog.cur);
|
list->push_front(mVU->prog.cur);
|
||||||
|
//mVUprintUniqueRatio<vuIndex>();
|
||||||
return entryPoint;
|
return entryPoint;
|
||||||
}
|
}
|
||||||
// If list.quick, then we've already found and recompiled the program ;)
|
// If list.quick, then we've already found and recompiled the program ;)
|
||||||
|
@ -361,22 +396,18 @@ void recMicroVU1::Clear(u32 addr, u32 size) {
|
||||||
mVUclear(µVU1, addr, size);
|
mVUclear(µVU1, addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint recMicroVU0::GetCacheReserve() const
|
uint recMicroVU0::GetCacheReserve() const {
|
||||||
{
|
|
||||||
return microVU0.cacheSize;
|
return microVU0.cacheSize;
|
||||||
}
|
}
|
||||||
uint recMicroVU1::GetCacheReserve() const
|
uint recMicroVU1::GetCacheReserve() const {
|
||||||
{
|
|
||||||
return microVU1.cacheSize;
|
return microVU1.cacheSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void recMicroVU0::SetCacheReserve( uint reserveInMegs ) const
|
void recMicroVU0::SetCacheReserve( uint reserveInMegs ) const {
|
||||||
{
|
|
||||||
DevCon.WriteLn("microVU0: Upping cache size [%dmb]", reserveInMegs);
|
DevCon.WriteLn("microVU0: Upping cache size [%dmb]", reserveInMegs);
|
||||||
microVU0.cacheSize = min(reserveInMegs, mVUcacheMaxReserve);
|
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);
|
DevCon.WriteLn("microVU1: Upping cache size [%dmb]", reserveInMegs);
|
||||||
microVU1.cacheSize = min(reserveInMegs, mVUcacheMaxReserve);
|
microVU1.cacheSize = min(reserveInMegs, mVUcacheMaxReserve);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,31 +38,43 @@ struct microBlockLink {
|
||||||
|
|
||||||
class microBlockManager {
|
class microBlockManager {
|
||||||
private:
|
private:
|
||||||
microBlockLink* blockList;
|
microBlockLink* qBlockList, *qBlockEnd; // Quick Search
|
||||||
microBlockLink* blockEnd;
|
microBlockLink* fBlockList, *fBlockEnd; // Full Search
|
||||||
int listI;
|
int qListI, fListI;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
microBlockManager() {
|
microBlockManager() {
|
||||||
listI = 0;
|
qListI = fListI = 0;
|
||||||
blockEnd = blockList = NULL;
|
qBlockEnd = qBlockList = NULL;
|
||||||
|
fBlockEnd = fBlockList = NULL;
|
||||||
}
|
}
|
||||||
~microBlockManager() { reset(); }
|
~microBlockManager() { reset(); }
|
||||||
void reset() {
|
void reset() {
|
||||||
for(microBlockLink* linkI = blockList; linkI != NULL; ) {
|
for(microBlockLink* linkI = qBlockList; linkI != NULL; ) {
|
||||||
microBlockLink* freeI = linkI;
|
microBlockLink* freeI = linkI;
|
||||||
safe_delete_array(linkI->block.jumpCache);
|
safe_delete_array(linkI->block.jumpCache);
|
||||||
linkI = linkI->next;
|
linkI = linkI->next;
|
||||||
_aligned_free(freeI);
|
_aligned_free(freeI);
|
||||||
}
|
}
|
||||||
listI = 0;
|
for(microBlockLink* linkI = fBlockList; linkI != NULL; ) {
|
||||||
blockEnd = blockList = 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* add(microBlock* pBlock) {
|
||||||
microBlock* thisBlock = search(&pBlock->pState);
|
microBlock* thisBlock = search(&pBlock->pState);
|
||||||
if (!thisBlock) {
|
if (!thisBlock) {
|
||||||
listI++;
|
u8 fullCmp = pBlock->pState.needExactMatch;
|
||||||
microBlockLink* newBlock = (microBlockLink*)_aligned_malloc(sizeof(microBlockLink), 16);
|
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->block.jumpCache = NULL;
|
||||||
newBlock->next = NULL;
|
newBlock->next = NULL;
|
||||||
|
|
||||||
|
@ -81,13 +93,13 @@ public:
|
||||||
}
|
}
|
||||||
__ri microBlock* search(microRegInfo* pState) {
|
__ri microBlock* search(microRegInfo* pState) {
|
||||||
if (pState->needExactMatch) { // Needs Detailed Search (Exact Match of Pipeline State)
|
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)))
|
if (mVUquickSearch((void*)pState, (void*)&linkI->block.pState, sizeof(microRegInfo)))
|
||||||
return &linkI->block;
|
return &linkI->block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // Can do Simple Search (Only Matches the Important Pipeline Stuff)
|
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 (doConstProp && (linkI->block.pState.vi15 != pState->vi15)) continue;
|
||||||
if (linkI->block.pState.quick32[0] != pState->quick32[0]) continue;
|
if (linkI->block.pState.quick32[0] != pState->quick32[0]) continue;
|
||||||
if (linkI->block.pState.quick32[1] != pState->quick32[1]) continue;
|
if (linkI->block.pState.quick32[1] != pState->quick32[1]) continue;
|
||||||
|
@ -96,9 +108,10 @@ public:
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void printInfo(int pc) {
|
void printInfo(int pc, bool printQuick) {
|
||||||
|
int listI = printQuick ? qListI : fListI;
|
||||||
if (listI < 7) return;
|
if (listI < 7) return;
|
||||||
microBlockLink* linkI = blockList;
|
microBlockLink* linkI = printQuick ? qBlockList : fBlockList;
|
||||||
for (int i = 0; i <= listI; i++) {
|
for (int i = 0; i <= listI; i++) {
|
||||||
u32 viCRC = 0, vfCRC = 0, crc = 0, z = sizeof(microRegInfo)/4;
|
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];
|
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
|
// recCall Function Pointer
|
||||||
typedef void (__fastcall *mVUrecCall)(u32, u32);
|
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());
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue