diff --git a/include/dynarmic/A32/a32.h b/include/dynarmic/A32/a32.h index aeaa8e03..046cd161 100644 --- a/include/dynarmic/A32/a32.h +++ b/include/dynarmic/A32/a32.h @@ -59,6 +59,16 @@ public: */ void HaltExecution(); + /** + * HACK: + * Exits execution from a callback, the callback must rewind the stack or + * never return to dynarmic from it's current stack. + */ + void ExceptionalExit(); + + /// HACK: Change processor ID. + void ChangeProcessorID(std::size_t new_processor); + /// View and modify registers. std::array& Regs(); const std::array& Regs() const; diff --git a/include/dynarmic/A32/config.h b/include/dynarmic/A32/config.h index 2a616d91..6d96c5a4 100644 --- a/include/dynarmic/A32/config.h +++ b/include/dynarmic/A32/config.h @@ -139,6 +139,11 @@ struct UserConfig { /// definite behaviour for some unpredictable instructions. bool define_unpredictable_behaviour = false; + /// HACK: + /// This tells the translator a wall clock will be used, thus allowing it + /// to avoid writting certain unnecessary code only needed for cycle timers. + bool wall_clock_cntpct = false; + /// This enables the fast dispatcher. bool enable_fast_dispatch = true; diff --git a/include/dynarmic/A64/a64.h b/include/dynarmic/A64/a64.h index 2e9fe15a..83aa536e 100644 --- a/include/dynarmic/A64/a64.h +++ b/include/dynarmic/A64/a64.h @@ -61,11 +61,15 @@ public: void HaltExecution(); /** + * HACK: * Exits execution from a callback, the callback must rewind the stack or * never return to dynarmic from it's current stack. */ void ExceptionalExit(); + /// HACK: Change processor ID. + void ChangeProcessorID(std::size_t new_processor); + /// Read Stack Pointer std::uint64_t GetSP() const; /// Modify Stack Pointer @@ -111,8 +115,6 @@ public: /// Modify PSTATE void SetPstate(std::uint32_t value); - void ChangeProcessorID(std::size_t new_processor); - /// Clears exclusive state for this core. void ClearExclusiveState(); diff --git a/include/dynarmic/A64/config.h b/include/dynarmic/A64/config.h index 3905eb88..e3c3de26 100644 --- a/include/dynarmic/A64/config.h +++ b/include/dynarmic/A64/config.h @@ -194,12 +194,12 @@ struct UserConfig { /// page boundary. bool only_detect_misalignment_via_page_table_on_page_boundary = false; - /// This option relates to translation. Generally when we run into an unpredictable /// instruction the ExceptionRaised callback is called. If this is true, we define /// definite behaviour for some unpredictable instructions. bool define_unpredictable_behaviour = false; + /// HACK: /// This tells the translator a wall clock will be used, thus allowing it /// to avoid writting certain unnecessary code only needed for cycle timers. bool wall_clock_cntpct = false; diff --git a/src/backend/x64/a32_emit_x64.h b/src/backend/x64/a32_emit_x64.h index 69e57faf..a86f26ce 100644 --- a/src/backend/x64/a32_emit_x64.h +++ b/src/backend/x64/a32_emit_x64.h @@ -47,8 +47,12 @@ public: void InvalidateCacheRanges(const boost::icl::interval_set& ranges); + void ChangeProcessorID(size_t value) { + conf.processor_id = value; + } + protected: - const A32::UserConfig conf; + A32::UserConfig conf; A32::Jit* jit_interface; BlockRangeInformation block_ranges; diff --git a/src/backend/x64/a32_interface.cpp b/src/backend/x64/a32_interface.cpp index 5743e88e..24eb3612 100644 --- a/src/backend/x64/a32_interface.cpp +++ b/src/backend/x64/a32_interface.cpp @@ -63,7 +63,7 @@ struct Jit::Impl { BlockOfCode block_of_code; A32EmitX64 emitter; - const A32::UserConfig conf; + A32::UserConfig conf; // Requests made during execution to invalidate the cache are queued up here. size_t invalid_cache_generation = 0; @@ -89,6 +89,19 @@ struct Jit::Impl { block_of_code.StepCode(&jit_state, GetCurrentSingleStep()); } + void ExceptionalExit() { + if (!conf.wall_clock_cntpct) { + const s64 ticks = jit_state.cycles_to_run - jit_state.cycles_remaining; + conf.callbacks->AddTicks(ticks); + } + PerformCacheInvalidation(); + } + + void ChangeProcessorID(size_t value) { + conf.processor_id = value; + emitter.ChangeProcessorID(value); + } + std::string Disassemble(const IR::LocationDescriptor& descriptor) { auto block = GetBasicBlock(descriptor); std::string result = fmt::format("address: {}\nsize: {} bytes\n", block.entrypoint, block.size); @@ -218,6 +231,15 @@ void Jit::HaltExecution() { impl->jit_state.halt_requested = true; } +void Jit::ExceptionalExit() { + impl->ExceptionalExit(); + is_executing = false; +} + +void Jit::ChangeProcessorID(size_t new_processor) { + impl->ChangeProcessorID(new_processor); +} + std::array& Jit::Regs() { return impl->jit_state.Reg; } diff --git a/src/backend/x64/a64_interface.cpp b/src/backend/x64/a64_interface.cpp index 05a76478..b3d8ceea 100644 --- a/src/backend/x64/a64_interface.cpp +++ b/src/backend/x64/a64_interface.cpp @@ -92,6 +92,11 @@ public: is_executing = false; } + void ChangeProcessorID(size_t value) { + conf.processor_id = value; + emitter.ChangeProcessorID(value); + } + void ClearCache() { invalidate_entire_cache = true; RequestCacheInvalidation(); @@ -194,11 +199,6 @@ public: jit_state.SetPstate(value); } - void ChangeProcessorID(size_t value) { - conf.processor_id = value; - emitter.ChangeProcessorID(value); - } - void ClearExclusiveState() { jit_state.exclusive_state = 0; } @@ -326,6 +326,10 @@ void Jit::ExceptionalExit() { impl->ExceptionalExit(); } +void Jit::ChangeProcessorID(size_t new_processor) { + impl->ChangeProcessorID(new_processor); +} + u64 Jit::GetSP() const { return impl->GetSP(); } @@ -398,10 +402,6 @@ void Jit::SetPstate(u32 value) { impl->SetPstate(value); } -void Jit::ChangeProcessorID(size_t new_processor) { - impl->ChangeProcessorID(new_processor); -} - void Jit::ClearExclusiveState() { impl->ClearExclusiveState(); }