diff --git a/External/FEXCore/Source/CMakeLists.txt b/External/FEXCore/Source/CMakeLists.txt index aa2c2da71..cbe6ebc93 100644 --- a/External/FEXCore/Source/CMakeLists.txt +++ b/External/FEXCore/Source/CMakeLists.txt @@ -229,6 +229,8 @@ set (LIBS fmt::fmt vixl xxhash tiny-json FEXHeaderUtils) if (NOT MINGW_BUILD) list (APPEND LIBS dl) +else() + list (APPEND LIBS synchronization) endif() if (ENABLE_JEMALLOC) @@ -399,6 +401,12 @@ function(AddLibrary Name Type) if (MINGW_BUILD) # Mingw build isn't building a linux shared library, so it can't have a SONAME. set_target_properties(${Name} PROPERTIES NO_SONAME ON) + # Change the suffixes otherwise cmake continues using .a and .so + if (${Type} STREQUAL SHARED) + set_target_properties(${Name} PROPERTIES SUFFIX ".dll") + elseif(${Type} STREQUAL STATIC) + set_target_properties(${Name} PROPERTIES SUFFIX ".lib") + endif() endif() AddDefaultOptionsToTarget(${Name}) diff --git a/External/FEXCore/Source/Common/SoftFloat.h b/External/FEXCore/Source/Common/SoftFloat.h index b42800867..31c35d0ad 100644 --- a/External/FEXCore/Source/Common/SoftFloat.h +++ b/External/FEXCore/Source/Common/SoftFloat.h @@ -445,6 +445,7 @@ struct FEX_PACKED X80SoftFloat { return FEXCore::BitCast(Result); } +#ifndef _WIN32 operator BIGFLOAT() const { #if BIGFLOATSIZE == 16 const float128_t Result = extF80_to_f128(*this); @@ -455,6 +456,7 @@ struct FEX_PACKED X80SoftFloat { return result; #endif } +#endif operator int16_t() const { auto rv = extF80_to_i32(*this, softfloat_roundingMode, false); @@ -523,6 +525,7 @@ struct FEX_PACKED X80SoftFloat { *this = f64_to_extF80(FEXCore::BitCast(rhs)); } +#ifndef _WIN32 X80SoftFloat(BIGFLOAT rhs) { #if BIGFLOATSIZE == 16 *this = f128_to_extF80(FEXCore::BitCast(rhs)); @@ -530,6 +533,7 @@ struct FEX_PACKED X80SoftFloat { *this = FEXCore::BitCast(rhs); #endif } +#endif X80SoftFloat(const int16_t rhs) { *this = i32_to_extF80(rhs); diff --git a/External/FEXCore/Source/Interface/Core/Core.cpp b/External/FEXCore/Source/Interface/Core/Core.cpp index aa49a24ba..b20253231 100644 --- a/External/FEXCore/Source/Interface/Core/Core.cpp +++ b/External/FEXCore/Source/Interface/Core/Core.cpp @@ -66,9 +66,7 @@ $end_info$ #include #include #include -#include #include -#include #include #include #include @@ -714,6 +712,7 @@ namespace FEXCore::Context { } static void IRDumper(FEXCore::Core::InternalThreadState *Thread, IR::IREmitter *IREmitter, uint64_t GuestRIP, IR::RegisterAllocationData* RA) { +#ifndef _WIN32 int FD {-1}; bool CloseAfter = false; const auto DumpIRStr = static_cast(Thread->CTX)->Config.DumpIR(); @@ -742,6 +741,7 @@ namespace FEXCore::Context { close(FD); } } +#endif }; static void ValidateIR(ContextImpl *ctx, IR::IREmitter *IREmitter) { diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp index 42bd4be8e..55191808e 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index f4439f333..c095f8ea4 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -23,7 +23,6 @@ $end_info$ #include "Utils/MemberFunctionToPointer.h" #include -#include #include #include #include @@ -31,7 +30,6 @@ $end_info$ #include "Interface/Core/Interpreter/InterpreterOps.h" -#include #include #include #include diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/MiscOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/MiscOps.cpp index 61bd7b782..4571eba3a 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/MiscOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/MiscOps.cpp @@ -4,7 +4,10 @@ tags: backend|arm64 $end_info$ */ +#ifndef _WIN32 #include +#endif + #include "Interface/Core/ArchHelpers/CodeEmitter/Emitter.h" #include "Interface/Core/JIT/Arm64/JITClass.h" #include "FEXCore/Debug/InternalThreadState.h" @@ -34,6 +37,7 @@ DEF_OP(Fence) { } } +#ifndef _WIN32 DEF_OP(Break) { auto Op = IROp->C(); @@ -73,6 +77,11 @@ DEF_OP(Break) { break; } } +#else +DEF_OP(Break) { + ERROR_AND_DIE_FMT("Unsupported"); +} +#endif DEF_OP(GetRoundingMode) { auto Dst = GetReg(Node); @@ -157,6 +166,7 @@ DEF_OP(Print) { PopDynamicRegsAndLR(); } +#ifndef _WIN32 DEF_OP(ProcessorID) { // We always need to spill x8 since we can't know if it is live at this SSA location uint32_t SpillMask = 1U << 8; @@ -207,6 +217,11 @@ DEF_OP(ProcessorID) { // Node is in w1 orr(ARMEmitter::Size::i64Bit, GetReg(Node), ARMEmitter::Reg::r0, ARMEmitter::Reg::r1, ARMEmitter::ShiftType::LSL, 12); } +#else +DEF_OP(ProcessorID) { + ERROR_AND_DIE_FMT("Unsupported"); +} +#endif DEF_OP(RDRAND) { auto Op = IROp->C(); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp index 13ff409fd..0bac3a0cb 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp @@ -35,7 +35,6 @@ $end_info$ #include #include #include -#include #include #include #include diff --git a/External/FEXCore/Source/Utils/LogManager.cpp b/External/FEXCore/Source/Utils/LogManager.cpp index 75cd33a85..da24b0424 100644 --- a/External/FEXCore/Source/Utils/LogManager.cpp +++ b/External/FEXCore/Source/Utils/LogManager.cpp @@ -9,9 +9,9 @@ $end_info$ #include #include -#include #include #include +#include namespace LogMan { diff --git a/External/FEXCore/Source/Utils/Profiler.cpp b/External/FEXCore/Source/Utils/Profiler.cpp index c927c444f..c1f22ac63 100644 --- a/External/FEXCore/Source/Utils/Profiler.cpp +++ b/External/FEXCore/Source/Utils/Profiler.cpp @@ -2,9 +2,11 @@ #include #include #include +#ifndef _WIN32 #include #include #include +#endif #include #include diff --git a/External/FEXCore/include/FEXCore/Utils/InterruptableConditionVariable.h b/External/FEXCore/include/FEXCore/Utils/InterruptableConditionVariable.h index a1f786da7..52535449c 100644 --- a/External/FEXCore/include/FEXCore/Utils/InterruptableConditionVariable.h +++ b/External/FEXCore/include/FEXCore/Utils/InterruptableConditionVariable.h @@ -4,8 +4,14 @@ #include #include #include +#ifndef _WIN32 #include #include +#else +#include +#include +#include +#endif #include namespace FEXCore { @@ -17,6 +23,7 @@ namespace FEXCore { * call can leave the condition variable in an invalid state that breaks later * uses of that object and may cause hangs as a consequence. */ +#ifndef _WIN32 class InterruptableConditionVariable final { public: bool Wait(struct timespec *Timeout = nullptr) { @@ -86,4 +93,68 @@ namespace FEXCore { } } }; +#else + class InterruptableConditionVariable final { + public: + bool Wait(struct timespec *Timeout = nullptr) { + while (true) { + uint32_t Expected = SIGNALED; + uint32_t Desired = UNSIGNALED; + + // If the mutex was already signaled then we can early exit + if (Mutex.compare_exchange_strong(Expected, Desired)) { + return true; + } + // Windows only supports millisecond granularity. + const uint32_t TimeoutMS = Timeout ? Timeout->tv_sec * 1000 + (Timeout->tv_nsec / 1000000) : 0; + + // WaitOnAddress returns when the value at `Address` differs from the value at `CompareAddress`. + bool Result = WaitOnAddress(&Mutex, &Desired, 4, TimeoutMS); + + if (Timeout && Result == false && GetLastError() == ERROR_TIMEOUT) { + return false; + } + } + } + + template + bool WaitFor(std::chrono::duration const& time) { + struct timespec Timeout{}; + auto SecondsDuration = std::chrono::duration_cast(time); + Timeout.tv_sec = SecondsDuration.count(); + Timeout.tv_nsec = std::chrono::duration_cast(time - SecondsDuration).count(); + return Wait(&Timeout); + } + + void NotifyOne() { + DoNotify(false); + } + + void NotifyAll() { + // Maximum number of waiters + DoNotify(true); + } + + private: + std::atomic Mutex{}; + constexpr static uint32_t SIGNALED = 1; + constexpr static uint32_t UNSIGNALED = 0; + + void DoNotify(bool All) { + uint32_t Expected = UNSIGNALED; + uint32_t Desired = SIGNALED; + + // If the mutex was in an unsignaled state then signal + if (Mutex.compare_exchange_strong(Expected, Desired)) { + if (All) { + WakeByAddressAll(&Mutex); + } + else { + WakeByAddressSingle(&Mutex); + } + } + } + }; + +#endif } diff --git a/FEXHeaderUtils/FEXHeaderUtils/ScopedSignalMask.h b/FEXHeaderUtils/FEXHeaderUtils/ScopedSignalMask.h index a24a977ba..0996b4b8b 100644 --- a/FEXHeaderUtils/FEXHeaderUtils/ScopedSignalMask.h +++ b/FEXHeaderUtils/FEXHeaderUtils/ScopedSignalMask.h @@ -6,8 +6,10 @@ #include #include #include +#ifndef _WIN32 #include #include +#endif #include namespace FHU { @@ -30,6 +32,7 @@ namespace FHU { * 1) Unlock Mutex * 2) Unmask signals */ +#ifndef _WIN32 template class ScopedSignalMaskWithMutexBase final { public: @@ -66,6 +69,39 @@ namespace FHU { uint64_t OriginalMask{}; MutexType *Mutex; }; +#else + // TODO: Doesn't block signals which may or may not cause issues. + template + class ScopedSignalMaskWithMutexBase final { + public: + + ScopedSignalMaskWithMutexBase(MutexType &_Mutex, [[maybe_unused]] uint64_t Mask = ~0ULL) + : Mutex {&_Mutex} { + // Lock the mutex + (Mutex->*lock_fn)(); + } + + // No copy or assignment possible + ScopedSignalMaskWithMutexBase(const ScopedSignalMaskWithMutexBase&) = delete; + ScopedSignalMaskWithMutexBase& operator=(ScopedSignalMaskWithMutexBase&) = delete; + + // Only move + ScopedSignalMaskWithMutexBase(ScopedSignalMaskWithMutexBase &&rhs) + : Mutex {rhs.Mutex} { + rhs.Mutex = nullptr; + } + + ~ScopedSignalMaskWithMutexBase() { + if (Mutex != nullptr) { + // Unlock the mutex + (Mutex->*unlock_fn)(); + } + } + private: + MutexType *Mutex; + }; + +#endif using ScopedSignalMaskWithMutex = ScopedSignalMaskWithMutexBase; using ScopedSignalMaskWithSharedLock = ScopedSignalMaskWithMutexBase; diff --git a/Source/Tools/FEXLoader/ELFCodeLoader.h b/Source/Tools/FEXLoader/ELFCodeLoader.h index 0223e40f9..78705f761 100644 --- a/Source/Tools/FEXLoader/ELFCodeLoader.h +++ b/Source/Tools/FEXLoader/ELFCodeLoader.h @@ -5,6 +5,7 @@ #include "Common/FDUtils.h" #include "FEXCore/Utils/Allocator.h" #include "LinuxSyscalls/Syscalls.h" +#include "LinuxSyscalls/UContext.h" #include "VDSO_Emulation.h" #include "Linux/Utils/ELFParser.h" #include "Linux/Utils/ELFSymbolDatabase.h" @@ -18,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/ArchHelpers/MContext.h b/Source/Tools/FEXLoader/LinuxSyscalls/ArchHelpers/MContext.h index 71e4109b1..bc4232430 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/ArchHelpers/MContext.h +++ b/Source/Tools/FEXLoader/LinuxSyscalls/ArchHelpers/MContext.h @@ -1,8 +1,9 @@ #pragma once +#include "LinuxSyscalls/UContext.h" + #include #include -#include #include #include diff --git a/External/FEXCore/include/FEXCore/Core/UContext.h b/Source/Tools/FEXLoader/LinuxSyscalls/UContext.h similarity index 100% rename from External/FEXCore/include/FEXCore/Core/UContext.h rename to Source/Tools/FEXLoader/LinuxSyscalls/UContext.h diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/x32/Signals.cpp b/Source/Tools/FEXLoader/LinuxSyscalls/x32/Signals.cpp index e668442b7..fbe237264 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/x32/Signals.cpp +++ b/Source/Tools/FEXLoader/LinuxSyscalls/x32/Signals.cpp @@ -6,12 +6,12 @@ $end_info$ #include "LinuxSyscalls/SignalDelegator.h" #include "LinuxSyscalls/Syscalls.h" +#include "LinuxSyscalls/UContext.h" #include "LinuxSyscalls/x64/Syscalls.h" #include "LinuxSyscalls/x32/Syscalls.h" #include "LinuxSyscalls/x32/Types.h" #include -#include #include #include #include diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/x32/Thread.cpp b/Source/Tools/FEXLoader/LinuxSyscalls/x32/Thread.cpp index 3f986609f..77406e456 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/x32/Thread.cpp +++ b/Source/Tools/FEXLoader/LinuxSyscalls/x32/Thread.cpp @@ -6,6 +6,7 @@ $end_info$ #include "LinuxSyscalls/SignalDelegator.h" #include "LinuxSyscalls/Syscalls.h" +#include "LinuxSyscalls/UContext.h" #include "LinuxSyscalls/x32/Syscalls.h" #include "LinuxSyscalls/x32/Thread.h" #include "LinuxSyscalls/x32/Types.h" @@ -13,7 +14,6 @@ $end_info$ #include "LinuxSyscalls/x64/Syscalls.h" #include -#include #include #include #include diff --git a/Source/Tools/FEXLoader/TestHarnessRunner/HostRunner.cpp b/Source/Tools/FEXLoader/TestHarnessRunner/HostRunner.cpp index 5fce12ef8..3f648053f 100644 --- a/Source/Tools/FEXLoader/TestHarnessRunner/HostRunner.cpp +++ b/Source/Tools/FEXLoader/TestHarnessRunner/HostRunner.cpp @@ -1,9 +1,9 @@ #include "LinuxSyscalls/SignalDelegator.h" +#include "LinuxSyscalls/UContext.h" #include #include #include #include -#include #include #include #include