Core: Move DelaySlotEffectsCompare into R4300iInstruction
This commit is contained in:
parent
0abc7ccaa4
commit
09b535551d
|
@ -18,200 +18,6 @@ void ExecuteInterpreterOps(uint32_t /*Cycles*/)
|
|||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2)
|
||||
{
|
||||
R4300iOpcode Command;
|
||||
|
||||
if (!g_MMU->MemoryValue32(PC + 4, Command.Value))
|
||||
{
|
||||
//g_Notify->DisplayError("Failed to load word 2");
|
||||
//ExitThread(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (Command.op)
|
||||
{
|
||||
case R4300i_SPECIAL:
|
||||
switch (Command.funct)
|
||||
{
|
||||
case R4300i_SPECIAL_SLL:
|
||||
case R4300i_SPECIAL_SRL:
|
||||
case R4300i_SPECIAL_SRA:
|
||||
case R4300i_SPECIAL_SLLV:
|
||||
case R4300i_SPECIAL_SRLV:
|
||||
case R4300i_SPECIAL_SRAV:
|
||||
case R4300i_SPECIAL_MFHI:
|
||||
case R4300i_SPECIAL_MTHI:
|
||||
case R4300i_SPECIAL_MFLO:
|
||||
case R4300i_SPECIAL_MTLO:
|
||||
case R4300i_SPECIAL_DSLLV:
|
||||
case R4300i_SPECIAL_DSRLV:
|
||||
case R4300i_SPECIAL_DSRAV:
|
||||
case R4300i_SPECIAL_ADD:
|
||||
case R4300i_SPECIAL_ADDU:
|
||||
case R4300i_SPECIAL_SUB:
|
||||
case R4300i_SPECIAL_SUBU:
|
||||
case R4300i_SPECIAL_AND:
|
||||
case R4300i_SPECIAL_OR:
|
||||
case R4300i_SPECIAL_XOR:
|
||||
case R4300i_SPECIAL_NOR:
|
||||
case R4300i_SPECIAL_SLT:
|
||||
case R4300i_SPECIAL_SLTU:
|
||||
case R4300i_SPECIAL_DADD:
|
||||
case R4300i_SPECIAL_DADDU:
|
||||
case R4300i_SPECIAL_DSUB:
|
||||
case R4300i_SPECIAL_DSUBU:
|
||||
case R4300i_SPECIAL_DSLL:
|
||||
case R4300i_SPECIAL_DSRL:
|
||||
case R4300i_SPECIAL_DSRA:
|
||||
case R4300i_SPECIAL_DSLL32:
|
||||
case R4300i_SPECIAL_DSRL32:
|
||||
case R4300i_SPECIAL_DSRA32:
|
||||
if (Command.rd == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Command.rd == Reg1 || Command.rd == Reg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_SPECIAL_MULT:
|
||||
case R4300i_SPECIAL_MULTU:
|
||||
case R4300i_SPECIAL_DIV:
|
||||
case R4300i_SPECIAL_DIVU:
|
||||
case R4300i_SPECIAL_DMULT:
|
||||
case R4300i_SPECIAL_DMULTU:
|
||||
case R4300i_SPECIAL_DDIV:
|
||||
case R4300i_SPECIAL_DDIVU:
|
||||
break;
|
||||
default:
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", R4300iInstruction(PC + 4, Command.Value).Name(), PC).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_CP0:
|
||||
switch (Command.rs)
|
||||
{
|
||||
case R4300i_COP0_MT: break;
|
||||
case R4300i_COP0_MF:
|
||||
if (Command.rt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Command.rt == Reg1 || Command.rt == Reg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ((Command.rs & 0x10) != 0)
|
||||
{
|
||||
switch (Command.funct)
|
||||
{
|
||||
case R4300i_COP0_CO_TLBR: break;
|
||||
case R4300i_COP0_CO_TLBWI: break;
|
||||
case R4300i_COP0_CO_TLBWR: break;
|
||||
case R4300i_COP0_CO_TLBP: break;
|
||||
default:
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?\n6", R4300iInstruction(PC + 4, Command.Value).Name(), PC).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?\n7", R4300iInstruction(PC + 4, Command.Value).Name(), PC).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case R4300i_CP1:
|
||||
switch (Command.fmt)
|
||||
{
|
||||
case R4300i_COP1_MF:
|
||||
if (Command.rt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Command.rt == Reg1 || Command.rt == Reg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_COP1_CF: break;
|
||||
case R4300i_COP1_MT: break;
|
||||
case R4300i_COP1_CT: break;
|
||||
case R4300i_COP1_S: break;
|
||||
case R4300i_COP1_D: break;
|
||||
case R4300i_COP1_W: break;
|
||||
case R4300i_COP1_L: break;
|
||||
default:
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", R4300iInstruction(PC + 4, Command.Value).Name(), PC).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_ANDI:
|
||||
case R4300i_ORI:
|
||||
case R4300i_XORI:
|
||||
case R4300i_LUI:
|
||||
case R4300i_ADDI:
|
||||
case R4300i_ADDIU:
|
||||
case R4300i_SLTI:
|
||||
case R4300i_SLTIU:
|
||||
case R4300i_DADDI:
|
||||
case R4300i_DADDIU:
|
||||
case R4300i_LB:
|
||||
case R4300i_LH:
|
||||
case R4300i_LW:
|
||||
case R4300i_LWL:
|
||||
case R4300i_LWR:
|
||||
case R4300i_LDL:
|
||||
case R4300i_LDR:
|
||||
case R4300i_LBU:
|
||||
case R4300i_LHU:
|
||||
case R4300i_LD:
|
||||
case R4300i_LWC1:
|
||||
case R4300i_LDC1:
|
||||
if (Command.rt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Command.rt == Reg1 || Command.rt == Reg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_CACHE: break;
|
||||
case R4300i_SB: break;
|
||||
case R4300i_SH: break;
|
||||
case R4300i_SW: break;
|
||||
case R4300i_SWR: break;
|
||||
case R4300i_SWL: break;
|
||||
case R4300i_SWC1: break;
|
||||
case R4300i_SDC1: break;
|
||||
case R4300i_SD: break;
|
||||
default:
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", R4300iInstruction(PC + 4, Command.Value).Name(), PC).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CInterpreterCPU::BuildCPU()
|
||||
{
|
||||
R4300iOp::m_TestTimer = false;
|
||||
|
|
|
@ -700,8 +700,6 @@ R4300iOp::Func * R4300iOp::BuildInterpreter()
|
|||
return Jump_Opcode;
|
||||
}
|
||||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
|
||||
|
||||
// Opcode functions
|
||||
|
||||
void R4300iOp::J()
|
||||
|
@ -734,7 +732,8 @@ void R4300iOp::BEQ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -754,7 +753,8 @@ void R4300iOp::BNE()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -774,7 +774,8 @@ void R4300iOp::BLEZ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -794,7 +795,8 @@ void R4300iOp::BGTZ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -895,7 +897,8 @@ void R4300iOp::BEQL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -916,7 +919,8 @@ void R4300iOp::BNEL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -937,7 +941,8 @@ void R4300iOp::BLEZL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -958,7 +963,8 @@ void R4300iOp::BGTZL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -1660,9 +1666,10 @@ void R4300iOp::REGIMM_BLTZ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1680,9 +1687,10 @@ void R4300iOp::REGIMM_BGEZ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1700,9 +1708,10 @@ void R4300iOp::REGIMM_BLTZL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1721,9 +1730,10 @@ void R4300iOp::REGIMM_BGEZL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1742,9 +1752,10 @@ void R4300iOp::REGIMM_BLTZAL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1775,9 +1786,10 @@ void R4300iOp::REGIMM_BGEZAL()
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
#include <Project64-core/N64System/N64System.h>
|
||||
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
|
||||
#include <Project64-core/N64System/Mips/SystemTiming.h>
|
||||
#include <Project64-core/N64System/Mips/R4300iInstruction.h>
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterCPU.h>
|
||||
#include <Project64-core/Logging.h>
|
||||
#include <Project64-core/Debugger.h>
|
||||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
|
||||
|
||||
#define TEST_COP1_USABLE_EXCEPTION \
|
||||
if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) {\
|
||||
g_Reg->DoCopUnusableException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,1);\
|
||||
|
@ -632,7 +631,8 @@ void R4300iOp32::BEQ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -652,7 +652,8 @@ void R4300iOp32::BNE()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -672,7 +673,8 @@ void R4300iOp32::BLEZ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -692,7 +694,8 @@ void R4300iOp32::BGTZ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -793,7 +796,8 @@ void R4300iOp32::BEQL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -814,7 +818,8 @@ void R4300iOp32::BNEL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -835,7 +840,8 @@ void R4300iOp32::BLEZL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -856,7 +862,8 @@ void R4300iOp32::BGTZL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
|
@ -1075,9 +1082,10 @@ void R4300iOp32::REGIMM_BLTZ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1095,9 +1103,10 @@ void R4300iOp32::REGIMM_BGEZ()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1115,9 +1124,10 @@ void R4300iOp32::REGIMM_BLTZL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1136,9 +1146,10 @@ void R4300iOp32::REGIMM_BGEZL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1157,9 +1168,10 @@ void R4300iOp32::REGIMM_BLTZAL()
|
|||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1190,9 +1202,10 @@ void R4300iOp32::REGIMM_BGEZAL()
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(*_PROGRAM_COUNTER + 4, DelaySlot.Value) && !R4300iInstruction(*_PROGRAM_COUNTER, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,6 +77,253 @@ bool R4300iInstruction::HasDelaySlot(void) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool R4300iInstruction::DelaySlotEffectsCompare(uint32_t DelayInstruction) const
|
||||
{
|
||||
R4300iInstruction DelaySlot(m_Address + 4, DelayInstruction);
|
||||
|
||||
uint32_t Reg1 = 0, Reg2 = 0;
|
||||
switch (m_Instruction.op)
|
||||
{
|
||||
case R4300i_SPECIAL:
|
||||
switch (m_Instruction.funct)
|
||||
{
|
||||
case R4300i_SPECIAL_JR:
|
||||
case R4300i_SPECIAL_JALR:
|
||||
Reg1 = m_Instruction.rs;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case R4300i_REGIMM:
|
||||
switch (m_Instruction.rt)
|
||||
{
|
||||
case R4300i_REGIMM_BLTZ:
|
||||
case R4300i_REGIMM_BGEZ:
|
||||
case R4300i_REGIMM_BLTZL:
|
||||
case R4300i_REGIMM_BGEZL:
|
||||
case R4300i_REGIMM_BLTZAL:
|
||||
case R4300i_REGIMM_BGEZAL:
|
||||
Reg1 = m_Instruction.rs;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case R4300i_BEQ:
|
||||
case R4300i_BNE:
|
||||
case R4300i_BEQL:
|
||||
case R4300i_BNEL:
|
||||
Reg1 = m_Instruction.rs;
|
||||
Reg2 = m_Instruction.rt;
|
||||
break;
|
||||
case R4300i_BLEZ:
|
||||
case R4300i_BGTZ:
|
||||
case R4300i_BLEZL:
|
||||
case R4300i_BGTZL:
|
||||
Reg1 = m_Instruction.rs;
|
||||
break;
|
||||
case R4300i_CP1:
|
||||
if (m_Instruction.fmt == R4300i_COP1_BC)
|
||||
{
|
||||
if (DelaySlot.m_Instruction.op == R4300i_CP1)
|
||||
{
|
||||
if ((DelaySlot.m_Instruction.fmt == R4300i_COP1_S && (DelaySlot.m_Instruction.funct & 0x30) == 0x30) ||
|
||||
(DelaySlot.m_Instruction.fmt == R4300i_COP1_D && (DelaySlot.m_Instruction.funct & 0x30) == 0x30))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (DelaySlot.m_Instruction.op)
|
||||
{
|
||||
case R4300i_SPECIAL:
|
||||
switch (DelaySlot.m_Instruction.funct)
|
||||
{
|
||||
case R4300i_SPECIAL_SLL:
|
||||
case R4300i_SPECIAL_SRL:
|
||||
case R4300i_SPECIAL_SRA:
|
||||
case R4300i_SPECIAL_SLLV:
|
||||
case R4300i_SPECIAL_SRLV:
|
||||
case R4300i_SPECIAL_SRAV:
|
||||
case R4300i_SPECIAL_MFHI:
|
||||
case R4300i_SPECIAL_MTHI:
|
||||
case R4300i_SPECIAL_MFLO:
|
||||
case R4300i_SPECIAL_MTLO:
|
||||
case R4300i_SPECIAL_DSLLV:
|
||||
case R4300i_SPECIAL_DSRLV:
|
||||
case R4300i_SPECIAL_DSRAV:
|
||||
case R4300i_SPECIAL_ADD:
|
||||
case R4300i_SPECIAL_ADDU:
|
||||
case R4300i_SPECIAL_SUB:
|
||||
case R4300i_SPECIAL_SUBU:
|
||||
case R4300i_SPECIAL_AND:
|
||||
case R4300i_SPECIAL_OR:
|
||||
case R4300i_SPECIAL_XOR:
|
||||
case R4300i_SPECIAL_NOR:
|
||||
case R4300i_SPECIAL_SLT:
|
||||
case R4300i_SPECIAL_SLTU:
|
||||
case R4300i_SPECIAL_DADD:
|
||||
case R4300i_SPECIAL_DADDU:
|
||||
case R4300i_SPECIAL_DSUB:
|
||||
case R4300i_SPECIAL_DSUBU:
|
||||
case R4300i_SPECIAL_DSLL:
|
||||
case R4300i_SPECIAL_DSRL:
|
||||
case R4300i_SPECIAL_DSRA:
|
||||
case R4300i_SPECIAL_DSLL32:
|
||||
case R4300i_SPECIAL_DSRL32:
|
||||
case R4300i_SPECIAL_DSRA32:
|
||||
if (DelaySlot.m_Instruction.rd == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (DelaySlot.m_Instruction.rd == Reg1 || DelaySlot.m_Instruction.rd == Reg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_SPECIAL_MULT:
|
||||
case R4300i_SPECIAL_MULTU:
|
||||
case R4300i_SPECIAL_DIV:
|
||||
case R4300i_SPECIAL_DIVU:
|
||||
case R4300i_SPECIAL_DMULT:
|
||||
case R4300i_SPECIAL_DMULTU:
|
||||
case R4300i_SPECIAL_DDIV:
|
||||
case R4300i_SPECIAL_DDIVU:
|
||||
break;
|
||||
default:
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", DelaySlot.Name(), m_Address).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_CP0:
|
||||
switch (DelaySlot.m_Instruction.rs)
|
||||
{
|
||||
case R4300i_COP0_MT: break;
|
||||
case R4300i_COP0_MF:
|
||||
if (DelaySlot.m_Instruction.rt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (DelaySlot.m_Instruction.rt == Reg1 || DelaySlot.m_Instruction.rt == Reg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ((DelaySlot.m_Instruction.rs & 0x10) != 0)
|
||||
{
|
||||
switch (DelaySlot.m_Instruction.funct)
|
||||
{
|
||||
case R4300i_COP0_CO_TLBR: break;
|
||||
case R4300i_COP0_CO_TLBWI: break;
|
||||
case R4300i_COP0_CO_TLBWR: break;
|
||||
case R4300i_COP0_CO_TLBP: break;
|
||||
default:
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?\n6", DelaySlot.Name(), m_Address).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?\n7", DelaySlot.Name(), m_Address).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case R4300i_CP1:
|
||||
switch (DelaySlot.m_Instruction.fmt)
|
||||
{
|
||||
case R4300i_COP1_MF:
|
||||
if (DelaySlot.m_Instruction.rt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (DelaySlot.m_Instruction.rt == Reg1 || DelaySlot.m_Instruction.rt == Reg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_COP1_CF: break;
|
||||
case R4300i_COP1_MT: break;
|
||||
case R4300i_COP1_CT: break;
|
||||
case R4300i_COP1_S: break;
|
||||
case R4300i_COP1_D: break;
|
||||
case R4300i_COP1_W: break;
|
||||
case R4300i_COP1_L: break;
|
||||
default:
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", DelaySlot.Name(), m_Address).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_ANDI:
|
||||
case R4300i_ORI:
|
||||
case R4300i_XORI:
|
||||
case R4300i_LUI:
|
||||
case R4300i_ADDI:
|
||||
case R4300i_ADDIU:
|
||||
case R4300i_SLTI:
|
||||
case R4300i_SLTIU:
|
||||
case R4300i_DADDI:
|
||||
case R4300i_DADDIU:
|
||||
case R4300i_LB:
|
||||
case R4300i_LH:
|
||||
case R4300i_LW:
|
||||
case R4300i_LWL:
|
||||
case R4300i_LWR:
|
||||
case R4300i_LDL:
|
||||
case R4300i_LDR:
|
||||
case R4300i_LBU:
|
||||
case R4300i_LHU:
|
||||
case R4300i_LD:
|
||||
case R4300i_LWC1:
|
||||
case R4300i_LDC1:
|
||||
if (DelaySlot.m_Instruction.rt == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (DelaySlot.m_Instruction.rt == Reg1 || DelaySlot.m_Instruction.rt == Reg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_CACHE: break;
|
||||
case R4300i_SB: break;
|
||||
case R4300i_SH: break;
|
||||
case R4300i_SW: break;
|
||||
case R4300i_SWR: break;
|
||||
case R4300i_SWL: break;
|
||||
case R4300i_SWC1: break;
|
||||
case R4300i_SDC1: break;
|
||||
case R4300i_SD: break;
|
||||
default:
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Does %s effect delay slot at %X?", DelaySlot.Name(), m_Address).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * R4300iInstruction::FPR_Type(uint32_t COP1OpCode)
|
||||
{
|
||||
if (COP1OpCode == R4300i_COP1_S) { return "S"; };
|
||||
|
|
|
@ -12,6 +12,7 @@ public:
|
|||
std::string NameAndParam();
|
||||
|
||||
bool HasDelaySlot(void) const;
|
||||
bool DelaySlotEffectsCompare(uint32_t DelayInstruction) const;
|
||||
|
||||
private:
|
||||
R4300iInstruction(void);
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#include <Project64-core/N64System/N64System.h>
|
||||
#include <Project64-core/N64System/Mips/R4300iInstruction.h>
|
||||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
|
||||
|
||||
#if defined(ANDROID) && (defined(__arm__) || defined(_M_ARM))
|
||||
/* bug-fix to implement __clear_cache (missing in Android; http://code.google.com/p/android/issues/detail?id=1803) */
|
||||
extern "C" void __clear_cache_android(uint8_t* begin, uint8_t *end);
|
||||
|
@ -493,7 +491,13 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
|
|||
}
|
||||
else
|
||||
{
|
||||
if (TargetPC == PC && !DelaySlotEffectsCompare(PC, Command.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(PC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
|
||||
if (TargetPC == PC && !R4300iInstruction(PC, Command.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
PermLoop = true;
|
||||
}
|
||||
|
@ -519,7 +523,12 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(PC, Command.rs, Command.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(PC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
if (!R4300iInstruction(PC, Command.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
PermLoop = true;
|
||||
}
|
||||
|
@ -537,7 +546,12 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
|
|||
TargetPC = PC + ((int16_t)Command.offset << 2) + 4;
|
||||
if (TargetPC == PC)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(PC, Command.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(PC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
if (!R4300iInstruction(PC, Command.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
PermLoop = true;
|
||||
}
|
||||
|
@ -583,8 +597,12 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
|
|||
{
|
||||
ContinuePC = PC + 8;
|
||||
}
|
||||
|
||||
if (TargetPC == PC && !DelaySlotEffectsCompare(PC, Command.rs, Command.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(PC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
if (TargetPC == PC && !R4300iInstruction(PC, Command.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
PermLoop = true;
|
||||
}
|
||||
|
@ -603,7 +621,12 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
|
|||
{
|
||||
if (TargetPC == PC)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(PC, Command.rs, Command.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(PC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
if (!R4300iInstruction(PC, Command.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
PermLoop = true;
|
||||
}
|
||||
|
@ -701,7 +724,12 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
|
|||
TargetPC = PC + ((int16_t)Command.offset << 2) + 4;
|
||||
if (TargetPC == PC)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(PC, Command.rs, Command.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(PC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
if (!R4300iInstruction(PC, Command.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
PermLoop = true;
|
||||
}
|
||||
|
@ -720,7 +748,12 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
|
|||
ContinuePC = PC + 8;
|
||||
if (TargetPC == PC)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(PC, Command.rs, Command.rt))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(PC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
if (!R4300iInstruction(PC, Command.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
PermLoop = true;
|
||||
}
|
||||
|
|
|
@ -13,94 +13,6 @@
|
|||
#include <Project64-core/ExceptionHandler.h>
|
||||
#include <Project64-core/Debugger.h>
|
||||
|
||||
void InPermLoop();
|
||||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
|
||||
|
||||
static bool DelaySlotEffectsJump(uint32_t JumpPC)
|
||||
{
|
||||
R4300iOpcode Command;
|
||||
|
||||
if (!g_MMU->MemoryValue32(JumpPC, Command.Value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (Command.op)
|
||||
{
|
||||
case R4300i_SPECIAL:
|
||||
switch (Command.funct)
|
||||
{
|
||||
case R4300i_SPECIAL_JR: return DelaySlotEffectsCompare(JumpPC, Command.rs, 0);
|
||||
case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(JumpPC, Command.rs, 31);
|
||||
}
|
||||
break;
|
||||
case R4300i_REGIMM:
|
||||
switch (Command.rt)
|
||||
{
|
||||
case R4300i_REGIMM_BLTZ:
|
||||
case R4300i_REGIMM_BGEZ:
|
||||
case R4300i_REGIMM_BLTZL:
|
||||
case R4300i_REGIMM_BGEZL:
|
||||
case R4300i_REGIMM_BLTZAL:
|
||||
case R4300i_REGIMM_BGEZAL:
|
||||
return DelaySlotEffectsCompare(JumpPC, Command.rs, 0);
|
||||
}
|
||||
break;
|
||||
case R4300i_JAL:
|
||||
case R4300i_SPECIAL_JALR: return DelaySlotEffectsCompare(JumpPC, 31, 0); break;
|
||||
case R4300i_J: return false;
|
||||
case R4300i_BEQ:
|
||||
case R4300i_BNE:
|
||||
case R4300i_BLEZ:
|
||||
case R4300i_BGTZ:
|
||||
return DelaySlotEffectsCompare(JumpPC, Command.rs, Command.rt);
|
||||
case R4300i_CP1:
|
||||
switch (Command.fmt)
|
||||
{
|
||||
case R4300i_COP1_BC:
|
||||
switch (Command.ft)
|
||||
{
|
||||
case R4300i_COP1_BC_BCF:
|
||||
case R4300i_COP1_BC_BCT:
|
||||
case R4300i_COP1_BC_BCFL:
|
||||
case R4300i_COP1_BC_BCTL:
|
||||
{
|
||||
bool EffectDelaySlot = false;
|
||||
R4300iOpcode NewCommand;
|
||||
|
||||
if (!g_MMU->MemoryValue32(JumpPC + 4, NewCommand.Value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NewCommand.op == R4300i_CP1)
|
||||
{
|
||||
if (NewCommand.fmt == R4300i_COP1_S && (NewCommand.funct & 0x30) == 0x30)
|
||||
{
|
||||
EffectDelaySlot = true;
|
||||
}
|
||||
if (NewCommand.fmt == R4300i_COP1_D && (NewCommand.funct & 0x30) == 0x30)
|
||||
{
|
||||
EffectDelaySlot = true;
|
||||
}
|
||||
}
|
||||
return EffectDelaySlot;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case R4300i_BEQL:
|
||||
case R4300i_BNEL:
|
||||
case R4300i_BLEZL:
|
||||
case R4300i_BGTZL:
|
||||
return DelaySlotEffectsCompare(JumpPC, Command.rs, Command.rt);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CCodeSection::CCodeSection(CCodeBlock * CodeBlock, uint32_t EnterPC, uint32_t ID, bool LinkAllowed) :
|
||||
m_BlockInfo(CodeBlock),
|
||||
m_SectionID(ID),
|
||||
|
@ -148,7 +60,10 @@ void CCodeSection::GenerateSectionLinkage()
|
|||
// Handle permanent loop
|
||||
if (m_RecompilerOps->GetCurrentPC() == m_Jump.TargetPC && (m_Cont.FallThrough == false))
|
||||
{
|
||||
if (!DelaySlotEffectsJump(m_RecompilerOps->GetCurrentPC()))
|
||||
R4300iOpcode JumpOp, DelaySlot;
|
||||
if (g_MMU->MemoryValue32(m_RecompilerOps->GetCurrentPC(), JumpOp.Value) &&
|
||||
g_MMU->MemoryValue32(m_RecompilerOps->GetCurrentPC() + 4, DelaySlot.Value) &&
|
||||
!R4300iInstruction(m_RecompilerOps->GetCurrentPC(), JumpOp.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
m_RecompilerOps->CompileInPermLoop(m_Jump.RegSet, m_RecompilerOps->GetCurrentPC());
|
||||
}
|
||||
|
@ -480,12 +395,12 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
|
|||
case R4300i_REGIMM:
|
||||
switch (Opcode.rt)
|
||||
{
|
||||
case R4300i_REGIMM_BLTZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, CRecompilerOps::BranchTypeRs, false); break;
|
||||
case R4300i_REGIMM_BGEZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, CRecompilerOps::BranchTypeRs, false); break;
|
||||
case R4300i_REGIMM_BLTZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, false); break;
|
||||
case R4300i_REGIMM_BGEZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, false); break;
|
||||
case R4300i_REGIMM_BLTZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBLTZ, false); break;
|
||||
case R4300i_REGIMM_BGEZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBGEZ, false); break;
|
||||
case R4300i_REGIMM_BLTZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, CRecompilerOps::BranchTypeRs, true); break;
|
||||
case R4300i_REGIMM_BGEZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, CRecompilerOps::BranchTypeRs, true); break;
|
||||
case R4300i_REGIMM_BLTZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, true); break;
|
||||
case R4300i_REGIMM_BGEZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, true); break;
|
||||
case R4300i_REGIMM_TEQI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTEQI); break;
|
||||
case R4300i_REGIMM_TNEI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTNEI); break;
|
||||
case R4300i_REGIMM_TGEI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEI); break;
|
||||
|
@ -496,10 +411,10 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
|
|||
m_RecompilerOps->UnknownOpcode(); break;
|
||||
}
|
||||
break;
|
||||
case R4300i_BEQ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBEQ, CRecompilerOps::BranchTypeRsRt, false); break;
|
||||
case R4300i_BNE: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBNE, CRecompilerOps::BranchTypeRsRt, false); break;
|
||||
case R4300i_BGTZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGTZ, CRecompilerOps::BranchTypeRs, false); break;
|
||||
case R4300i_BLEZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLEZ, CRecompilerOps::BranchTypeRs, false); break;
|
||||
case R4300i_BEQ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBEQ, false); break;
|
||||
case R4300i_BNE: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBNE, false); break;
|
||||
case R4300i_BGTZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGTZ, false); break;
|
||||
case R4300i_BLEZ: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLEZ, false); break;
|
||||
case R4300i_J: m_RecompilerOps->J(); break;
|
||||
case R4300i_JAL: m_RecompilerOps->JAL(); break;
|
||||
case R4300i_ADDI: m_RecompilerOps->ADDI(); break;
|
||||
|
@ -546,8 +461,8 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
|
|||
case R4300i_COP1_BC:
|
||||
switch (Opcode.ft)
|
||||
{
|
||||
case R4300i_COP1_BC_BCF: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeCOP1BCF, CRecompilerOps::BranchTypeCop1, false); break;
|
||||
case R4300i_COP1_BC_BCT: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeCOP1BCT, CRecompilerOps::BranchTypeCop1, false); break;
|
||||
case R4300i_COP1_BC_BCF: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeCOP1BCF, false); break;
|
||||
case R4300i_COP1_BC_BCT: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeCOP1BCT, false); break;
|
||||
case R4300i_COP1_BC_BCFL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCF, false); break;
|
||||
case R4300i_COP1_BC_BCTL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeCOP1BCT, false); break;
|
||||
default:
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#define CHECKED_BUILD 1
|
||||
#endif
|
||||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
|
||||
|
||||
LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) :
|
||||
m_EnterSection(Section),
|
||||
m_BlockInfo(CodeBlock),
|
||||
|
@ -261,7 +259,10 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
|
|||
}
|
||||
if (m_PC == Section->m_Jump.TargetPC)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0) && !Section->m_Jump.PermLoop)
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(m_PC + 4, DelaySlot.Value) &&
|
||||
!R4300iInstruction(m_PC, m_Command.Value).DelaySlotEffectsCompare(DelaySlot.Value) &&
|
||||
!Section->m_Jump.PermLoop)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
@ -291,7 +292,10 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
|
|||
}*/
|
||||
if (m_PC == m_PC + ((int16_t)m_Command.offset << 2) + 4)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, 0) && !Section->m_Jump.PermLoop)
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(m_PC + 4, DelaySlot.Value) &&
|
||||
!R4300iInstruction(m_PC, m_Command.Value).DelaySlotEffectsCompare(DelaySlot.Value) &&
|
||||
!Section->m_Jump.PermLoop)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
@ -351,7 +355,10 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
|
|||
}
|
||||
if (m_PC == Section->m_Jump.TargetPC)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop)
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(m_PC + 4, DelaySlot.Value) &&
|
||||
!R4300iInstruction(m_PC, m_Command.Value).DelaySlotEffectsCompare(DelaySlot.Value) &&
|
||||
!Section->m_Jump.PermLoop)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
@ -380,7 +387,10 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
|
|||
}
|
||||
if (m_PC == Section->m_Jump.TargetPC)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop)
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(m_PC + 4, DelaySlot.Value) &&
|
||||
!R4300iInstruction(m_PC, m_Command.Value).DelaySlotEffectsCompare(DelaySlot.Value) &&
|
||||
!Section->m_Jump.PermLoop)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
@ -562,7 +572,10 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
|
|||
}*/
|
||||
if (m_PC == m_PC + ((int16_t)m_Command.offset << 2) + 4)
|
||||
{
|
||||
if (!DelaySlotEffectsCompare(m_PC, m_Command.rs, m_Command.rt) && !Section->m_Jump.PermLoop)
|
||||
R4300iOpcode DelaySlot;
|
||||
if (g_MMU->MemoryValue32(m_PC + 4, DelaySlot.Value) &&
|
||||
!R4300iInstruction(m_PC, m_Command.Value).DelaySlotEffectsCompare(DelaySlot.Value) &&
|
||||
!Section->m_Jump.PermLoop)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
virtual void Compile_TrapCompare(TRAP_COMPARE CompareType) = 0;
|
||||
|
||||
// Branch functions
|
||||
virtual void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link) = 0;
|
||||
virtual void Compile_Branch(BRANCH_COMPARE CompareType, bool Link) = 0;
|
||||
virtual void Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link) = 0;
|
||||
|
||||
// Opcode functions
|
||||
|
|
|
@ -364,8 +364,6 @@ void CX86RecompilerOps::CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg)
|
|||
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::TLBWriteMiss, false, JeLabel32);
|
||||
}
|
||||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
|
||||
|
||||
// Trap functions
|
||||
void CX86RecompilerOps::Compile_TrapCompare(TRAP_COMPARE CompareType)
|
||||
{
|
||||
|
@ -462,7 +460,7 @@ void CX86RecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType)
|
|||
}
|
||||
}
|
||||
|
||||
void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link)
|
||||
void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, bool Link)
|
||||
{
|
||||
static CRegInfo RegBeforeDelay;
|
||||
static bool EffectDelaySlot;
|
||||
|
@ -480,33 +478,12 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
|
|||
|
||||
if ((m_CompilePC & 0xFFC) != 0xFFC)
|
||||
{
|
||||
switch (BranchType)
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(m_CompilePC + 4, DelaySlot.Value))
|
||||
{
|
||||
case BranchTypeRs: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0); break;
|
||||
case BranchTypeRsRt: EffectDelaySlot = DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, m_Opcode.rt); break;
|
||||
case BranchTypeCop1:
|
||||
{
|
||||
R4300iOpcode Command;
|
||||
|
||||
if (!g_MMU->MemoryValue32(m_CompilePC + 4, Command.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
|
||||
EffectDelaySlot = false;
|
||||
if (Command.op == R4300i_CP1)
|
||||
{
|
||||
if ((Command.fmt == R4300i_COP1_S && (Command.funct & 0x30) == 0x30) ||
|
||||
(Command.fmt == R4300i_COP1_D && (Command.funct & 0x30) == 0x30))
|
||||
{
|
||||
EffectDelaySlot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (HaveDebugger()) { g_Notify->DisplayError("Unknown branch type"); }
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
EffectDelaySlot = R4300iInstruction(m_CompilePC, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4323,7 +4300,13 @@ void CX86RecompilerOps::SPECIAL_JR()
|
|||
m_Section->m_Cont.LinkLocation = nullptr;
|
||||
m_Section->m_Cont.LinkLocation2 = nullptr;
|
||||
|
||||
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(m_CompilePC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
|
||||
if (R4300iInstruction(m_CompilePC, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
if (IsConst(m_Opcode.rs))
|
||||
{
|
||||
|
@ -4342,7 +4325,13 @@ void CX86RecompilerOps::SPECIAL_JR()
|
|||
}
|
||||
else if (m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT_DONE)
|
||||
{
|
||||
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(m_CompilePC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
|
||||
if (R4300iInstruction(m_CompilePC, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, nullptr);
|
||||
}
|
||||
|
@ -4379,7 +4368,13 @@ void CX86RecompilerOps::SPECIAL_JALR()
|
|||
{
|
||||
if (m_PipelineStage == PIPELINE_STAGE_NORMAL)
|
||||
{
|
||||
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0) && (m_CompilePC & 0xFFC) != 0xFFC)
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(m_CompilePC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
|
||||
if (R4300iInstruction(m_CompilePC, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value) && (m_CompilePC & 0xFFC) != 0xFFC)
|
||||
{
|
||||
if (IsConst(m_Opcode.rs))
|
||||
{
|
||||
|
@ -4424,7 +4419,13 @@ void CX86RecompilerOps::SPECIAL_JALR()
|
|||
}
|
||||
else if (m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT_DONE)
|
||||
{
|
||||
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0))
|
||||
R4300iOpcode DelaySlot;
|
||||
if (!g_MMU->MemoryValue32(m_CompilePC + 4, DelaySlot.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
|
||||
if (R4300iInstruction(m_CompilePC, m_Opcode.Value).DelaySlotEffectsCompare(DelaySlot.Value))
|
||||
{
|
||||
CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, nullptr);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
|
||||
// Branch functions
|
||||
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
|
||||
void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);
|
||||
void Compile_Branch(BRANCH_COMPARE CompareType, bool Link);
|
||||
void Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link);
|
||||
void BNE_Compare();
|
||||
void BEQ_Compare();
|
||||
|
|
Loading…
Reference in New Issue