From 66455b708ae3f8d94a3601087e73394cab5977ca Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 9 Jul 2026 17:17:19 +0200 Subject: [PATCH] CodeCache: Switch between 32-/64-bit compilers during cache generation --- Source/Tools/FEXOfflineCompiler/CMakeLists.txt | 5 +++++ Source/Tools/FEXOfflineCompiler/Main.cpp | 18 +++++++++++++----- Source/Windows/Common/ImageTracker.cpp | 5 +++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Source/Tools/FEXOfflineCompiler/CMakeLists.txt b/Source/Tools/FEXOfflineCompiler/CMakeLists.txt index 33f337043..5ce74795d 100644 --- a/Source/Tools/FEXOfflineCompiler/CMakeLists.txt +++ b/Source/Tools/FEXOfflineCompiler/CMakeLists.txt @@ -9,6 +9,11 @@ target_link_libraries(FEXOfflineCompiler PRIVATE fmt::fmt) if (MINGW) + if (ARCHITECTURE_arm64ec) + set_target_properties(FEXOfflineCompiler PROPERTIES OUTPUT_NAME "FEXOfflineCompiler64") + else() + set_target_properties(FEXOfflineCompiler PROPERTIES OUTPUT_NAME "FEXOfflineCompiler32") + endif() patch_library_wine(FEXOfflineCompiler) target_include_directories(FEXOfflineCompiler PRIVATE "${CMAKE_SOURCE_DIR}/Source/Windows/include/" diff --git a/Source/Tools/FEXOfflineCompiler/Main.cpp b/Source/Tools/FEXOfflineCompiler/Main.cpp index 4b469f13f..e969af057 100644 --- a/Source/Tools/FEXOfflineCompiler/Main.cpp +++ b/Source/Tools/FEXOfflineCompiler/Main.cpp @@ -51,6 +51,14 @@ static std::unique_ptr OvercommitTracker; #endif static FEXCore::Core::InternalThreadState* Thread = nullptr; +#ifdef _WIN32 +#ifdef _M_ARM64EC +const bool Is64BitCompiler = true; +#else +const bool Is64BitCompiler = false; +#endif +#endif + #ifdef _WIN32 class AOTSyscallHandler : public FEXCore::HLE::SyscallHandler { #else @@ -396,10 +404,8 @@ static std::optional GenerateSingleCache(FEXCore::ExecutableFileInf return std::nullopt; } const bool Is64Bit = Loader.Is64BitMode(); -#elif defined(_M_ARM64EC) - const bool Is64Bit = true; #else - const bool Is64Bit = false; + const bool Is64Bit = Is64BitCompiler; #endif FEXCore::Config::Set(FEXCore::Config::CONFIG_IS64BIT_MODE, Is64Bit ? "1" : "0"); @@ -774,11 +780,13 @@ static int ProcessAll() { } #ifdef _WIN32 - // For WoA, spawn a subprocess for each cache generation run to - // ensure robustness against JIT crashes. + // For WoA, spawn a subprocess for each cache generation run. + // This ensures robustness and allows for switching FEXOfflineCompiler between WoW64 and ARM64EC. char SelfPathRaw[PATH_MAX]; GetModuleFileNameA(nullptr, SelfPathRaw, sizeof(SelfPathRaw)); std::string SelfPath = SelfPathRaw; + auto NewExecName = fmt::format("FEXOfflineCompiler{}.exe", ExecutableIt->second.ExecutableBitness.value()); + SelfPath.replace(SelfPath.size() - NewExecName.size(), NewExecName.size(), NewExecName); #endif fmt::println("\nChecking caches for executable {}", ExecutableIt->second.Filename); diff --git a/Source/Windows/Common/ImageTracker.cpp b/Source/Windows/Common/ImageTracker.cpp index 42c4c87b0..4d6c0dd59 100644 --- a/Source/Windows/Common/ImageTracker.cpp +++ b/Source/Windows/Common/ImageTracker.cpp @@ -227,8 +227,9 @@ int ImageTracker::OpenCodeMapFile() { void ImageTracker::LoadAOTImages(MappedImageInfo& ImageInfo) { // Don't attempt cache loading for FEXOfflineCompiler itself - static bool IsFOC = ImageInfo.Info.Filename.ends_with("fexofflinecompiler.exe"); - if (IsFOC) { + static bool IsFOC32 = ImageInfo.Info.Filename.ends_with("fexofflinecompiler32.exe"); + static bool IsFOC64 = ImageInfo.Info.Filename.ends_with("fexofflinecompiler64.exe"); + if (IsFOC32 || IsFOC64) { return; }