| 454 | } |
| 455 | |
| 456 | void DebuggerWindow::onStepOver() |
| 457 | { |
| 458 | DebugInterface* cpu = currentCPU(); |
| 459 | if (!cpu) |
| 460 | return; |
| 461 | |
| 462 | if (!cpu->isAlive() || !cpu->isCpuPaused()) |
| 463 | return; |
| 464 | |
| 465 | const u32 pc = cpu->getPC(); |
| 466 | const MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu, pc); |
| 467 | |
| 468 | u32 bpAddr = pc + 0x4; // Default to the next instruction |
| 469 | |
| 470 | if (info.isBranch) |
| 471 | { |
| 472 | if (!info.isConditional) |
| 473 | { |
| 474 | if (info.isLinkedBranch) // jal, jalr |
| 475 | { |
| 476 | // it's a function call with a delay slot - skip that too |
| 477 | bpAddr += 4; |
| 478 | } |
| 479 | else // j, ... |
| 480 | { |
| 481 | // in case of absolute branches, set the breakpoint at the branch target |
| 482 | bpAddr = info.branchTarget; |
| 483 | } |
| 484 | } |
| 485 | else // beq, ... |
| 486 | { |
| 487 | if (info.conditionMet) |
| 488 | { |
| 489 | bpAddr = info.branchTarget; |
| 490 | } |
| 491 | else |
| 492 | { |
| 493 | bpAddr = pc + (2 * 4); // Skip branch delay slot |
| 494 | } |
| 495 | } |
| 496 | } |
| 497 | |
| 498 | Host::RunOnCPUThread([cpu, bpAddr] { |
| 499 | CBreakPoints::AddBreakPoint(cpu->getCpuType(), bpAddr, true, true, true); |
| 500 | cpu->resumeCpu(); |
| 501 | }); |
| 502 | |
| 503 | update(); |
| 504 | } |
| 505 | |
| 506 | void DebuggerWindow::onStepOut() |
| 507 | { |
nothing calls this directly
no test coverage detected