From 9d1bc6ecc28ea7a7dde8af937ce3b328e1bbee98 Mon Sep 17 00:00:00 2001 From: kynex7510 <48837309+kynex7510@users.noreply.github.com> Date: Thu, 16 Nov 2023 23:23:27 +0100 Subject: [PATCH] A32: Introduce PreCodeReadHook (#763) * A32: Introduce PreCodeReadHook * A32: Invert code read hook return value --- src/dynarmic/frontend/A32/translate/translate_arm.cpp | 5 +++++ src/dynarmic/frontend/A32/translate/translate_callbacks.h | 8 +++++++- src/dynarmic/frontend/A32/translate/translate_thumb.cpp | 5 +++++ src/dynarmic/interface/A32/config.h | 6 ++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/dynarmic/frontend/A32/translate/translate_arm.cpp b/src/dynarmic/frontend/A32/translate/translate_arm.cpp index 3ee908fc..24b5797d 100644 --- a/src/dynarmic/frontend/A32/translate/translate_arm.cpp +++ b/src/dynarmic/frontend/A32/translate/translate_arm.cpp @@ -30,6 +30,11 @@ IR::Block TranslateArm(LocationDescriptor descriptor, TranslateCallbacks* tcb, c const u32 arm_pc = visitor.ir.current_location.PC(); u64 ticks_for_instruction = 1; + if (!tcb->PreCodeReadHook(false, arm_pc, visitor.ir)) { + should_continue = false; + break; + } + if (const auto arm_instruction = tcb->MemoryReadCode(arm_pc)) { visitor.current_instruction_size = 4; diff --git a/src/dynarmic/frontend/A32/translate/translate_callbacks.h b/src/dynarmic/frontend/A32/translate/translate_callbacks.h index aab01853..e0ad48ea 100644 --- a/src/dynarmic/frontend/A32/translate/translate_callbacks.h +++ b/src/dynarmic/frontend/A32/translate/translate_callbacks.h @@ -18,7 +18,13 @@ struct TranslateCallbacks { // Memory must be interpreted as little endian. virtual std::optional MemoryReadCode(VAddr vaddr) = 0; - // Thus function is called before the instruction at pc is interpreted. + // This function is called before the instruction at pc is read. + // IR code can be emitted by the callee prior to instruction handling. + // By returning false the callee precludes the translation of the instruction; + // in such case the callee is responsible for setting the terminal. + virtual bool PreCodeReadHook(bool is_thumb, VAddr pc, A32::IREmitter& ir) = 0; + + // This function is called before the instruction at pc is interpreted. // IR code can be emitted by the callee prior to translation of the instruction. virtual void PreCodeTranslationHook(bool is_thumb, VAddr pc, A32::IREmitter& ir) = 0; diff --git a/src/dynarmic/frontend/A32/translate/translate_thumb.cpp b/src/dynarmic/frontend/A32/translate/translate_thumb.cpp index 845a0679..d61d8ccb 100644 --- a/src/dynarmic/frontend/A32/translate/translate_thumb.cpp +++ b/src/dynarmic/frontend/A32/translate/translate_thumb.cpp @@ -111,6 +111,11 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, TranslateCallbacks* tcb, const u32 arm_pc = visitor.ir.current_location.PC(); u64 ticks_for_instruction = 1; + if (!tcb->PreCodeReadHook(true, arm_pc, visitor.ir)) { + should_continue = false; + break; + } + if (const auto maybe_instruction = ReadThumbInstruction(arm_pc, tcb)) { const auto [thumb_instruction, inst_size] = *maybe_instruction; const bool is_thumb_16 = inst_size == ThumbInstSize::Thumb16; diff --git a/src/dynarmic/interface/A32/config.h b/src/dynarmic/interface/A32/config.h index a7b194ab..a3c2aa15 100644 --- a/src/dynarmic/interface/A32/config.h +++ b/src/dynarmic/interface/A32/config.h @@ -65,6 +65,12 @@ struct UserCallbacks : public TranslateCallbacks { // Memory must be interpreted as little endian. std::optional MemoryReadCode(VAddr vaddr) override { return MemoryRead32(vaddr); } + // This function is called before the instruction at pc is read. + // IR code can be emitted by the callee prior to instruction handling. + // By returning true the callee precludes the translation of the instruction; + // in such case the callee is responsible for setting the terminal. + bool PreCodeReadHook(bool /*is_thumb*/, VAddr /*pc*/, A32::IREmitter& /*ir*/) override { return true; } + // Thus function is called before the instruction at pc is interpreted. // IR code can be emitted by the callee prior to translation of the instruction. void PreCodeTranslationHook(bool /*is_thumb*/, VAddr /*pc*/, A32::IREmitter& /*ir*/) override {}