From 02c8b434c72466c7186f25fd4b0619e5d0eff960 Mon Sep 17 00:00:00 2001 From: Liam Date: Sat, 25 Jun 2022 14:51:19 -0400 Subject: [PATCH] interface: allow clear of previously-signaled halt --- src/dynarmic/backend/x64/a32_interface.cpp | 8 ++++++++ src/dynarmic/backend/x64/a64_interface.cpp | 8 ++++++++ src/dynarmic/common/atomic.h | 8 ++++++++ src/dynarmic/interface/A32/a32.h | 7 ++++++- src/dynarmic/interface/A64/a64.h | 7 ++++++- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/dynarmic/backend/x64/a32_interface.cpp b/src/dynarmic/backend/x64/a32_interface.cpp index 9d64c702..6d2bf610 100644 --- a/src/dynarmic/backend/x64/a32_interface.cpp +++ b/src/dynarmic/backend/x64/a32_interface.cpp @@ -101,6 +101,10 @@ struct Jit::Impl { Atomic::Or(&jit_state.halt_reason, static_cast(hr)); } + void ClearHalt(HaltReason hr) { + Atomic::And(&jit_state.halt_reason, ~static_cast(hr)); + } + void ClearExclusiveState() { jit_state.exclusive_state = 0; } @@ -232,6 +236,10 @@ void Jit::HaltExecution(HaltReason hr) { impl->HaltExecution(hr); } +void Jit::ClearHalt(HaltReason hr) { + impl->ClearHalt(hr); +} + void Jit::ClearExclusiveState() { impl->ClearExclusiveState(); } diff --git a/src/dynarmic/backend/x64/a64_interface.cpp b/src/dynarmic/backend/x64/a64_interface.cpp index 80f30ef0..fcc289b1 100644 --- a/src/dynarmic/backend/x64/a64_interface.cpp +++ b/src/dynarmic/backend/x64/a64_interface.cpp @@ -134,6 +134,10 @@ public: Atomic::Or(&jit_state.halt_reason, static_cast(hr)); } + void ClearHalt(HaltReason hr) { + Atomic::And(&jit_state.halt_reason, ~static_cast(hr)); + } + u64 GetSP() const { return jit_state.sp; } @@ -351,6 +355,10 @@ void Jit::HaltExecution(HaltReason hr) { impl->HaltExecution(hr); } +void Jit::ClearHalt(HaltReason hr) { + impl->ClearHalt(hr); +} + u64 Jit::GetSP() const { return impl->GetSP(); } diff --git a/src/dynarmic/common/atomic.h b/src/dynarmic/common/atomic.h index 8be5fc44..7a27d928 100644 --- a/src/dynarmic/common/atomic.h +++ b/src/dynarmic/common/atomic.h @@ -17,4 +17,12 @@ inline void Or(volatile u32* ptr, u32 value) { #endif } +inline void And(volatile u32* ptr, u32 value) { +#ifdef _MSC_VER + _InterlockedAnd(reinterpret_cast(ptr), value); +#else + __atomic_and_fetch(ptr, value, __ATOMIC_SEQ_CST); +#endif +} + } // namespace Dynarmic::Atomic diff --git a/src/dynarmic/interface/A32/a32.h b/src/dynarmic/interface/A32/a32.h index 48a5c342..e65d1a3a 100644 --- a/src/dynarmic/interface/A32/a32.h +++ b/src/dynarmic/interface/A32/a32.h @@ -57,10 +57,15 @@ public: /** * Stops execution in Jit::Run. - * Can only be called from a callback. */ void HaltExecution(HaltReason hr = HaltReason::UserDefined1); + /** + * Clears a halt reason from flags. + * Warning: Only use this if you're sure this won't introduce races. + */ + void ClearHalt(HaltReason hr = HaltReason::UserDefined1); + /// View and modify registers. std::array& Regs(); const std::array& Regs() const; diff --git a/src/dynarmic/interface/A64/a64.h b/src/dynarmic/interface/A64/a64.h index b5e008ce..f2c7055b 100644 --- a/src/dynarmic/interface/A64/a64.h +++ b/src/dynarmic/interface/A64/a64.h @@ -58,10 +58,15 @@ public: /** * Stops execution in Jit::Run. - * Can only be called from a callback. */ void HaltExecution(HaltReason hr = HaltReason::UserDefined1); + /** + * Clears a halt reason from flags. + * Warning: Only use this if you're sure this won't introduce races. + */ + void ClearHalt(HaltReason hr = HaltReason::UserDefined1); + /// Read Stack Pointer std::uint64_t GetSP() const; /// Modify Stack Pointer