mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-07 17:00:19 +02:00
WOW64: Report CPU features based off of the emulated cpuid
This commit is contained in:
1 parent
2add8a7751
commit
be4fcaf65c
1 file changed
+98
-1
@@ -70,6 +70,8 @@ namespace {
|
||||
fextl::unique_ptr<FEX::DummyHandlers::DummySignalDelegator> SignalDelegator;
|
||||
fextl::unique_ptr<WowSyscallHandler> SyscallHandler;
|
||||
|
||||
SYSTEM_CPU_INFORMATION CpuInfo{};
|
||||
|
||||
std::pair<NTSTATUS, TLS> GetThreadTLS(HANDLE Thread) {
|
||||
THREAD_BASIC_INFORMATION Info;
|
||||
const NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr);
|
||||
@@ -179,7 +181,7 @@ namespace Context {
|
||||
(State.flags[FEXCore::X86State::X87FLAG_C3_LOC] << 14);
|
||||
XSave->TagWord = State.AbridgedFTW;
|
||||
|
||||
Context->FloatSave.ControlWord = State.FCW;
|
||||
Context->FloatSave.ControlWord = XSave->ControlWord;
|
||||
Context->FloatSave.StatusWord = XSave->StatusWord;
|
||||
Context->FloatSave.TagWord = FEXCore::FPState::ConvertFromAbridgedFTW(XSave->StatusWord, State.mm, XSave->TagWord);
|
||||
Context->FloatSave.ErrorOffset = XSave->ErrorOffset;
|
||||
@@ -303,6 +305,39 @@ void BTCpuProcessInit() {
|
||||
CTX->SetSignalDelegator(SignalDelegator.get());
|
||||
CTX->SetSyscallHandler(SyscallHandler.get());
|
||||
CTX->InitCore(0, 0);
|
||||
|
||||
CpuInfo.ProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
|
||||
|
||||
// Baseline FEX feature-set
|
||||
CpuInfo.ProcessorFeatureBits = CPU_FEATURE_VME | CPU_FEATURE_TSC | CPU_FEATURE_CMOV | CPU_FEATURE_PGE |
|
||||
CPU_FEATURE_PSE | CPU_FEATURE_MTRR | CPU_FEATURE_CX8 | CPU_FEATURE_MMX |
|
||||
CPU_FEATURE_X86 | CPU_FEATURE_PAT | CPU_FEATURE_FXSR | CPU_FEATURE_SEP |
|
||||
CPU_FEATURE_SSE | CPU_FEATURE_3DNOW | CPU_FEATURE_SSE2 | CPU_FEATURE_SSE3 |
|
||||
CPU_FEATURE_CX128 | CPU_FEATURE_NX | CPU_FEATURE_SSSE3 | CPU_FEATURE_SSE41 |
|
||||
CPU_FEATURE_PAE | CPU_FEATURE_DAZ;
|
||||
|
||||
// Features that require specific host CPU support
|
||||
const auto CPUIDResult01 = CTX->RunCPUIDFunction(0x01, 0);
|
||||
if (CPUIDResult01.ecx & (1 << 20)) {
|
||||
CpuInfo.ProcessorFeatureBits |= CPU_FEATURE_SSE42;
|
||||
}
|
||||
if (CPUIDResult01.ecx & (1 << 27)) {
|
||||
CpuInfo.ProcessorFeatureBits |= CPU_FEATURE_XSAVE;
|
||||
}
|
||||
if (CPUIDResult01.ecx & (1 << 28)) {
|
||||
CpuInfo.ProcessorFeatureBits |= CPU_FEATURE_AVX;
|
||||
}
|
||||
|
||||
const auto CPUIDResult07 = CTX->RunCPUIDFunction(0x07, 0);
|
||||
if (CPUIDResult07.ebx & (1 << 5)) {
|
||||
CpuInfo.ProcessorFeatureBits |= CPU_FEATURE_AVX2;
|
||||
}
|
||||
|
||||
const auto FamilyIdentifier = CPUIDResult01.eax;
|
||||
CpuInfo.ProcessorLevel = ((FamilyIdentifier >> 8) & 0xf) + ((FamilyIdentifier >> 20) & 0xff); // Family
|
||||
CpuInfo.ProcessorRevision = (FamilyIdentifier & 0xf0000) >> 4; // Extended Model
|
||||
CpuInfo.ProcessorRevision |= (FamilyIdentifier & 0xf0) << 4; // Model
|
||||
CpuInfo.ProcessorRevision |= FamilyIdentifier & 0xf; // Stepping
|
||||
}
|
||||
|
||||
NTSTATUS BTCpuThreadInit() {
|
||||
@@ -387,3 +422,65 @@ void BTCpuSimulate() {
|
||||
Context::UnlockJITContext();
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN WINAPI BTCpuIsProcessorFeaturePresent(UINT Feature) {
|
||||
switch (Feature) {
|
||||
case PF_FLOATING_POINT_PRECISION_ERRATA:
|
||||
return FALSE;
|
||||
case PF_FLOATING_POINT_EMULATED:
|
||||
return FALSE;
|
||||
case PF_COMPARE_EXCHANGE_DOUBLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_CX8);
|
||||
case PF_MMX_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_MMX);
|
||||
case PF_XMMI_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_SSE);
|
||||
case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_3DNOW);
|
||||
case PF_RDTSC_INSTRUCTION_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_TSC);
|
||||
case PF_PAE_ENABLED:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_PAE);
|
||||
case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_SSE2);
|
||||
case PF_SSE3_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_SSE3);
|
||||
case PF_SSSE3_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_SSSE3);
|
||||
case PF_XSAVE_ENABLED:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_XSAVE);
|
||||
case PF_COMPARE_EXCHANGE128:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_CX128);
|
||||
case PF_SSE_DAZ_MODE_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_DAZ);
|
||||
case PF_NX_ENABLED:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_NX);
|
||||
case PF_SECOND_LEVEL_ADDRESS_TRANSLATION:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_2NDLEV);
|
||||
case PF_VIRT_FIRMWARE_ENABLED:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_VIRT);
|
||||
case PF_RDWRFSGSBASE_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_RDFS);
|
||||
case PF_FASTFAIL_AVAILABLE:
|
||||
return TRUE;
|
||||
case PF_SSE4_1_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_SSE41);
|
||||
case PF_SSE4_2_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_SSE42);
|
||||
case PF_AVX_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_AVX);
|
||||
case PF_AVX2_INSTRUCTIONS_AVAILABLE:
|
||||
return !!(CpuInfo.ProcessorFeatureBits & CPU_FEATURE_AVX2);
|
||||
default:
|
||||
LogMan::Msg::DFmt("Unknown CPU feature: {:X}", Feature);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN BTCpuUpdateProcessorInformation(SYSTEM_CPU_INFORMATION *Info) {
|
||||
Info->ProcessorArchitecture = CpuInfo.ProcessorArchitecture;
|
||||
Info->ProcessorLevel = CpuInfo.ProcessorLevel;
|
||||
Info->ProcessorRevision = CpuInfo.ProcessorRevision;
|
||||
Info->ProcessorFeatureBits = CpuInfo.ProcessorFeatureBits;
|
||||
return TRUE;
|
||||
}
|
||||
Reference in new issue
Block a user