diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index fb0527455..0dfe0bd31 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -37,14 +37,7 @@ namespace ChocolArm64.Instruction public static void Add_S(AILEmitterCtx Context) { - if (AOptimizations.UseSse2) - { - EmitSse2Call(Context, nameof(Sse2.AddScalar)); - } - else - { - EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Add)); - } + EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Add)); } public static void Add_V(AILEmitterCtx Context) @@ -1132,14 +1125,7 @@ namespace ChocolArm64.Instruction public static void Sub_S(AILEmitterCtx Context) { - if (AOptimizations.UseSse2) - { - EmitSse2Call(Context, nameof(Sse2.SubtractScalar)); - } - else - { - EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub)); - } + EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub)); } public static void Sub_V(AILEmitterCtx Context) diff --git a/ChocolArm64/Instruction/AVectorHelper.cs b/ChocolArm64/Instruction/AVectorHelper.cs index 8ebba7a3d..b9d1e6de7 100644 --- a/ChocolArm64/Instruction/AVectorHelper.cs +++ b/ChocolArm64/Instruction/AVectorHelper.cs @@ -334,10 +334,10 @@ namespace ChocolArm64.Instruction switch (Size) { case 0: - return Sse41.Extract(Sse.StaticCast(Vector), Index); + return ExtractSByte(Vector, Index); case 1: - return Sse2.Extract(Sse.StaticCast(Vector), Index); + return ExtractShort(Vector, Index); case 2: return Sse41.Extract(Sse.StaticCast(Vector), Index); @@ -352,6 +352,22 @@ namespace ChocolArm64.Instruction throw new PlatformNotSupportedException(); } + [MethodImpl(MethodImplOptions.NoInlining)] + private static sbyte ExtractSByte(Vector128 Vector, byte Index) + { + //Workaround to JIT bug. + //https://github.com/dotnet/coreclr/issues/17957 + return Sse41.Extract(Sse.StaticCast(Vector), Index); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static short ExtractShort(Vector128 Vector, byte Index) + { + //Workaround to JIT bug. + //https://github.com/dotnet/coreclr/issues/17957 + return Sse2.Extract(Sse.StaticCast(Vector), Index); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float VectorExtractSingle(Vector128 Vector, byte Index) { diff --git a/Ryujinx.Tests/Cpu/CpuTest.cs b/Ryujinx.Tests/Cpu/CpuTest.cs index 67e836f0f..3ff1e4a0d 100644 --- a/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/Ryujinx.Tests/Cpu/CpuTest.cs @@ -4,7 +4,10 @@ using ChocolArm64.State; using NUnit.Framework; +using System; using System.Threading; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; namespace Ryujinx.Tests.Cpu { @@ -54,7 +57,9 @@ namespace Ryujinx.Tests.Cpu } protected void SetThreadState(ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0, - AVec V0 = default(AVec), AVec V1 = default(AVec), AVec V2 = default(AVec), + Vector128 V0 = default(Vector128), + Vector128 V1 = default(Vector128), + Vector128 V2 = default(Vector128), bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false, int Fpcr = 0x0, int Fpsr = 0x0) { @@ -93,7 +98,9 @@ namespace Ryujinx.Tests.Cpu protected AThreadState SingleOpcode(uint Opcode, ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0, - AVec V0 = default(AVec), AVec V1 = default(AVec), AVec V2 = default(AVec), + Vector128 V0 = default(Vector128), + Vector128 V1 = default(Vector128), + Vector128 V2 = default(Vector128), bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false, int Fpcr = 0x0, int Fpsr = 0x0) { @@ -105,5 +112,42 @@ namespace Ryujinx.Tests.Cpu return GetThreadState(); } + + protected static double VectorExtractDouble(Vector128 Vector, byte Index) + { + long Value = Sse41.Extract(Sse.StaticCast(Vector), Index); + + return BitConverter.Int64BitsToDouble(Value); + } + + protected static Vector128 MakeVectorE0(double A) + { + return Sse.StaticCast(Sse2.SetVector128(0, BitConverter.DoubleToInt64Bits(A))); + } + + protected static Vector128 MakeVectorE0(ulong A) + { + return Sse.StaticCast(Sse2.SetVector128(0, A)); + } + + protected static Vector128 MakeVectorE0E1(ulong A, ulong B) + { + return Sse.StaticCast(Sse2.SetVector128(B, A)); + } + + protected static Vector128 MakeVectorE1(ulong B) + { + return Sse.StaticCast(Sse2.SetVector128(B, 0)); + } + + protected static ulong GetVectorE0(Vector128 Vector) + { + return Sse41.Extract(Sse.StaticCast(Vector), 0); + } + + protected static ulong GetVectorE1(Vector128 Vector) + { + return Sse41.Extract(Sse.StaticCast(Vector), 1); + } } } diff --git a/Ryujinx.Tests/Cpu/CpuTestAlu.cs b/Ryujinx.Tests/Cpu/CpuTestAlu.cs index 564fadec2..1efb2a015 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAlu.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAlu.cs @@ -1,14 +1,9 @@ //#define Alu -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("Alu"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestAlu : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestAluImm.cs b/Ryujinx.Tests/Cpu/CpuTestAluImm.cs index 5d1f0b6ba..73f7bff34 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluImm.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAluImm.cs @@ -1,14 +1,9 @@ //#define AluImm -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("AluImm"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestAluImm : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestAluRs.cs b/Ryujinx.Tests/Cpu/CpuTestAluRs.cs index b81f7100c..2ecaf9973 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluRs.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAluRs.cs @@ -1,14 +1,9 @@ //#define AluRs -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("AluRs"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestAluRs : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestAluRx.cs b/Ryujinx.Tests/Cpu/CpuTestAluRx.cs index 26169bca6..c60d86c14 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluRx.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAluRx.cs @@ -1,14 +1,9 @@ //#define AluRx -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("AluRx"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestAluRx : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestBfm.cs b/Ryujinx.Tests/Cpu/CpuTestBfm.cs index 2952bca4c..f6fd02ce6 100644 --- a/Ryujinx.Tests/Cpu/CpuTestBfm.cs +++ b/Ryujinx.Tests/Cpu/CpuTestBfm.cs @@ -1,14 +1,9 @@ //#define Bfm -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("Bfm"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestBfm : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs b/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs index 38d73878a..915acc3eb 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs +++ b/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs @@ -1,14 +1,9 @@ //#define CcmpImm -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("CcmpImm"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestCcmpImm : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs b/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs index eb1c3abf2..6bec214b3 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs +++ b/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs @@ -1,14 +1,9 @@ //#define CcmpReg -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("CcmpReg"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestCcmpReg : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestCsel.cs b/Ryujinx.Tests/Cpu/CpuTestCsel.cs index 9dd61957f..93683adcb 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCsel.cs +++ b/Ryujinx.Tests/Cpu/CpuTestCsel.cs @@ -1,14 +1,9 @@ //#define Csel -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("Csel"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestCsel : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestMisc.cs b/Ryujinx.Tests/Cpu/CpuTestMisc.cs index 647d46c00..6db653d3f 100644 --- a/Ryujinx.Tests/Cpu/CpuTestMisc.cs +++ b/Ryujinx.Tests/Cpu/CpuTestMisc.cs @@ -2,6 +2,8 @@ using ChocolArm64.State; using NUnit.Framework; +using System.Runtime.Intrinsics.X86; + namespace Ryujinx.Tests.Cpu { [Category("Misc"), Explicit] @@ -73,7 +75,9 @@ namespace Ryujinx.Tests.Cpu RET */ - SetThreadState(V0: new AVec { S0 = A }, V1: new AVec { S0 = B }); + SetThreadState( + V0: Sse.SetScalarVector128(A), + V1: Sse.SetScalarVector128(B)); Opcode(0x1E2E1002); Opcode(0x1E201840); Opcode(0x1E211841); @@ -84,7 +88,7 @@ namespace Ryujinx.Tests.Cpu Opcode(0xD65F03C0); ExecuteOpcodes(); - Assert.That(GetThreadState().V0.S0, Is.EqualTo(16f)); + Assert.That(Sse41.Extract(GetThreadState().V0, 0), Is.EqualTo(16f)); } [TestCase(-20d, -5d)] // 18 integer solutions. @@ -120,7 +124,9 @@ namespace Ryujinx.Tests.Cpu RET */ - SetThreadState(V0: new AVec { D0 = A }, V1: new AVec { D0 = B }); + SetThreadState( + V0: Sse.StaticCast(Sse2.SetScalarVector128(A)), + V1: Sse.StaticCast(Sse2.SetScalarVector128(B))); Opcode(0x1E6E1002); Opcode(0x1E601840); Opcode(0x1E611841); @@ -131,7 +137,7 @@ namespace Ryujinx.Tests.Cpu Opcode(0xD65F03C0); ExecuteOpcodes(); - Assert.That(GetThreadState().V0.D0, Is.EqualTo(16d)); + Assert.That(VectorExtractDouble(GetThreadState().V0, 0), Is.EqualTo(16d)); } [Test] diff --git a/Ryujinx.Tests/Cpu/CpuTestMov.cs b/Ryujinx.Tests/Cpu/CpuTestMov.cs index 9c7e3255a..bd753b213 100644 --- a/Ryujinx.Tests/Cpu/CpuTestMov.cs +++ b/Ryujinx.Tests/Cpu/CpuTestMov.cs @@ -1,14 +1,9 @@ //#define Mov -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("Mov"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestMov : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestMul.cs b/Ryujinx.Tests/Cpu/CpuTestMul.cs index 9bdc1fa65..23aab0370 100644 --- a/Ryujinx.Tests/Cpu/CpuTestMul.cs +++ b/Ryujinx.Tests/Cpu/CpuTestMul.cs @@ -1,14 +1,9 @@ //#define Mul -using ChocolArm64.State; - using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - [Category("Mul"), Ignore("Tested: first half of 2018.")] public sealed class CpuTestMul : CpuTest { diff --git a/Ryujinx.Tests/Cpu/CpuTestScalar.cs b/Ryujinx.Tests/Cpu/CpuTestScalar.cs index c7c3aa051..d1a0c3131 100644 --- a/Ryujinx.Tests/Cpu/CpuTestScalar.cs +++ b/Ryujinx.Tests/Cpu/CpuTestScalar.cs @@ -1,6 +1,9 @@ using ChocolArm64.State; + using NUnit.Framework; +using System.Runtime.Intrinsics.X86; + namespace Ryujinx.Tests.Cpu { public class CpuTestScalar : CpuTest @@ -25,8 +28,10 @@ namespace Ryujinx.Tests.Cpu public void Fmax_S(uint Opcode, ulong A, ulong B, ulong Result) { // FMAX S0, S1, S2 - AThreadState ThreadState = SingleOpcode(Opcode, V1: new AVec { X0 = A }, V2: new AVec { X0 = B }); - Assert.AreEqual(Result, ThreadState.V0.X0); + AThreadState ThreadState = SingleOpcode(Opcode, + V1: Sse.StaticCast(Sse2.SetVector128(0, A)), + V2: Sse.StaticCast(Sse2.SetVector128(0, B))); + Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast(ThreadState.V0), 0)); } [TestCase(0x1E225820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000080000000ul)] @@ -49,8 +54,10 @@ namespace Ryujinx.Tests.Cpu public void Fmin_S(uint Opcode, ulong A, ulong B, ulong Result) { // FMIN S0, S1, S2 - AThreadState ThreadState = SingleOpcode(Opcode, V1: new AVec { X0 = A }, V2: new AVec { X0 = B }); - Assert.AreEqual(Result, ThreadState.V0.X0); + AThreadState ThreadState = SingleOpcode(Opcode, + V1: Sse.StaticCast(Sse2.SetVector128(0, A)), + V2: Sse.StaticCast(Sse2.SetVector128(0, B))); + Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast(ThreadState.V0), 0)); } } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimd.cs b/Ryujinx.Tests/Cpu/CpuTestSimd.cs index 95fca86a3..e2adc9955 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimd.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimd.cs @@ -4,6 +4,8 @@ using ChocolArm64.State; using NUnit.Framework; +using System.Runtime.Intrinsics; + namespace Ryujinx.Tests.Cpu { using Tester; @@ -74,8 +76,8 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x5EE0B820; // ABS D0, D1 Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.V(1, new Bits(A)); @@ -83,8 +85,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -96,8 +98,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.V(1, new Bits(A)); @@ -105,8 +107,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -119,7 +121,7 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -128,8 +130,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -140,8 +142,8 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x5EF1B820; // ADDP D0, V1.2D Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -150,8 +152,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -163,9 +165,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = TestContext.CurrentContext.Random.NextULong(), - X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), + TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(0, 0, new Bits(TestContext.CurrentContext.Random.NextULong())); @@ -174,8 +176,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -188,9 +190,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = TestContext.CurrentContext.Random.NextULong(), - X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V0 = MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), + TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(0, 0, new Bits(TestContext.CurrentContext.Random.NextULong())); @@ -200,8 +202,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -213,8 +215,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.V(1, new Bits(A)); @@ -222,8 +224,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -236,7 +238,7 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -245,8 +247,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -258,8 +260,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.V(1, new Bits(A)); @@ -267,8 +269,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -281,7 +283,7 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -290,8 +292,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -301,8 +303,8 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x7EE0B820; // NEG D0, D1 Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.V(1, new Bits(A)); @@ -310,8 +312,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -323,8 +325,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.V(1, new Bits(A)); @@ -332,8 +334,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -346,7 +348,7 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -355,8 +357,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -368,9 +370,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = TestContext.CurrentContext.Random.NextULong(), - X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), + TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(0, 0, new Bits(TestContext.CurrentContext.Random.NextULong())); @@ -379,8 +381,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); Assert.That(((ThreadState.Fpsr >> 27) & 1) != 0, Is.EqualTo(Shared.FPSR[27])); // FIXME: Temporary solution. } @@ -394,8 +396,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -404,8 +406,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); Assert.That(((ThreadState.Fpsr >> 27) & 1) != 0, Is.EqualTo(Shared.FPSR[27])); // FIXME: Temporary solution. } @@ -420,8 +422,8 @@ namespace Ryujinx.Tests.Cpu Bits Op = new Bits(Opcode); ulong _X0 = TestContext.CurrentContext.Random.NextULong(); - AVec V0 = new AVec { X0 = _X0 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V0 = MakeVectorE0(_X0); + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -430,8 +432,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0)); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(_X0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); Assert.That(((ThreadState.Fpsr >> 27) & 1) != 0, Is.EqualTo(Shared.FPSR[27])); // FIXME: Temporary solution. } @@ -444,9 +446,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = TestContext.CurrentContext.Random.NextULong(), - X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; + Vector128 V0 = MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), + TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(0, 0, new Bits(TestContext.CurrentContext.Random.NextULong())); @@ -455,8 +457,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); Assert.That(((ThreadState.Fpsr >> 27) & 1) != 0, Is.EqualTo(Shared.FPSR[27])); // FIXME: Temporary solution. } @@ -470,8 +472,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -480,8 +482,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); Assert.That(((ThreadState.Fpsr >> 27) & 1) != 0, Is.EqualTo(Shared.FPSR[27])); // FIXME: Temporary solution. } @@ -496,8 +498,8 @@ namespace Ryujinx.Tests.Cpu Bits Op = new Bits(Opcode); ulong _X0 = TestContext.CurrentContext.Random.NextULong(); - AVec V0 = new AVec { X0 = _X0 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; + Vector128 V0 = MakeVectorE0(_X0); + Vector128 V1 = MakeVectorE0E1(A0, A1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); AArch64.Vpart(1, 0, new Bits(A0)); @@ -506,8 +508,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0)); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(_X0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); Assert.That(((ThreadState.Fpsr >> 27) & 1) != 0, Is.EqualTo(Shared.FPSR[27])); // FIXME: Temporary solution. } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs b/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs index f32fe398d..f4982c1b2 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs @@ -1,6 +1,10 @@ using ChocolArm64.State; + using NUnit.Framework; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + namespace Ryujinx.Tests.Cpu { public class CpuTestSimdArithmetic : CpuTest @@ -35,13 +39,13 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x4EE28420u, 0x0102030405060708ul, 0xAAAAAAAAAAAAAAAAul, 0x0807060504030201ul, 0x2222222222222222ul, 0x0909090909090909ul, 0xCCCCCCCCCCCCCCCCul)] public void Add_V(uint Opcode, ulong A0, ulong A1, ulong B0, ulong B1, ulong Result0, ulong Result1) { - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } @@ -61,13 +65,13 @@ namespace Ryujinx.Tests.Cpu public void Fmax_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1) { uint Opcode = 0x4E22F420; - AVec V1 = new AVec { X0 = A, X1 = B }; - AVec V2 = new AVec { X0 = C, X1 = D }; + Vector128 V1 = MakeVectorE0E1(A, B); + Vector128 V2 = MakeVectorE0E1(C, D); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } @@ -87,63 +91,68 @@ namespace Ryujinx.Tests.Cpu public void Fmin_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1) { uint Opcode = 0x4EA2F420; - AVec V1 = new AVec { X0 = A, X1 = B }; - AVec V2 = new AVec { X0 = C, X1 = D }; + Vector128 V1 = MakeVectorE0E1(A, B); + Vector128 V2 = MakeVectorE0E1(C, D); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } [Test, Description("fmul s6, s1, v0.s[2]")] public void Fmul_Se([Random(10)] float A, [Random(10)] float B) { - AThreadState ThreadState = SingleOpcode(0x5F809826, V1: new AVec { S0 = A }, V0: new AVec { S2 = B }); + AThreadState ThreadState = SingleOpcode(0x5F809826, + V1: Sse.SetVector128(0, 0, 0, A), + V0: Sse.SetVector128(0, B, 0, 0)); - Assert.That(ThreadState.V6.S0, Is.EqualTo(A * B)); + Assert.That(Sse41.Extract(ThreadState.V6, (byte)0), Is.EqualTo(A * B)); } [Test, Description("frecpe v2.4s, v0.4s")] public void Frecpe_V([Random(100)] float A) { - AThreadState ThreadState = SingleOpcode(0x4EA1D802, V0: new AVec { S0 = A, S1 = A, S2 = A, S3 = A }); + AThreadState ThreadState = SingleOpcode(0x4EA1D802, V0: Sse.SetAllVector128(A)); - Assert.That(ThreadState.V2.S0, Is.EqualTo(1 / A)); - Assert.That(ThreadState.V2.S1, Is.EqualTo(1 / A)); - Assert.That(ThreadState.V2.S2, Is.EqualTo(1 / A)); - Assert.That(ThreadState.V2.S3, Is.EqualTo(1 / A)); + Assert.That(Sse41.Extract(ThreadState.V2, (byte)0), Is.EqualTo(1 / A)); + Assert.That(Sse41.Extract(ThreadState.V2, (byte)1), Is.EqualTo(1 / A)); + Assert.That(Sse41.Extract(ThreadState.V2, (byte)2), Is.EqualTo(1 / A)); + Assert.That(Sse41.Extract(ThreadState.V2, (byte)3), Is.EqualTo(1 / A)); } [Test, Description("frecpe d0, d1")] public void Frecpe_S([Random(100)] double A) { - AThreadState ThreadState = SingleOpcode(0x5EE1D820, V1: new AVec { D0 = A }); + AThreadState ThreadState = SingleOpcode(0x5EE1D820, V1: MakeVectorE0(A)); - Assert.That(ThreadState.V0.D0, Is.EqualTo(1 / A)); + Assert.That(VectorExtractDouble(ThreadState.V0, 0), Is.EqualTo(1 / A)); } [Test, Description("frecps v4.4s, v2.4s, v0.4s")] public void Frecps_V([Random(10)] float A, [Random(10)] float B) { - AThreadState ThreadState = SingleOpcode(0x4E20FC44, V2: new AVec { S0 = A, S1 = A, S2 = A, S3 = A }, - V0: new AVec { S0 = B, S1 = B, S2 = B, S3 = B }); + AThreadState ThreadState = SingleOpcode(0x4E20FC44, + V2: Sse.SetAllVector128(A), + V0: Sse.SetAllVector128(B)); - Assert.That(ThreadState.V4.S0, Is.EqualTo(2 - (A * B))); - Assert.That(ThreadState.V4.S1, Is.EqualTo(2 - (A * B))); - Assert.That(ThreadState.V4.S2, Is.EqualTo(2 - (A * B))); - Assert.That(ThreadState.V4.S3, Is.EqualTo(2 - (A * B))); + Assert.That(Sse41.Extract(ThreadState.V4, (byte)0), Is.EqualTo(2 - (A * B))); + Assert.That(Sse41.Extract(ThreadState.V4, (byte)1), Is.EqualTo(2 - (A * B))); + Assert.That(Sse41.Extract(ThreadState.V4, (byte)2), Is.EqualTo(2 - (A * B))); + Assert.That(Sse41.Extract(ThreadState.V4, (byte)3), Is.EqualTo(2 - (A * B))); } [Test, Description("frecps d0, d1, d2")] public void Frecps_S([Random(10)] double A, [Random(10)] double B) { - AThreadState ThreadState = SingleOpcode(0x5E62FC20, V1: new AVec { D0 = A }, V2: new AVec { D0 = B }); + AThreadState ThreadState = SingleOpcode(0x5E62FC20, + V1: MakeVectorE0(A), + V2: MakeVectorE0(B)); - Assert.That(ThreadState.V0.D0, Is.EqualTo(2 - (A * B))); + Assert.That(VectorExtractDouble(ThreadState.V0, 0), Is.EqualTo(2 - (A * B))); } - + [TestCase(0x3FE66666u, false, 0x40000000u)] [TestCase(0x3F99999Au, false, 0x3F800000u)] [TestCase(0x404CCCCDu, false, 0x40400000u)] @@ -189,17 +198,17 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp = 0x2000000; } - AVec V1 = new AVec { X0 = A }; + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, ThreadState.V0.X0); + Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); } [TestCase(0x6E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [TestCase(0x6E618820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x6E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x3f80000040000000ul)] - [TestCase(0x6E219820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] - [TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x0000000000000000ul)] + [TestCase(0x6E219820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] + [TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x0000000000000000ul)] [TestCase(0x2E219820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] [TestCase(0x2E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] [TestCase(0x2E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] @@ -212,12 +221,12 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp = 0x2000000; } - AVec V1 = new AVec { X0 = A, X1 = B }; + Vector128 V1 = MakeVectorE0E1(A, B); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } @@ -286,9 +295,9 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp |= 1 << 25; } - AVec V1 = new AVec { X0 = A }; + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(0x1E27C020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, ThreadState.V0.X0); + Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); } [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] @@ -300,11 +309,11 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x3f80000040000000ul)] - [TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)] + [TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)] [TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)] [TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)] [TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x0000000000000000ul)] - [TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)] + [TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)] [TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x0000000000000000ul)] [TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x0000000000000000ul)] [TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)] @@ -348,12 +357,12 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp |= 1 << 25; } - AVec V1 = new AVec { X0 = A, X1 = B }; + Vector128 V1 = MakeVectorE0E1(A, B); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } @@ -402,15 +411,15 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp = 0x2000000; } - AVec V1 = new AVec { X0 = A }; + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(0x1E254020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, ThreadState.V0.X0); + Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); } [TestCase(0x4E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [TestCase(0x4E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] - [TestCase(0x4E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)] - [TestCase(0xE219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f8000003f800000ul, 0x0000000000000000ul)] + [TestCase(0x4E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)] + [TestCase(0xE219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f8000003f800000ul, 0x0000000000000000ul)] [TestCase(0xE219820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] [TestCase(0xE219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] [TestCase(0xE219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")] @@ -422,12 +431,12 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp = 0x2000000; } - AVec V1 = new AVec { X0 = A, X1 = B }; + Vector128 V1 = MakeVectorE0E1(A, B); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } @@ -476,17 +485,17 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp = 0x2000000; } - AVec V1 = new AVec { X0 = A }; + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, ThreadState.V0.X0); + Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); } [TestCase(0x4E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [TestCase(0x4E618820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x4E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x4E218820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x3f80000040000000ul)] - [TestCase(0x4E218820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] - [TestCase(0xE218820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x0000000000000000ul)] + [TestCase(0x4E218820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] + [TestCase(0xE218820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x0000000000000000ul)] [TestCase(0xE218820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] [TestCase(0xE218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] [TestCase(0xE218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] @@ -499,12 +508,12 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp = 0x2000000; } - AVec V1 = new AVec { X0 = A, X1 = B }; + Vector128 V1 = MakeVectorE0E1(A, B); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } @@ -553,15 +562,15 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp = 0x2000000; } - AVec V1 = new AVec { X0 = A }; + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(0x1E24C020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, ThreadState.V0.X0); + Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); } [TestCase(0x4EE18820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x4EE18820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)] - [TestCase(0x4EA18820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] - [TestCase(0xEA18820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] + [TestCase(0x4EA18820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] + [TestCase(0xEA18820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] [TestCase(0xEA18820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] [TestCase(0xEA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] [TestCase(0xEA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")] @@ -573,12 +582,12 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp = 0x2000000; } - AVec V1 = new AVec { X0 = A, X1 = B }; + Vector128 V1 = MakeVectorE0E1(A, B); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } @@ -647,9 +656,9 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp |= 1 << 25; } - AVec V1 = new AVec { X0 = A }; + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(0x1E274020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, ThreadState.V0.X0); + Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); } [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] @@ -661,11 +670,11 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x3f80000040000000ul)] - [TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)] + [TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)] [TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)] [TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)] [TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x0000000000000000ul)] - [TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)] + [TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)] [TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x0000000000000000ul)] [TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x0000000000000000ul)] [TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)] @@ -709,21 +718,21 @@ namespace Ryujinx.Tests.Cpu { FpcrTemp |= 1 << 25; } - AVec V1 = new AVec { X0 = A, X1 = B }; + Vector128 V1 = MakeVectorE0E1(A, B); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); Assert.Multiple(() => { - Assert.AreEqual(Result0, ThreadState.V0.X0); - Assert.AreEqual(Result1, ThreadState.V0.X1); + Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); }); } [TestCase(0x41200000u, 0x3EA18000u)] public void Frsqrte_S(uint A, uint Result) { - AVec V1 = new AVec { X0 = A }; + Vector128 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(0x7EA1D820, V1: V1); - Assert.AreEqual(Result, ThreadState.V0.X0); + Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); } } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdMove.cs b/Ryujinx.Tests/Cpu/CpuTestSimdMove.cs index 0681b6139..e2766a166 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdMove.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdMove.cs @@ -1,6 +1,10 @@ using ChocolArm64.State; + using NUnit.Framework; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + namespace Ryujinx.Tests.Cpu { public class CpuTestSimdMove : CpuTest @@ -10,15 +14,17 @@ namespace Ryujinx.Tests.Cpu [Random(2)] uint B0, [Random(2)] uint B1, [Random(2)] uint B2, [Random(2)] uint B3) { uint Opcode = 0x4E822820; - AVec V1 = new AVec { W0 = A0, W1 = A1, W2 = A2, W3 = A3 }; - AVec V2 = new AVec { W0 = B0, W1 = B1, W2 = B2, W3 = B3 }; + Vector128 V1 = Sse.StaticCast(Sse2.SetVector128(A3, A2, A1, A0)); + Vector128 V2 = Sse.StaticCast(Sse2.SetVector128(B3, B2, B1, B0)); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); - Assert.That(ThreadState.V0.W0, Is.EqualTo(A0)); - Assert.That(ThreadState.V0.W1, Is.EqualTo(B0)); - Assert.That(ThreadState.V0.W2, Is.EqualTo(A2)); - Assert.That(ThreadState.V0.W3, Is.EqualTo(B2)); + Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)0); + + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)0), Is.EqualTo(A0)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)1), Is.EqualTo(B0)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)2), Is.EqualTo(A2)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)3), Is.EqualTo(B2)); } [Test, Description("trn1 v0.8b, v1.8b, v2.8b")] @@ -28,19 +34,19 @@ namespace Ryujinx.Tests.Cpu [Random(2)] byte B4, [Random(1)] byte B5, [Random(2)] byte B6, [Random(1)] byte B7) { uint Opcode = 0x0E022820; - AVec V1 = new AVec { B0 = A0, B1 = A1, B2 = A2, B3 = A3, B4 = A4, B5 = A5, B6 = A6, B7 = A7 }; - AVec V2 = new AVec { B0 = B0, B1 = B1, B2 = B2, B3 = B3, B4 = B4, B5 = B5, B6 = B6, B7 = B7 }; + Vector128 V1 = Sse.StaticCast(Sse2.SetVector128(0, 0, 0, 0, 0, 0, 0, 0, A7, A6, A5, A4, A3, A2, A1, A0)); + Vector128 V2 = Sse.StaticCast(Sse2.SetVector128(0, 0, 0, 0, 0, 0, 0, 0, B7, B6, B5, B4, B3, B2, B1, B0)); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); - Assert.That(ThreadState.V0.B0, Is.EqualTo(A0)); - Assert.That(ThreadState.V0.B1, Is.EqualTo(B0)); - Assert.That(ThreadState.V0.B2, Is.EqualTo(A2)); - Assert.That(ThreadState.V0.B3, Is.EqualTo(B2)); - Assert.That(ThreadState.V0.B4, Is.EqualTo(A4)); - Assert.That(ThreadState.V0.B5, Is.EqualTo(B4)); - Assert.That(ThreadState.V0.B6, Is.EqualTo(A6)); - Assert.That(ThreadState.V0.B7, Is.EqualTo(B6)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)0), Is.EqualTo(A0)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)1), Is.EqualTo(B0)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)2), Is.EqualTo(A2)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)3), Is.EqualTo(B2)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)4), Is.EqualTo(A4)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)5), Is.EqualTo(B4)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)6), Is.EqualTo(A6)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)7), Is.EqualTo(B6)); } [Test, Description("trn2 v0.4s, v1.4s, v2.4s")] @@ -48,15 +54,15 @@ namespace Ryujinx.Tests.Cpu [Random(2)] uint B0, [Random(2)] uint B1, [Random(2)] uint B2, [Random(2)] uint B3) { uint Opcode = 0x4E826820; - AVec V1 = new AVec { W0 = A0, W1 = A1, W2 = A2, W3 = A3 }; - AVec V2 = new AVec { W0 = B0, W1 = B1, W2 = B2, W3 = B3 }; + Vector128 V1 = Sse.StaticCast(Sse2.SetVector128(A3, A2, A1, A0)); + Vector128 V2 = Sse.StaticCast(Sse2.SetVector128(B3, B2, B1, B0)); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); - Assert.That(ThreadState.V0.W0, Is.EqualTo(A1)); - Assert.That(ThreadState.V0.W1, Is.EqualTo(B1)); - Assert.That(ThreadState.V0.W2, Is.EqualTo(A3)); - Assert.That(ThreadState.V0.W3, Is.EqualTo(B3)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)0), Is.EqualTo(A1)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)1), Is.EqualTo(B1)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)2), Is.EqualTo(A3)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)3), Is.EqualTo(B3)); } [Test, Description("trn2 v0.8b, v1.8b, v2.8b")] @@ -66,19 +72,19 @@ namespace Ryujinx.Tests.Cpu [Random(1)] byte B4, [Random(2)] byte B5, [Random(1)] byte B6, [Random(2)] byte B7) { uint Opcode = 0x0E026820; - AVec V1 = new AVec { B0 = A0, B1 = A1, B2 = A2, B3 = A3, B4 = A4, B5 = A5, B6 = A6, B7 = A7 }; - AVec V2 = new AVec { B0 = B0, B1 = B1, B2 = B2, B3 = B3, B4 = B4, B5 = B5, B6 = B6, B7 = B7 }; + Vector128 V1 = Sse.StaticCast(Sse2.SetVector128(0, 0, 0, 0, 0, 0, 0, 0, A7, A6, A5, A4, A3, A2, A1, A0)); + Vector128 V2 = Sse.StaticCast(Sse2.SetVector128(0, 0, 0, 0, 0, 0, 0, 0, B7, B6, B5, B4, B3, B2, B1, B0)); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); - Assert.That(ThreadState.V0.B0, Is.EqualTo(A1)); - Assert.That(ThreadState.V0.B1, Is.EqualTo(B1)); - Assert.That(ThreadState.V0.B2, Is.EqualTo(A3)); - Assert.That(ThreadState.V0.B3, Is.EqualTo(B3)); - Assert.That(ThreadState.V0.B4, Is.EqualTo(A5)); - Assert.That(ThreadState.V0.B5, Is.EqualTo(B5)); - Assert.That(ThreadState.V0.B6, Is.EqualTo(A7)); - Assert.That(ThreadState.V0.B7, Is.EqualTo(B7)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)0), Is.EqualTo(A1)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)1), Is.EqualTo(B1)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)2), Is.EqualTo(A3)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)3), Is.EqualTo(B3)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)4), Is.EqualTo(A5)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)5), Is.EqualTo(B5)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)6), Is.EqualTo(A7)); + Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V0), (byte)7), Is.EqualTo(B7)); } [TestCase(0u, 0u, 0x2313221221112010ul, 0x0000000000000000ul)] @@ -92,11 +98,11 @@ namespace Ryujinx.Tests.Cpu { // ZIP1 V0., V1., V2. uint Opcode = 0x0E023820 | (Q << 30) | (size << 22); - AVec V1 = new AVec { X0 = 0x1716151413121110, X1 = 0x1F1E1D1C1B1A1918 }; - AVec V2 = new AVec { X0 = 0x2726252423222120, X1 = 0x2F2E2D2C2B2A2928 }; + Vector128 V1 = MakeVectorE0E1(0x1716151413121110, 0x1F1E1D1C1B1A1918); + Vector128 V2 = MakeVectorE0E1(0x2726252423222120, 0x2F2E2D2C2B2A2928); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); - Assert.AreEqual(Result_0, ThreadState.V0.X0); - Assert.AreEqual(Result_1, ThreadState.V0.X1); + Assert.AreEqual(Result_0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result_1, GetVectorE1(ThreadState.V0)); } [TestCase(0u, 0u, 0x2717261625152414ul, 0x0000000000000000ul)] @@ -110,11 +116,11 @@ namespace Ryujinx.Tests.Cpu { // ZIP2 V0., V1., V2. uint Opcode = 0x0E027820 | (Q << 30) | (size << 22); - AVec V1 = new AVec { X0 = 0x1716151413121110, X1 = 0x1F1E1D1C1B1A1918 }; - AVec V2 = new AVec { X0 = 0x2726252423222120, X1 = 0x2F2E2D2C2B2A2928 }; + Vector128 V1 = MakeVectorE0E1(0x1716151413121110, 0x1F1E1D1C1B1A1918); + Vector128 V2 = MakeVectorE0E1(0x2726252423222120, 0x2F2E2D2C2B2A2928); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); - Assert.AreEqual(Result_0, ThreadState.V0.X0); - Assert.AreEqual(Result_1, ThreadState.V0.X1); + Assert.AreEqual(Result_0, GetVectorE0(ThreadState.V0)); + Assert.AreEqual(Result_1, GetVectorE1(ThreadState.V0)); } } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs b/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs index e9d53eb76..88aebfbe7 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs @@ -4,6 +4,8 @@ using ChocolArm64.State; using NUnit.Framework; +using System.Runtime.Intrinsics; + namespace Ryujinx.Tests.Cpu { using Tester; @@ -65,9 +67,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x5EE28420; // ADD D0, D1, D2 Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -76,8 +78,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -90,9 +92,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -101,8 +103,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -117,8 +119,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -129,8 +131,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -145,9 +147,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -158,8 +160,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -175,9 +177,9 @@ namespace Ryujinx.Tests.Cpu Bits Op = new Bits(Opcode); ulong _X0 = TestContext.CurrentContext.Random.NextULong(); - AVec V0 = new AVec { X0 = _X0 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE0(_X0); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -188,8 +190,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0)); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(_X0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -202,9 +204,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -213,8 +215,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -229,8 +231,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -241,8 +243,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -253,9 +255,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E221C20; // AND V0.8B, V1.8B, V2.8B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -264,8 +266,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -278,8 +280,8 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E221C20; // AND V0.16B, V1.16B, V2.16B Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -290,8 +292,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -302,9 +304,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E621C20; // BIC V0.8B, V1.8B, V2.8B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -313,8 +315,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -327,8 +329,8 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E621C20; // BIC V0.16B, V1.16B, V2.16B Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -339,8 +341,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -352,9 +354,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2EE21C20; // BIF V0.8B, V1.8B, V2.8B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = _Z, X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE0E1(_Z, TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(0, 0, new Bits(_Z)); @@ -364,8 +366,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -380,9 +382,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6EE21C20; // BIF V0.16B, V1.16B, V2.16B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = _Z0, X1 = _Z1 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE0E1(_Z0, _Z1); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(0, 0, new Bits(_Z0)); @@ -395,8 +397,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -408,9 +410,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2EA21C20; // BIT V0.8B, V1.8B, V2.8B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = _Z, X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE0E1(_Z, TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(0, 0, new Bits(_Z)); @@ -420,8 +422,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -436,9 +438,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6EA21C20; // BIT V0.16B, V1.16B, V2.16B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = _Z0, X1 = _Z1 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE0E1(_Z0, _Z1); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(0, 0, new Bits(_Z0)); @@ -451,8 +453,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -464,9 +466,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E621C20; // BSL V0.8B, V1.8B, V2.8B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = _Z, X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE0E1(_Z, TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(0, 0, new Bits(_Z)); @@ -476,8 +478,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -492,9 +494,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E621C20; // BSL V0.16B, V1.16B, V2.16B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X0 = _Z0, X1 = _Z1 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE0E1(_Z0, _Z1); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(0, 0, new Bits(_Z0)); @@ -507,8 +509,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -519,9 +521,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0EE21C20; // ORN V0.8B, V1.8B, V2.8B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -530,8 +532,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -544,8 +546,8 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4EE21C20; // ORN V0.16B, V1.16B, V2.16B Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -556,8 +558,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -568,9 +570,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0EA21C20; // ORR V0.8B, V1.8B, V2.8B Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -579,8 +581,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -593,8 +595,8 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4EA21C20; // ORR V0.16B, V1.16B, V2.16B Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -605,8 +607,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -621,9 +623,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -634,8 +636,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -651,9 +653,9 @@ namespace Ryujinx.Tests.Cpu Bits Op = new Bits(Opcode); ulong _X0 = TestContext.CurrentContext.Random.NextULong(); - AVec V0 = new AVec { X0 = _X0 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE0(_X0); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -664,8 +666,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0)); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(_X0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -680,9 +682,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -693,8 +695,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -710,9 +712,9 @@ namespace Ryujinx.Tests.Cpu Bits Op = new Bits(Opcode); ulong _X0 = TestContext.CurrentContext.Random.NextULong(); - AVec V0 = new AVec { X0 = _X0 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE0(_X0); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -723,8 +725,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0)); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(_X0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -735,9 +737,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x7EE28420; // SUB D0, D1, D2 Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -746,8 +748,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -760,9 +762,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A }; - AVec V2 = new AVec { X0 = B }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.V(1, new Bits(A)); @@ -771,8 +773,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -787,8 +789,8 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -799,8 +801,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } @@ -815,9 +817,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= ((size & 3) << 22); Bits Op = new Bits(Opcode); - AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE1(TestContext.CurrentContext.Random.NextULong()); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -828,8 +830,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64())); - Assert.That(ThreadState.V0.X1, Is.Zero); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.V(64, 0).ToUInt64())); + Assert.That(GetVectorE1(ThreadState.V0), Is.Zero); }); } @@ -845,9 +847,9 @@ namespace Ryujinx.Tests.Cpu Bits Op = new Bits(Opcode); ulong _X0 = TestContext.CurrentContext.Random.NextULong(); - AVec V0 = new AVec { X0 = _X0 }; - AVec V1 = new AVec { X0 = A0, X1 = A1 }; - AVec V2 = new AVec { X0 = B0, X1 = B1 }; + Vector128 V0 = MakeVectorE0(_X0); + Vector128 V1 = MakeVectorE0E1(A0, A1); + Vector128 V2 = MakeVectorE0E1(B0, B1); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); AArch64.Vpart(1, 0, new Bits(A0)); @@ -858,8 +860,8 @@ namespace Ryujinx.Tests.Cpu Assert.Multiple(() => { - Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0)); - Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(_X0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64())); }); } #endif