A32/Thumb: Correct behaviour for UDF and Unpredictable instructions
Raise an exception instead of calling the interpreter and ASSERT-ing respectively.
This commit is contained in:
parent
c7d20f3f2f
commit
1aa7b62e92
4 changed files with 12 additions and 4 deletions
|
@ -885,7 +885,7 @@ bool ThumbTranslatorVisitor::thumb16_CBZ_CBNZ(bool nonzero, Imm<1> i, Imm<5> imm
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThumbTranslatorVisitor::thumb16_UDF() {
|
bool ThumbTranslatorVisitor::thumb16_UDF() {
|
||||||
return InterpretThisInstruction();
|
return UndefinedInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
// BX <Rm>
|
// BX <Rm>
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct ThumbTranslatorVisitor final {
|
||||||
|
|
||||||
bool InterpretThisInstruction();
|
bool InterpretThisInstruction();
|
||||||
bool UnpredictableInstruction();
|
bool UnpredictableInstruction();
|
||||||
|
bool UndefinedInstruction();
|
||||||
bool RaiseException(Exception exception);
|
bool RaiseException(Exception exception);
|
||||||
|
|
||||||
// thumb16
|
// thumb16
|
||||||
|
|
|
@ -122,12 +122,19 @@ bool ThumbTranslatorVisitor::InterpretThisInstruction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThumbTranslatorVisitor::UnpredictableInstruction() {
|
bool ThumbTranslatorVisitor::UnpredictableInstruction() {
|
||||||
ASSERT_MSG(false, "UNPREDICTABLE");
|
ir.ExceptionRaised(Exception::UnpredictableInstruction);
|
||||||
|
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThumbTranslatorVisitor::UndefinedInstruction() {
|
||||||
|
ir.ExceptionRaised(Exception::UndefinedInstruction);
|
||||||
|
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThumbTranslatorVisitor::RaiseException(Exception exception) {
|
bool ThumbTranslatorVisitor::RaiseException(Exception exception) {
|
||||||
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2));
|
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2)); // TODO: T32
|
||||||
ir.ExceptionRaised(exception);
|
ir.ExceptionRaised(exception);
|
||||||
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
|
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
MemoryWrite32(vaddr + 4, static_cast<u32>(value >> 32));
|
MemoryWrite32(vaddr + 4, static_cast<u32>(value >> 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterFallback(u32 pc, size_t num_instructions) override { ASSERT_MSG(false, "InterpreterFallback({:08x}, {})", pc, num_instructions); }
|
void InterpreterFallback(u32 pc, size_t num_instructions) override { ASSERT_MSG(false, "InterpreterFallback({:08x}, {}) code = {:08x}", pc, num_instructions, MemoryReadCode(pc)); }
|
||||||
|
|
||||||
void CallSVC(std::uint32_t swi) override { ASSERT_MSG(false, "CallSVC({})", swi); }
|
void CallSVC(std::uint32_t swi) override { ASSERT_MSG(false, "CallSVC({})", swi); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue