|
|
|
|
@ -2730,26 +2730,28 @@ bool CodeGenerator::Compile_cop0(Instruction instruction, const CodeCache::Instr
|
|
|
|
|
// Emit an interrupt check on load of CAUSE/SR.
|
|
|
|
|
Value sr_value = m_register_cache.AllocateScratch(RegSize_32);
|
|
|
|
|
Value cause_value = m_register_cache.AllocateScratch(RegSize_32);
|
|
|
|
|
m_register_cache.InhibitAllocation();
|
|
|
|
|
|
|
|
|
|
// m_cop0_regs.sr.IEc && ((m_cop0_regs.cause.Ip & m_cop0_regs.sr.Im) != 0)
|
|
|
|
|
LabelType no_interrupt;
|
|
|
|
|
EmitLoadCPUStructField(sr_value.host_reg, sr_value.size, offsetof(State, cop0_regs.sr.bits));
|
|
|
|
|
EmitLoadCPUStructField(cause_value.host_reg, cause_value.size, offsetof(State, cop0_regs.cause.bits));
|
|
|
|
|
EmitBranchIfBitClear(sr_value.host_reg, sr_value.size, 0, &no_interrupt);
|
|
|
|
|
m_register_cache.InhibitAllocation();
|
|
|
|
|
EmitAnd(sr_value.host_reg, sr_value.host_reg, cause_value);
|
|
|
|
|
EmitTest(sr_value.host_reg, Value::FromConstantU32(0xFF00));
|
|
|
|
|
EmitConditionalBranch(Condition::Zero, false, &no_interrupt);
|
|
|
|
|
m_register_cache.UninhibitAllocation();
|
|
|
|
|
|
|
|
|
|
EmitBranch(GetCurrentFarCodePointer());
|
|
|
|
|
SwitchToFarCode();
|
|
|
|
|
m_register_cache.PushState();
|
|
|
|
|
WriteNewPC(CalculatePC(), false);
|
|
|
|
|
EmitStoreCPUStructField(offsetof(State, downcount), Value::FromConstantU32(0));
|
|
|
|
|
EmitExceptionExit();
|
|
|
|
|
m_register_cache.PopState();
|
|
|
|
|
SwitchToNearCode();
|
|
|
|
|
|
|
|
|
|
EmitBindLabel(&no_interrupt);
|
|
|
|
|
m_register_cache.UninhibitAllocation();
|
|
|
|
|
}
|
|
|
|
|
else if (reg == Cop0Reg::DCIC && g_settings.cpu_recompiler_memory_exceptions)
|
|
|
|
|
{
|
|
|
|
|
@ -2780,8 +2782,10 @@ bool CodeGenerator::Compile_cop0(Instruction instruction, const CodeCache::Instr
|
|
|
|
|
// exit block early if enabled
|
|
|
|
|
EmitBranch(GetCurrentFarCodePointer());
|
|
|
|
|
SwitchToFarCode();
|
|
|
|
|
m_register_cache.PushState();
|
|
|
|
|
WriteNewPC(CalculatePC(), false);
|
|
|
|
|
EmitExceptionExit();
|
|
|
|
|
m_register_cache.PopState();
|
|
|
|
|
SwitchToNearCode();
|
|
|
|
|
|
|
|
|
|
EmitBindLabel(¬_enabled);
|
|
|
|
|
|