CPU: Move alignment check to branch instead of fetch
There is no other way to end up with an unaligned PC.
This commit is contained in:
parent
7448cbaf9d
commit
b4a6c98bbe
|
@ -88,6 +88,7 @@ bool Core::DoState(StateWrapper& sw)
|
|||
|
||||
void Core::SetPC(u32 new_pc)
|
||||
{
|
||||
DebugAssert(Common::IsAlignedPow2(new_pc, 4));
|
||||
m_regs.npc = new_pc;
|
||||
FlushPipeline();
|
||||
}
|
||||
|
@ -228,6 +229,14 @@ bool Core::SafeWriteMemoryWord(VirtualMemoryAddress addr, u32 value)
|
|||
|
||||
void Core::Branch(u32 target)
|
||||
{
|
||||
if (!Common::IsAlignedPow2(target, 4))
|
||||
{
|
||||
// The BadVaddr and EPC must be set to the fetching address, not the instruction about to execute.
|
||||
m_cop0_regs.BadVaddr = target;
|
||||
RaiseException(Exception::AdEL, target, false, false, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
m_regs.npc = target;
|
||||
m_branch_was_taken = true;
|
||||
}
|
||||
|
@ -562,14 +571,8 @@ void Core::Execute()
|
|||
|
||||
bool Core::FetchInstruction()
|
||||
{
|
||||
if (!Common::IsAlignedPow2(m_regs.npc, 4))
|
||||
{
|
||||
// The EPC must be set to the fetching address, not the instruction about to execute.
|
||||
m_cop0_regs.BadVaddr = m_regs.npc;
|
||||
RaiseException(Exception::AdEL, m_regs.npc, false, false, 0);
|
||||
return false;
|
||||
}
|
||||
else if (DoMemoryAccess<MemoryAccessType::Read, MemoryAccessSize::Word>(m_regs.npc, m_next_instruction.bits) < 0)
|
||||
DebugAssert(Common::IsAlignedPow2(m_regs.npc, 4));
|
||||
if (DoMemoryAccess<MemoryAccessType::Read, MemoryAccessSize::Word>(m_regs.npc, m_next_instruction.bits) < 0)
|
||||
{
|
||||
// Bus errors don't set BadVaddr.
|
||||
RaiseException(Exception::IBE, m_regs.npc, false, false, 0);
|
||||
|
|
Loading…
Reference in New Issue