Core: Lighten IOP breakpoint load

standardizeBreakpintAddress calls on the IOP just return the address unmodified. Considering this is called at least once every load / store instruction when there is an IOP OR EE memcheck enabled, it's pretty hot.
This commit is contained in:
Ty Lamontagne 2022-01-20 23:59:48 -05:00 committed by refractionpcsx2
parent e64e2f2c4e
commit a632f3c5cb
6 changed files with 23 additions and 58 deletions

View File

@ -31,15 +31,7 @@ std::vector<MemCheck *> CBreakPoints::cleanupMemChecks_;
bool CBreakPoints::breakpointTriggered_ = false;
// called from the dynarec
u32 __fastcall standardizeBreakpointAddress(BreakPointCpu cpu, u32 addr)
{
if (cpu == BREAKPOINT_IOP)
return standardizeBreakpointAddressIop(addr);
else
return standardizeBreakpointAddressEE(addr);
}
u32 __fastcall standardizeBreakpointAddressEE(u32 addr)
u32 __fastcall standardizeBreakpointAddress(u32 addr)
{
if (addr >= 0xFFFF8000)
return addr;
@ -54,11 +46,6 @@ u32 __fastcall standardizeBreakpointAddressEE(u32 addr)
return addr;
}
u32 __fastcall standardizeBreakpointAddressIop(u32 addr)
{
return addr;
}
MemCheck::MemCheck()
: start(0)
, end(0)
@ -137,11 +124,12 @@ void MemCheck::JitCleanup()
size_t CBreakPoints::FindBreakpoint(BreakPointCpu cpu, u32 addr, bool matchTemp, bool temp)
{
addr = standardizeBreakpointAddress(cpu, addr);
if (cpu == BREAKPOINT_EE)
addr = standardizeBreakpointAddress(addr);
for (size_t i = 0; i < breakPoints_.size(); ++i)
{
u32 cmp = standardizeBreakpointAddress(cpu, breakPoints_[i].addr);
u32 cmp = cpu == BREAKPOINT_EE ? standardizeBreakpointAddress(breakPoints_[i].addr) : breakPoints_[i].addr;
if (cpu == breakPoints_[i].cpu && cmp == addr && (!matchTemp || breakPoints_[i].temporary == temp))
return i;
}
@ -151,13 +139,16 @@ size_t CBreakPoints::FindBreakpoint(BreakPointCpu cpu, u32 addr, bool matchTemp,
size_t CBreakPoints::FindMemCheck(BreakPointCpu cpu, u32 start, u32 end)
{
start = standardizeBreakpointAddress(cpu, start);
end = standardizeBreakpointAddress(cpu, end);
if (cpu == BREAKPOINT_EE)
{
start = standardizeBreakpointAddress(start);
end = standardizeBreakpointAddress(end);
}
for (size_t i = 0; i < memChecks_.size(); ++i)
{
u32 cmpStart = standardizeBreakpointAddress(cpu, memChecks_[i].start);
u32 cmpEnd = standardizeBreakpointAddress(cpu, memChecks_[i].end);
u32 cmpStart = cpu == BREAKPOINT_EE ? standardizeBreakpointAddress(memChecks_[i].start) : memChecks_[i].start;
u32 cmpEnd = cpu == BREAKPOINT_EE ? standardizeBreakpointAddress(memChecks_[i].end) : memChecks_[i].end;
if (memChecks_[i].cpu == cpu && cmpStart == start && cmpEnd == end)
return i;
}
@ -361,19 +352,18 @@ void CBreakPoints::SetSkipFirst(BreakPointCpu cpu, u32 pc)
{
if (cpu == BREAKPOINT_EE)
{
breakSkipFirstAtEE_ = standardizeBreakpointAddress(cpu, pc);
breakSkipFirstAtEE_ = standardizeBreakpointAddress(pc);
breakSkipFirstTicksEE_ = r5900Debug.getCycles();
}
else if (cpu == BREAKPOINT_IOP)
{
breakSkipFirstAtIop_ = standardizeBreakpointAddress(cpu, pc);
breakSkipFirstAtIop_ = pc;
breakSkipFirstTicksIop_ = r3000Debug.getCycles();
}
}
u32 CBreakPoints::CheckSkipFirst(BreakPointCpu cpu, u32 cmpPc)
{
cmpPc = standardizeBreakpointAddress(cpu, cmpPc);
if (cpu == BREAKPOINT_EE && breakSkipFirstTicksEE_ == r5900Debug.getCycles())
return breakSkipFirstAtEE_;
else if (cpu == BREAKPOINT_IOP && breakSkipFirstTicksIop_ == r3000Debug.getCycles())

View File

@ -169,6 +169,4 @@ private:
// called from the dynarec
u32 __fastcall standardizeBreakpointAddress(BreakPointCpu cpu, u32 addr);
u32 __fastcall standardizeBreakpointAddressEE(u32 addr);
u32 __fastcall standardizeBreakpointAddressIop(u32 addr);
u32 __fastcall standardizeBreakpointAddress(u32 addr);

View File

@ -43,13 +43,6 @@ static void intEventTest();
// These macros are used to assemble the repassembler functions
static void debugI()
{
if( !IsDevBuild ) return;
if( cpuRegs.GPR.n.r0.UD[0] || cpuRegs.GPR.n.r0.UD[1] ) Console.Error("R0 is not zero!!!!");
}
void intBreakpoint(bool memcheck)
{
u32 pc = cpuRegs.pc;
@ -79,7 +72,7 @@ void intMemcheck(u32 op, u32 bits, bool store)
if (bits == 128)
start &= ~0x0F;
start = standardizeBreakpointAddress(BREAKPOINT_EE, start);
start = standardizeBreakpointAddress(start);
u32 end = start + bits/8;
auto checks = CBreakPoints::GetMemChecks();
@ -140,7 +133,7 @@ static void execI()
// Extra note: due to some cycle count issue PCSX2's internal debugger is
// not yet usable with the interpreter
//#define EXTRA_DEBUG
#ifdef EXTRA_DEBUG
#if defined(EXTRA_DEBUG) || defined(PCSX2_DEVBUILD)
// check if any breakpoints or memchecks are triggered by this instruction
if (isBreakpointNeeded(cpuRegs.pc))
intBreakpoint(false);
@ -155,11 +148,6 @@ static void execI()
// interprete instruction
cpuRegs.code = memRead32( pc );
// Honestly I think this code is useless nowadays.
#ifdef EXTRA_DEBUG
if( IsDebugBuild )
debugI();
#endif
const OPCODE& opcode = GetCurrentInstruction();
#if 0

View File

@ -153,10 +153,7 @@ void psxMemcheck(u32 op, u32 bits, bool store)
u32 start = psxRegs.GPR.r[(op >> 21) & 0x1F];
if ((s16)op != 0)
start += (s16)op;
if (bits == 128)
start &= ~0x0F;
start = standardizeBreakpointAddress(BREAKPOINT_IOP, start);
u32 end = start + bits / 8;
auto checks = CBreakPoints::GetMemChecks();
@ -204,9 +201,6 @@ void psxCheckMemcheck()
case MEMTYPE_DWORD:
psxMemcheck(op, 64, store);
break;
case MEMTYPE_QWORD:
psxMemcheck(op, 128, store);
break;
}
}
@ -218,7 +212,7 @@ static __fi void execI()
// This function is called for every instruction.
// Enabling the define below will probably, no, will cause the interpretor to be slower.
//#define EXTRA_DEBUG
#ifdef EXTRA_DEBUG
#if defined(EXTRA_DEBUG) || defined(PCSX2_DEVBUILD)
if (psxIsBreakpointNeeded(psxRegs.pc))
psxBreakpoint(false);

View File

@ -1162,12 +1162,8 @@ void psxRecMemcheck(u32 op, u32 bits, bool store)
_psxMoveGPRtoR(ecx, (op >> 21) & 0x1F);
if ((s16)op != 0)
xADD(ecx, (s16)op);
if (bits == 128)
xAND(ecx, ~0x0F);
xFastCall((void*)standardizeBreakpointAddressIop, ecx);
xMOV(ecx, eax);
xMOV(edx, eax);
xMOV(edx, ecx);
xADD(edx, bits / 8);
// ecx = access address
@ -1187,11 +1183,11 @@ void psxRecMemcheck(u32 op, u32 bits, bool store)
// logic: memAddress < bpEnd && bpStart < memAddress+memSize
xMOV(eax, standardizeBreakpointAddress(BREAKPOINT_IOP, checks[i].end));
xMOV(eax, checks[i].end);
xCMP(ecx, eax); // address < end
xForwardJGE8 next1; // if address >= end then goto next1
xMOV(eax, standardizeBreakpointAddress(BREAKPOINT_IOP, checks[i].start));
xMOV(eax, checks[i].start);
xCMP(eax, edx); // start < address+size
xForwardJGE8 next2; // if start >= address+size then goto next2
@ -1242,7 +1238,6 @@ void psxEncodeMemcheck()
case MEMTYPE_HALF: psxRecMemcheck(op, 16, store); break;
case MEMTYPE_WORD: psxRecMemcheck(op, 32, store); break;
case MEMTYPE_DWORD: psxRecMemcheck(op, 64, store); break;
case MEMTYPE_QWORD: psxRecMemcheck(op, 128, store); break;
}
}

View File

@ -1353,7 +1353,7 @@ void recMemcheck(u32 op, u32 bits, bool store)
if (bits == 128)
xAND(ecx, ~0x0F);
xFastCall((void*)standardizeBreakpointAddressEE, ecx);
xFastCall((void*)standardizeBreakpointAddress, ecx);
xMOV(ecx, eax);
xMOV(edx, eax);
xADD(edx, bits / 8);
@ -1375,11 +1375,11 @@ void recMemcheck(u32 op, u32 bits, bool store)
// logic: memAddress < bpEnd && bpStart < memAddress+memSize
xMOV(eax, standardizeBreakpointAddress(BREAKPOINT_EE, checks[i].end));
xMOV(eax, standardizeBreakpointAddress(checks[i].end));
xCMP(ecx, eax); // address < end
xForwardJGE8 next1; // if address >= end then goto next1
xMOV(eax, standardizeBreakpointAddress(BREAKPOINT_EE, checks[i].start));
xMOV(eax, standardizeBreakpointAddress(checks[i].start));
xCMP(eax, edx); // start < address+size
xForwardJGE8 next2; // if start >= address+size then goto next2