From 966e04d03d52065145d0fa816dd3a4c06d89e584 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 1 May 2019 21:54:39 -0400 Subject: [PATCH] A32: Allow hooking of hint instructions in ARM mode. Mirrors the hooking functionality from the AArch64 frontend to make the behavior of both consistent. --- include/dynarmic/A32/config.h | 10 ++++++ src/CMakeLists.txt | 1 + src/frontend/A32/translate/translate_arm.cpp | 7 ++++ .../A32/translate/translate_arm/hint.cpp | 32 +++++++++++++++++++ .../translate/translate_arm/translate_arm.h | 13 +++++--- 5 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 src/frontend/A32/translate/translate_arm/hint.cpp diff --git a/include/dynarmic/A32/config.h b/include/dynarmic/A32/config.h index 5e18e408..49a569dd 100644 --- a/include/dynarmic/A32/config.h +++ b/include/dynarmic/A32/config.h @@ -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. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 44126f72..b076fa8c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/frontend/A32/translate/translate_arm.cpp b/src/frontend/A32/translate/translate_arm.cpp index 913a297b..bca2b9e6 100644 --- a/src/frontend/A32/translate/translate_arm.cpp +++ b/src/frontend/A32/translate/translate_arm.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 ArmTranslatorVisitor::EmitImmShift(IR::U32 value, ShiftType type, Imm<5> imm5, IR::U1 carry_in) { u8 imm5_value = imm5.ZeroExtend(); diff --git a/src/frontend/A32/translate/translate_arm/hint.cpp b/src/frontend/A32/translate/translate_arm/hint.cpp new file mode 100644 index 00000000..8d78ed60 --- /dev/null +++ b/src/frontend/A32/translate/translate_arm/hint.cpp @@ -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 +#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 diff --git a/src/frontend/A32/translate/translate_arm/translate_arm.h b/src/frontend/A32/translate/translate_arm/translate_arm.h index 0a1160b9..049a2062 100644 --- a/src/frontend/A32/translate/translate_arm/translate_arm.h +++ b/src/frontend/A32/translate/translate_arm/translate_arm.h @@ -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(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();