diff --git a/FEXCore/Source/Interface/Context/Context.h b/FEXCore/Source/Interface/Context/Context.h index 12228cbcc..7574cb098 100644 --- a/FEXCore/Source/Interface/Context/Context.h +++ b/FEXCore/Source/Interface/Context/Context.h @@ -216,6 +216,9 @@ namespace FEXCore::Context { // this is for internal use bool ValidateIRarser { false }; + // Used if the JIT needs to have its interrupt fault code emitted. + bool NeedsPendingInterruptFaultCheck { false }; + FEX_CONFIG_OPT(Multiblock, MULTIBLOCK); FEX_CONFIG_OPT(SingleStepConfig, SINGLESTEP); FEX_CONFIG_OPT(GdbServer, GDBSERVER); diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index ab6d7b852..aac04da0f 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -368,6 +368,9 @@ namespace FEXCore::Context { #ifndef _WIN32 ThunkHandler = FEXCore::ThunkHandler::Create(); +#else + // WIN32 always needs the interrupt fault check to be enabled. + Config.NeedsPendingInterruptFaultCheck = true; #endif using namespace FEXCore::Core; @@ -1084,7 +1087,7 @@ namespace FEXCore::Context { // FEX currently throws away the CPUBackend::CompiledCode object other than the entrypoint // In the future with code caching getting wired up, we will pass the rest of the data forward. // TODO: Pass the data forward when code caching is wired up to this. - .CompiledCode = Thread->CPUBackend->CompileCode(GuestRIP, IRList, DebugData, RAData.get(), GetGdbServerStatus()).BlockEntry, + .CompiledCode = Thread->CPUBackend->CompileCode(GuestRIP, IRList, DebugData, RAData.get()).BlockEntry, .IRData = IRList, .DebugData = DebugData, .RAData = std::move(RAData), diff --git a/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp b/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp index 8c5d83061..0c296de84 100644 --- a/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp +++ b/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp @@ -549,40 +549,6 @@ void Dispatcher::ExecuteJITCallback(FEXCore::Core::CpuStateFrame *Frame, uint64_ #endif -size_t Dispatcher::GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestRIP) { - FEXCore::ARMEmitter::Emitter emit{CodeBuffer, MaxGDBPauseCheckSize}; - - ARMEmitter::ForwardLabel RunBlock; - - // If we have a gdb server running then run in a less efficient mode that checks if we need to exit - // This happens when single stepping - - static_assert(sizeof(FEXCore::Context::ContextImpl::Config.RunningMode) == 4, "This is expected to be size of 4"); - emit.ldr(ARMEmitter::XReg::x0, STATE_PTR(CpuStateFrame, Thread)); - emit.ldr(ARMEmitter::XReg::x0, ARMEmitter::Reg::r0, offsetof(FEXCore::Core::InternalThreadState, CTX)); // Get Context - emit.ldr(ARMEmitter::WReg::w0, ARMEmitter::Reg::r0, offsetof(FEXCore::Context::ContextImpl, Config.RunningMode)); - - // If the value == 0 then we don't need to stop - emit.cbz(ARMEmitter::Size::i32Bit, ARMEmitter::Reg::r0, &RunBlock); - { - ARMEmitter::ForwardLabel l_GuestRIP; - // Make sure RIP is syncronized to the context - emit.ldr(ARMEmitter::XReg::x0, &l_GuestRIP); - emit.str(ARMEmitter::XReg::x0, STATE_PTR(CpuStateFrame, State.rip)); - - // Stop the thread - emit.ldr(ARMEmitter::XReg::x0, STATE_PTR(CpuStateFrame, Pointers.Common.ThreadPauseHandlerSpillSRA)); - emit.br(ARMEmitter::Reg::r0); - emit.Bind(&l_GuestRIP); - emit.dc64(GuestRIP); - } - emit.Bind(&RunBlock); - - auto UsedBytes = emit.GetCursorOffset(); - emit.ClearICache(CodeBuffer, UsedBytes); - return UsedBytes; -} - void Dispatcher::InitThreadPointers(FEXCore::Core::InternalThreadState *Thread) { // Setup dispatcher specific pointers that need to be accessed from JIT code { diff --git a/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h b/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h index 9bbc6efdc..c7056ec57 100644 --- a/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h +++ b/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h @@ -71,11 +71,6 @@ public: void InitThreadPointers(FEXCore::Core::InternalThreadState *Thread); - // These are across all arches for now - static constexpr size_t MaxGDBPauseCheckSize = 128; - - size_t GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestRIP); - #ifdef VIXL_SIMULATOR void ExecuteDispatch(FEXCore::Core::CpuStateFrame *Frame) ; void ExecuteJITCallback(FEXCore::Core::CpuStateFrame *Frame, uint64_t RIP); diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index 23480c345..7df56dff2 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -689,8 +689,7 @@ bool Arm64JITCore::IsGPRPair(IR::NodeID Node) const { CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, FEXCore::IR::IRListView const *IR, FEXCore::Core::DebugData *DebugData, - FEXCore::IR::RegisterAllocationData *RAData, - bool GDBEnabled) { + FEXCore::IR::RegisterAllocationData *RAData) { FEXCORE_PROFILE_SCOPED("Arm64::CompileCode"); JumpTargets.clear(); @@ -702,7 +701,7 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, this->IR = IR; // Fairly excessive buffer range to make sure we don't overflow - uint32_t BufferRange = SSACount * 16 + GDBEnabled * Dispatcher::MaxGDBPauseCheckSize; + uint32_t BufferRange = SSACount * 16; if ((GetCursorOffset() + BufferRange) > CurrentCodeBuffer->Size) { CTX->ClearCodeCache(ThreadState); } @@ -746,16 +745,11 @@ CPUBackend::CompiledCode Arm64JITCore::CompileCode(uint64_t Entry, adr(TMP1, &JITCodeHeaderLabel); str(TMP1, STATE, offsetof(FEXCore::Core::CPUState, InlineJITBlockHeader)); -#ifdef _WIN32 - // Trigger a fault if there are any pending interrupts - // Used only for suspend on WIN32 at the moment - strb(ARMEmitter::XReg::zr, STATE, offsetof(FEXCore::Core::InternalThreadState, InterruptFaultPage) - - offsetof(FEXCore::Core::InternalThreadState, BaseFrameState)); -#endif - - if (GDBEnabled) { - auto GDBSize = CTX->Dispatcher->GenerateGDBPauseCheck(CodeData.BlockEntry, Entry); - CursorIncrement(GDBSize); + if (CTX->Config.NeedsPendingInterruptFaultCheck) { + // Trigger a fault if there are any pending interrupts + // Used only for suspend on WIN32 at the moment + strb(ARMEmitter::XReg::zr, STATE, offsetof(FEXCore::Core::InternalThreadState, InterruptFaultPage) - + offsetof(FEXCore::Core::InternalThreadState, BaseFrameState)); } //LOGMAN_THROW_A_FMT(RAData->HasFullRA(), "Arm64 JIT only works with RA"); diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index 2926255f3..63ebc6c6c 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -44,7 +44,7 @@ public: [[nodiscard]] CPUBackend::CompiledCode CompileCode(uint64_t Entry, FEXCore::IR::IRListView const *IR, FEXCore::Core::DebugData *DebugData, - FEXCore::IR::RegisterAllocationData *RAData, bool GDBEnabled) override; + FEXCore::IR::RegisterAllocationData *RAData) override; [[nodiscard]] void *MapRegion(void* HostPtr, uint64_t, uint64_t) override { return HostPtr; } diff --git a/FEXCore/include/FEXCore/Core/CPUBackend.h b/FEXCore/include/FEXCore/Core/CPUBackend.h index 9d36efb22..42fae4fdf 100644 --- a/FEXCore/include/FEXCore/Core/CPUBackend.h +++ b/FEXCore/include/FEXCore/Core/CPUBackend.h @@ -136,7 +136,7 @@ namespace CPU { [[nodiscard]] virtual CompiledCode CompileCode(uint64_t Entry, FEXCore::IR::IRListView const *IR, FEXCore::Core::DebugData *DebugData, - FEXCore::IR::RegisterAllocationData *RAData, bool GDBEnabled) = 0; + FEXCore::IR::RegisterAllocationData *RAData) = 0; /** * @brief Relocates a block of code from the JIT code object cache