diff --git a/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp b/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp index e45c9f6d2..248472beb 100644 --- a/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp +++ b/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp @@ -624,7 +624,7 @@ void Arm64Emitter::SpillStaticRegs(ARMEmitter::Register TmpReg, bool FPRs, uint3 } if (FPRs) { - if (EmitterCTX->HostFeatures.SupportsSVE256) { + if (EmitterCTX->HostFeatures.SupportsAVX && EmitterCTX->HostFeatures.SupportsSVE256) { for (size_t i = 0; i < StaticFPRegisters.size(); i++) { const auto Reg = StaticFPRegisters[i]; @@ -715,7 +715,9 @@ void Arm64Emitter::FillStaticRegs(bool FPRs, uint32_t GPRFillMask, uint32_t FPRF if (EmitterCTX->HostFeatures.SupportsSVE256) { ptrue(ARMEmitter::SubRegSize::i8Bit, PRED_TMP_32B, ARMEmitter::PredicatePattern::SVE_VL32); + } + if (EmitterCTX->HostFeatures.SupportsAVX && EmitterCTX->HostFeatures.SupportsSVE256) { for (size_t i = 0; i < StaticFPRegisters.size(); i++) { const auto Reg = StaticFPRegisters[i]; if (((1U << Reg.Idx()) & FPRFillMask) != 0) { diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index 705066451..699bd1759 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -523,6 +523,7 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::ContextImpl* ctx, FEXCore::Core::In , Arm64Emitter(ctx) , HostSupportsSVE128 {ctx->HostFeatures.SupportsSVE128} , HostSupportsSVE256 {ctx->HostFeatures.SupportsSVE256} + , HostSupportsAVX256 {ctx->HostFeatures.SupportsAVX && ctx->HostFeatures.SupportsSVE256} , HostSupportsRPRES {ctx->HostFeatures.SupportsRPRES} , HostSupportsAFP {ctx->HostFeatures.SupportsAFP} , CTX {ctx} { diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index 83f29355f..413436e8e 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -72,6 +72,7 @@ private: const bool HostSupportsSVE128 {}; const bool HostSupportsSVE256 {}; + const bool HostSupportsAVX256 {}; const bool HostSupportsRPRES {}; const bool HostSupportsAFP {}; diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp index b3492bed5..7bfdca2e6 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/MemoryOps.cpp @@ -99,7 +99,7 @@ DEF_OP(LoadRegister) { } } } else if (Op->Class == IR::FPRClass) { - const auto regSize = HostSupportsSVE256 ? Core::CPUState::XMM_AVX_REG_SIZE : Core::CPUState::XMM_SSE_REG_SIZE; + const auto regSize = HostSupportsAVX256 ? Core::CPUState::XMM_AVX_REG_SIZE : Core::CPUState::XMM_SSE_REG_SIZE; LOGMAN_THROW_A_FMT(Op->Reg < StaticFPRegisters.size(), "out of range reg"); LOGMAN_THROW_A_FMT(OpSize == regSize, "expected sized"); @@ -107,7 +107,7 @@ DEF_OP(LoadRegister) { const auto host = GetVReg(Node); if (host.Idx() != guest.Idx()) { - if (HostSupportsSVE256) { + if (HostSupportsAVX256) { mov(ARMEmitter::SubRegSize::i64Bit, host.Z(), PRED_TMP_32B.Merging(), guest.Z()); } else { mov(host.Q(), guest.Q()); @@ -137,7 +137,7 @@ DEF_OP(StoreRegister) { mov(ARMEmitter::Size::i64Bit, reg, Src); } } else if (Op->Class == IR::FPRClass) { - const auto regSize = HostSupportsSVE256 ? Core::CPUState::XMM_AVX_REG_SIZE : Core::CPUState::XMM_SSE_REG_SIZE; + const auto regSize = HostSupportsAVX256 ? Core::CPUState::XMM_AVX_REG_SIZE : Core::CPUState::XMM_SSE_REG_SIZE; LOGMAN_THROW_A_FMT(Op->Reg < StaticFPRegisters.size(), "reg out of range"); LOGMAN_THROW_A_FMT(OpSize == regSize, "expected sized"); @@ -145,7 +145,7 @@ DEF_OP(StoreRegister) { const auto host = GetVReg(Op->Value.ID()); if (guest.Idx() != host.Idx()) { - if (HostSupportsSVE256) { + if (HostSupportsAVX256) { mov(ARMEmitter::SubRegSize::i64Bit, guest.Z(), PRED_TMP_32B.Merging(), host.Z()); } else { mov(guest.Q(), host.Q()); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 45a9df7b7..2753e7078 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -4453,7 +4453,7 @@ void OpDispatchBuilder::StoreResult_WithOpSize(FEXCore::IR::RegisterClassType Cl StoreContext(MM0Index + gpr - FEXCore::X86State::REG_MM_0, Src); } else if (gpr >= FEXCore::X86State::REG_XMM_0) { const auto gprIndex = gpr - X86State::REG_XMM_0; - const auto VectorSize = CTX->HostFeatures.SupportsSVE256 ? 32 : 16; + const auto VectorSize = (CTX->HostFeatures.SupportsSVE256 && CTX->HostFeatures.SupportsAVX) ? 32 : 16; auto Result = Src; if (OpSize != VectorSize) { @@ -5451,7 +5451,7 @@ void OpDispatchBuilder::InstallHostSpecificOpcodeHandlers() { InstallToTable(FEXCore::X86Tables::SecondInstGroupOps, SecondaryExtensionOp_RDRAND); } - if (CTX->HostFeatures.SupportsSVE256) { + if (CTX->HostFeatures.SupportsAVX && CTX->HostFeatures.SupportsSVE256) { InstallToTable(FEXCore::X86Tables::VEXTableOps, AVXTable); InstallToTable(FEXCore::X86Tables::VEXTableGroupOps, VEXTableGroupOps); if (CTX->HostFeatures.SupportsPMULL_128Bit) { diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 50367e8de..769432fe8 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -1292,7 +1292,7 @@ public: CalculateDeferredFlags(); const uint8_t GPRSize = CTX->GetGPRSize(); - const auto VectorSize = CTX->HostFeatures.SupportsSVE256 ? 32 : 16; + const auto VectorSize = (CTX->HostFeatures.SupportsSVE256 && CTX->HostFeatures.SupportsAVX) ? 32 : 16; // Write backwards. This is a heuristic to improve coalescing, since we // often copy from (low) fixed GPRs to (high) PF/AF for celebrity @@ -1610,7 +1610,7 @@ private: } constexpr OpSize GetGuestVectorLength() const { - return CTX->HostFeatures.SupportsSVE256 ? OpSize::i256Bit : OpSize::i128Bit; + return (CTX->HostFeatures.SupportsSVE256 && CTX->HostFeatures.SupportsAVX) ? OpSize::i256Bit : OpSize::i128Bit; } [[nodiscard]] @@ -1910,8 +1910,8 @@ private: } Ref LoadXMMRegister(uint8_t Reg) { - const auto Size = CTX->HostFeatures.SupportsSVE256 ? 32 : 16; - return LoadRegCache(Reg, FPR0Index + Reg, FPRClass, Size); + const auto VectorSize = (CTX->HostFeatures.SupportsSVE256 && CTX->HostFeatures.SupportsAVX) ? 32 : 16; + return LoadRegCache(Reg, FPR0Index + Reg, FPRClass, VectorSize); } Ref LoadDF() {