CPU/Recompiler: Exit block early on DCIC/BPCM change
Fixes booting Xplorer cartridge with recompiler.
This commit is contained in:
parent
307bd86b72
commit
18c509a679
|
@ -105,6 +105,8 @@ protected:
|
|||
FLUSH_FOR_BRANCH = (FLUSH_FLUSH_MIPS_REGISTERS),
|
||||
FLUSH_FOR_EXCEPTION =
|
||||
(FLUSH_CYCLES | FLUSH_GTE_DONE_CYCLE), // GTE cycles needed because it stalls when a GTE instruction is next.
|
||||
FLUSH_FOR_EARLY_BLOCK_EXIT =
|
||||
(FLUSH_FLUSH_MIPS_REGISTERS | FLUSH_CYCLES | FLUSH_GTE_DONE_CYCLE | FLUSH_PC | FLUSH_LOAD_DELAY),
|
||||
FLUSH_FOR_INTERPRETER = (FLUSH_FLUSH_MIPS_REGISTERS | FLUSH_INVALIDATE_MIPS_REGISTERS |
|
||||
FLUSH_FREE_CALLER_SAVED_REGISTERS | FLUSH_PC | FLUSH_CYCLES | FLUSH_INSTRUCTION_BITS |
|
||||
FLUSH_LOAD_DELAY | FLUSH_GTE_DONE_CYCLE | FLUSH_INVALIDATE_SPECULATIVE_CONSTANTS),
|
||||
|
|
|
@ -2286,11 +2286,17 @@ void CPU::ARM32Recompiler::Compile_mtc0(CompileFlags cf)
|
|||
armAsm->ldr(RARG1, PTR(&g_state.cop0_regs.sr.bits));
|
||||
TestInterrupts(RARG1);
|
||||
}
|
||||
|
||||
if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
||||
else if (reg == Cop0Reg::DCIC || reg == Cop0Reg::BPCM)
|
||||
{
|
||||
// TODO: DCIC handling for debug breakpoints
|
||||
WARNING_LOG("TODO: DCIC handling for debug breakpoints");
|
||||
// need to check whether we're switching to debug mode
|
||||
Flush(FLUSH_FOR_C_CALL);
|
||||
EmitCall(reinterpret_cast<const void*>(&CPU::UpdateDebugDispatcherFlag));
|
||||
SwitchToFarCodeIfRegZeroOrNonZero(RRET, true);
|
||||
BackupHostState();
|
||||
Flush(FLUSH_FOR_EARLY_BLOCK_EXIT);
|
||||
EmitCall(reinterpret_cast<const void*>(&CPU::ExitExecution)); // does not return
|
||||
RestoreHostState();
|
||||
SwitchToNearCode(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2443,11 +2443,17 @@ void CPU::ARM64Recompiler::Compile_mtc0(CompileFlags cf)
|
|||
armAsm->ldr(RWARG1, PTR(&g_state.cop0_regs.sr.bits));
|
||||
TestInterrupts(RWARG1);
|
||||
}
|
||||
|
||||
if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
||||
else if (reg == Cop0Reg::DCIC || reg == Cop0Reg::BPCM)
|
||||
{
|
||||
// TODO: DCIC handling for debug breakpoints
|
||||
WARNING_LOG("TODO: DCIC handling for debug breakpoints");
|
||||
// need to check whether we're switching to debug mode
|
||||
Flush(FLUSH_FOR_C_CALL);
|
||||
EmitCall(reinterpret_cast<const void*>(&CPU::UpdateDebugDispatcherFlag));
|
||||
SwitchToFarCodeIfRegZeroOrNonZero(RWRET, true);
|
||||
BackupHostState();
|
||||
Flush(FLUSH_FOR_EARLY_BLOCK_EXIT);
|
||||
EmitCall(reinterpret_cast<const void*>(&CPU::ExitExecution)); // does not return
|
||||
RestoreHostState();
|
||||
SwitchToNearCode(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2300,11 +2300,17 @@ void CPU::RISCV64Recompiler::Compile_mtc0(CompileFlags cf)
|
|||
rvAsm->LW(RARG1, PTR(&g_state.cop0_regs.sr.bits));
|
||||
TestInterrupts(RARG1);
|
||||
}
|
||||
|
||||
if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
||||
else if (reg == Cop0Reg::DCIC || reg == Cop0Reg::BPCM)
|
||||
{
|
||||
// TODO: DCIC handling for debug breakpoints
|
||||
WARNING_LOG("TODO: DCIC handling for debug breakpoints");
|
||||
// need to check whether we're switching to debug mode
|
||||
Flush(FLUSH_FOR_C_CALL);
|
||||
EmitCall(reinterpret_cast<const void*>(&CPU::UpdateDebugDispatcherFlag));
|
||||
SwitchToFarCode(true, &Assembler::BEQ, RRET, zero);
|
||||
BackupHostState();
|
||||
Flush(FLUSH_FOR_EARLY_BLOCK_EXIT);
|
||||
EmitCall(reinterpret_cast<const void*>(&CPU::ExitExecution)); // does not return
|
||||
RestoreHostState();
|
||||
SwitchToNearCode(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2259,11 +2259,18 @@ void CPU::X64Recompiler::Compile_mtc0(CompileFlags cf)
|
|||
cg->mov(RWARG1, cg->dword[PTR(&g_state.cop0_regs.sr.bits)]);
|
||||
TestInterrupts(RWARG1);
|
||||
}
|
||||
|
||||
if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
||||
else if (reg == Cop0Reg::DCIC || reg == Cop0Reg::BPCM)
|
||||
{
|
||||
// TODO: DCIC handling for debug breakpoints
|
||||
WARNING_LOG("TODO: DCIC handling for debug breakpoints");
|
||||
// need to check whether we're switching to debug mode
|
||||
Flush(FLUSH_FOR_C_CALL);
|
||||
cg->call(&CPU::UpdateDebugDispatcherFlag);
|
||||
cg->test(cg->al, cg->al);
|
||||
SwitchToFarCode(true, &Xbyak::CodeGenerator::jnz);
|
||||
BackupHostState();
|
||||
Flush(FLUSH_FOR_EARLY_BLOCK_EXIT);
|
||||
cg->call(&CPU::ExitExecution); // does not return
|
||||
RestoreHostState();
|
||||
SwitchToNearCode(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue