mirror of https://github.com/PCSX2/pcsx2.git
x86/microVU: Add a reference list for quick block lookups
This way, we can pack 8 entries in a single cache line, instead of one.
This commit is contained in:
parent
197d4d1c81
commit
ab295f0f10
|
@ -43,11 +43,18 @@ struct microBlockLink
|
||||||
microBlockLink* next;
|
microBlockLink* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct microBlockLinkRef
|
||||||
|
{
|
||||||
|
microBlock* pBlock;
|
||||||
|
u64 quick;
|
||||||
|
};
|
||||||
|
|
||||||
class microBlockManager
|
class microBlockManager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
microBlockLink *qBlockList, *qBlockEnd; // Quick Search
|
microBlockLink *qBlockList, *qBlockEnd; // Quick Search
|
||||||
microBlockLink *fBlockList, *fBlockEnd; // Full Search
|
microBlockLink *fBlockList, *fBlockEnd; // Full Search
|
||||||
|
std::vector<microBlockLinkRef> quickLookup;
|
||||||
int qListI, fListI;
|
int qListI, fListI;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -55,20 +62,20 @@ public:
|
||||||
microBlockManager()
|
microBlockManager()
|
||||||
{
|
{
|
||||||
qListI = fListI = 0;
|
qListI = fListI = 0;
|
||||||
qBlockEnd = qBlockList = NULL;
|
qBlockEnd = qBlockList = nullptr;
|
||||||
fBlockEnd = fBlockList = NULL;
|
fBlockEnd = fBlockList = nullptr;
|
||||||
}
|
}
|
||||||
~microBlockManager() { reset(); }
|
~microBlockManager() { reset(); }
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
for (microBlockLink* linkI = qBlockList; linkI != NULL;)
|
for (microBlockLink* linkI = qBlockList; linkI != nullptr;)
|
||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
for (microBlockLink* linkI = fBlockList; linkI != NULL;)
|
for (microBlockLink* linkI = fBlockList; linkI != nullptr;)
|
||||||
{
|
{
|
||||||
microBlockLink* freeI = linkI;
|
microBlockLink* freeI = linkI;
|
||||||
safe_delete_array(linkI->block.jumpCache);
|
safe_delete_array(linkI->block.jumpCache);
|
||||||
|
@ -76,8 +83,9 @@ public:
|
||||||
_aligned_free(freeI);
|
_aligned_free(freeI);
|
||||||
}
|
}
|
||||||
qListI = fListI = 0;
|
qListI = fListI = 0;
|
||||||
qBlockEnd = qBlockList = NULL;
|
qBlockEnd = qBlockList = nullptr;
|
||||||
fBlockEnd = fBlockList = NULL;
|
fBlockEnd = fBlockList = nullptr;
|
||||||
|
quickLookup.clear();
|
||||||
};
|
};
|
||||||
microBlock* add(microBlock* pBlock)
|
microBlock* add(microBlock* pBlock)
|
||||||
{
|
{
|
||||||
|
@ -93,8 +101,8 @@ public:
|
||||||
microBlockLink*& blockList = fullCmp ? fBlockList : qBlockList;
|
microBlockLink*& blockList = fullCmp ? fBlockList : qBlockList;
|
||||||
microBlockLink*& blockEnd = fullCmp ? fBlockEnd : qBlockEnd;
|
microBlockLink*& blockEnd = fullCmp ? fBlockEnd : qBlockEnd;
|
||||||
microBlockLink* newBlock = (microBlockLink*)_aligned_malloc(sizeof(microBlockLink), SSE_ALIGN_N);
|
microBlockLink* newBlock = (microBlockLink*)_aligned_malloc(sizeof(microBlockLink), SSE_ALIGN_N);
|
||||||
newBlock->block.jumpCache = NULL;
|
newBlock->block.jumpCache = nullptr;
|
||||||
newBlock->next = NULL;
|
newBlock->next = nullptr;
|
||||||
|
|
||||||
if (blockEnd)
|
if (blockEnd)
|
||||||
{
|
{
|
||||||
|
@ -106,8 +114,10 @@ public:
|
||||||
blockEnd = blockList = newBlock;
|
blockEnd = blockList = newBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&newBlock->block, pBlock, sizeof(microBlock));
|
std::memcpy(&newBlock->block, pBlock, sizeof(microBlock));
|
||||||
thisBlock = &newBlock->block;
|
thisBlock = &newBlock->block;
|
||||||
|
|
||||||
|
quickLookup.push_back({&newBlock->block, pBlock->pState.quick64[0]});
|
||||||
}
|
}
|
||||||
return thisBlock;
|
return thisBlock;
|
||||||
}
|
}
|
||||||
|
@ -115,23 +125,34 @@ public:
|
||||||
{
|
{
|
||||||
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 = fBlockList; linkI != NULL; linkI = linkI->next)
|
microBlockLink* prevI = nullptr;
|
||||||
|
for (microBlockLink* linkI = fBlockList; linkI != nullptr; prevI = linkI, linkI = linkI->next)
|
||||||
{
|
{
|
||||||
if (mVUquickSearch((void*)pState, (void*)&linkI->block.pState, sizeof(microRegInfo)))
|
if (mVUquickSearch(pState, &linkI->block.pState, sizeof(microRegInfo)))
|
||||||
|
{
|
||||||
|
if (linkI != fBlockList)
|
||||||
|
{
|
||||||
|
prevI->next = linkI->next;
|
||||||
|
linkI->next = fBlockList;
|
||||||
|
fBlockList = linkI;
|
||||||
|
}
|
||||||
|
|
||||||
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 = qBlockList; linkI != NULL; linkI = linkI->next)
|
const u64 quick64 = pState->quick64[0];
|
||||||
|
for (const microBlockLinkRef& ref : quickLookup)
|
||||||
{
|
{
|
||||||
if (linkI->block.pState.quick64[0] != pState->quick64[0]) continue;
|
if (ref.quick != quick64) continue;
|
||||||
if (doConstProp && (linkI->block.pState.vi15 != pState->vi15)) continue;
|
if (doConstProp && (ref.pBlock->pState.vi15 != pState->vi15)) continue;
|
||||||
if (doConstProp && (linkI->block.pState.vi15v != pState->vi15v)) continue;
|
if (doConstProp && (ref.pBlock->pState.vi15v != pState->vi15v)) continue;
|
||||||
return &linkI->block;
|
return ref.pBlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void printInfo(int pc, bool printQuick)
|
void printInfo(int pc, bool printQuick)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue