From eefe2b20fceb56da2b4507717108b80d935cfc2e Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Sun, 10 Nov 2019 03:21:03 +0100 Subject: [PATCH] Fix Fcmge_S/V & Fcmgt_S/V Inst.s (#815) * Fix Fcmge_S/V & Fcmgt_S/V. Follow-up Fcm**_S/V & Fc*mp*_S. Improve CmpCondition enum. Nits. * Optimize Fccmp*_S & Fcmp*_S. * Fix cvtsd2si opcode. * Address PR feedback. --- ARMeilleure/CodeGen/X86/Assembler.cs | 2 +- ARMeilleure/CodeGen/X86/CodeGenerator.cs | 16 +++- .../CodeGen/X86/HardwareCapabilities.cs | 2 +- ARMeilleure/CodeGen/X86/IntrinsicTable.cs | 1 + ARMeilleure/Instructions/InstEmitSimdCmp.cs | 77 ++++++++++--------- ARMeilleure/Instructions/InstEmitSimdCvt.cs | 34 ++++---- .../Instructions/InstEmitSimdHelper.cs | 15 ++++ .../IntermediateRepresentation/Intrinsic.cs | 1 + ARMeilleure/Optimizations.cs | 2 + .../Ryujinx.Tests.Unicorn.csproj | 2 +- Ryujinx.Tests/Ryujinx.Tests.csproj | 2 +- 11 files changed, 92 insertions(+), 62 deletions(-) diff --git a/ARMeilleure/CodeGen/X86/Assembler.cs b/ARMeilleure/CodeGen/X86/Assembler.cs index c64838945..ee80d892b 100644 --- a/ARMeilleure/CodeGen/X86/Assembler.cs +++ b/ARMeilleure/CodeGen/X86/Assembler.cs @@ -94,7 +94,7 @@ namespace ARMeilleure.CodeGen.X86 Add(X86Instruction.Cvtpd2ps, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5a, InstructionFlags.Vex | InstructionFlags.Prefix66)); Add(X86Instruction.Cvtps2dq, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5b, InstructionFlags.Vex | InstructionFlags.Prefix66)); Add(X86Instruction.Cvtps2pd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5a, InstructionFlags.Vex)); - Add(X86Instruction.Cvtsd2si, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f2c, InstructionFlags.Vex | InstructionFlags.PrefixF2)); + Add(X86Instruction.Cvtsd2si, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f2d, InstructionFlags.Vex | InstructionFlags.PrefixF2)); Add(X86Instruction.Cvtsd2ss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f5a, InstructionFlags.Vex | InstructionFlags.PrefixF2)); Add(X86Instruction.Cvtsi2sd, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f2a, InstructionFlags.Vex | InstructionFlags.PrefixF2)); Add(X86Instruction.Cvtsi2ss, new InstructionInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f2a, InstructionFlags.Vex | InstructionFlags.PrefixF3)); diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index ae24b5631..33fc2aee3 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -265,7 +265,21 @@ namespace ARMeilleure.CodeGen.X86 Debug.Assert(dest.Type.IsInteger() && !source.Type.IsInteger()); - context.Assembler.WriteInstruction(info.Inst, dest, source, dest.Type); + if (intrinOp.Intrinsic == Intrinsic.X86Cvtsi2si) + { + if (dest.Type == OperandType.I32) + { + context.Assembler.Movd(dest, source); // int _mm_cvtsi128_si32 + } + else /* if (dest.Type == OperandType.I64) */ + { + context.Assembler.Movq(dest, source); // __int64 _mm_cvtsi128_si64 + } + } + else + { + context.Assembler.WriteInstruction(info.Inst, dest, source, dest.Type); + } break; } diff --git a/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs b/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs index 7f930d6b9..ed8148292 100644 --- a/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs +++ b/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs @@ -26,7 +26,7 @@ namespace ARMeilleure.CodeGen.X86 public static bool ForceLegacySse { get; set; } - public static bool SupportsVexEncoding => !ForceLegacySse && SupportsAvx; + public static bool SupportsVexEncoding => SupportsAvx && !ForceLegacySse; static HardwareCapabilities() { diff --git a/ARMeilleure/CodeGen/X86/IntrinsicTable.cs b/ARMeilleure/CodeGen/X86/IntrinsicTable.cs index e225f2542..73fb5fd1b 100644 --- a/ARMeilleure/CodeGen/X86/IntrinsicTable.cs +++ b/ARMeilleure/CodeGen/X86/IntrinsicTable.cs @@ -37,6 +37,7 @@ namespace ARMeilleure.CodeGen.X86 Add(Intrinsic.X86Cvtps2pd, new IntrinsicInfo(X86Instruction.Cvtps2pd, IntrinsicType.Unary)); Add(Intrinsic.X86Cvtsd2si, new IntrinsicInfo(X86Instruction.Cvtsd2si, IntrinsicType.UnaryToGpr)); Add(Intrinsic.X86Cvtsd2ss, new IntrinsicInfo(X86Instruction.Cvtsd2ss, IntrinsicType.Binary)); + Add(Intrinsic.X86Cvtsi2si, new IntrinsicInfo(X86Instruction.Movd, IntrinsicType.UnaryToGpr)); Add(Intrinsic.X86Cvtss2sd, new IntrinsicInfo(X86Instruction.Cvtss2sd, IntrinsicType.Binary)); Add(Intrinsic.X86Divpd, new IntrinsicInfo(X86Instruction.Divpd, IntrinsicType.Binary)); Add(Intrinsic.X86Divps, new IntrinsicInfo(X86Instruction.Divps, IntrinsicType.Binary)); diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp.cs b/ARMeilleure/Instructions/InstEmitSimdCmp.cs index f27121bb3..ac1bffcb2 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp.cs @@ -322,7 +322,7 @@ namespace ARMeilleure.Instructions public static void Fcmge_S(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { EmitCmpSseOrSse2OpF(context, CmpCondition.GreaterThanOrEqual, scalar: true); } @@ -334,7 +334,7 @@ namespace ARMeilleure.Instructions public static void Fcmge_V(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { EmitCmpSseOrSse2OpF(context, CmpCondition.GreaterThanOrEqual, scalar: false); } @@ -346,7 +346,7 @@ namespace ARMeilleure.Instructions public static void Fcmgt_S(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { EmitCmpSseOrSse2OpF(context, CmpCondition.GreaterThan, scalar: true); } @@ -358,7 +358,7 @@ namespace ARMeilleure.Instructions public static void Fcmgt_V(ArmEmitterContext context) { - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && Optimizations.UseAvx) { EmitCmpSseOrSse2OpF(context, CmpCondition.GreaterThan, scalar: false); } @@ -372,7 +372,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitCmpSseOrSse2OpF(context, CmpCondition.GreaterThanOrEqual, scalar: true, isLeOrLt: true); + EmitCmpSseOrSse2OpF(context, CmpCondition.LessThanOrEqual, scalar: true); } else { @@ -384,7 +384,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitCmpSseOrSse2OpF(context, CmpCondition.GreaterThanOrEqual, scalar: false, isLeOrLt: true); + EmitCmpSseOrSse2OpF(context, CmpCondition.LessThanOrEqual, scalar: false); } else { @@ -396,7 +396,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitCmpSseOrSse2OpF(context, CmpCondition.GreaterThan, scalar: true, isLeOrLt: true); + EmitCmpSseOrSse2OpF(context, CmpCondition.LessThan, scalar: true); } else { @@ -408,7 +408,7 @@ namespace ARMeilleure.Instructions { if (Optimizations.FastFP && Optimizations.UseSse2) { - EmitCmpSseOrSse2OpF(context, CmpCondition.GreaterThan, scalar: false, isLeOrLt: true); + EmitCmpSseOrSse2OpF(context, CmpCondition.LessThan, scalar: false); } else { @@ -426,7 +426,7 @@ namespace ARMeilleure.Instructions EmitFcmpOrFcmpe(context, signalNaNs: true); } - public static void EmitFccmpOrFccmpe(ArmEmitterContext context, bool signalNaNs) + private static void EmitFccmpOrFccmpe(ArmEmitterContext context, bool signalNaNs) { OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp; @@ -435,7 +435,7 @@ namespace ARMeilleure.Instructions context.BranchIfTrue(lblTrue, InstEmitFlowHelper.GetCondTrue(context, op.Cond)); - EmitSetNzcv(context, Const(op.Nzcv)); + EmitSetNzcv(context, op.Nzcv); context.Branch(lblEnd); @@ -446,27 +446,47 @@ namespace ARMeilleure.Instructions context.MarkLabel(lblEnd); } + private static void EmitSetNzcv(ArmEmitterContext context, int nzcv) + { + Operand Extract(int value, int bit) + { + if (bit != 0) + { + value >>= bit; + } + + value &= 1; + + return Const(value); + } + + SetFlag(context, PState.VFlag, Extract(nzcv, 0)); + SetFlag(context, PState.CFlag, Extract(nzcv, 1)); + SetFlag(context, PState.ZFlag, Extract(nzcv, 2)); + SetFlag(context, PState.NFlag, Extract(nzcv, 3)); + } + private static void EmitFcmpOrFcmpe(ArmEmitterContext context, bool signalNaNs) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; - const int cmpOrdered = 7; - bool cmpWithZero = !(op is OpCodeSimdFcond) ? op.Bit3 : false; - if (Optimizations.FastFP && Optimizations.UseSse2) + if (Optimizations.FastFP && (signalNaNs ? Optimizations.UseAvx : Optimizations.UseSse2)) { Operand n = GetVec(op.Rn); Operand m = cmpWithZero ? context.VectorZero() : GetVec(op.Rm); + CmpCondition cmpOrdered = signalNaNs ? CmpCondition.OrderedS : CmpCondition.OrderedQ; + Operand lblNaN = Label(); Operand lblEnd = Label(); if (op.Size == 0) { - Operand ordMask = context.AddIntrinsic(Intrinsic.X86Cmpss, n, m, Const(cmpOrdered)); + Operand ordMask = context.AddIntrinsic(Intrinsic.X86Cmpss, n, m, Const((int)cmpOrdered)); - Operand isOrdered = context.VectorExtract16(ordMask, 0); + Operand isOrdered = context.AddIntrinsicInt(Intrinsic.X86Cvtsi2si, ordMask); context.BranchIfFalse(lblNaN, isOrdered); @@ -481,9 +501,9 @@ namespace ARMeilleure.Instructions } else /* if (op.Size == 1) */ { - Operand ordMask = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, m, Const(cmpOrdered)); + Operand ordMask = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, m, Const((int)cmpOrdered)); - Operand isOrdered = context.VectorExtract16(ordMask, 0); + Operand isOrdered = context.AddIntrinsicLong(Intrinsic.X86Cvtsi2si, ordMask); context.BranchIfFalse(lblNaN, isOrdered); @@ -653,18 +673,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - private enum CmpCondition - { - Equal = 0, - GreaterThanOrEqual = 5, - GreaterThan = 6 - } - - private static void EmitCmpSseOrSse2OpF( - ArmEmitterContext context, - CmpCondition cond, - bool scalar, - bool isLeOrLt = false) + private static void EmitCmpSseOrSse2OpF(ArmEmitterContext context, CmpCondition cond, bool scalar) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -677,9 +686,7 @@ namespace ARMeilleure.Instructions { Intrinsic inst = scalar ? Intrinsic.X86Cmpss : Intrinsic.X86Cmpps; - Operand res = isLeOrLt - ? context.AddIntrinsic(inst, m, n, Const((int)cond)) - : context.AddIntrinsic(inst, n, m, Const((int)cond)); + Operand res = context.AddIntrinsic(inst, n, m, Const((int)cond)); if (scalar) { @@ -696,9 +703,7 @@ namespace ARMeilleure.Instructions { Intrinsic inst = scalar ? Intrinsic.X86Cmpsd : Intrinsic.X86Cmppd; - Operand res = isLeOrLt - ? context.AddIntrinsic(inst, m, n, Const((int)cond)) - : context.AddIntrinsic(inst, n, m, Const((int)cond)); + Operand res = context.AddIntrinsic(inst, n, m, Const((int)cond)); if (scalar) { @@ -709,4 +714,4 @@ namespace ARMeilleure.Instructions } } } -} \ No newline at end of file +} diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt.cs b/ARMeilleure/Instructions/InstEmitSimdCvt.cs index 012bfcce2..e2b6dbd74 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCvt.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCvt.cs @@ -732,8 +732,7 @@ namespace ARMeilleure.Instructions Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64); Debug.Assert((uint)size < 2); - OperandType type = size == 0 ? OperandType.FP32 - : OperandType.FP64; + OperandType type = size == 0 ? OperandType.FP32 : OperandType.FP64; if (signed) { @@ -837,15 +836,12 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); - const int cmpGreaterThanOrEqual = 5; - const int cmpOrdered = 7; - // sizeF == ((OpCodeSimdShImm64)op).Size - 2 int sizeF = op.Size & 1; if (sizeF == 0) { - Operand nMask = context.AddIntrinsic(Intrinsic.X86Cmpps, n, n, Const(cmpOrdered)); + Operand nMask = context.AddIntrinsic(Intrinsic.X86Cmpps, n, n, Const((int)CmpCondition.OrderedQ)); Operand nScaled = context.AddIntrinsic(Intrinsic.X86Pand, nMask, n); @@ -867,7 +863,7 @@ namespace ARMeilleure.Instructions Operand mask = X86GetAllElements(context, 0x4F000000); // 2.14748365E9f (2147483648) - Operand mask2 = context.AddIntrinsic(Intrinsic.X86Cmpps, nRnd, mask, Const(cmpGreaterThanOrEqual)); + Operand mask2 = context.AddIntrinsic(Intrinsic.X86Cmpps, nRnd, mask, Const((int)CmpCondition.NotLessThan)); Operand res = context.AddIntrinsic(Intrinsic.X86Pxor, nInt, mask2); @@ -884,7 +880,7 @@ namespace ARMeilleure.Instructions } else /* if (sizeF == 1) */ { - Operand nMask = context.AddIntrinsic(Intrinsic.X86Cmppd, n, n, Const(cmpOrdered)); + Operand nMask = context.AddIntrinsic(Intrinsic.X86Cmppd, n, n, Const((int)CmpCondition.OrderedQ)); Operand nScaled = context.AddIntrinsic(Intrinsic.X86Pand, nMask, n); @@ -920,7 +916,7 @@ namespace ARMeilleure.Instructions Operand mask = X86GetAllElements(context, 0x43E0000000000000L); // 9.2233720368547760E18d (9223372036854775808) - Operand mask2 = context.AddIntrinsic(Intrinsic.X86Cmppd, nRnd, mask, Const(cmpGreaterThanOrEqual)); + Operand mask2 = context.AddIntrinsic(Intrinsic.X86Cmppd, nRnd, mask, Const((int)CmpCondition.NotLessThan)); Operand res = context.AddIntrinsic(Intrinsic.X86Pxor, nInt, mask2); @@ -939,16 +935,12 @@ namespace ARMeilleure.Instructions Operand n = GetVec(op.Rn); - const int cmpGreaterThanOrEqual = 5; - const int cmpGreaterThan = 6; - const int cmpOrdered = 7; - // sizeF == ((OpCodeSimdShImm)op).Size - 2 int sizeF = op.Size & 1; if (sizeF == 0) { - Operand nMask = context.AddIntrinsic(Intrinsic.X86Cmpps, n, n, Const(cmpOrdered)); + Operand nMask = context.AddIntrinsic(Intrinsic.X86Cmpps, n, n, Const((int)CmpCondition.OrderedQ)); Operand nScaled = context.AddIntrinsic(Intrinsic.X86Pand, nMask, n); @@ -966,7 +958,7 @@ namespace ARMeilleure.Instructions Operand nRnd = context.AddIntrinsic(Intrinsic.X86Roundps, nScaled, Const(X86GetRoundControl(roundMode))); - Operand nRndMask = context.AddIntrinsic(Intrinsic.X86Cmpps, nRnd, context.VectorZero(), Const(cmpGreaterThan)); + Operand nRndMask = context.AddIntrinsic(Intrinsic.X86Cmpps, nRnd, context.VectorZero(), Const((int)CmpCondition.NotLessThanOrEqual)); Operand nRndMasked = context.AddIntrinsic(Intrinsic.X86Pand, nRnd, nRndMask); @@ -976,13 +968,13 @@ namespace ARMeilleure.Instructions Operand res = context.AddIntrinsic(Intrinsic.X86Subps, nRndMasked, mask); - Operand mask2 = context.AddIntrinsic(Intrinsic.X86Cmpps, res, context.VectorZero(), Const(cmpGreaterThan)); + Operand mask2 = context.AddIntrinsic(Intrinsic.X86Cmpps, res, context.VectorZero(), Const((int)CmpCondition.NotLessThanOrEqual)); Operand resMasked = context.AddIntrinsic(Intrinsic.X86Pand, res, mask2); res = context.AddIntrinsic(Intrinsic.X86Cvtps2dq, resMasked); - Operand mask3 = context.AddIntrinsic(Intrinsic.X86Cmpps, resMasked, mask, Const(cmpGreaterThanOrEqual)); + Operand mask3 = context.AddIntrinsic(Intrinsic.X86Cmpps, resMasked, mask, Const((int)CmpCondition.NotLessThan)); res = context.AddIntrinsic(Intrinsic.X86Pxor, res, mask3); res = context.AddIntrinsic(Intrinsic.X86Paddd, res, nInt); @@ -1000,7 +992,7 @@ namespace ARMeilleure.Instructions } else /* if (sizeF == 1) */ { - Operand nMask = context.AddIntrinsic(Intrinsic.X86Cmppd, n, n, Const(cmpOrdered)); + Operand nMask = context.AddIntrinsic(Intrinsic.X86Cmppd, n, n, Const((int)CmpCondition.OrderedQ)); Operand nScaled = context.AddIntrinsic(Intrinsic.X86Pand, nMask, n); @@ -1018,7 +1010,7 @@ namespace ARMeilleure.Instructions Operand nRnd = context.AddIntrinsic(Intrinsic.X86Roundpd, nScaled, Const(X86GetRoundControl(roundMode))); - Operand nRndMask = context.AddIntrinsic(Intrinsic.X86Cmppd, nRnd, context.VectorZero(), Const(cmpGreaterThan)); + Operand nRndMask = context.AddIntrinsic(Intrinsic.X86Cmppd, nRnd, context.VectorZero(), Const((int)CmpCondition.NotLessThanOrEqual)); Operand nRndMasked = context.AddIntrinsic(Intrinsic.X86Pand, nRnd, nRndMask); @@ -1042,7 +1034,7 @@ namespace ARMeilleure.Instructions Operand res = context.AddIntrinsic(Intrinsic.X86Subpd, nRndMasked, mask); - Operand mask2 = context.AddIntrinsic(Intrinsic.X86Cmppd, res, context.VectorZero(), Const(cmpGreaterThan)); + Operand mask2 = context.AddIntrinsic(Intrinsic.X86Cmppd, res, context.VectorZero(), Const((int)CmpCondition.NotLessThanOrEqual)); Operand resMasked = context.AddIntrinsic(Intrinsic.X86Pand, res, mask2); @@ -1056,7 +1048,7 @@ namespace ARMeilleure.Instructions res = EmitVectorLongCreate(context, low, high); - Operand mask3 = context.AddIntrinsic(Intrinsic.X86Cmppd, resMasked, mask, Const(cmpGreaterThanOrEqual)); + Operand mask3 = context.AddIntrinsic(Intrinsic.X86Cmppd, resMasked, mask, Const((int)CmpCondition.NotLessThan)); res = context.AddIntrinsic(Intrinsic.X86Pxor, res, mask3); res = context.AddIntrinsic(Intrinsic.X86Paddq, res, nInt); diff --git a/ARMeilleure/Instructions/InstEmitSimdHelper.cs b/ARMeilleure/Instructions/InstEmitSimdHelper.cs index a3da80fb0..f0880079e 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHelper.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHelper.cs @@ -1108,6 +1108,21 @@ namespace ARMeilleure.Instructions } } + public enum CmpCondition + { + // Legacy Sse. + Equal = 0, // Ordered, non-signaling. + LessThan = 1, // Ordered, signaling. + LessThanOrEqual = 2, // Ordered, signaling. + NotLessThan = 5, // Unordered, signaling. + NotLessThanOrEqual = 6, // Unordered, signaling. + OrderedQ = 7, // Non-signaling. + + // Vex. + GreaterThanOrEqual = 13, // Ordered, signaling. + GreaterThan = 14, // Ordered, signaling. + OrderedS = 23 // Signaling. + } [Flags] public enum SaturatingFlags diff --git a/ARMeilleure/IntermediateRepresentation/Intrinsic.cs b/ARMeilleure/IntermediateRepresentation/Intrinsic.cs index 1fe29e855..e2d3c6dba 100644 --- a/ARMeilleure/IntermediateRepresentation/Intrinsic.cs +++ b/ARMeilleure/IntermediateRepresentation/Intrinsic.cs @@ -26,6 +26,7 @@ namespace ARMeilleure.IntermediateRepresentation X86Cvtps2pd, X86Cvtsd2si, X86Cvtsd2ss, + X86Cvtsi2si, X86Cvtss2sd, X86Divpd, X86Divps, diff --git a/ARMeilleure/Optimizations.cs b/ARMeilleure/Optimizations.cs index 0b9885dc9..28af0936c 100644 --- a/ARMeilleure/Optimizations.cs +++ b/ARMeilleure/Optimizations.cs @@ -15,6 +15,7 @@ namespace ARMeilleure public static bool UseSse41IfAvailable { get; set; } = true; public static bool UseSse42IfAvailable { get; set; } = true; public static bool UsePopCntIfAvailable { get; set; } = true; + public static bool UseAvxIfAvailable { get; set; } = true; public static bool ForceLegacySse { @@ -29,5 +30,6 @@ namespace ARMeilleure internal static bool UseSse41 => UseSse41IfAvailable && HardwareCapabilities.SupportsSse41; internal static bool UseSse42 => UseSse42IfAvailable && HardwareCapabilities.SupportsSse42; internal static bool UsePopCnt => UsePopCntIfAvailable && HardwareCapabilities.SupportsPopcnt; + internal static bool UseAvx => UseAvxIfAvailable && HardwareCapabilities.SupportsAvx && !ForceLegacySse; } } \ No newline at end of file diff --git a/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj b/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj index f01e8ced5..36310f3d2 100644 --- a/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj +++ b/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj @@ -22,7 +22,7 @@ - + diff --git a/Ryujinx.Tests/Ryujinx.Tests.csproj b/Ryujinx.Tests/Ryujinx.Tests.csproj index 143c4cec8..83ec2e964 100644 --- a/Ryujinx.Tests/Ryujinx.Tests.csproj +++ b/Ryujinx.Tests/Ryujinx.Tests.csproj @@ -27,7 +27,7 @@ - +