diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index 46cedca69b..8844cf5935 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -321,8 +321,6 @@ bool ContextImpl::InitCore() { // Set up the SignalDelegator config since core is initialized. FEXCore::SignalDelegator::SignalDelegatorConfig SignalConfig { - .SupportsAVX = HostFeatures.SupportsAVX, - .DispatcherBegin = Dispatcher->Start, .DispatcherEnd = Dispatcher->End, diff --git a/FEXCore/include/FEXCore/Core/SignalDelegator.h b/FEXCore/include/FEXCore/Core/SignalDelegator.h index f33d1dd423..315da6a9e6 100644 --- a/FEXCore/include/FEXCore/Core/SignalDelegator.h +++ b/FEXCore/include/FEXCore/Core/SignalDelegator.h @@ -40,8 +40,6 @@ class SignalDelegator { virtual ~SignalDelegator() = default; struct SignalDelegatorConfig { - bool SupportsAVX {}; - // Dispatcher information uint64_t DispatcherBegin; uint64_t DispatcherEnd; diff --git a/Source/Tools/FEXLoader/FEXLoader.cpp b/Source/Tools/FEXLoader/FEXLoader.cpp index 8a0b45b6a0..2c590aa1c4 100644 --- a/Source/Tools/FEXLoader/FEXLoader.cpp +++ b/Source/Tools/FEXLoader/FEXLoader.cpp @@ -498,16 +498,18 @@ int main(int argc, char** argv, char** const envp) { // System allocator is now system allocator or FEX FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT); + bool SupportsAVX {}; fextl::unique_ptr CTX; { auto HostFeatures = FEX::FetchHostFeatures(); CTX = FEXCore::Context::Context::CreateNewContext(HostFeatures); + SupportsAVX = HostFeatures.SupportsAVX; } // Setup TSO hardware emulation immediately after initializing the context. FEX::TSO::SetupTSOEmulation(CTX.get()); - auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), Program.ProgramName); + auto SignalDelegation = FEX::HLE::CreateSignalDelegator(CTX.get(), Program.ProgramName, SupportsAVX); auto SyscallHandler = Loader.Is64BitMode() ? FEX::HLE::x64::CreateHandler(CTX.get(), SignalDelegation.get()) : FEX::HLE::x32::CreateHandler(CTX.get(), SignalDelegation.get(), std::move(Allocator)); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp index 6863034127..a19e07d58e 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp @@ -118,7 +118,7 @@ void SignalDelegator::SpillSRA(FEXCore::Core::InternalThreadState* Thread, void* Thread->CurrentFrame->State.gregs[i] = ArchHelpers::Context::GetArmReg(ucontext, SRAIdxMap); } - if (Config.SupportsAVX) { + if (SupportsAVX) { // TODO: This doesn't save the upper 128-bits of the 256-bit registers. // This needs to be implemented still. for (size_t i = 0; i < Config.SRAFPRCount; i++) { @@ -178,8 +178,6 @@ ArchHelpers::Context::ContextBackup* SignalDelegator::StoreThreadState(FEXCore:: } void SignalDelegator::RestoreThreadState(FEXCore::Core::InternalThreadState* Thread, void* ucontext, RestoreType Type) { - const bool IsAVXEnabled = Config.SupportsAVX; - uint64_t OldSP {}; if (Type == RestoreType::TYPE_PAUSE) [[unlikely]] { OldSP = ArchHelpers::Context::GetSp(ucontext); @@ -203,7 +201,7 @@ void SignalDelegator::RestoreThreadState(FEXCore::Core::InternalThreadState* Thr GuestSP += sizeof(siginfo_t); GuestSP = FEXCore::AlignUp(GuestSP, alignof(siginfo_t)); - if (IsAVXEnabled) { + if (SupportsAVX) { GuestSP += sizeof(FEXCore::x86_64::xstate); GuestSP = FEXCore::AlignUp(GuestSP, alignof(FEXCore::x86_64::xstate)); } else { @@ -221,7 +219,7 @@ void SignalDelegator::RestoreThreadState(FEXCore::Core::InternalThreadState* Thr GuestSP += sizeof(SigFrame_i32) - 8; GuestSP = FEXCore::AlignUp(GuestSP, alignof(SigFrame_i32)); - if (IsAVXEnabled) { + if (SupportsAVX) { GuestSP += sizeof(FEXCore::x86::xstate); GuestSP = FEXCore::AlignUp(GuestSP, alignof(FEXCore::x86::xstate)); } else { @@ -238,7 +236,7 @@ void SignalDelegator::RestoreThreadState(FEXCore::Core::InternalThreadState* Thr GuestSP += sizeof(RTSigFrame_i32) - 4; GuestSP = FEXCore::AlignUp(GuestSP, alignof(RTSigFrame_i32)); - if (IsAVXEnabled) { + if (SupportsAVX) { GuestSP += sizeof(FEXCore::x86::xstate); GuestSP = FEXCore::AlignUp(GuestSP, alignof(FEXCore::x86::xstate)); } else { @@ -833,9 +831,10 @@ void SignalDelegator::QueueSignal(pid_t tgid, pid_t tid, int Signal, siginfo_t* } } -SignalDelegator::SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName) +SignalDelegator::SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName, bool SupportsAVX) : CTX {_CTX} - , ApplicationName {ApplicationName} { + , ApplicationName {ApplicationName} + , SupportsAVX {SupportsAVX} { // Signal zero isn't real HostHandlers[0].Installed = true; @@ -1295,7 +1294,8 @@ uint64_t SignalDelegator::GuestSignalFD(int fd, const uint64_t* set, size_t sigs return Result == -1 ? -errno : Result; } -fextl::unique_ptr CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName) { - return fextl::make_unique(CTX, ApplicationName); +fextl::unique_ptr +CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName, bool SupportsAVX) { + return fextl::make_unique(CTX, ApplicationName, SupportsAVX); } } // namespace FEX::HLE diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h index ac6cd02429..8541b789a7 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h @@ -50,7 +50,7 @@ class SignalDelegator final : public FEXCore::SignalDelegator, public FEXCore::A // Returns true if the host handled the signal // Arguments are the same as sigaction handler - SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName); + SignalDelegator(FEXCore::Context::Context* _CTX, const std::string_view ApplicationName, bool SupportsAVX); ~SignalDelegator() override; // Called from the signal trampoline function. @@ -274,7 +274,9 @@ class SignalDelegator final : public FEXCore::SignalDelegator, public FEXCore::A std::mutex HostDelegatorMutex; std::mutex GuestDelegatorMutex; + bool SupportsAVX; }; -fextl::unique_ptr CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName); +fextl::unique_ptr +CreateSignalDelegator(FEXCore::Context::Context* CTX, const std::string_view ApplicationName, bool SupportsAVX); } // namespace FEX::HLE diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator/GuestFramesManagement.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator/GuestFramesManagement.cpp index 3b32cd5cfe..01cd8a68a6 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator/GuestFramesManagement.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator/GuestFramesManagement.cpp @@ -110,8 +110,6 @@ static void SetXStateInfo(T* xstate, bool is_avx_enabled) { void SignalDelegator::RestoreFrame_x64(FEXCore::Core::InternalThreadState* Thread, ArchHelpers::Context::ContextBackup* Context, FEXCore::Core::CpuStateFrame* Frame, void* ucontext) { - const bool IsAVXEnabled = Config.SupportsAVX; - auto* guest_uctx = reinterpret_cast(Context->UContextLocation); [[maybe_unused]] auto* guest_siginfo = reinterpret_cast(Context->SigInfoLocation); @@ -155,7 +153,7 @@ void SignalDelegator::RestoreFrame_x64(FEXCore::Core::InternalThreadState* Threa // Copy float registers memcpy(Frame->State.mm, fpstate->_st, sizeof(Frame->State.mm)); - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, nullptr); @@ -176,8 +174,6 @@ void SignalDelegator::RestoreFrame_x64(FEXCore::Core::InternalThreadState* Threa void SignalDelegator::RestoreFrame_ia32(FEXCore::Core::InternalThreadState* Thread, ArchHelpers::Context::ContextBackup* Context, FEXCore::Core::CpuStateFrame* Frame, void* ucontext) { - const bool IsAVXEnabled = Config.SupportsAVX; - SigFrame_i32* guest_uctx = reinterpret_cast(Context->UContextLocation); // If the guest modified the RIP then we need to take special precautions here if (Context->OriginalRIP != guest_uctx->sc.ip || Context->FaultToTopAndGeneratedException) { @@ -228,7 +224,7 @@ void SignalDelegator::RestoreFrame_ia32(FEXCore::Core::InternalThreadState* Thre } // Extended XMM state - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, nullptr); @@ -249,8 +245,6 @@ void SignalDelegator::RestoreFrame_ia32(FEXCore::Core::InternalThreadState* Thre void SignalDelegator::RestoreRTFrame_ia32(FEXCore::Core::InternalThreadState* Thread, ArchHelpers::Context::ContextBackup* Context, FEXCore::Core::CpuStateFrame* Frame, void* ucontext) { - const bool IsAVXEnabled = Config.SupportsAVX; - RTSigFrame_i32* guest_uctx = reinterpret_cast(Context->UContextLocation); // If the guest modified the RIP then we need to take special precautions here if (Context->OriginalRIP != guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_EIP] || Context->FaultToTopAndGeneratedException) { @@ -302,7 +296,7 @@ void SignalDelegator::RestoreRTFrame_ia32(FEXCore::Core::InternalThreadState* Th } // Extended XMM state - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->SetXMMRegistersFromState(Thread, fpstate->_xmm, nullptr); @@ -329,8 +323,6 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr // 32-bit doesn't have a redzone NewGuestSP -= 128; - const bool IsAVXEnabled = Config.SupportsAVX; - // On 64-bit the kernel sets up the siginfo_t and ucontext_t regardless of SA_SIGINFO set. // This allows the application to /always/ get the siginfo and ucontext even if it didn't set this flag. // @@ -345,7 +337,7 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr uint64_t HostStackLocation = NewGuestSP; - if (IsAVXEnabled) { + if (SupportsAVX) { NewGuestSP -= sizeof(FEXCore::x86_64::xstate); NewGuestSP = FEXCore::AlignDown(NewGuestSP, alignof(FEXCore::x86_64::xstate)); } else { @@ -378,7 +370,7 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr // Pointer to where the fpreg memory is guest_uctx->uc_mcontext.fpregs = reinterpret_cast(FPStateLocation); auto* xstate = reinterpret_cast(FPStateLocation); - SetXStateInfo(xstate, IsAVXEnabled); + SetXStateInfo(xstate, SupportsAVX); guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_RIP] = ContextBackup->OriginalRIP; guest_uctx->uc_mcontext.gregs[FEXCore::x86_64::FEX_REG_EFL] = eflags; @@ -427,7 +419,7 @@ uint64_t SignalDelegator::SetupFrame_x64(FEXCore::Core::InternalThreadState* Thr // Copy float registers memcpy(fpstate->_st, Frame->State.mm, sizeof(Frame->State.mm)); - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, nullptr); @@ -472,7 +464,6 @@ uint64_t SignalDelegator::SetupFrame_ia32(FEXCore::Core::InternalThreadState* Th FEXCore::Core::CpuStateFrame* Frame, int Signal, siginfo_t* HostSigInfo, void* ucontext, GuestSigAction* GuestAction, stack_t* GuestStack, uint64_t NewGuestSP, const uint32_t eflags) { - const bool IsAVXEnabled = Config.SupportsAVX; const uint64_t SignalReturn = reinterpret_cast(VDSOPointers.VDSO_kernel_sigreturn); NewGuestSP -= sizeof(uint64_t); @@ -480,7 +471,7 @@ uint64_t SignalDelegator::SetupFrame_ia32(FEXCore::Core::InternalThreadState* Th uint64_t HostStackLocation = NewGuestSP; - if (IsAVXEnabled) { + if (SupportsAVX) { NewGuestSP -= sizeof(FEXCore::x86::xstate); NewGuestSP = FEXCore::AlignDown(NewGuestSP, alignof(FEXCore::x86::xstate)); } else { @@ -505,7 +496,7 @@ uint64_t SignalDelegator::SetupFrame_ia32(FEXCore::Core::InternalThreadState* Th // Pointer to where the fpreg memory is guest_uctx->sc.fpstate = static_cast(FPStateLocation); auto* xstate = reinterpret_cast(FPStateLocation); - SetXStateInfo(xstate, IsAVXEnabled); + SetXStateInfo(xstate, SupportsAVX); guest_uctx->sc.cs = Frame->State.cs_idx; guest_uctx->sc.ds = Frame->State.ds_idx; @@ -549,7 +540,7 @@ uint64_t SignalDelegator::SetupFrame_ia32(FEXCore::Core::InternalThreadState* Th // Extended XMM state fpstate->status = FEXCore::x86::fpstate_magic::MAGIC_XFPSTATE; - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, nullptr); @@ -601,7 +592,6 @@ uint64_t SignalDelegator::SetupRTFrame_ia32(FEXCore::Core::InternalThreadState* FEXCore::Core::CpuStateFrame* Frame, int Signal, siginfo_t* HostSigInfo, void* ucontext, GuestSigAction* GuestAction, stack_t* GuestStack, uint64_t NewGuestSP, const uint32_t eflags) { - const bool IsAVXEnabled = Config.SupportsAVX; const uint64_t SignalReturn = reinterpret_cast(VDSOPointers.VDSO_kernel_rt_sigreturn); NewGuestSP -= sizeof(uint64_t); @@ -609,7 +599,7 @@ uint64_t SignalDelegator::SetupRTFrame_ia32(FEXCore::Core::InternalThreadState* uint64_t HostStackLocation = NewGuestSP; - if (IsAVXEnabled) { + if (SupportsAVX) { NewGuestSP -= sizeof(FEXCore::x86::xstate); NewGuestSP = FEXCore::AlignDown(NewGuestSP, alignof(FEXCore::x86::xstate)); } else { @@ -638,7 +628,7 @@ uint64_t SignalDelegator::SetupRTFrame_ia32(FEXCore::Core::InternalThreadState* // Pointer to where the fpreg memory is guest_uctx->uc.uc_mcontext.fpregs = static_cast(FPStateLocation); auto* xstate = reinterpret_cast(FPStateLocation); - SetXStateInfo(xstate, IsAVXEnabled); + SetXStateInfo(xstate, SupportsAVX); guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_CS] = Frame->State.cs_idx; guest_uctx->uc.uc_mcontext.gregs[FEXCore::x86::FEX_REG_DS] = Frame->State.ds_idx; @@ -684,7 +674,7 @@ uint64_t SignalDelegator::SetupRTFrame_ia32(FEXCore::Core::InternalThreadState* // Extended XMM state fpstate->status = FEXCore::x86::fpstate_magic::MAGIC_XFPSTATE; - if (IsAVXEnabled) { + if (SupportsAVX) { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, xstate->ymmh.ymmh_space); } else { CTX->ReconstructXMMRegisters(Thread, fpstate->_xmm, nullptr);