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.
|
/// 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.
|
/// This behaviour is up to the user of this library to define.
|
||||||
UnpredictableInstruction,
|
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.
|
/// A BKPT instruction was executed.
|
||||||
Breakpoint,
|
Breakpoint,
|
||||||
|
/// A PLD instruction was executed.
|
||||||
|
PreloadData,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// These function pointers may be inserted into compiled code.
|
/// 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/divide.cpp
|
||||||
frontend/A32/translate/translate_arm/exception_generating.cpp
|
frontend/A32/translate/translate_arm/exception_generating.cpp
|
||||||
frontend/A32/translate/translate_arm/extension.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/load_store.cpp
|
||||||
frontend/A32/translate/translate_arm/misc.cpp
|
frontend/A32/translate/translate_arm/misc.cpp
|
||||||
frontend/A32/translate/translate_arm/multiply.cpp
|
frontend/A32/translate/translate_arm/multiply.cpp
|
||||||
|
|
|
@ -157,6 +157,13 @@ bool ArmTranslatorVisitor::UndefinedInstruction() {
|
||||||
return false;
|
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) {
|
IR::ResultAndCarry<IR::U32> ArmTranslatorVisitor::EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in) {
|
||||||
u8 imm5_value = imm5.ZeroExtend<u8>();
|
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 {
|
namespace Dynarmic::A32 {
|
||||||
|
|
||||||
|
enum class Exception;
|
||||||
|
|
||||||
enum class ConditionalState {
|
enum class ConditionalState {
|
||||||
/// We haven't met any conditional instructions yet.
|
/// We haven't met any conditional instructions yet.
|
||||||
None,
|
None,
|
||||||
|
@ -40,6 +42,7 @@ struct ArmTranslatorVisitor final {
|
||||||
bool InterpretThisInstruction();
|
bool InterpretThisInstruction();
|
||||||
bool UnpredictableInstruction();
|
bool UnpredictableInstruction();
|
||||||
bool UndefinedInstruction();
|
bool UndefinedInstruction();
|
||||||
|
bool RaiseException(Exception exception);
|
||||||
|
|
||||||
static u32 ArmExpandImm(int rotate, Imm<8> imm8) {
|
static u32 ArmExpandImm(int rotate, Imm<8> imm8) {
|
||||||
return Common::RotateRight<u32>(imm8.ZeroExtend(), rotate * 2);
|
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);
|
bool arm_UXTH(Cond cond, Reg d, SignExtendRotation rotate, Reg m);
|
||||||
|
|
||||||
// Hint instructions
|
// Hint instructions
|
||||||
bool arm_PLD() { return true; }
|
bool arm_PLD();
|
||||||
bool arm_SEV() { return true; }
|
bool arm_SEV();
|
||||||
bool arm_WFE() { return true; }
|
bool arm_WFE();
|
||||||
bool arm_WFI() { return true; }
|
bool arm_WFI();
|
||||||
bool arm_YIELD() { return true; }
|
bool arm_YIELD();
|
||||||
|
|
||||||
// Load/Store
|
// Load/Store
|
||||||
bool arm_LDRBT();
|
bool arm_LDRBT();
|
||||||
|
|
Loading…
Add table
Reference in a new issue