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)
|
void Core::SetPC(u32 new_pc)
|
||||||
{
|
{
|
||||||
|
DebugAssert(Common::IsAlignedPow2(new_pc, 4));
|
||||||
m_regs.npc = new_pc;
|
m_regs.npc = new_pc;
|
||||||
FlushPipeline();
|
FlushPipeline();
|
||||||
}
|
}
|
||||||
|
@ -228,6 +229,14 @@ bool Core::SafeWriteMemoryWord(VirtualMemoryAddress addr, u32 value)
|
||||||
|
|
||||||
void Core::Branch(u32 target)
|
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_regs.npc = target;
|
||||||
m_branch_was_taken = true;
|
m_branch_was_taken = true;
|
||||||
}
|
}
|
||||||
|
@ -562,14 +571,8 @@ void Core::Execute()
|
||||||
|
|
||||||
bool Core::FetchInstruction()
|
bool Core::FetchInstruction()
|
||||||
{
|
{
|
||||||
if (!Common::IsAlignedPow2(m_regs.npc, 4))
|
DebugAssert(Common::IsAlignedPow2(m_regs.npc, 4));
|
||||||
{
|
if (DoMemoryAccess<MemoryAccessType::Read, MemoryAccessSize::Word>(m_regs.npc, m_next_instruction.bits) < 0)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
// Bus errors don't set BadVaddr.
|
// Bus errors don't set BadVaddr.
|
||||||
RaiseException(Exception::IBE, m_regs.npc, false, false, 0);
|
RaiseException(Exception::IBE, m_regs.npc, false, false, 0);
|
||||||
|
|
Loading…
Reference in New Issue