microVU: Fix program range wrapping

This commit is contained in:
refractionpcsx2 2020-10-26 21:47:53 +00:00
parent 9ebcb3b141
commit 3dc44bafb3
3 changed files with 24 additions and 20 deletions

View File

@ -230,29 +230,28 @@ void mVUprintUniqueRatio(microVU& mVU) {
DevCon.WriteLn("%d / %d [%3.1f%%]", v.size(), total, 100.-(double)v.size()/(double)total*100.);
}
// Compare partial program by only checking compiled ranges...
__ri bool mVUcmpPartial(microVU& mVU, microProgram& prog) {
std::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); }
if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU.regs().Micro), ((it[0].end + 8) - it[0].start))) {
return 0;
}
}
return 1;
}
// Compare Cached microProgram to mVU.regs().Micro
__fi bool mVUcmpProg(microVU& mVU, microProgram& prog, const bool cmpWholeProg) {
if ((cmpWholeProg && !memcmp_mmx((u8*)prog.data, mVU.regs().Micro, mVU.microMemSize))
|| (!cmpWholeProg && mVUcmpPartial(mVU, prog))) {
if (cmpWholeProg)
{
if (memcmp_mmx((u8*)prog.data, mVU.regs().Micro, mVU.microMemSize))
return false;
}
else
{
for (const auto& range : *prog.ranges) {
auto cmpOffset = [&](void* x) { return (u8*)x + range.start; };
if ((range.start < 0) || (range.end < 0)) { DevCon.Error("microVU%d: Negative Range![%d][%d]", mVU.index, range.start, range.end); }
if (memcmp_mmx(cmpOffset(prog.data), cmpOffset(mVU.regs().Micro), ((range.end+8) - range.start))) {
return false;
}
}
}
mVU.prog.cleared = 0;
mVU.prog.cur = &prog;
mVU.prog.isSame = cmpWholeProg ? 1 : -1;
return true;
}
return false;
}
// Searches for Cached Micro Program and sets prog.cur to it (returns entry-point to program)
_mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) {

View File

@ -692,6 +692,12 @@ void* mVUcompile(microVU& mVU, u32 startPC, uptr pState)
goto perf_and_return;
}
else if (!mVUinfo.isBdelay) {
// Handle range wrapping
if ((xPC + 8) == mVU.microMemSize)
{
mVUsetupRange(mVU, xPC, false);
mVUsetupRange(mVU, 0, 1);
}
incPC(1);
}
else {

View File

@ -229,7 +229,6 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
#define setCode() { mVU.code = curI; }
#define bSaveAddr (((xPC + 16) & (mVU.microMemSize-8)) / 8)
#define shufflePQ (((mVU.p) ? 0xb0 : 0xe0) | ((mVU.q) ? 0x01 : 0x04))
#define cmpOffset(x) ((u8*)&(((u8*)x)[it[0].start]))
#define Rmem &mVU.regs().VI[REG_R].UL
#define aWrap(x, m) ((x > m) ? 0 : x)
#define shuffleSS(x) ((x==1)?(0x27):((x==2)?(0xc6):((x==4)?(0xe1):(0xe4))))