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_BRANCH = (FLUSH_FLUSH_MIPS_REGISTERS),
|
||||||
FLUSH_FOR_EXCEPTION =
|
FLUSH_FOR_EXCEPTION =
|
||||||
(FLUSH_CYCLES | FLUSH_GTE_DONE_CYCLE), // GTE cycles needed because it stalls when a GTE instruction is next.
|
(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_FOR_INTERPRETER = (FLUSH_FLUSH_MIPS_REGISTERS | FLUSH_INVALIDATE_MIPS_REGISTERS |
|
||||||
FLUSH_FREE_CALLER_SAVED_REGISTERS | FLUSH_PC | FLUSH_CYCLES | FLUSH_INSTRUCTION_BITS |
|
FLUSH_FREE_CALLER_SAVED_REGISTERS | FLUSH_PC | FLUSH_CYCLES | FLUSH_INSTRUCTION_BITS |
|
||||||
FLUSH_LOAD_DELAY | FLUSH_GTE_DONE_CYCLE | FLUSH_INVALIDATE_SPECULATIVE_CONSTANTS),
|
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));
|
armAsm->ldr(RARG1, PTR(&g_state.cop0_regs.sr.bits));
|
||||||
TestInterrupts(RARG1);
|
TestInterrupts(RARG1);
|
||||||
}
|
}
|
||||||
|
else if (reg == Cop0Reg::DCIC || reg == Cop0Reg::BPCM)
|
||||||
if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
|
||||||
{
|
{
|
||||||
// TODO: DCIC handling for debug breakpoints
|
// need to check whether we're switching to debug mode
|
||||||
WARNING_LOG("TODO: DCIC handling for debug breakpoints");
|
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));
|
armAsm->ldr(RWARG1, PTR(&g_state.cop0_regs.sr.bits));
|
||||||
TestInterrupts(RWARG1);
|
TestInterrupts(RWARG1);
|
||||||
}
|
}
|
||||||
|
else if (reg == Cop0Reg::DCIC || reg == Cop0Reg::BPCM)
|
||||||
if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
|
||||||
{
|
{
|
||||||
// TODO: DCIC handling for debug breakpoints
|
// need to check whether we're switching to debug mode
|
||||||
WARNING_LOG("TODO: DCIC handling for debug breakpoints");
|
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));
|
rvAsm->LW(RARG1, PTR(&g_state.cop0_regs.sr.bits));
|
||||||
TestInterrupts(RARG1);
|
TestInterrupts(RARG1);
|
||||||
}
|
}
|
||||||
|
else if (reg == Cop0Reg::DCIC || reg == Cop0Reg::BPCM)
|
||||||
if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
|
||||||
{
|
{
|
||||||
// TODO: DCIC handling for debug breakpoints
|
// need to check whether we're switching to debug mode
|
||||||
WARNING_LOG("TODO: DCIC handling for debug breakpoints");
|
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)]);
|
cg->mov(RWARG1, cg->dword[PTR(&g_state.cop0_regs.sr.bits)]);
|
||||||
TestInterrupts(RWARG1);
|
TestInterrupts(RWARG1);
|
||||||
}
|
}
|
||||||
|
else if (reg == Cop0Reg::DCIC || reg == Cop0Reg::BPCM)
|
||||||
if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
|
||||||
{
|
{
|
||||||
// TODO: DCIC handling for debug breakpoints
|
// need to check whether we're switching to debug mode
|
||||||
WARNING_LOG("TODO: DCIC handling for debug breakpoints");
|
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