mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
interp: Allow breakpoints in release mode.
This commit is contained in:
parent
1662bd3bb8
commit
76cf4dbf12
@ -646,10 +646,12 @@ const std::vector<BreakPoint> CBreakPoints::GetBreakpoints()
|
||||
return breakPoints_;
|
||||
}
|
||||
|
||||
bool CBreakPoints::HasMemChecks()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(memCheckMutex_);
|
||||
return !memChecks_.empty();
|
||||
bool CBreakPoints::HasBreakPoints() {
|
||||
return anyBreakPoints_;
|
||||
}
|
||||
|
||||
bool CBreakPoints::HasMemChecks() {
|
||||
return anyMemChecks_;
|
||||
}
|
||||
|
||||
void CBreakPoints::Update(u32 addr) {
|
||||
|
@ -167,6 +167,7 @@ public:
|
||||
static const std::vector<MemCheck> GetMemChecks();
|
||||
static const std::vector<BreakPoint> GetBreakpoints();
|
||||
|
||||
static bool HasBreakPoints();
|
||||
static bool HasMemChecks();
|
||||
|
||||
static void Update(u32 addr = 0);
|
||||
|
@ -938,8 +938,7 @@ void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, bool tabsToSpaces) {
|
||||
}
|
||||
}
|
||||
|
||||
void MIPSInterpret(MIPSOpcode op) {
|
||||
const MIPSInstruction *instr = MIPSGetInstruction(op);
|
||||
static inline void Interpret(const MIPSInstruction *instr, MIPSOpcode op) {
|
||||
if (instr && instr->interpret) {
|
||||
instr->interpret(op);
|
||||
} else {
|
||||
@ -952,66 +951,96 @@ void MIPSInterpret(MIPSOpcode op) {
|
||||
}
|
||||
}
|
||||
|
||||
inline int GetInstructionCycleEstimate(const MIPSInstruction *instr) {
|
||||
if (instr)
|
||||
return instr->flags.cycles;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MIPSInterpret(MIPSOpcode op) {
|
||||
const MIPSInstruction *instr = MIPSGetInstruction(op);
|
||||
Interpret(instr, op);
|
||||
}
|
||||
|
||||
#define _RS ((op>>21) & 0x1F)
|
||||
#define _RT ((op>>16) & 0x1F)
|
||||
#define _RD ((op>>11) & 0x1F)
|
||||
#define R(i) (curMips->r[i])
|
||||
|
||||
|
||||
int MIPSInterpret_RunUntil(u64 globalTicks)
|
||||
{
|
||||
static inline void RunUntilFast() {
|
||||
MIPSState *curMips = currentMIPS;
|
||||
while (coreState == CORE_RUNNING)
|
||||
{
|
||||
CoreTiming::Advance();
|
||||
|
||||
// NEVER stop in a delay slot!
|
||||
while (curMips->downcount >= 0 && coreState == CORE_RUNNING)
|
||||
{
|
||||
// int cycles = 0;
|
||||
{
|
||||
again:
|
||||
while (curMips->downcount >= 0 && coreState == CORE_RUNNING) {
|
||||
do {
|
||||
// Replacements and similar are processed here, intentionally.
|
||||
MIPSOpcode op = MIPSOpcode(Memory::Read_U32(curMips->pc));
|
||||
//MIPSOpcode op = Memory::Read_Opcode_JIT(mipsr4k.pc);
|
||||
|
||||
//2: check for breakpoint (VERY SLOW)
|
||||
#if defined(_DEBUG)
|
||||
bool wasInDelaySlot = curMips->inDelaySlot;
|
||||
const MIPSInstruction *instr = MIPSGetInstruction(op);
|
||||
Interpret(instr, op);
|
||||
curMips->downcount -= GetInstructionCycleEstimate(instr);
|
||||
|
||||
// The reason we have to check this is the delay slot hack in Int_Syscall.
|
||||
if (curMips->inDelaySlot && wasInDelaySlot) {
|
||||
curMips->pc = curMips->nextPC;
|
||||
curMips->inDelaySlot = false;
|
||||
}
|
||||
} while (curMips->inDelaySlot);
|
||||
}
|
||||
}
|
||||
|
||||
static void RunUntilWithChecks(u64 globalTicks) {
|
||||
MIPSState *curMips = currentMIPS;
|
||||
// NEVER stop in a delay slot!
|
||||
while (curMips->downcount >= 0 && coreState == CORE_RUNNING) {
|
||||
do {
|
||||
// Replacements and similar are processed here, intentionally.
|
||||
MIPSOpcode op = MIPSOpcode(Memory::Read_U32(curMips->pc));
|
||||
|
||||
// Check for breakpoint
|
||||
if (CBreakPoints::IsAddressBreakPoint(curMips->pc) && CBreakPoints::CheckSkipFirst() != curMips->pc) {
|
||||
auto cond = CBreakPoints::GetBreakPointCondition(currentMIPS->pc);
|
||||
if (!cond || cond->Evaluate())
|
||||
{
|
||||
if (!cond || cond->Evaluate()) {
|
||||
Core_EnableStepping(true, "cpu.breakpoint", curMips->pc);
|
||||
if (CBreakPoints::IsTempBreakPoint(curMips->pc))
|
||||
CBreakPoints::RemoveBreakPoint(curMips->pc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool wasInDelaySlot = curMips->inDelaySlot;
|
||||
MIPSInterpret(op);
|
||||
curMips->downcount -= MIPSGetInstructionCycleEstimate(op);
|
||||
const MIPSInstruction *instr = MIPSGetInstruction(op);
|
||||
Interpret(instr, op);
|
||||
curMips->downcount -= GetInstructionCycleEstimate(instr);
|
||||
|
||||
if (curMips->inDelaySlot)
|
||||
{
|
||||
// The reason we have to check this is the delay slot hack in Int_Syscall.
|
||||
if (wasInDelaySlot)
|
||||
{
|
||||
if (curMips->inDelaySlot && wasInDelaySlot) {
|
||||
curMips->pc = curMips->nextPC;
|
||||
curMips->inDelaySlot = false;
|
||||
continue;
|
||||
}
|
||||
goto again;
|
||||
} while (curMips->inDelaySlot);
|
||||
|
||||
if (CoreTiming::GetTicks() > globalTicks)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (CoreTiming::GetTicks() > globalTicks)
|
||||
{
|
||||
int MIPSInterpret_RunUntil(u64 globalTicks) {
|
||||
MIPSState *curMips = currentMIPS;
|
||||
while (coreState == CORE_RUNNING) {
|
||||
CoreTiming::Advance();
|
||||
|
||||
uint64_t ticksLeft = globalTicks - CoreTiming::GetTicks();
|
||||
if (CBreakPoints::HasBreakPoints() || CBreakPoints::HasMemChecks() || ticksLeft <= curMips->downcount)
|
||||
RunUntilWithChecks(globalTicks);
|
||||
else
|
||||
RunUntilFast();
|
||||
|
||||
if (CoreTiming::GetTicks() > globalTicks) {
|
||||
// DEBUG_LOG(CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1048,8 +1077,8 @@ MIPSInterpretFunc MIPSGetInterpretFunc(MIPSOpcode op)
|
||||
// TODO: Do something that makes sense here.
|
||||
int MIPSGetInstructionCycleEstimate(MIPSOpcode op)
|
||||
{
|
||||
MIPSInfo info = MIPSGetInfo(op);
|
||||
return info.cycles;
|
||||
const MIPSInstruction *instr = MIPSGetInstruction(op);
|
||||
return GetInstructionCycleEstimate(instr);
|
||||
}
|
||||
|
||||
const char *MIPSDisasmAt(u32 compilerPC) {
|
||||
|
Loading…
Reference in New Issue
Block a user