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:
Lioncash 2019-05-01 21:54:39 -04:00 committed by MerryMage
parent dd79a3dc6b
commit 966e04d03d
5 changed files with 58 additions and 5 deletions

View file

@ -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.

View file

@ -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

View file

@ -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>();

View 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

View file

@ -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();