diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index e4f544fc1..122280675 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -4778,35 +4778,36 @@ void OpDispatchBuilder::INTOp(OpcodeArgs) { case 0xCD: { // INT imm8 uint8_t Literal = Op->Src[0].Literal(); -#ifndef _WIN32 - constexpr uint8_t SYSCALL_LITERAL = 0x80; - if (Literal == SYSCALL_LITERAL) { - if (Is64BitMode) [[unlikely]] { - LogMan::Msg::EFmt("[Unsupported] Trying to execute 32-bit syscall from a 64-bit process."); - UnhandledOp(Op); + if (CTX->HostFeatures.HostType == FEXCore::HostFeatures::HostTypeEnum::Linux) { + constexpr uint8_t SYSCALL_LITERAL = 0x80; + if (Literal == SYSCALL_LITERAL) { + if (Is64BitMode) [[unlikely]] { + LogMan::Msg::EFmt("[Unsupported] Trying to execute 32-bit syscall from a 64-bit process."); + UnhandledOp(Op); + return; + } + // Syscall on linux + SyscallOp(Op, false); + return; + } + } else if (CTX->HostFeatures.HostType == FEXCore::HostFeatures::HostTypeEnum::Wow64 || + CTX->HostFeatures.HostType == FEXCore::HostFeatures::HostTypeEnum::Arm64ec) { + constexpr uint8_t SYSCALL_LITERAL = 0x2E; + if (Literal == SYSCALL_LITERAL) { + // Can be used for both 64-bit and 32-bit syscalls on windows + SyscallOp(Op, false); return; } - // Syscall on linux - SyscallOp(Op, false); - return; - } -#else - constexpr uint8_t SYSCALL_LITERAL = 0x2E; - if (Literal == SYSCALL_LITERAL) { - // Can be used for both 64-bit and 32-bit syscalls on windows - SyscallOp(Op, false); - return; - } -#endif -#ifdef ARCHITECTURE_arm64ec - // This is used when QueryPerformanceCounter is called on recent Windows versions, it causes CNTVCT to be written into RAX. - constexpr uint8_t GET_CNTVCT_LITERAL = 0x81; - if (Literal == GET_CNTVCT_LITERAL) { - StoreGPRRegister(X86State::REG_RAX, _CycleCounter(false)); - return; + if (CTX->HostFeatures.HostType == FEXCore::HostFeatures::HostTypeEnum::Arm64ec) { + // This is used when QueryPerformanceCounter is called on recent Windows versions, it causes CNTVCT to be written into RAX. + constexpr uint8_t GET_CNTVCT_LITERAL = 0x81; + if (Literal == GET_CNTVCT_LITERAL) { + StoreGPRRegister(X86State::REG_RAX, _CycleCounter(false)); + return; + } + } } -#endif Reason.ErrorRegister = Literal << 3 | (0b010); Reason.Signal = Core::FAULT_SIGSEGV; diff --git a/FEXCore/include/FEXCore/Core/HostFeatures.h b/FEXCore/include/FEXCore/Core/HostFeatures.h index 2e07bc3c6..e74b62531 100644 --- a/FEXCore/include/FEXCore/Core/HostFeatures.h +++ b/FEXCore/include/FEXCore/Core/HostFeatures.h @@ -48,6 +48,15 @@ struct HostFeatures { bool SupportsAFP {}; bool SupportsFloatExceptions {}; + // Changes code generation slightly. + enum class HostTypeEnum { + Unknown, + Linux, + Wow64, + Arm64ec, + }; + HostTypeEnum HostType {}; + // Flag if this is InstCountCI bool IsInstCountCI {}; diff --git a/Source/Common/HostFeatures.cpp b/Source/Common/HostFeatures.cpp index 8eda92bb9..f60ee2790 100644 --- a/Source/Common/HostFeatures.cpp +++ b/Source/Common/HostFeatures.cpp @@ -766,6 +766,7 @@ FEXCore::HostFeatures FetchHostFeatures() { FetchHostFeatures(Features, HostFeatures, true, CTR, MIDR); HostFeatures.SupportsCPUIndexInTPIDRRO = false; + HostFeatures.HostType = FEXCore::HostFeatures::HostTypeEnum::Linux; return HostFeatures; } } // namespace FEX diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index 6f27dc0e3..6ceecd878 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -603,7 +603,7 @@ NTSTATUS ProcessInit() { FEX::Windows::UnixLib::Init(NtDll); { - auto HostFeatures = FEX::Windows::CPUFeatures::FetchHostFeatures(IsWine); + auto HostFeatures = FEX::Windows::CPUFeatures::FetchHostFeatures(IsWine, FEXCore::HostFeatures::HostTypeEnum::Arm64ec); CTX = FEXCore::Context::Context::CreateNewContext(HostFeatures); } diff --git a/Source/Windows/Common/CPUFeatures.cpp b/Source/Windows/Common/CPUFeatures.cpp index 9860eb6e2..034c2ca52 100644 --- a/Source/Windows/Common/CPUFeatures.cpp +++ b/Source/Windows/Common/CPUFeatures.cpp @@ -56,7 +56,7 @@ public: } }; -FEXCore::HostFeatures CPUFeatures::FetchHostFeatures(bool IsWine) { +FEXCore::HostFeatures CPUFeatures::FetchHostFeatures(bool IsWine, FEXCore::HostFeatures::HostTypeEnum HostType) { HKEY Key = OpenProcessorKey(0); if (!Key) { ERROR_AND_DIE_FMT("Couldn't detect CPU features"); @@ -82,6 +82,13 @@ FEXCore::HostFeatures CPUFeatures::FetchHostFeatures(bool IsWine) { HostFeatures.SupportsSVE256 = false; HostFeatures.SupportsCPUIndexInTPIDRRO = !IsWine; + + HostFeatures.HostType = HostType; + + if (HostType == FEXCore::HostFeatures::HostTypeEnum::Wow64) { + // AVX is unsupported for WOW64 + HostFeatures.SupportsAVX = false; + } return HostFeatures; } diff --git a/Source/Windows/Common/CPUFeatures.h b/Source/Windows/Common/CPUFeatures.h index 4cd960bc7..61d93efae 100644 --- a/Source/Windows/Common/CPUFeatures.h +++ b/Source/Windows/Common/CPUFeatures.h @@ -16,7 +16,7 @@ class Context; namespace FEX::Windows { class CPUFeatures { public: - static FEXCore::HostFeatures FetchHostFeatures(bool IsWine); + static FEXCore::HostFeatures FetchHostFeatures(bool IsWine, FEXCore::HostFeatures::HostTypeEnum HostType); CPUFeatures(FEXCore::Context::Context& CTX); diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index 085dc2523..bff9ae2da 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -531,9 +531,7 @@ void BTCpuProcessInit() { FEX::Windows::UnixLib::Init(NtDll); { - auto HostFeatures = FEX::Windows::CPUFeatures::FetchHostFeatures(IsWine); - // AVX is unsupported for WOW64 - HostFeatures.SupportsAVX = false; + auto HostFeatures = FEX::Windows::CPUFeatures::FetchHostFeatures(IsWine, FEXCore::HostFeatures::HostTypeEnum::Wow64); CTX = FEXCore::Context::Context::CreateNewContext(HostFeatures); }