diff --git a/include/dynarmic/A64/config.h b/include/dynarmic/A64/config.h index 2efc238c..e1fd2f45 100644 --- a/include/dynarmic/A64/config.h +++ b/include/dynarmic/A64/config.h @@ -28,17 +28,17 @@ enum class Exception { /// This behaviour is up to the user of this library to define. /// Note: Constraints on unpredictable behaviour are specified in the ARMv8 ARM. UnpredictableInstruction, - /// A WFI instruction was executed. You may now enter a low-power state. + /// A WFI instruction was executed. You may now enter a low-power state. (Hint instruction.) WaitForInterrupt, - /// A WFE instruction was executed. You may now enter a low-power state if the event register is clear. + /// A WFE instruction was executed. You may now enter a low-power state if the event register is clear. (Hint instruction.) WaitForEvent, - /// A SEV instruction was executed. The event register of all PEs should be set. + /// A SEV instruction was executed. The event register of all PEs should be set. (Hint instruction.) SendEvent, - /// A SEVL instruction was executed. The event register of the current PE should be set. + /// A SEVL instruction was executed. The event register of the current PE should be set. (Hint instruction.) SendEventLocal, - /// A YIELD instruction was executed. + /// A YIELD instruction was executed. (Hint instruction.) Yield, - /// A BRK instruction was executed. + /// A BRK instruction was executed. (Hint instruction.) Breakpoint, }; @@ -122,6 +122,10 @@ struct UserConfig { /// Executing DC ZVA in this mode will result in zeros being written to memory. bool hook_data_cache_operations = false; + /// When set to true, UserCallbacks::ExceptionRaised will be called when any hint + /// instruction is executed. + bool hook_hint_instructions = false; + /// Counter-timer frequency register. The value of the register is not interpreted by /// dynarmic. std::uint32_t cntfrq_el0 = 600000000; diff --git a/src/frontend/A64/translate/impl/system.cpp b/src/frontend/A64/translate/impl/system.cpp index 281ff1c8..de3c1b9e 100644 --- a/src/frontend/A64/translate/impl/system.cpp +++ b/src/frontend/A64/translate/impl/system.cpp @@ -37,22 +37,37 @@ bool TranslatorVisitor::NOP() { } bool TranslatorVisitor::YIELD() { + if (!options.hook_hint_instructions) { + return true; + } return RaiseException(Exception::Yield); } bool TranslatorVisitor::WFE() { + if (!options.hook_hint_instructions) { + return true; + } return RaiseException(Exception::WaitForEvent); } bool TranslatorVisitor::WFI() { + if (!options.hook_hint_instructions) { + return true; + } return RaiseException(Exception::WaitForInterrupt); } bool TranslatorVisitor::SEV() { + if (!options.hook_hint_instructions) { + return true; + } return RaiseException(Exception::SendEvent); } bool TranslatorVisitor::SEVL() { + if (!options.hook_hint_instructions) { + return true; + } return RaiseException(Exception::SendEventLocal); } diff --git a/src/frontend/A64/translate/translate.h b/src/frontend/A64/translate/translate.h index 8d5158d8..af5dc55f 100644 --- a/src/frontend/A64/translate/translate.h +++ b/src/frontend/A64/translate/translate.h @@ -26,6 +26,11 @@ struct TranslationOptions { /// If this is false, the ExceptionRaised IR instruction is emitted. /// If this is true, we define some behaviour for some instructions. bool define_unpredictable_behaviour = false; + + /// This changes what IR we emit when we translate a hint instruction. + /// If this is false, we treat the instruction as a NOP. + /// If this is true, we emit an ExceptionRaised instruction. + bool hook_hint_instructions = true; }; /**