diff options
author | kynex7510 <[email protected]> | 2023-11-16 23:23:27 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2023-11-16 22:23:27 +0000 |
commit | 9d1bc6ecc28ea7a7dde8af937ce3b328e1bbee98 (patch) | |
tree | 5ed3cb58667866241ff2104eef483fc7170f0593 | |
parent | 0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378 (diff) | |
download | dynarmic-9d1bc6ecc28ea7a7dde8af937ce3b328e1bbee98.tar.gz dynarmic-9d1bc6ecc28ea7a7dde8af937ce3b328e1bbee98.zip |
A32: Introduce PreCodeReadHook (#763)
* A32: Introduce PreCodeReadHook
* A32: Invert code read hook return value
4 files changed, 23 insertions, 1 deletions
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<std::uint32_t> 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<std::uint32_t> 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 {} |