A32: Allow hooking of hint instructions in ARM mode.
Mirrors the hooking functionality from the AArch64 frontend to make the behavior of both consistent.
This commit is contained in:
parent
dd79a3dc6b
commit
966e04d03d
5 changed files with 58 additions and 5 deletions
|
@ -24,8 +24,18 @@ enum class Exception {
|
|||
/// An unpredictable instruction is to be executed. Implementation-defined behaviour should now happen.
|
||||
/// This behaviour is up to the user of this library to define.
|
||||
UnpredictableInstruction,
|
||||
/// A SEV instruction was executed. The event register of all PEs should be set.
|
||||
SendEvent,
|
||||
/// A WFI instruction was executed. You may now enter a low-power state.
|
||||
WaitForInterrupt,
|
||||
/// A WFE instruction was executed. You may now enter a low-power state if the event register is clear.
|
||||
WaitForEvent,
|
||||
/// A YIELD instruction was executed.
|
||||
Yield,
|
||||
/// A BKPT instruction was executed.
|
||||
Breakpoint,
|
||||
/// A PLD instruction was executed.
|
||||
PreloadData,
|
||||
};
|
||||
|
||||
/// These function pointers may be inserted into compiled code.
|
||||
|
|
|
@ -103,6 +103,7 @@ add_library(dynarmic
|
|||
frontend/A32/translate/translate_arm/divide.cpp
|
||||
frontend/A32/translate/translate_arm/exception_generating.cpp
|
||||
frontend/A32/translate/translate_arm/extension.cpp
|
||||
frontend/A32/translate/translate_arm/hint.cpp
|
||||
frontend/A32/translate/translate_arm/load_store.cpp
|
||||
frontend/A32/translate/translate_arm/misc.cpp
|
||||
frontend/A32/translate/translate_arm/multiply.cpp
|
||||
|
|
|
@ -157,6 +157,13 @@ bool ArmTranslatorVisitor::UndefinedInstruction() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::RaiseException(Exception exception) {
|
||||
ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 4));
|
||||
ir.ExceptionRaised(exception);
|
||||
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
|
||||
return false;
|
||||
}
|
||||
|
||||
IR::ResultAndCarry<IR::U32> ArmTranslatorVisitor::EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in) {
|
||||
u8 imm5_value = imm5.ZeroExtend<u8>();
|
||||
|
||||
|
|
32
src/frontend/A32/translate/translate_arm/hint.cpp
Normal file
32
src/frontend/A32/translate/translate_arm/hint.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2019 MerryMage
|
||||
* This software may be used and distributed according to the terms of the GNU
|
||||
* General Public License version 2 or any later version.
|
||||
*/
|
||||
|
||||
#include <dynarmic/A32/config.h>
|
||||
#include "translate_arm.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
bool ArmTranslatorVisitor::arm_PLD() {
|
||||
return RaiseException(Exception::PreloadData);
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_SEV() {
|
||||
return RaiseException(Exception::SendEvent);
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_WFE() {
|
||||
return RaiseException(Exception::WaitForEvent);
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_WFI() {
|
||||
return RaiseException(Exception::WaitForInterrupt);
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_YIELD() {
|
||||
return RaiseException(Exception::Yield);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
enum class Exception;
|
||||
|
||||
enum class ConditionalState {
|
||||
/// We haven't met any conditional instructions yet.
|
||||
None,
|
||||
|
@ -40,6 +42,7 @@ struct ArmTranslatorVisitor final {
|
|||
bool InterpretThisInstruction();
|
||||
bool UnpredictableInstruction();
|
||||
bool UndefinedInstruction();
|
||||
bool RaiseException(Exception exception);
|
||||
|
||||
static u32 ArmExpandImm(int rotate, Imm<8> imm8) {
|
||||
return Common::RotateRight<u32>(imm8.ZeroExtend(), rotate * 2);
|
||||
|
@ -157,11 +160,11 @@ struct ArmTranslatorVisitor final {
|
|||
bool arm_UXTH(Cond cond, Reg d, SignExtendRotation rotate, Reg m);
|
||||
|
||||
// Hint instructions
|
||||
bool arm_PLD() { return true; }
|
||||
bool arm_SEV() { return true; }
|
||||
bool arm_WFE() { return true; }
|
||||
bool arm_WFI() { return true; }
|
||||
bool arm_YIELD() { return true; }
|
||||
bool arm_PLD();
|
||||
bool arm_SEV();
|
||||
bool arm_WFE();
|
||||
bool arm_WFI();
|
||||
bool arm_YIELD();
|
||||
|
||||
// Load/Store
|
||||
bool arm_LDRBT();
|
||||
|
|
Loading…
Reference in a new issue