| 460 | } |
| 461 | |
| 462 | FEXCore::HostFeatures FetchHostFeatures(FEX::CPUFeatures& Features, bool SupportsCacheMaintenanceOps, uint64_t CTR, uint64_t MIDR) { |
| 463 | FEXCore::HostFeatures HostFeatures; |
| 464 | |
| 465 | FEX_CONFIG_OPT(ForceSVEWidth, FORCESVEWIDTH); |
| 466 | FEX_CONFIG_OPT(Is64BitMode, IS64BIT_MODE); |
| 467 | |
| 468 | HostFeatures.SupportsCacheMaintenanceOps = SupportsCacheMaintenanceOps; |
| 469 | |
| 470 | HostFeatures.SupportsAES = Features.Supports(CPUFeatures::Feature::AES); |
| 471 | HostFeatures.SupportsCRC = Features.Supports(CPUFeatures::Feature::CRC32); |
| 472 | HostFeatures.SupportsSHA = Features.Supports(CPUFeatures::Feature::SHA1) && Features.Supports(CPUFeatures::Feature::SHA2); |
| 473 | HostFeatures.SupportsAtomics = Features.Supports(CPUFeatures::Feature::LSE); |
| 474 | HostFeatures.SupportsRAND = Features.Supports(CPUFeatures::Feature::RNDR); |
| 475 | |
| 476 | // Only supported when FEAT_AFP is supported |
| 477 | HostFeatures.SupportsAFP = Features.Supports(CPUFeatures::Feature::AFP); |
| 478 | HostFeatures.SupportsRCPC = Features.Supports(CPUFeatures::Feature::LRCPC); |
| 479 | HostFeatures.SupportsTSOImm9 = Features.Supports(CPUFeatures::Feature::LRCPC2); |
| 480 | HostFeatures.SupportsPMULL_128Bit = Features.Supports(CPUFeatures::Feature::PMULL); |
| 481 | HostFeatures.SupportsCSSC = Features.Supports(CPUFeatures::Feature::CSSC); |
| 482 | HostFeatures.SupportsFCMA = Features.Supports(CPUFeatures::Feature::FCMA); |
| 483 | HostFeatures.SupportsFlagM = Features.Supports(CPUFeatures::Feature::FlagM); |
| 484 | HostFeatures.SupportsFlagM2 = Features.Supports(CPUFeatures::Feature::FlagM2); |
| 485 | HostFeatures.SupportsFRINTTS = Features.Supports(CPUFeatures::Feature::FRINTTS); |
| 486 | HostFeatures.SupportsRPRES = Features.Supports(CPUFeatures::Feature::RPRES); |
| 487 | HostFeatures.SupportsSVEBitPerm = Features.Supports(CPUFeatures::Feature::SVE_BitPerm); |
| 488 | HostFeatures.SupportsECV = Features.Supports(CPUFeatures::Feature::ECV); |
| 489 | HostFeatures.SupportsWFXT = Features.Supports(CPUFeatures::Feature::WFxt); |
| 490 | |
| 491 | #ifdef VIXL_SIMULATOR |
| 492 | // Hardcode enable SVE with 256-bit wide registers. |
| 493 | HostFeatures.SupportsSVE128 = ForceSVEWidth() ? ForceSVEWidth() >= 128 : true; |
| 494 | HostFeatures.SupportsSVE256 = ForceSVEWidth() ? ForceSVEWidth() >= 256 : true; |
| 495 | #else |
| 496 | HostFeatures.SupportsSVE128 = Features.Supports(CPUFeatures::Feature::SVE2); |
| 497 | HostFeatures.SupportsSVE256 = Features.Supports(CPUFeatures::Feature::SVE2) && ReadSVEVectorLengthInBits() >= 256; |
| 498 | #endif |
| 499 | HostFeatures.SupportsAVX = true; |
| 500 | |
| 501 | #ifdef _WIN32 |
| 502 | // Disable 3DNow! by default to better match the set of extensions exposed on modern CPUs. |
| 503 | // This works around a bug that manifests in some games using native d3dx9 DLLs (most easily reproduced in WoW64 builds). |
| 504 | // For example, Fallout: New Vegas and some old EA games will run with a blackscreen. |
| 505 | HostFeatures.Supports3DNow = false; |
| 506 | #else |
| 507 | HostFeatures.Supports3DNow = true; |
| 508 | #endif |
| 509 | |
| 510 | HostFeatures.SupportsAES256 = HostFeatures.SupportsAVX && HostFeatures.SupportsAES; |
| 511 | |
| 512 | if (!HostFeatures.SupportsAtomics) { |
| 513 | WARN_ONCE_FMT("Host CPU doesn't support atomics. Expect bad performance"); |
| 514 | } |
| 515 | |
| 516 | #ifdef _M_ARM_64 |
| 517 | // Test if this CPU supports float exception trapping by attempting to enable |
| 518 | // On unsupported these bits are architecturally defined as RAZ/WI |
| 519 | constexpr uint32_t ExceptionEnableTraps = (1U << 8) | // Invalid Operation float exception trap enable |