From ca1e37a29553f97ecf574fb3678422dd93a2b91d Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Sat, 8 Sep 2018 19:23:07 +0200 Subject: [PATCH] Remove old Tester, update Tests (some reworks). (#400) * Delete Bits.cs * Delete Integer.cs * Delete Instructions.cs * Delete Pseudocode.cs * Add files via upload * Add mnemonic. * Literals all uppercase. * Nit. * Allow FPSR control. * Allow FPSR control. * Allow FPSR control. --- Ryujinx.Tests/Cpu/CpuTest.cs | 103 +- Ryujinx.Tests/Cpu/CpuTestAlu.cs | 223 +- Ryujinx.Tests/Cpu/CpuTestAluImm.cs | 556 +- Ryujinx.Tests/Cpu/CpuTestAluRs.cs | 1337 +--- Ryujinx.Tests/Cpu/CpuTestAluRx.cs | 825 +-- Ryujinx.Tests/Cpu/CpuTestBfm.cs | 159 +- Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs | 99 +- Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs | 102 +- Ryujinx.Tests/Cpu/CpuTestCsel.cs | 189 +- Ryujinx.Tests/Cpu/CpuTestMisc.cs | 66 +- Ryujinx.Tests/Cpu/CpuTestMov.cs | 127 +- Ryujinx.Tests/Cpu/CpuTestMul.cs | 257 +- Ryujinx.Tests/Cpu/CpuTestSimd.cs | 1058 +-- Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs | 391 +- Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs | 52 +- Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs | 8 + Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs | 4 +- Ryujinx.Tests/Cpu/CpuTestSimdReg.cs | 1772 +---- Ryujinx.Tests/Cpu/Tester/Instructions.cs | 7346 -------------------- Ryujinx.Tests/Cpu/Tester/Pseudocode.cs | 1740 ----- Ryujinx.Tests/Cpu/Tester/Types/Bits.cs | 282 - Ryujinx.Tests/Cpu/Tester/Types/Integer.cs | 42 - 22 files changed, 1354 insertions(+), 15384 deletions(-) delete mode 100644 Ryujinx.Tests/Cpu/Tester/Instructions.cs delete mode 100644 Ryujinx.Tests/Cpu/Tester/Pseudocode.cs delete mode 100644 Ryujinx.Tests/Cpu/Tester/Types/Bits.cs delete mode 100644 Ryujinx.Tests/Cpu/Tester/Types/Integer.cs diff --git a/Ryujinx.Tests/Cpu/CpuTest.cs b/Ryujinx.Tests/Cpu/CpuTest.cs index 6e013aa0..1f7151ff 100644 --- a/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/Ryujinx.Tests/Cpu/CpuTest.cs @@ -33,9 +33,10 @@ namespace Ryujinx.Tests.Cpu static CpuTest() { UnicornAvailable = UnicornAArch64.IsAvailable(); + if (!UnicornAvailable) { - Console.WriteLine("WARNING: Could not find unicorn"); + Console.WriteLine("WARNING: Could not find Unicorn."); } } @@ -43,7 +44,7 @@ namespace Ryujinx.Tests.Cpu public void Setup() { Position = 0x1000; - Size = 0x1000; + Size = 0x1000; EntryPoint = Position; @@ -79,10 +80,12 @@ namespace Ryujinx.Tests.Cpu protected void Opcode(uint Opcode) { Thread.Memory.WriteUInt32(Position, Opcode); + if (UnicornAvailable) { UnicornEmu.MemoryWrite32((ulong)Position, Opcode); } + Position += 4; } @@ -97,14 +100,18 @@ namespace Ryujinx.Tests.Cpu Thread.ThreadState.X1 = X1; Thread.ThreadState.X2 = X2; Thread.ThreadState.X3 = X3; + Thread.ThreadState.X31 = X31; + Thread.ThreadState.V0 = V0; Thread.ThreadState.V1 = V1; Thread.ThreadState.V2 = V2; + Thread.ThreadState.Overflow = Overflow; - Thread.ThreadState.Carry = Carry; - Thread.ThreadState.Zero = Zero; + Thread.ThreadState.Carry = Carry; + Thread.ThreadState.Zero = Zero; Thread.ThreadState.Negative = Negative; + Thread.ThreadState.Fpcr = Fpcr; Thread.ThreadState.Fpsr = Fpsr; @@ -114,14 +121,18 @@ namespace Ryujinx.Tests.Cpu UnicornEmu.X[1] = X1; UnicornEmu.X[2] = X2; UnicornEmu.X[3] = X3; + UnicornEmu.SP = X31; + UnicornEmu.Q[0] = V0; UnicornEmu.Q[1] = V1; UnicornEmu.Q[2] = V2; + UnicornEmu.OverflowFlag = Overflow; - UnicornEmu.CarryFlag = Carry; - UnicornEmu.ZeroFlag = Zero; + UnicornEmu.CarryFlag = Carry; + UnicornEmu.ZeroFlag = Zero; UnicornEmu.NegativeFlag = Negative; + UnicornEmu.Fpcr = Fpcr; UnicornEmu.Fpsr = Fpsr; } @@ -144,10 +155,7 @@ namespace Ryujinx.Tests.Cpu } } - protected AThreadState GetThreadState() - { - return Thread.ThreadState; - } + protected AThreadState GetThreadState() => Thread.ThreadState; protected AThreadState SingleOpcode(uint Opcode, ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0, @@ -166,23 +174,44 @@ namespace Ryujinx.Tests.Cpu return GetThreadState(); } - protected void CompareAgainstUnicorn() + [Flags] + protected enum FPSR + { + None = 0, + + /// Invalid Operation cumulative floating-point exception bit. + IOC = 1 << 0, + /// Divide by Zero cumulative floating-point exception bit. + DZC = 1 << 1, + /// Overflow cumulative floating-point exception bit. + OFC = 1 << 2, + /// Underflow cumulative floating-point exception bit. + UFC = 1 << 3, + /// Inexact cumulative floating-point exception bit. + IXC = 1 << 4, + /// Input Denormal cumulative floating-point exception bit. + IDC = 1 << 7, + /// Cumulative saturation bit. + QC = 1 << 27 + } + + protected void CompareAgainstUnicorn(FPSR FpsrMask = FPSR.None) { if (!UnicornAvailable) { return; } - Assert.That(Thread.ThreadState.X0, Is.EqualTo(UnicornEmu.X[0])); - Assert.That(Thread.ThreadState.X1, Is.EqualTo(UnicornEmu.X[1])); - Assert.That(Thread.ThreadState.X2, Is.EqualTo(UnicornEmu.X[2])); - Assert.That(Thread.ThreadState.X3, Is.EqualTo(UnicornEmu.X[3])); - Assert.That(Thread.ThreadState.X4, Is.EqualTo(UnicornEmu.X[4])); - Assert.That(Thread.ThreadState.X5, Is.EqualTo(UnicornEmu.X[5])); - Assert.That(Thread.ThreadState.X6, Is.EqualTo(UnicornEmu.X[6])); - Assert.That(Thread.ThreadState.X7, Is.EqualTo(UnicornEmu.X[7])); - Assert.That(Thread.ThreadState.X8, Is.EqualTo(UnicornEmu.X[8])); - Assert.That(Thread.ThreadState.X9, Is.EqualTo(UnicornEmu.X[9])); + Assert.That(Thread.ThreadState.X0, Is.EqualTo(UnicornEmu.X[0])); + Assert.That(Thread.ThreadState.X1, Is.EqualTo(UnicornEmu.X[1])); + Assert.That(Thread.ThreadState.X2, Is.EqualTo(UnicornEmu.X[2])); + Assert.That(Thread.ThreadState.X3, Is.EqualTo(UnicornEmu.X[3])); + Assert.That(Thread.ThreadState.X4, Is.EqualTo(UnicornEmu.X[4])); + Assert.That(Thread.ThreadState.X5, Is.EqualTo(UnicornEmu.X[5])); + Assert.That(Thread.ThreadState.X6, Is.EqualTo(UnicornEmu.X[6])); + Assert.That(Thread.ThreadState.X7, Is.EqualTo(UnicornEmu.X[7])); + Assert.That(Thread.ThreadState.X8, Is.EqualTo(UnicornEmu.X[8])); + Assert.That(Thread.ThreadState.X9, Is.EqualTo(UnicornEmu.X[9])); Assert.That(Thread.ThreadState.X10, Is.EqualTo(UnicornEmu.X[10])); Assert.That(Thread.ThreadState.X11, Is.EqualTo(UnicornEmu.X[11])); Assert.That(Thread.ThreadState.X12, Is.EqualTo(UnicornEmu.X[12])); @@ -204,17 +233,19 @@ namespace Ryujinx.Tests.Cpu Assert.That(Thread.ThreadState.X28, Is.EqualTo(UnicornEmu.X[28])); Assert.That(Thread.ThreadState.X29, Is.EqualTo(UnicornEmu.X[29])); Assert.That(Thread.ThreadState.X30, Is.EqualTo(UnicornEmu.X[30])); + Assert.That(Thread.ThreadState.X31, Is.EqualTo(UnicornEmu.SP)); - Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0])); - Assert.That(Thread.ThreadState.V1, Is.EqualTo(UnicornEmu.Q[1])); - Assert.That(Thread.ThreadState.V2, Is.EqualTo(UnicornEmu.Q[2])); - Assert.That(Thread.ThreadState.V3, Is.EqualTo(UnicornEmu.Q[3])); - Assert.That(Thread.ThreadState.V4, Is.EqualTo(UnicornEmu.Q[4])); - Assert.That(Thread.ThreadState.V5, Is.EqualTo(UnicornEmu.Q[5])); - Assert.That(Thread.ThreadState.V6, Is.EqualTo(UnicornEmu.Q[6])); - Assert.That(Thread.ThreadState.V7, Is.EqualTo(UnicornEmu.Q[7])); - Assert.That(Thread.ThreadState.V8, Is.EqualTo(UnicornEmu.Q[8])); - Assert.That(Thread.ThreadState.V9, Is.EqualTo(UnicornEmu.Q[9])); + + Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0])); + Assert.That(Thread.ThreadState.V1, Is.EqualTo(UnicornEmu.Q[1])); + Assert.That(Thread.ThreadState.V2, Is.EqualTo(UnicornEmu.Q[2])); + Assert.That(Thread.ThreadState.V3, Is.EqualTo(UnicornEmu.Q[3])); + Assert.That(Thread.ThreadState.V4, Is.EqualTo(UnicornEmu.Q[4])); + Assert.That(Thread.ThreadState.V5, Is.EqualTo(UnicornEmu.Q[5])); + Assert.That(Thread.ThreadState.V6, Is.EqualTo(UnicornEmu.Q[6])); + Assert.That(Thread.ThreadState.V7, Is.EqualTo(UnicornEmu.Q[7])); + Assert.That(Thread.ThreadState.V8, Is.EqualTo(UnicornEmu.Q[8])); + Assert.That(Thread.ThreadState.V9, Is.EqualTo(UnicornEmu.Q[9])); Assert.That(Thread.ThreadState.V10, Is.EqualTo(UnicornEmu.Q[10])); Assert.That(Thread.ThreadState.V11, Is.EqualTo(UnicornEmu.Q[11])); Assert.That(Thread.ThreadState.V12, Is.EqualTo(UnicornEmu.Q[12])); @@ -238,11 +269,13 @@ namespace Ryujinx.Tests.Cpu Assert.That(Thread.ThreadState.V30, Is.EqualTo(UnicornEmu.Q[30])); Assert.That(Thread.ThreadState.V31, Is.EqualTo(UnicornEmu.Q[31])); Assert.That(Thread.ThreadState.V31, Is.EqualTo(UnicornEmu.Q[31])); - Assert.That(Thread.ThreadState.Fpcr, Is.EqualTo(UnicornEmu.Fpcr)); - Assert.That(Thread.ThreadState.Fpsr & 0x08000000, Is.EqualTo(UnicornEmu.Fpsr & 0x08000000)); + + Assert.That(Thread.ThreadState.Fpcr, Is.EqualTo(UnicornEmu.Fpcr)); + Assert.That(Thread.ThreadState.Fpsr & (int)FpsrMask, Is.EqualTo(UnicornEmu.Fpsr & (int)FpsrMask)); + Assert.That(Thread.ThreadState.Overflow, Is.EqualTo(UnicornEmu.OverflowFlag)); - Assert.That(Thread.ThreadState.Carry, Is.EqualTo(UnicornEmu.CarryFlag)); - Assert.That(Thread.ThreadState.Zero, Is.EqualTo(UnicornEmu.ZeroFlag)); + Assert.That(Thread.ThreadState.Carry, Is.EqualTo(UnicornEmu.CarryFlag)); + Assert.That(Thread.ThreadState.Zero, Is.EqualTo(UnicornEmu.ZeroFlag)); Assert.That(Thread.ThreadState.Negative, Is.EqualTo(UnicornEmu.NegativeFlag)); } diff --git a/Ryujinx.Tests/Cpu/CpuTestAlu.cs b/Ryujinx.Tests/Cpu/CpuTestAlu.cs index 3a47dbee..43952d19 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAlu.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAlu.cs @@ -1,4 +1,4 @@ -//#define Alu +#define Alu using ChocolArm64.State; @@ -6,334 +6,185 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("Alu"), Ignore("Tested: second half of 2018.")] + [Category("Alu")] // Tested: second half of 2018. public sealed class CpuTestAlu : CpuTest { #if Alu - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; - [Test, Description("CLS , ")] + [Test, Pairwise, Description("CLS , ")] public void Cls_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn) { uint Opcode = 0xDAC01400; // CLS X0, X0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - Base.Cls(Op[31], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("CLS , ")] + [Test, Pairwise, Description("CLS , ")] public void Cls_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn) { uint Opcode = 0x5AC01400; // CLS W0, W0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - Base.Cls(Op[31], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } + CompareAgainstUnicorn(); } - [Test, Description("CLZ , ")] + [Test, Pairwise, Description("CLZ , ")] public void Clz_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn) { uint Opcode = 0xDAC01000; // CLZ X0, X0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - Base.Clz(Op[31], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("CLZ , ")] + [Test, Pairwise, Description("CLZ , ")] public void Clz_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn) { uint Opcode = 0x5AC01000; // CLZ W0, W0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - Base.Clz(Op[31], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("RBIT , ")] + [Test, Pairwise, Description("RBIT , ")] public void Rbit_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn) { uint Opcode = 0xDAC00000; // RBIT X0, X0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - Base.Rbit(Op[31], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("RBIT , ")] + [Test, Pairwise, Description("RBIT , ")] public void Rbit_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn) { uint Opcode = 0x5AC00000; // RBIT W0, W0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - Base.Rbit(Op[31], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("REV16 , ")] + [Test, Pairwise, Description("REV16 , ")] public void Rev16_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn) { uint Opcode = 0xDAC00400; // REV16 X0, X0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - Base.Rev16(Op[31], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("REV16 , ")] + [Test, Pairwise, Description("REV16 , ")] public void Rev16_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn) { uint Opcode = 0x5AC00400; // REV16 W0, W0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - Base.Rev16(Op[31], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("REV32 , ")] + [Test, Pairwise, Description("REV32 , ")] public void Rev32_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn) { uint Opcode = 0xDAC00800; // REV32 X0, X0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - Base.Rev32(Op[31], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("REV , ")] + [Test, Pairwise, Description("REV , ")] public void Rev32_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn) { uint Opcode = 0x5AC00800; // REV W0, W0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - Base.Rev32(Op[31], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("REV64 , ")] + [Test, Pairwise, Description("REV64 , ")] public void Rev64_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn) { uint Opcode = 0xDAC00C00; // REV64 X0, X0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - Base.Rev64(Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestAluImm.cs b/Ryujinx.Tests/Cpu/CpuTestAluImm.cs index b648a337..61eadefd 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluImm.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAluImm.cs @@ -1,4 +1,4 @@ -//#define AluImm +#define AluImm using ChocolArm64.State; @@ -6,824 +6,448 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("AluImm"), Ignore("Tested: second half of 2018.")] + [Category("AluImm")] // Tested: second half of 2018. public sealed class CpuTestAluImm : CpuTest { #if AluImm - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; + private const int RndCntImm = 2; + private const int RndCntImms = 2; + private const int RndCntImmr = 2; - [Test, Description("ADD , , #{, }")] + [Test, Pairwise, Description("ADD , , #{, }")] public void Add_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP, - [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, + [Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm, [Values(0b00u, 0b01u)] uint shift) // { uint Opcode = 0x91000000; // ADD X0, X0, #0, LSL #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ThreadState = SingleOpcode(Opcode, X1: Xn_SP); - - AArch64.X((int)Rn, new Bits(Xn_SP)); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP); - - AArch64.SP(new Bits(Xn_SP)); } - Base.Add_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADD , , #{, }")] + [Test, Pairwise, Description("ADD , , #{, }")] public void Add_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP, - [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, + [Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm, [Values(0b00u, 0b01u)] uint shift) // { uint Opcode = 0x11000000; // ADD W0, W0, #0, LSL #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ThreadState = SingleOpcode(Opcode, X1: Wn_WSP); - - AArch64.X((int)Rn, new Bits(Wn_WSP)); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP); - - AArch64.SP(new Bits(Wn_WSP)); } - Base.Add_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADDS , , #{, }")] + [Test, Pairwise, Description("ADDS , , #{, }")] public void Adds_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP, - [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, + [Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm, [Values(0b00u, 0b01u)] uint shift) // { uint Opcode = 0xB1000000; // ADDS X0, X0, #0, LSL #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ThreadState = SingleOpcode(Opcode, X1: Xn_SP); - - AArch64.X((int)Rn, new Bits(Xn_SP)); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP); - - AArch64.SP(new Bits(Xn_SP)); } - Base.Adds_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADDS , , #{, }")] + [Test, Pairwise, Description("ADDS , , #{, }")] public void Adds_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP, - [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, + [Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm, [Values(0b00u, 0b01u)] uint shift) // { uint Opcode = 0x31000000; // ADDS W0, W0, #0, LSL #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ThreadState = SingleOpcode(Opcode, X1: Wn_WSP); - - AArch64.X((int)Rn, new Bits(Wn_WSP)); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP); - - AArch64.SP(new Bits(Wn_WSP)); } - Base.Adds_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint _W31 = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("AND , , #")] + [Test, Pairwise, Description("AND , , #")] public void And_N1_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // { uint Opcode = 0x92400000; // AND X0, X0, #0x1 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("AND , , #")] + [Test, Pairwise, Description("AND , , #")] public void And_N0_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // { uint Opcode = 0x92000000; // AND X0, X0, #0x100000001 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("AND , , #")] + [Test, Pairwise, Description("AND , , #")] public void And_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, - [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // { uint Opcode = 0x12000000; // AND W0, W0, #0x1 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn)); - Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("ANDS , , #")] + [Test, Pairwise, Description("ANDS , , #")] public void Ands_N1_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // { uint Opcode = 0xF2400000; // ANDS X0, X0, #0x1 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - if (Rd != 31) - { - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ANDS , , #")] + [Test, Pairwise, Description("ANDS , , #")] public void Ands_N0_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // { uint Opcode = 0xF2000000; // ANDS X0, X0, #0x100000001 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - if (Rd != 31) - { - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ANDS , , #")] + [Test, Pairwise, Description("ANDS , , #")] public void Ands_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, - [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // { uint Opcode = 0x72000000; // ANDS W0, W0, #0x1 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn)); - Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - if (Rd != 31) - { - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("EOR , , #")] + [Test, Pairwise, Description("EOR , , #")] public void Eor_N1_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // { uint Opcode = 0xD2400000; // EOR X0, X0, #0x1 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("EOR , , #")] + [Test, Pairwise, Description("EOR , , #")] public void Eor_N0_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // { uint Opcode = 0xD2000000; // EOR X0, X0, #0x100000001 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("EOR , , #")] + [Test, Pairwise, Description("EOR , , #")] public void Eor_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, - [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // { uint Opcode = 0x52000000; // EOR W0, W0, #0x1 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn)); - Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("ORR , , #")] + [Test, Pairwise, Description("ORR , , #")] public void Orr_N1_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // { uint Opcode = 0xB2400000; // ORR X0, X0, #0x1 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("ORR , , #")] + [Test, Pairwise, Description("ORR , , #")] public void Orr_N0_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // { uint Opcode = 0xB2000000; // ORR X0, X0, #0x100000001 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("ORR , , #")] + [Test, Pairwise, Description("ORR , , #")] public void Orr_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, - [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // { uint Opcode = 0x32000000; // ORR W0, W0, #0x1 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn)); - Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , #{, }")] + [Test, Pairwise, Description("SUB , , #{, }")] public void Sub_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP, - [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, + [Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm, [Values(0b00u, 0b01u)] uint shift) // { uint Opcode = 0xD1000000; // SUB X0, X0, #0, LSL #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ThreadState = SingleOpcode(Opcode, X1: Xn_SP); - - AArch64.X((int)Rn, new Bits(Xn_SP)); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP); - - AArch64.SP(new Bits(Xn_SP)); } - Base.Sub_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , #{, }")] + [Test, Pairwise, Description("SUB , , #{, }")] public void Sub_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP, - [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, + [Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm, [Values(0b00u, 0b01u)] uint shift) // { uint Opcode = 0x51000000; // SUB W0, W0, #0, LSL #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ThreadState = SingleOpcode(Opcode, X1: Wn_WSP); - - AArch64.X((int)Rn, new Bits(Wn_WSP)); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP); - - AArch64.SP(new Bits(Wn_WSP)); } - Base.Sub_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUBS , , #{, }")] + [Test, Pairwise, Description("SUBS , , #{, }")] public void Subs_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP, - [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, + [Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm, [Values(0b00u, 0b01u)] uint shift) // { uint Opcode = 0xF1000000; // SUBS X0, X0, #0, LSL #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ThreadState = SingleOpcode(Opcode, X1: Xn_SP); - - AArch64.X((int)Rn, new Bits(Xn_SP)); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP); - - AArch64.SP(new Bits(Xn_SP)); } - Base.Subs_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUBS , , #{, }")] + [Test, Pairwise, Description("SUBS , , #{, }")] public void Subs_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP, - [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, + [Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm, [Values(0b00u, 0b01u)] uint shift) // { uint Opcode = 0x71000000; // SUBS W0, W0, #0, LSL #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ThreadState = SingleOpcode(Opcode, X1: Wn_WSP); - - AArch64.X((int)Rn, new Bits(Wn_WSP)); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP); - - AArch64.SP(new Bits(Wn_WSP)); } - Base.Subs_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint _W31 = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestAluRs.cs b/Ryujinx.Tests/Cpu/CpuTestAluRs.cs index 49c82b74..58a99dfb 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluRs.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAluRs.cs @@ -1,4 +1,4 @@ -//#define AluRs +#define AluRs using ChocolArm64.State; @@ -6,1958 +6,1117 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("AluRs"), Ignore("Tested: second half of 2018.")] + [Category("AluRs")] // Tested: second half of 2018. public sealed class CpuTestAluRs : CpuTest { #if AluRs - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; + private const int RndCntAmount = 2; + private const int RndCntLsb = 2; - [Test, Description("ADC , , ")] + [Test, Pairwise, Description("ADC , , ")] public void Adc_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values] bool CarryIn) { uint Opcode = 0x9A000000; // ADC X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31, Carry: CarryIn); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Shared.PSTATE.C = CarryIn; - Base.Adc(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("ADC , , ")] + [Test, Pairwise, Description("ADC , , ")] public void Adc_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values] bool CarryIn) { uint Opcode = 0x1A000000; // ADC W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31, Carry: CarryIn); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Shared.PSTATE.C = CarryIn; - Base.Adc(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("ADCS , , ")] + [Test, Pairwise, Description("ADCS , , ")] public void Adcs_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values] bool CarryIn) { uint Opcode = 0xBA000000; // ADCS X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31, Carry: CarryIn); - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Shared.PSTATE.C = CarryIn; - Base.Adcs(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - if (Rd != 31) - { - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADCS , , ")] + [Test, Pairwise, Description("ADCS , , ")] public void Adcs_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values] bool CarryIn) { uint Opcode = 0x3A000000; // ADCS W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31, Carry: CarryIn); - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Shared.PSTATE.C = CarryIn; - Base.Adcs(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - if (Rd != 31) - { - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADD , , {, #}")] + [Test, Pairwise, Description("ADD , , {, #}")] public void Add_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0x8B000000; // ADD X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Add_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("ADD , , {, #}")] + [Test, Pairwise, Description("ADD , , {, #}")] public void Add_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x0B000000; // ADD W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Add_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - CompareAgainstUnicorn(); - } + CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, #}")] + [Test, Pairwise, Description("ADDS , , {, #}")] public void Adds_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xAB000000; // ADDS X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Adds_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - if (Rd != 31) - { - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, #}")] + [Test, Pairwise, Description("ADDS , , {, #}")] public void Adds_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x2B000000; // ADDS W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Adds_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - if (Rd != 31) - { - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("AND , , {, #}")] + [Test, Pairwise, Description("AND , , {, #}")] public void And_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0x8A000000; // AND X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.And_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("AND , , {, #}")] + [Test, Pairwise, Description("AND , , {, #}")] public void And_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x0A000000; // AND W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.And_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("ANDS , , {, #}")] + [Test, Pairwise, Description("ANDS , , {, #}")] public void Ands_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xEA000000; // ANDS X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Ands_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - if (Rd != 31) - { - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ANDS , , {, #}")] + [Test, Pairwise, Description("ANDS , , {, #}")] public void Ands_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x6A000000; // ANDS W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Ands_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - if (Rd != 31) - { - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ASRV , , ")] + [Test, Pairwise, Description("ASRV , , ")] public void Asrv_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0ul, 31ul, 32ul, 63ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(5)] ulong Xm) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9AC02800; // ASRV X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Asrv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("ASRV , , ")] + [Test, Pairwise, Description("ASRV , , ")] public void Asrv_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0u, 15u, 16u, 31u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(5)] uint Wm) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm) { uint Opcode = 0x1AC02800; // ASRV W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Asrv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("BIC , , {, #}")] + [Test, Pairwise, Description("BIC , , {, #}")] public void Bic_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0x8A200000; // BIC X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Bic(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("BIC , , {, #}")] + [Test, Pairwise, Description("BIC , , {, #}")] public void Bic_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x0A200000; // BIC W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Bic(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("BICS , , {, #}")] + [Test, Pairwise, Description("BICS , , {, #}")] public void Bics_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xEA200000; // BICS X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Bics(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - if (Rd != 31) - { - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("BICS , , {, #}")] + [Test, Pairwise, Description("BICS , , {, #}")] public void Bics_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x6A200000; // BICS W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Bics(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - if (Rd != 31) - { - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("CRC32X , , ")] + [Test, Pairwise, Description("CRC32X , , "), Ignore("Unicorn fails.")] public void Crc32x([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, - [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + [Values(0x00000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values((ulong)0x00_00_00_00_00_00_00_00, (ulong)0x7F_FF_FF_FF_FF_FF_FF_FF, (ulong)0x80_00_00_00_00_00_00_00, - (ulong)0xFF_FF_FF_FF_FF_FF_FF_FF)] [Random(64)] ulong Xm) + (ulong)0xFF_FF_FF_FF_FF_FF_FF_FF)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9AC04C00; // CRC32X W0, W0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Xm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Crc32(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("CRC32W , , ")] + [Test, Pairwise, Description("CRC32W , , "), Ignore("Unicorn fails.")] public void Crc32w([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, - [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + [Values(0x00000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values((uint)0x00_00_00_00, (uint)0x7F_FF_FF_FF, - (uint)0x80_00_00_00, (uint)0xFF_FF_FF_FF)] [Random(64)] uint Wm) + (uint)0x80_00_00_00, (uint)0xFF_FF_FF_FF)] [Random(RndCnt)] uint Wm) { uint Opcode = 0x1AC04800; // CRC32W W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Crc32(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("CRC32H , , ")] + [Test, Pairwise, Description("CRC32H , , "), Ignore("Unicorn fails.")] public void Crc32h([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, - [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + [Values(0x00000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values((ushort)0x00_00, (ushort)0x7F_FF, - (ushort)0x80_00, (ushort)0xFF_FF)] [Random(64)] ushort Wm) + (ushort)0x80_00, (ushort)0xFF_FF)] [Random(RndCnt)] ushort Wm) { uint Opcode = 0x1AC04400; // CRC32H W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Crc32(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("CRC32B , , ")] + [Test, Pairwise, Description("CRC32B , , "), Ignore("Unicorn fails.")] public void Crc32b([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, - [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + [Values(0x00000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(64)] byte Wm) + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm) { uint Opcode = 0x1AC04000; // CRC32B W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Crc32(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("CRC32CX , , ")] + [Test, Pairwise, Description("CRC32CX , , ")] public void Crc32cx([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, - [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + [Values(0x00000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values((ulong)0x00_00_00_00_00_00_00_00, (ulong)0x7F_FF_FF_FF_FF_FF_FF_FF, (ulong)0x80_00_00_00_00_00_00_00, - (ulong)0xFF_FF_FF_FF_FF_FF_FF_FF)] [Random(64)] ulong Xm) + (ulong)0xFF_FF_FF_FF_FF_FF_FF_FF)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9AC05C00; // CRC32CX W0, W0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Xm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Crc32c(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("CRC32CW , , ")] + [Test, Pairwise, Description("CRC32CW , , ")] public void Crc32cw([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, - [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + [Values(0x00000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values((uint)0x00_00_00_00, (uint)0x7F_FF_FF_FF, - (uint)0x80_00_00_00, (uint)0xFF_FF_FF_FF)] [Random(64)] uint Wm) + (uint)0x80_00_00_00, (uint)0xFF_FF_FF_FF)] [Random(RndCnt)] uint Wm) { uint Opcode = 0x1AC05800; // CRC32CW W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Crc32c(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("CRC32CH , , ")] + [Test, Pairwise, Description("CRC32CH , , ")] public void Crc32ch([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, - [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + [Values(0x00000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values((ushort)0x00_00, (ushort)0x7F_FF, - (ushort)0x80_00, (ushort)0xFF_FF)] [Random(64)] ushort Wm) + (ushort)0x80_00, (ushort)0xFF_FF)] [Random(RndCnt)] ushort Wm) { uint Opcode = 0x1AC05400; // CRC32CH W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Crc32c(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("CRC32CB , , ")] + [Test, Pairwise, Description("CRC32CB , , ")] public void Crc32cb([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, - [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + [Values(0x00000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(64)] byte Wm) + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm) { uint Opcode = 0x1AC05000; // CRC32CB W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Crc32c(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("EON , , {, #}")] + [Test, Pairwise, Description("EON , , {, #}")] public void Eon_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xCA200000; // EON X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Eon(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("EON , , {, #}")] + [Test, Pairwise, Description("EON , , {, #}")] public void Eon_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x4A200000; // EON W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Eon(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("EOR , , {, #}")] + [Test, Pairwise, Description("EOR , , {, #}")] public void Eor_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xCA000000; // EOR X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Eor_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("EOR , , {, #}")] + [Test, Pairwise, Description("EOR , , {, #}")] public void Eor_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x4A000000; // EOR W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Eor_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("EXTR , , , #")] + [Test, Pairwise, Description("EXTR , , , #")] public void Extr_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm, - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint lsb) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntLsb)] uint lsb) { uint Opcode = 0x93C00000; // EXTR X0, X0, X0, #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((lsb & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Extr(Op[31], Op[22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("EXTR , , , #")] + [Test, Pairwise, Description("EXTR , , , #")] public void Extr_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm, - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint lsb) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntLsb)] uint lsb) { uint Opcode = 0x13800000; // EXTR W0, W0, W0, #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((lsb & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Extr(Op[31], Op[22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("LSLV , , ")] + [Test, Pairwise, Description("LSLV , , ")] public void Lslv_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0ul, 31ul, 32ul, 63ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(5)] ulong Xm) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9AC02000; // LSLV X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Lslv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("LSLV , , ")] + [Test, Pairwise, Description("LSLV , , ")] public void Lslv_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0u, 15u, 16u, 31u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(5)] uint Wm) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm) { uint Opcode = 0x1AC02000; // LSLV W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Lslv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("LSRV , , ")] + [Test, Pairwise, Description("LSRV , , ")] public void Lsrv_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0ul, 31ul, 32ul, 63ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(5)] ulong Xm) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9AC02400; // LSRV X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Lsrv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("LSRV , , ")] + [Test, Pairwise, Description("LSRV , , ")] public void Lsrv_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0u, 15u, 16u, 31u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(5)] uint Wm) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm) { uint Opcode = 0x1AC02400; // LSRV W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Lsrv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("ORN , , {, #}")] + [Test, Pairwise, Description("ORN , , {, #}")] public void Orn_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xAA200000; // ORN X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Orn(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("ORN , , {, #}")] + [Test, Pairwise, Description("ORN , , {, #}")] public void Orn_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x2A200000; // ORN W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Orn(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("ORR , , {, #}")] + [Test, Pairwise, Description("ORR , , {, #}")] public void Orr_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xAA000000; // ORR X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Orr_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("ORR , , {, #}")] + [Test, Pairwise, Description("ORR , , {, #}")] public void Orr_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x2A000000; // ORR W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Orr_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("RORV , , ")] + [Test, Pairwise, Description("RORV , , ")] public void Rorv_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0ul, 31ul, 32ul, 63ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(5)] ulong Xm) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9AC02C00; // RORV X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Rorv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("RORV , , ")] + [Test, Pairwise, Description("RORV , , ")] public void Rorv_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0u, 15u, 16u, 31u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(5)] uint Wm) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm) { uint Opcode = 0x1AC02C00; // RORV W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Rorv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("SBC , , ")] + [Test, Pairwise, Description("SBC , , ")] public void Sbc_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values] bool CarryIn) { uint Opcode = 0xDA000000; // SBC X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31, Carry: CarryIn); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Shared.PSTATE.C = CarryIn; - Base.Sbc(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("SBC , , ")] + [Test, Pairwise, Description("SBC , , ")] public void Sbc_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values] bool CarryIn) { uint Opcode = 0x5A000000; // SBC W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31, Carry: CarryIn); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Shared.PSTATE.C = CarryIn; - Base.Sbc(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("SBCS , , ")] + [Test, Pairwise, Description("SBCS , , ")] public void Sbcs_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values] bool CarryIn) { uint Opcode = 0xFA000000; // SBCS X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31, Carry: CarryIn); - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Shared.PSTATE.C = CarryIn; - Base.Sbcs(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - if (Rd != 31) - { - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SBCS , , ")] + [Test, Pairwise, Description("SBCS , , ")] public void Sbcs_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values] bool CarryIn) { uint Opcode = 0x7A000000; // SBCS W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31, Carry: CarryIn); - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Shared.PSTATE.C = CarryIn; - Base.Sbcs(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - if (Rd != 31) - { - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SDIV , , ")] + [Test, Pairwise, Description("SDIV , , ")] public void Sdiv_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xm) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9AC00C00; // SDIV X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Sdiv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("SDIV , , ")] + [Test, Pairwise, Description("SDIV , , ")] public void Sdiv_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wm) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm) { uint Opcode = 0x1AC00C00; // SDIV W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Sdiv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, #}")] + [Test, Pairwise, Description("SUB , , {, #}")] public void Sub_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xCB000000; // SUB X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Sub_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, #}")] + [Test, Pairwise, Description("SUB , , {, #}")] public void Sub_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x4B000000; // SUB W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Sub_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, #}")] + [Test, Pairwise, Description("SUBS , , {, #}")] public void Subs_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b00u, 0b01u, 0b10u)] uint shift, // - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount) + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntAmount)] uint amount) { uint Opcode = 0xEB000000; // SUBS X0, X0, X0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); - Bits Op = new Bits(Opcode); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Subs_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - if (Rd != 31) - { - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, #}")] + [Test, Pairwise, Description("SUBS , , {, #}")] public void Subs_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b00u, 0b01u, 0b10u)] uint shift, // - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount) + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount) { uint Opcode = 0x6B000000; // SUBS W0, W0, W0, LSL #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10); - Bits Op = new Bits(Opcode); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Subs_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - if (Rd != 31) - { - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("UDIV , , ")] + [Test, Pairwise, Description("UDIV , , ")] public void Udiv_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xm) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9AC00800; // UDIV X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Udiv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("UDIV , , ")] + [Test, Pairwise, Description("UDIV , , ")] public void Udiv_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wm) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm) { uint Opcode = 0x1AC00800; // UDIV W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - Base.Udiv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestAluRx.cs b/Ryujinx.Tests/Cpu/CpuTestAluRx.cs index 41fd580a..9c66532b 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluRx.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAluRx.cs @@ -1,4 +1,4 @@ -//#define AluRx +#define AluRx using ChocolArm64.State; @@ -6,77 +6,51 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("AluRx"), Ignore("Tested: second half of 2018.")] + [Category("AluRx")] // Tested: second half of 2018. public sealed class CpuTestAluRx : CpuTest { #if AluRx - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; - [Test, Description("ADD , , {, {#}}")] + [Test, Pairwise, Description("ADD , , {, {#}}")] public void Add_X_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((ulong)0x0000000000000000, (ulong)0x7FFFFFFFFFFFFFFF, - (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(2)] ulong Xm, + (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(RndCnt)] ulong Xm, [Values(0b011u, 0b111u)] uint extend, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) { uint Opcode = 0x8B206000; // ADD X0, X0, X0, UXTX #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ulong _X31 = TestContext.CurrentContext.Random.NextULong(); - ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn_SP)); + ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: _X31); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Xm); - - AArch64.SP(new Bits(Xn_SP)); } - AArch64.X((int)Rm, new Bits(Xm)); - Base.Add_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADD , , {, {#}}")] + [Test, Pairwise, Description("ADD , , {, {#}}")] public void Add_W_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((uint)0x00000000, (uint)0x7FFFFFFF, - (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(2)] uint Wm, + (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -84,50 +58,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x8B200000; // ADD X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ulong _X31 = TestContext.CurrentContext.Random.NextULong(); - ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn_SP)); + ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm); - - AArch64.SP(new Bits(Xn_SP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Add_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADD , , {, {#}}")] + [Test, Pairwise, Description("ADD , , {, {#}}")] public void Add_H_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((ushort)0x0000, (ushort)0x7FFF, - (ushort)0x8000, (ushort)0xFFFF)] [Random(2)] ushort Wm, + (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -135,50 +90,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x8B200000; // ADD X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ulong _X31 = TestContext.CurrentContext.Random.NextULong(); - ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn_SP)); + ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm); - - AArch64.SP(new Bits(Xn_SP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Add_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADD , , {, {#}}")] + [Test, Pairwise, Description("ADD , , {, {#}}")] public void Add_B_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(2)] byte Wm, + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -186,50 +122,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x8B200000; // ADD X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ulong _X31 = TestContext.CurrentContext.Random.NextULong(); - ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn_SP)); + ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm); - - AArch64.SP(new Bits(Xn_SP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Add_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADD , , {, {#}}")] + [Test, Pairwise, Description("ADD , , {, {#}}")] public void Add_W_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((uint)0x00000000, (uint)0x7FFFFFFF, - (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(2)] uint Wm, + (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -237,50 +154,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0B200000; // ADD W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { uint _W31 = TestContext.CurrentContext.Random.NextUInt(); - ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn_WSP)); + ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm); - - AArch64.SP(new Bits(Wn_WSP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Add_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADD , , {, {#}}")] + [Test, Pairwise, Description("ADD , , {, {#}}")] public void Add_H_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((ushort)0x0000, (ushort)0x7FFF, - (ushort)0x8000, (ushort)0xFFFF)] [Random(2)] ushort Wm, + (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -288,50 +186,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0B200000; // ADD W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { uint _W31 = TestContext.CurrentContext.Random.NextUInt(); - ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn_WSP)); + ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm); - - AArch64.SP(new Bits(Wn_WSP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Add_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADD , , {, {#}}")] + [Test, Pairwise, Description("ADD , , {, {#}}")] public void Add_B_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(2)] byte Wm, + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -339,95 +218,51 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0B200000; // ADD W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { uint _W31 = TestContext.CurrentContext.Random.NextUInt(); - ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn_WSP)); + ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm); - - AArch64.SP(new Bits(Wn_WSP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Add_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, {#}}")] + [Test, Pairwise, Description("ADDS , , {, {#}}")] public void Adds_X_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((ulong)0x0000000000000000, (ulong)0x7FFFFFFFFFFFFFFF, - (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(2)] ulong Xm, + (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(RndCnt)] ulong Xm, [Values(0b011u, 0b111u)] uint extend, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) { uint Opcode = 0xAB206000; // ADDS X0, X0, X0, UXTX #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: Xn_SP); - AArch64.X((int)Rn, new Bits(Xn_SP)); - AArch64.X((int)Rm, new Bits(Xm)); - AArch64.SP(new Bits(Xn_SP)); - Base.Adds_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, {#}}")] + [Test, Pairwise, Description("ADDS , , {, {#}}")] public void Adds_W_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((uint)0x00000000, (uint)0x7FFFFFFF, - (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(2)] uint Wm, + (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -435,45 +270,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xAB200000; // ADDS X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP); - AArch64.X((int)Rn, new Bits(Xn_SP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Xn_SP)); - Base.Adds_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, {#}}")] + [Test, Pairwise, Description("ADDS , , {, {#}}")] public void Adds_H_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((ushort)0x0000, (ushort)0x7FFF, - (ushort)0x8000, (ushort)0xFFFF)] [Random(2)] ushort Wm, + (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -481,45 +291,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xAB200000; // ADDS X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP); - AArch64.X((int)Rn, new Bits(Xn_SP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Xn_SP)); - Base.Adds_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, {#}}")] + [Test, Pairwise, Description("ADDS , , {, {#}}")] public void Adds_B_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(2)] byte Wm, + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -527,45 +312,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xAB200000; // ADDS X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP); - AArch64.X((int)Rn, new Bits(Xn_SP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Xn_SP)); - Base.Adds_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, {#}}")] + [Test, Pairwise, Description("ADDS , , {, {#}}")] public void Adds_W_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((uint)0x00000000, (uint)0x7FFFFFFF, - (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(2)] uint Wm, + (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -573,45 +333,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2B200000; // ADDS W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP); - AArch64.X((int)Rn, new Bits(Wn_WSP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Wn_WSP)); - Base.Adds_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint _W31 = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, {#}}")] + [Test, Pairwise, Description("ADDS , , {, {#}}")] public void Adds_H_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((ushort)0x0000, (ushort)0x7FFF, - (ushort)0x8000, (ushort)0xFFFF)] [Random(2)] ushort Wm, + (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -619,45 +354,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2B200000; // ADDS W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP); - AArch64.X((int)Rn, new Bits(Wn_WSP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Wn_WSP)); - Base.Adds_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint _W31 = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("ADDS , , {, {#}}")] + [Test, Pairwise, Description("ADDS , , {, {#}}")] public void Adds_B_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(2)] byte Wm, + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -665,95 +375,51 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2B200000; // ADDS W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP); - AArch64.X((int)Rn, new Bits(Wn_WSP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Wn_WSP)); - Base.Adds_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint _W31 = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, {#}}")] + [Test, Pairwise, Description("SUB , , {, {#}}")] public void Sub_X_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((ulong)0x0000000000000000, (ulong)0x7FFFFFFFFFFFFFFF, - (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(2)] ulong Xm, + (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(RndCnt)] ulong Xm, [Values(0b011u, 0b111u)] uint extend, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) { uint Opcode = 0xCB206000; // SUB X0, X0, X0, UXTX #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ulong _X31 = TestContext.CurrentContext.Random.NextULong(); - ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn_SP)); + ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: _X31); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Xm); - - AArch64.SP(new Bits(Xn_SP)); } - AArch64.X((int)Rm, new Bits(Xm)); - Base.Sub_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, {#}}")] + [Test, Pairwise, Description("SUB , , {, {#}}")] public void Sub_W_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((uint)0x00000000, (uint)0x7FFFFFFF, - (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(2)] uint Wm, + (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -761,50 +427,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xCB200000; // SUB X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ulong _X31 = TestContext.CurrentContext.Random.NextULong(); - ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn_SP)); + ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm); - - AArch64.SP(new Bits(Xn_SP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Sub_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, {#}}")] + [Test, Pairwise, Description("SUB , , {, {#}}")] public void Sub_H_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((ushort)0x0000, (ushort)0x7FFF, - (ushort)0x8000, (ushort)0xFFFF)] [Random(2)] ushort Wm, + (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -812,50 +459,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xCB200000; // SUB X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ulong _X31 = TestContext.CurrentContext.Random.NextULong(); - ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn_SP)); + ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm); - - AArch64.SP(new Bits(Xn_SP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Sub_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, {#}}")] + [Test, Pairwise, Description("SUB , , {, {#}}")] public void Sub_B_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(2)] byte Wm, + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -863,50 +491,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xCB200000; // SUB X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { ulong _X31 = TestContext.CurrentContext.Random.NextULong(); - ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); - AArch64.X((int)Rn, new Bits(Xn_SP)); + ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: _X31); } else { ThreadState = SingleOpcode(Opcode, X31: Xn_SP, X2: Wm); - - AArch64.SP(new Bits(Xn_SP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Sub_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong SP = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, {#}}")] + [Test, Pairwise, Description("SUB , , {, {#}}")] public void Sub_W_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((uint)0x00000000, (uint)0x7FFFFFFF, - (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(2)] uint Wm, + (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -914,50 +523,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4B200000; // SUB W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { uint _W31 = TestContext.CurrentContext.Random.NextUInt(); - ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn_WSP)); + ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm); - - AArch64.SP(new Bits(Wn_WSP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Sub_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, {#}}")] + [Test, Pairwise, Description("SUB , , {, {#}}")] public void Sub_H_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((ushort)0x0000, (ushort)0x7FFF, - (ushort)0x8000, (ushort)0xFFFF)] [Random(2)] ushort Wm, + (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -965,50 +555,31 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4B200000; // SUB W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { uint _W31 = TestContext.CurrentContext.Random.NextUInt(); - ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn_WSP)); + ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm); - - AArch64.SP(new Bits(Wn_WSP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Sub_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUB , , {, {#}}")] + [Test, Pairwise, Description("SUB , , {, {#}}")] public void Sub_B_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(2)] byte Wm, + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -1016,95 +587,51 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4B200000; // SUB W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState; if (Rn != 31) { uint _W31 = TestContext.CurrentContext.Random.NextUInt(); - ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); - AArch64.X((int)Rn, new Bits(Wn_WSP)); + ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: _W31); } else { ThreadState = SingleOpcode(Opcode, X31: Wn_WSP, X2: Wm); - - AArch64.SP(new Bits(Wn_WSP)); } - AArch64.X((int)Rm, new Bits(Wm)); - Base.Sub_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint WSP = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); - } CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, {#}}")] + [Test, Pairwise, Description("SUBS , , {, {#}}")] public void Subs_X_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((ulong)0x0000000000000000, (ulong)0x7FFFFFFFFFFFFFFF, - (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(2)] ulong Xm, + (ulong)0x8000000000000000, (ulong)0xFFFFFFFFFFFFFFFF)] [Random(RndCnt)] ulong Xm, [Values(0b011u, 0b111u)] uint extend, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) { uint Opcode = 0xEB206000; // SUBS X0, X0, X0, UXTX #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Xm, X31: Xn_SP); - AArch64.X((int)Rn, new Bits(Xn_SP)); - AArch64.X((int)Rm, new Bits(Xm)); - AArch64.SP(new Bits(Xn_SP)); - Base.Subs_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, {#}}")] + [Test, Pairwise, Description("SUBS , , {, {#}}")] public void Subs_W_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((uint)0x00000000, (uint)0x7FFFFFFF, - (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(2)] uint Wm, + (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -1112,45 +639,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xEB200000; // SUBS X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP); - AArch64.X((int)Rn, new Bits(Xn_SP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Xn_SP)); - Base.Subs_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, {#}}")] + [Test, Pairwise, Description("SUBS , , {, {#}}")] public void Subs_H_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((ushort)0x0000, (ushort)0x7FFF, - (ushort)0x8000, (ushort)0xFFFF)] [Random(2)] ushort Wm, + (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -1158,45 +660,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xEB200000; // SUBS X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP); - AArch64.X((int)Rn, new Bits(Xn_SP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Xn_SP)); - Base.Subs_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, {#}}")] + [Test, Pairwise, Description("SUBS , , {, {#}}")] public void Subs_B_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn_SP, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(2)] byte Wm, + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm, [Values(0b000u, 0b001u, 0b010u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -1204,45 +681,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0xEB200000; // SUBS X0, X0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn_SP, X2: Wm, X31: Xn_SP); - AArch64.X((int)Rn, new Bits(Xn_SP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Xn_SP)); - Base.Subs_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - ulong _X31 = AArch64.SP(64).ToUInt64(); - - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, {#}}")] + [Test, Pairwise, Description("SUBS , , {, {#}}")] public void Subs_W_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((uint)0x00000000, (uint)0x7FFFFFFF, - (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(2)] uint Wm, + (uint)0x80000000, (uint)0xFFFFFFFF)] [Random(RndCnt)] uint Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -1250,45 +702,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6B200000; // SUBS W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP); - AArch64.X((int)Rn, new Bits(Wn_WSP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Wn_WSP)); - Base.Subs_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint _W31 = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, {#}}")] + [Test, Pairwise, Description("SUBS , , {, {#}}")] public void Subs_H_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((ushort)0x0000, (ushort)0x7FFF, - (ushort)0x8000, (ushort)0xFFFF)] [Random(2)] ushort Wm, + (ushort)0x8000, (ushort)0xFFFF)] [Random(RndCnt)] ushort Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -1296,45 +723,20 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6B200000; // SUBS W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP); - AArch64.X((int)Rn, new Bits(Wn_WSP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Wn_WSP)); - Base.Subs_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint _W31 = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("SUBS , , {, {#}}")] + [Test, Pairwise, Description("SUBS , , {, {#}}")] public void Subs_B_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn_WSP, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP, [Values((byte)0x00, (byte)0x7F, - (byte)0x80, (byte)0xFF)] [Random(2)] byte Wm, + (byte)0x80, (byte)0xFF)] [Random(RndCnt)] byte Wm, [Values(0b000u, 0b001u, 0b010u, 0b011u, // [Values(0u, 1u, 2u, 3u, 4u)] uint amount) @@ -1342,34 +744,9 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6B200000; // SUBS W0, W0, W0, UXTB #0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((extend & 7) << 13) | ((amount & 7) << 10); - Bits Op = new Bits(Opcode); AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn_WSP, X2: Wm, X31: Wn_WSP); - AArch64.X((int)Rn, new Bits(Wn_WSP)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.SP(new Bits(Wn_WSP)); - Base.Subs_Rx(Op[31], Op[20, 16], Op[15, 13], Op[12, 10], Op[9, 5], Op[4, 0]); - - if (Rd != 31) - { - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - uint _W31 = AArch64.SP(32).ToUInt32(); - - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } - Assert.Multiple(() => - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestBfm.cs b/Ryujinx.Tests/Cpu/CpuTestBfm.cs index c5be5788..427396f8 100644 --- a/Ryujinx.Tests/Cpu/CpuTestBfm.cs +++ b/Ryujinx.Tests/Cpu/CpuTestBfm.cs @@ -1,4 +1,4 @@ -//#define Bfm +#define Bfm using ChocolArm64.State; @@ -6,212 +6,127 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("Bfm"), Ignore("Tested: second half of 2018.")] + [Category("Bfm")] // Tested: second half of 2018. public sealed class CpuTestBfm : CpuTest { #if Bfm - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; + private const int RndCntImmr = 2; + private const int RndCntImms = 2; - [Test, Description("BFM , , #, #")] + [Test, Pairwise, Description("BFM , , #, #")] public void Bfm_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, - [Random(2)] ulong _Xd, + [Random(RndCnt)] ulong _Xd, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr, - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr, + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms) { uint Opcode = 0xB3400000; // BFM X0, X0, #0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rd, new Bits(_Xd)); - AArch64.X((int)Rn, new Bits(Xn)); - Base.Bfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("BFM , , #, #")] + [Test, Pairwise, Description("BFM , , #, #")] public void Bfm_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, - [Random(2)] uint _Wd, + [Random(RndCnt)] uint _Wd, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr, - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr, + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms) { uint Opcode = 0x33000000; // BFM W0, W0, #0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X1: Wn, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rd, new Bits(_Wd)); - AArch64.X((int)Rn, new Bits(Wn)); - Base.Bfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("SBFM , , #, #")] + [Test, Pairwise, Description("SBFM , , #, #")] public void Sbfm_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr, - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr, + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms) { uint Opcode = 0x93400000; // SBFM X0, X0, #0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - Base.Sbfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("SBFM , , #, #")] + [Test, Pairwise, Description("SBFM , , #, #")] public void Sbfm_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr, - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr, + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms) { uint Opcode = 0x13000000; // SBFM W0, W0, #0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - Base.Sbfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("UBFM , , #, #")] + [Test, Pairwise, Description("UBFM , , #, #")] public void Ubfm_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr, - [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr, + [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms) { uint Opcode = 0xD3400000; // UBFM X0, X0, #0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - Base.Ubfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("UBFM , , #, #")] + [Test, Pairwise, Description("UBFM , , #, #")] public void Ubfm_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr, - [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr, + [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms) { uint Opcode = 0x53000000; // UBFM W0, W0, #0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - Base.Ubfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs b/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs index 245b04c0..7ca92d4f 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs +++ b/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs @@ -1,4 +1,4 @@ -//#define CcmpImm +#define CcmpImm using ChocolArm64.State; @@ -6,25 +6,20 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("CcmpImm"), Ignore("Tested: second half of 2018.")] + [Category("CcmpImm")] // Tested: second half of 2018. public sealed class CpuTestCcmpImm : CpuTest { #if CcmpImm - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; + private const int RndCntImm = 2; + private const int RndCntNzcv = 2; - [Test, Description("CCMN , #, #, ")] + [Test, Pairwise, Description("CCMN , #, #, ")] public void Ccmn_64bit([Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, - [Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm, - [Random(0u, 15u, 1)] uint nzcv, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm, + [Random(0u, 15u, RndCntNzcv)] uint nzcv, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("CCMN , #, #, ")] + [Test, Pairwise, Description("CCMN , #, #, ")] public void Ccmn_32bit([Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, - [Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm, - [Random(0u, 15u, 1)] uint nzcv, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm, + [Random(0u, 15u, RndCntNzcv)] uint nzcv, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("CCMP , #, #, ")] + [Test, Pairwise, Description("CCMP , #, #, ")] public void Ccmp_64bit([Values(1u, 31u)] uint Rn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, - [Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm, - [Random(0u, 15u, 1)] uint nzcv, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, + [Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm, + [Random(0u, 15u, RndCntNzcv)] uint nzcv, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("CCMP , #, #, ")] + [Test, Pairwise, Description("CCMP , #, #, ")] public void Ccmp_32bit([Values(1u, 31u)] uint Rn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, - [Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm, - [Random(0u, 15u, 1)] uint nzcv, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, + [Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm, + [Random(0u, 15u, RndCntNzcv)] uint nzcv, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs b/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs index 8c4e503e..36120f74 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs +++ b/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs @@ -1,4 +1,4 @@ -//#define CcmpReg +#define CcmpReg using ChocolArm64.State; @@ -6,27 +6,21 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("CcmpReg"), Ignore("Tested: second half of 2018.")] + [Category("CcmpReg")] // Tested: second half of 2018. public sealed class CpuTestCcmpReg : CpuTest { #if CcmpReg - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; + private const int RndCntNzcv = 2; - [Test, Description("CCMN , , #, ")] + [Test, Pairwise, Description("CCMN , , #, ")] public void Ccmn_64bit([Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, - [Random(0u, 15u, 1)] uint nzcv, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, + [Random(0u, 15u, RndCntNzcv)] uint nzcv, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("CCMN , , #, ")] + [Test, Pairwise, Description("CCMN , , #, ")] public void Ccmn_32bit([Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, - [Random(0u, 15u, 1)] uint nzcv, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, + [Random(0u, 15u, RndCntNzcv)] uint nzcv, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("CCMP , , #, ")] + [Test, Pairwise, Description("CCMP , , #, ")] public void Ccmp_64bit([Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, - [Random(0u, 15u, 1)] uint nzcv, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, + [Random(0u, 15u, RndCntNzcv)] uint nzcv, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } - [Test, Description("CCMP , , #, ")] + [Test, Pairwise, Description("CCMP , , #, ")] public void Ccmp_32bit([Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, - [Random(0u, 15u, 1)] uint nzcv, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, + [Random(0u, 15u, RndCntNzcv)] uint nzcv, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // - { - Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N)); - Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z)); - Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C)); - Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V)); - }); CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestCsel.cs b/Ryujinx.Tests/Cpu/CpuTestCsel.cs index d532a12c..2d88b9f0 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCsel.cs +++ b/Ryujinx.Tests/Cpu/CpuTestCsel.cs @@ -1,4 +1,4 @@ -//#define Csel +#define Csel using ChocolArm64.State; @@ -6,27 +6,20 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("Csel"), Ignore("Tested: second half of 2018.")] + [Category("Csel")] // Tested: second half of 2018. public sealed class CpuTestCsel : CpuTest { #if Csel - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; - [Test, Description("CSEL , , , ")] + [Test, Pairwise, Description("CSEL , , , ")] public void Csel_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // , , , ")] + [Test, Pairwise, Description("CSEL , , , ")] public void Csel_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // , , , ")] + [Test, Pairwise, Description("CSINC , , , ")] public void Csinc_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // , , , ")] + [Test, Pairwise, Description("CSINC , , , ")] public void Csinc_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // , , , ")] + [Test, Pairwise, Description("CSINV , , , ")] public void Csinv_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // , , , ")] + [Test, Pairwise, Description("CSINV , , , ")] public void Csinv_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // , , , ")] + [Test, Pairwise, Description("CSNEG , , , ")] public void Csneg_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // , , , ")] + [Test, Pairwise, Description("CSNEG , , , ")] public void Csneg_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // , #{, LSL #}")] + [Test, Pairwise, Description("MOVK , #{, LSL #}")] public void Movk_64bit([Values(0u, 31u)] uint Rd, - [Random(12)] ulong _Xd, - [Values(0u, 65535u)] [Random(0u, 65535u, 10)] uint imm, + [Random(RndCntImm)] ulong _Xd, + [Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm, [Values(0u, 16u, 32u, 48u)] uint shift) { uint Opcode = 0xF2800000; // MOVK X0, #0, LSL #0 @@ -30,29 +23,16 @@ namespace Ryujinx.Tests.Cpu Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rd, new Bits(_Xd)); - Base.Movk(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("MOVK , #{, LSL #}")] + [Test, Pairwise, Description("MOVK , #{, LSL #}")] public void Movk_32bit([Values(0u, 31u)] uint Rd, - [Random(12)] uint _Wd, - [Values(0u, 65535u)] [Random(0u, 65535u, 10)] uint imm, + [Random(RndCntImm)] uint _Wd, + [Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm, [Values(0u, 16u)] uint shift) { uint Opcode = 0x72800000; // MOVK W0, #0, LSL #0 @@ -60,28 +40,15 @@ namespace Ryujinx.Tests.Cpu Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rd, new Bits(_Wd)); - Base.Movk(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("MOVN , #{, LSL #}")] + [Test, Pairwise, Description("MOVN , #{, LSL #}")] public void Movn_64bit([Values(0u, 31u)] uint Rd, - [Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm, + [Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm, [Values(0u, 16u, 32u, 48u)] uint shift) { uint Opcode = 0x92800000; // MOVN X0, #0, LSL #0 @@ -89,27 +56,15 @@ namespace Ryujinx.Tests.Cpu Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - Base.Movn(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("MOVN , #{, LSL #}")] + [Test, Pairwise, Description("MOVN , #{, LSL #}")] public void Movn_32bit([Values(0u, 31u)] uint Rd, - [Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm, + [Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm, [Values(0u, 16u)] uint shift) { uint Opcode = 0x12800000; // MOVN W0, #0, LSL #0 @@ -117,27 +72,15 @@ namespace Ryujinx.Tests.Cpu Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - Base.Movn(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("MOVZ , #{, LSL #}")] + [Test, Pairwise, Description("MOVZ , #{, LSL #}")] public void Movz_64bit([Values(0u, 31u)] uint Rd, - [Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm, + [Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm, [Values(0u, 16u, 32u, 48u)] uint shift) { uint Opcode = 0xD2800000; // MOVZ X0, #0, LSL #0 @@ -145,27 +88,15 @@ namespace Ryujinx.Tests.Cpu Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - Base.Movz(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("MOVZ , #{, LSL #}")] + [Test, Pairwise, Description("MOVZ , #{, LSL #}")] public void Movz_32bit([Values(0u, 31u)] uint Rd, - [Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm, + [Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm, [Values(0u, 16u)] uint shift) { uint Opcode = 0x52800000; // MOVZ W0, #0, LSL #0 @@ -173,21 +104,9 @@ namespace Ryujinx.Tests.Cpu Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - Base.Movz(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestMul.cs b/Ryujinx.Tests/Cpu/CpuTestMul.cs index 2e8aa76f..056c4543 100644 --- a/Ryujinx.Tests/Cpu/CpuTestMul.cs +++ b/Ryujinx.Tests/Cpu/CpuTestMul.cs @@ -1,4 +1,4 @@ -//#define Mul +#define Mul using ChocolArm64.State; @@ -6,378 +6,223 @@ using NUnit.Framework; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("Mul"), Ignore("Tested: second half of 2018.")] + [Category("Mul")] // Tested: second half of 2018. public sealed class CpuTestMul : CpuTest { #if Mul - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } + private const int RndCnt = 2; - [Test, Description("MADD , , , ")] + [Test, Pairwise, Description("MADD , , , ")] public void Madd_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(3u, 31u)] uint Ra, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa) { uint Opcode = 0x9B000000; // MADD X0, X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - AArch64.X((int)Ra, new Bits(Xa)); - Base.Madd(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("MADD , , , ")] + [Test, Pairwise, Description("MADD , , , ")] public void Madd_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(3u, 31u)] uint Ra, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wa) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wa) { uint Opcode = 0x1B000000; // MADD W0, W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.X((int)Ra, new Bits(Wa)); - Base.Madd(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("MSUB , , , ")] + [Test, Pairwise, Description("MSUB , , , ")] public void Msub_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(3u, 31u)] uint Ra, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa) { uint Opcode = 0x9B008000; // MSUB X0, X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - AArch64.X((int)Ra, new Bits(Xa)); - Base.Msub(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("MSUB , , , ")] + [Test, Pairwise, Description("MSUB , , , ")] public void Msub_32bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(3u, 31u)] uint Ra, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wa) + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wa) { uint Opcode = 0x1B008000; // MSUB W0, W0, W0, W0 Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0); uint _W31 = TestContext.CurrentContext.Random.NextUInt(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.X((int)Ra, new Bits(Wa)); - Base.Msub(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]); - uint Wd = AArch64.X(32, (int)Rd).ToUInt32(); - - Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd)); - } - else - { - Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); - } CompareAgainstUnicorn(); } - [Test, Description("SMADDL , , , ")] + [Test, Pairwise, Description("SMADDL , , , ")] public void Smaddl_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(3u, 31u)] uint Ra, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa) { uint Opcode = 0x9B200000; // SMADDL X0, W0, W0, X0 Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.X((int)Ra, new Bits(Xa)); - Base.Smaddl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("UMADDL , , , ")] + [Test, Pairwise, Description("UMADDL , , , ")] public void Umaddl_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(3u, 31u)] uint Ra, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa) { uint Opcode = 0x9BA00000; // UMADDL X0, W0, W0, X0 Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.X((int)Ra, new Bits(Xa)); - Base.Umaddl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("SMSUBL , , , ")] + [Test, Pairwise, Description("SMSUBL , , , ")] public void Smsubl_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(3u, 31u)] uint Ra, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa) { uint Opcode = 0x9B208000; // SMSUBL X0, W0, W0, X0 Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.X((int)Ra, new Bits(Xa)); - Base.Smsubl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("UMSUBL , , , ")] + [Test, Pairwise, Description("UMSUBL , , , ")] public void Umsubl_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(3u, 31u)] uint Ra, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn, [Values(0x00000000u, 0x7FFFFFFFu, - 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm, + 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa) { uint Opcode = 0x9BA08000; // UMSUBL X0, W0, W0, X0 Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Wn)); - AArch64.X((int)Rm, new Bits(Wm)); - AArch64.X((int)Ra, new Bits(Xa)); - Base.Umsubl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("SMULH , , ")] + [Test, Pairwise, Description("SMULH , , ")] public void Smulh_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xm) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9B407C00; // SMULH X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Smulh(Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } - [Test, Description("UMULH , , ")] + [Test, Pairwise, Description("UMULH , , ")] public void Umulh_64bit([Values(0u, 31u)] uint Rd, [Values(1u, 31u)] uint Rn, [Values(2u, 31u)] uint Rm, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xn, + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn, [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, - 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xm) + 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm) { uint Opcode = 0x9BC07C00; // UMULH X0, X0, X0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); ulong _X31 = TestContext.CurrentContext.Random.NextULong(); + AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31); - if (Rd != 31) - { - Bits Op = new Bits(Opcode); - - AArch64.X((int)Rn, new Bits(Xn)); - AArch64.X((int)Rm, new Bits(Xm)); - Base.Umulh(Op[20, 16], Op[9, 5], Op[4, 0]); - ulong Xd = AArch64.X(64, (int)Rd).ToUInt64(); - - Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd)); - } - else - { - Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); - } CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestSimd.cs b/Ryujinx.Tests/Cpu/CpuTestSimd.cs index 37fb3e97..ec0cd104 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimd.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimd.cs @@ -8,18 +8,10 @@ using System.Runtime.Intrinsics; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("Simd")/*, Ignore("Tested: second half of 2018.")*/] + [Category("Simd")] // Tested: second half of 2018. public sealed class CpuTestSimd : CpuTest { #if Simd - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } #region "ValueSource" private static ulong[] _1B1H1S1D_() @@ -156,7 +148,7 @@ namespace Ryujinx.Tests.Cpu } #endregion - private const int RndCnt = 4; + private const int RndCnt = 2; [Test, Pairwise, Description("ABS , ")] public void Abs_S_D([Values(0u)] uint Rd, @@ -166,21 +158,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EE0B800; // ABS D0, D0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Abs_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -194,21 +177,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E20B800; // ABS V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Abs_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -222,21 +196,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E20B800; // ABS V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Abs_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -248,21 +213,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EF1B800; // ADDP D0, V0.2D Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Addp_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -276,21 +232,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E31B800; // ADDV B0, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Addv_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -304,21 +251,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E31B800; // ADDV B0, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Addv_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -332,21 +270,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E204800; // CLS V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cls_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -360,21 +289,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E204800; // CLS V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Cls_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -388,21 +308,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E204800; // CLZ V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Clz_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -416,21 +327,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E204800; // CLZ V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Clz_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -442,21 +344,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EE09800; // CMEQ D0, D0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmeq_Zero_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -470,21 +363,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E209800; // CMEQ V0.8B, V0.8B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmeq_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -498,21 +382,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E209800; // CMEQ V0.16B, V0.16B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Cmeq_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -524,21 +399,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x7EE08800; // CMGE D0, D0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmge_Zero_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -552,21 +418,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E208800; // CMGE V0.8B, V0.8B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmge_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -580,21 +437,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E208800; // CMGE V0.16B, V0.16B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Cmge_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -606,21 +454,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EE08800; // CMGT D0, D0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmgt_Zero_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -634,21 +473,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E208800; // CMGT V0.8B, V0.8B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmgt_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -662,21 +492,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E208800; // CMGT V0.16B, V0.16B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Cmgt_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -688,21 +509,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x7EE09800; // CMLE D0, D0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmle_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -716,21 +528,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E209800; // CMLE V0.8B, V0.8B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmle_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -744,21 +547,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E209800; // CMLE V0.16B, V0.16B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Cmle_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -770,21 +564,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EE0A800; // CMLT D0, D0, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmlt_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -798,21 +583,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E20A800; // CMLT V0.8B, V0.8B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cmlt_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -826,21 +602,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E20A800; // CMLT V0.16B, V0.16B, #0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Cmlt_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -852,21 +619,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x0E205800; // CNT V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Cnt_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -878,21 +636,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4E205800; // CNT V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Cnt_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -904,37 +653,17 @@ namespace Ryujinx.Tests.Cpu { //const int FZFlagBit = 24; // Flush-to-zero mode control bit. - //const int IDCFlagBit = 7; // Input Denormal cumulative floating-point exception bit. - //const int IXCFlagBit = 4; // Inexact cumulative floating-point exception bit. - //const int IOCFlagBit = 0; // Invalid Operation cumulative floating-point exception bit. - uint Opcode = 0x5E21A800; // FCVTNS S0, S0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled. Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - //Shared.FPCR = new Bits((uint)Fpcr); - SimdFp.Fcvtns_S(Op[22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - /*Assert.Multiple(() => - { - Assert.That(((ThreadState.Fpsr >> IDCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IDCFlagBit])); - Assert.That(((ThreadState.Fpsr >> IXCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IXCFlagBit])); - Assert.That(((ThreadState.Fpsr >> IOCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IOCFlagBit])); - });*/ + CompareAgainstUnicorn(/*FpsrMask: FPSR.IDC | FPSR.IXC | FPSR.IOC*/); } [Test, Pairwise, Description("FCVTNS , ")] @@ -943,23 +672,19 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1D_F_")] [Random(RndCnt)] ulong Z, [ValueSource("_1D_F_")] [Random(RndCnt)] ulong A) { + //const int FZFlagBit = 24; // Flush-to-zero mode control bit. + uint Opcode = 0x5E61A800; // FCVTNS D0, D0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); + + //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled. Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Fcvtns_S(Op[22], Op[9, 5], Op[4, 0]); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/); - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(/*FpsrMask: FPSR.IDC | FPSR.IXC | FPSR.IOC*/); } [Test, Pairwise, Description("FCVTNS ., .")] @@ -969,24 +694,20 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_2S_F_")] [Random(RndCnt)] ulong A, [Values(0b0u, 0b1u)] uint Q) // <2S, 4S> { + //const int FZFlagBit = 24; // Flush-to-zero mode control bit. + uint Opcode = 0x0E21A800; // FCVTNS V0.2S, V0.2S Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((Q & 1) << 30); - Bits Op = new Bits(Opcode); + + //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled. Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A * Q); - AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A * Q)); - SimdFp.Fcvtns_V(Op[30], Op[22], Op[9, 5], Op[4, 0]); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/); - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(/*FpsrMask: FPSR.IDC | FPSR.IXC | FPSR.IOC*/); } [Test, Pairwise, Description("FCVTNS ., .")] @@ -995,23 +716,19 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1D_F_")] [Random(RndCnt)] ulong Z, [ValueSource("_1D_F_")] [Random(RndCnt)] ulong A) { + //const int FZFlagBit = 24; // Flush-to-zero mode control bit. + uint Opcode = 0x4E61A800; // FCVTNS V0.2D, V0.2D Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); + + //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled. Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); - AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Fcvtns_V(Op[30], Op[22], Op[9, 5], Op[4, 0]); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/); - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(/*FpsrMask: FPSR.IDC | FPSR.IXC | FPSR.IOC*/); } [Test, Pairwise, Description("FCVTNU , ")] @@ -1022,37 +739,17 @@ namespace Ryujinx.Tests.Cpu { //const int FZFlagBit = 24; // Flush-to-zero mode control bit. - //const int IDCFlagBit = 7; // Input Denormal cumulative floating-point exception bit. - //const int IXCFlagBit = 4; // Inexact cumulative floating-point exception bit. - //const int IOCFlagBit = 0; // Invalid Operation cumulative floating-point exception bit. - uint Opcode = 0x7E21A800; // FCVTNU S0, S0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled. Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - //Shared.FPCR = new Bits((uint)Fpcr); - SimdFp.Fcvtnu_S(Op[22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - /*Assert.Multiple(() => - { - Assert.That(((ThreadState.Fpsr >> IDCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IDCFlagBit])); - Assert.That(((ThreadState.Fpsr >> IXCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IXCFlagBit])); - Assert.That(((ThreadState.Fpsr >> IOCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IOCFlagBit])); - });*/ + CompareAgainstUnicorn(/*FpsrMask: FPSR.IDC | FPSR.IXC | FPSR.IOC*/); } [Test, Pairwise, Description("FCVTNU , ")] @@ -1061,23 +758,19 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1D_F_")] [Random(RndCnt)] ulong Z, [ValueSource("_1D_F_")] [Random(RndCnt)] ulong A) { + //const int FZFlagBit = 24; // Flush-to-zero mode control bit. + uint Opcode = 0x7E61A800; // FCVTNU D0, D0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); + + //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled. Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Fcvtnu_S(Op[22], Op[9, 5], Op[4, 0]); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/); - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(/*FpsrMask: FPSR.IDC | FPSR.IXC | FPSR.IOC*/); } [Test, Pairwise, Description("FCVTNU ., .")] @@ -1087,24 +780,20 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_2S_F_")] [Random(RndCnt)] ulong A, [Values(0b0u, 0b1u)] uint Q) // <2S, 4S> { + //const int FZFlagBit = 24; // Flush-to-zero mode control bit. + uint Opcode = 0x2E21A800; // FCVTNU V0.2S, V0.2S Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((Q & 1) << 30); - Bits Op = new Bits(Opcode); + + //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled. Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A * Q); - AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A * Q)); - SimdFp.Fcvtnu_V(Op[30], Op[22], Op[9, 5], Op[4, 0]); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/); - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(/*FpsrMask: FPSR.IDC | FPSR.IXC | FPSR.IOC*/); } [Test, Pairwise, Description("FCVTNU ., .")] @@ -1113,23 +802,19 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1D_F_")] [Random(RndCnt)] ulong Z, [ValueSource("_1D_F_")] [Random(RndCnt)] ulong A) { + //const int FZFlagBit = 24; // Flush-to-zero mode control bit. + uint Opcode = 0x6E61A800; // FCVTNU V0.2D, V0.2D Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); + + //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled. Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); - AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Fcvtnu_V(Op[30], Op[22], Op[9, 5], Op[4, 0]); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/); - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(/*FpsrMask: FPSR.IDC | FPSR.IXC | FPSR.IOC*/); } [Test, Pairwise, Description("NEG , ")] @@ -1140,21 +825,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x7EE0B800; // NEG D0, D0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Neg_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1168,21 +844,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E20B800; // NEG V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Neg_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1196,21 +863,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E20B800; // NEG V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Neg_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1222,21 +880,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x2E205800; // NOT V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Not_V(Op[30], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1248,21 +897,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x6E205800; // NOT V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Not_V(Op[30], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1274,21 +914,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x2E605800; // RBIT V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Rbit_V(Op[30], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1300,21 +931,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x6E605800; // RBIT V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Rbit_V(Op[30], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1326,21 +948,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x0E201800; // REV16 V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Rev16_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1352,21 +965,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4E201800; // REV16 V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Rev16_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1380,21 +984,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E200800; // REV32 V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Rev32_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1408,21 +1003,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E200800; // REV32 V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Rev32_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1436,21 +1022,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E200800; // REV64 V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Rev64_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1464,21 +1041,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E200800; // REV64 V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Rev64_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1492,21 +1060,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E206800; // SADALP V0.4H, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Sadalp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1520,21 +1079,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E206800; // SADALP V0.8H, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Sadalp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1548,21 +1098,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E202800; // SADDLP V0.4H, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Saddlp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1576,21 +1117,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E202800; // SADDLP V0.8H, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Saddlp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1602,26 +1134,12 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5E282800; // SHA256SU0 V0.4S, V0.4S Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z0, Z1); Vector128 V1 = MakeVectorE0E1(A0, A1); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z0)); AArch64.Vpart(0, 1, new Bits(Z1)); - AArch64.Vpart(1, 0, new Bits(A0)); AArch64.Vpart(1, 1, new Bits(A1)); - SimdFp.Sha256su0_V(Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.Multiple(() => - { - Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 0).ToUInt64())); - Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 1).ToUInt64())); - }); CompareAgainstUnicorn(); } @@ -1632,28 +1150,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x5E207800; // SQABS B0, B0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Sqabs_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQABS ., .")] @@ -1663,28 +1169,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x0E207800; // SQABS V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Sqabs_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQABS ., .")] @@ -1694,28 +1188,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x4E207800; // SQABS V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Sqabs_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQNEG , ")] @@ -1725,28 +1207,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x7E207800; // SQNEG B0, B0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Sqneg_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQNEG ., .")] @@ -1756,28 +1226,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x2E207800; // SQNEG V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Sqneg_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQNEG ., .")] @@ -1787,28 +1245,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x6E207800; // SQNEG V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Sqneg_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQXTN , ")] @@ -1818,28 +1264,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x5E214800; // SQXTN B0, H0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Sqxtn_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQXTN{2} ., .")] @@ -1849,28 +1283,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x0E214800; // SQXTN V0.8B, V0.8H Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Sqxtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQXTN{2} ., .")] @@ -1880,28 +1302,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x4E214800; // SQXTN2 V0.16B, V0.8H Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Sqxtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQXTUN , ")] @@ -1911,28 +1321,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x7E212800; // SQXTUN B0, H0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Sqxtun_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQXTUN{2} ., .")] @@ -1942,28 +1340,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x2E212800; // SQXTUN V0.8B, V0.8H Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Sqxtun_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQXTUN{2} ., .")] @@ -1973,28 +1359,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x6E212800; // SQXTUN2 V0.16B, V0.8H Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Sqxtun_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SUQADD , ")] @@ -2004,28 +1378,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x5E203800; // SUQADD B0, B0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Suqadd_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SUQADD ., .")] @@ -2035,28 +1397,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x0E203800; // SUQADD V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Suqadd_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SUQADD ., .")] @@ -2066,28 +1416,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x4E203800; // SUQADD V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Suqadd_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("UADALP ., .")] @@ -2100,21 +1438,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E206800; // UADALP V0.4H, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Uadalp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2128,21 +1457,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E206800; // UADALP V0.8H, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Uadalp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2156,21 +1476,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E202800; // UADDLP V0.4H, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Uaddlp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2184,21 +1495,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E202800; // UADDLP V0.8H, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Uaddlp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2209,28 +1511,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x7E214800; // UQXTN B0, H0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Uqxtn_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("UQXTN{2} ., .")] @@ -2240,28 +1530,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x2E214800; // UQXTN V0.8B, V0.8H Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Uqxtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("UQXTN{2} ., .")] @@ -2271,28 +1549,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x6E214800; // UQXTN2 V0.16B, V0.8H Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Uqxtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("USQADD , ")] @@ -2302,28 +1568,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x7E203800; // USQADD B0, B0 Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Usqadd_S(Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("USQADD ., .")] @@ -2333,28 +1587,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x2E203800; // USQADD V0.8B, V0.8B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0(A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - SimdFp.Usqadd_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("USQADD ., .")] @@ -2364,28 +1606,16 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x6E203800; // USQADD V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Usqadd_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); - CompareAgainstUnicorn(); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("XTN{2} ., .")] @@ -2398,21 +1628,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E212800; // XTN V0.8B, V0.8H Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Xtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2426,21 +1647,12 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E212800; // XTN2 V0.16B, V0.8H Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - SimdFp.Xtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs b/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs index e9fd462e..7a67d53b 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs @@ -9,7 +9,7 @@ namespace Ryujinx.Tests.Cpu { public class CpuTestSimdArithmetic : CpuTest { - [TestCase(0x1E224820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000000000000ul)] + [TestCase(0x1E224820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000000000000ul)] // FMAX S0, S1, S2 [TestCase(0x1E224820u, 0x0000000080000000ul, 0x0000000000000000ul, 0x0000000000000000ul)] [TestCase(0x1E224820u, 0x0000000080000000ul, 0x0000000080000000ul, 0x0000000080000000ul)] [TestCase(0x1E224820u, 0x0000000080000000ul, 0x000000003DCCCCCDul, 0x000000003DCCCCCDul)] @@ -22,17 +22,19 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x1E224820u, 0x000000007F800001ul, 0x000000007FC00042ul, 0x000000007FC00001ul)] [TestCase(0x1E224820u, 0x000000007FC00042ul, 0x000000007F800001ul, 0x000000007FC00001ul)] [TestCase(0x1E224820u, 0x000000007FC0000Aul, 0x000000007FC0000Bul, 0x000000007FC0000Aul)] - [TestCase(0x1E624820u, 0x0000000000000000ul, 0x8000000000000000ul, 0x0000000000000000ul)] + [TestCase(0x1E624820u, 0x0000000000000000ul, 0x8000000000000000ul, 0x0000000000000000ul)] // FMAX D0, D1, D2 [TestCase(0x1E624820u, 0x8000000000000000ul, 0x0000000000000000ul, 0x0000000000000000ul)] [TestCase(0x1E624820u, 0x8000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)] [TestCase(0x1E624820u, 0x8000000000000000ul, 0x3FF3333333333333ul, 0x3FF3333333333333ul)] public void Fmax_S(uint Opcode, ulong A, ulong B, ulong Result) { - // FMAX S0, S1, S2 - 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)); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } @@ -51,19 +53,23 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x7FC0000Au, 0x7FC0000Au, 0x7FC0000Bu, 0x7FC0000Bu, 0x7FC0000Au, 0x7FC0000Au)] public void Fmax_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1) { - uint Opcode = 0x4E22F420; + uint Opcode = 0x4E22F420; // FMAX V0.4S, V1.4S, V2.4S + Vector128 V1 = MakeVectorE0E1(A, B); Vector128 V2 = MakeVectorE0E1(C, D); + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); + Assert.Multiple(() => { - Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); - Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1)); }); + CompareAgainstUnicorn(); } - [TestCase(0x1E225820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000080000000ul)] + [TestCase(0x1E225820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000080000000ul)] // FMIN S0, S1, S2 [TestCase(0x1E225820u, 0x0000000080000000ul, 0x0000000000000000ul, 0x0000000080000000ul)] [TestCase(0x1E225820u, 0x0000000080000000ul, 0x0000000080000000ul, 0x0000000080000000ul)] [TestCase(0x1E225820u, 0x0000000080000000ul, 0x000000003DCCCCCDul, 0x0000000080000000ul)] @@ -76,17 +82,19 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x1E225820u, 0x000000007F800001ul, 0x000000007FC00042ul, 0x000000007FC00001ul)] [TestCase(0x1E225820u, 0x000000007FC00042ul, 0x000000007F800001ul, 0x000000007FC00001ul)] [TestCase(0x1E225820u, 0x000000007FC0000Aul, 0x000000007FC0000Bul, 0x000000007FC0000Aul)] - [TestCase(0x1E625820u, 0x0000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)] + [TestCase(0x1E625820u, 0x0000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)] // FMIN D0, D1, D2 [TestCase(0x1E625820u, 0x8000000000000000ul, 0x0000000000000000ul, 0x8000000000000000ul)] [TestCase(0x1E625820u, 0x8000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)] [TestCase(0x1E625820u, 0x8000000000000000ul, 0x3FF3333333333333ul, 0x8000000000000000ul)] public void Fmin_S(uint Opcode, ulong A, ulong B, ulong Result) { - // FMIN S0, S1, S2 - 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)); + Vector128 V1 = MakeVectorE0(A); + Vector128 V2 = MakeVectorE0(B); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } @@ -105,15 +113,19 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x7FC0000Au, 0x7FC0000Au, 0x7FC0000Bu, 0x7FC0000Bu, 0x7FC0000Au, 0x7FC0000Au)] public void Fmin_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1) { - uint Opcode = 0x4EA2F420; + uint Opcode = 0x4EA2F420; // FMIN V0.4S, V1.4S, V2.4S + Vector128 V1 = MakeVectorE0E1(A, B); Vector128 V2 = MakeVectorE0E1(C, D); + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2); + Assert.Multiple(() => { - Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); - Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1)); }); + CompareAgainstUnicorn(); } @@ -125,6 +137,7 @@ namespace Ryujinx.Tests.Cpu V0: Sse.SetVector128(0, B, 0, 0)); Assert.That(Sse41.Extract(ThreadState.V6, (byte)0), Is.EqualTo(A * B)); + CompareAgainstUnicorn(); } @@ -137,21 +150,27 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x007FF000u, 0x7E800000u)] public void Frecpe_S(uint A, uint Result) { + uint Opcode = 0x5EA1D820; // FRECPE S0, S1 + Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(0x5EA1D820, V1: V1); - Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } - [Test, Description("FRECPS D0, D1, D2")] + [Test, Description("FRECPS D0, D1, D2"), Ignore("Not accurate enough.")] public void Frecps_S([Random(10)] double A, [Random(10)] double B) { AThreadState ThreadState = SingleOpcode(0x5E62FC20, V1: MakeVectorE0(A), V2: MakeVectorE0(B)); - Assert.That(VectorExtractDouble(ThreadState.V0, 0), Is.EqualTo(2 - (A * B))); - //CompareAgainstUnicorn(); // Not accurate enough + Assert.That(VectorExtractDouble(ThreadState.V0, (byte)0), Is.EqualTo(2 - (A * B))); + + CompareAgainstUnicorn(); } [Test, Description("FRECPS V4.4S, V2.4S, V0.4S")] @@ -170,6 +189,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(Sse41.Extract(ThreadState.V4, (byte)2), Is.EqualTo(Result)); Assert.That(Sse41.Extract(ThreadState.V4, (byte)3), Is.EqualTo(Result)); }); + CompareAgainstUnicorn(); } @@ -177,7 +197,7 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x3F99999Au, false, 0x3F800000u)] [TestCase(0x404CCCCDu, false, 0x40400000u)] [TestCase(0x40733333u, false, 0x40800000u)] - [TestCase(0x3fc00000u, false, 0x40000000u)] + [TestCase(0x3FC00000u, false, 0x40000000u)] [TestCase(0x40200000u, false, 0x40400000u)] [TestCase(0x00000000u, false, 0x00000000u)] [TestCase(0x00000000u, false, 0x00000000u)] @@ -213,42 +233,53 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")] public void Frinta_S(uint A, bool DefaultNaN, uint Result) { + uint Opcode = 0x1E264020; // FRINTA S0, S1 + + Vector128 V1 = MakeVectorE0(A); + int FpcrTemp = 0x0; if(DefaultNaN) { FpcrTemp = 0x2000000; } - Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } - [TestCase(0x6E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] + [Ignore("Wrong opcodes.")] + [TestCase(0x6E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTA V0.2D, V1.2D [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(0x2E219820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] - [TestCase(0x2E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] + [TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTX V0.4S, V1.4S + [TestCase(0x6E219820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] + [TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTX V0.2S, V1.2S + [TestCase(0x2E219820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] + [TestCase(0x2E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] // FRINTA V0.2S, V1.2S [TestCase(0x2E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] [TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")] [TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] public void Frinta_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1) { + Vector128 V1 = MakeVectorE0E1(A, B); + int FpcrTemp = 0x0; if(DefaultNaN) { FpcrTemp = 0x2000000; } - Vector128 V1 = MakeVectorE0E1(A, B); + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + Assert.Multiple(() => { - Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); - Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1)); }); + CompareAgainstUnicorn(); } @@ -294,36 +325,31 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")] public void Frinti_S(uint A, char RoundType, bool DefaultNaN, uint Result) { + uint Opcode = 0x1E27C020; // FRINTI S0, S1 + + Vector128 V1 = MakeVectorE0(A); + int FpcrTemp = 0x0; switch(RoundType) { - case 'N': - FpcrTemp = 0x0; - break; - - case 'P': - FpcrTemp = 0x400000; - break; - - case 'M': - FpcrTemp = 0x800000; - break; - - case 'Z': - FpcrTemp = 0xC00000; - break; + case 'N': FpcrTemp = 0x0; break; + case 'P': FpcrTemp = 0x400000; break; + case 'M': FpcrTemp = 0x800000; break; + case 'Z': FpcrTemp = 0xC00000; break; } if(DefaultNaN) { FpcrTemp |= 1 << 25; } - Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(0x1E27C020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } - [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] + [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTI V0.2D, V1.2D [TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'N', false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)] @@ -331,14 +357,14 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [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, '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, 'M', false, 0x3f8000003f800000ul, 0x0000000000000000ul)] - [TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x0000000000000000ul)] + [TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTI V0.4S, V1.4S + [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)] // FRINTI V0.2S, V1.2S + [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)] [TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)] [TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'M', false, 0x0000000080000000ul, 0x0000000000000000ul)] @@ -357,36 +383,29 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] public void Frinti_V(uint Opcode, ulong A, ulong B, char RoundType, bool DefaultNaN, ulong Result0, ulong Result1) { + Vector128 V1 = MakeVectorE0E1(A, B); + int FpcrTemp = 0x0; switch(RoundType) { - case 'N': - FpcrTemp = 0x0; - break; - - case 'P': - FpcrTemp = 0x400000; - break; - - case 'M': - FpcrTemp = 0x800000; - break; - - case 'Z': - FpcrTemp = 0xC00000; - break; + case 'N': FpcrTemp = 0x0; break; + case 'P': FpcrTemp = 0x400000; break; + case 'M': FpcrTemp = 0x800000; break; + case 'Z': FpcrTemp = 0xC00000; break; } if(DefaultNaN) { FpcrTemp |= 1 << 25; } - Vector128 V1 = MakeVectorE0E1(A, B); + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + Assert.Multiple(() => { - Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); - Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1)); }); + CompareAgainstUnicorn(); } @@ -394,7 +413,7 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x3F99999Au, false, 0x3F800000u)] [TestCase(0x404CCCCDu, false, 0x40400000u)] [TestCase(0x40733333u, false, 0x40400000u)] - [TestCase(0x3fc00000u, false, 0x3F800000u)] + [TestCase(0x3FC00000u, false, 0x3F800000u)] [TestCase(0x40200000u, false, 0x40000000u)] [TestCase(0x00000000u, false, 0x00000000u)] [TestCase(0x00000000u, false, 0x00000000u)] @@ -430,47 +449,58 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")] public void Frintm_S(uint A, bool DefaultNaN, uint Result) { + uint Opcode = 0x1E254020; // FRINTM S0, S1 + + Vector128 V1 = MakeVectorE0(A); + int FpcrTemp = 0x0; if(DefaultNaN) { FpcrTemp = 0x2000000; } - Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(0x1E254020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } - [TestCase(0x4E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] + [TestCase(0x4E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTM V0.2D, V1.2D [TestCase(0x4E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] - [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.")] - [TestCase(0xE219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] + [TestCase(0x4E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)] // FRINTM V0.4S, V1.4S + [TestCase(0x0E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F8000003F800000ul, 0x0000000000000000ul)] // FRINTM V0.2S, V1.2S + [TestCase(0x0E219820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] + [TestCase(0x0E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] + [TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")] + [TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] public void Frintm_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1) { + Vector128 V1 = MakeVectorE0E1(A, B); + int FpcrTemp = 0x0; if(DefaultNaN) { FpcrTemp = 0x2000000; } - Vector128 V1 = MakeVectorE0E1(A, B); + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + Assert.Multiple(() => { - Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); - Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1)); }); + CompareAgainstUnicorn(); } + [Ignore("Wrong opcode.")] [TestCase(0x3FE66666u, false, 0x40000000u)] [TestCase(0x3F99999Au, false, 0x3F800000u)] [TestCase(0x404CCCCDu, false, 0x40400000u)] [TestCase(0x40733333u, false, 0x40800000u)] - [TestCase(0x3fc00000u, false, 0x40000000u)] + [TestCase(0x3FC00000u, false, 0x40000000u)] [TestCase(0x40200000u, false, 0x40400000u)] [TestCase(0x00000000u, false, 0x00000000u)] [TestCase(0x00000000u, false, 0x00000000u)] @@ -506,42 +536,52 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")] public void Frintn_S(uint A, bool DefaultNaN, uint Result) { + uint Opcode = 0x1E264020; // FRINTA S0, S1 + + Vector128 V1 = MakeVectorE0(A); + int FpcrTemp = 0x0; if(DefaultNaN) { FpcrTemp = 0x2000000; } - Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } - [TestCase(0x4E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] + [TestCase(0x4E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTN V0.2D, V1.2D [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(0xE218820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] - [TestCase(0xE218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] - [TestCase(0xE218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] - [TestCase(0xE218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")] - [TestCase(0xE218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] + [TestCase(0x4E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTN V0.4S, V1.4S + [TestCase(0x4E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] + [TestCase(0x0E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTN V0.2S, V1.2S + [TestCase(0x0E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] + [TestCase(0x0E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] + [TestCase(0x0E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] + [TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")] + [TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] public void Frintn_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1) { + Vector128 V1 = MakeVectorE0E1(A, B); + int FpcrTemp = 0x0; if(DefaultNaN) { FpcrTemp = 0x2000000; } - Vector128 V1 = MakeVectorE0E1(A, B); + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + Assert.Multiple(() => { - Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); - Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1)); }); + CompareAgainstUnicorn(); } @@ -549,7 +589,7 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x3F99999Au, false, 0x40000000u)] [TestCase(0x404CCCCDu, false, 0x40800000u)] [TestCase(0x40733333u, false, 0x40800000u)] - [TestCase(0x3fc00000u, false, 0x40000000u)] + [TestCase(0x3FC00000u, false, 0x40000000u)] [TestCase(0x40200000u, false, 0x40400000u)] [TestCase(0x00000000u, false, 0x00000000u)] [TestCase(0x00000000u, false, 0x00000000u)] @@ -585,39 +625,49 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")] public void Frintp_S(uint A, bool DefaultNaN, uint Result) { + uint Opcode = 0x1E24C020; // FRINTP S0, S1 + + Vector128 V1 = MakeVectorE0(A); + int FpcrTemp = 0x0; if(DefaultNaN) { FpcrTemp = 0x2000000; } - Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(0x1E24C020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } - [TestCase(0x4EE18820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x4000000000000000ul, 0x4000000000000000ul)] + [TestCase(0x4EE18820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x4000000000000000ul, 0x4000000000000000ul)] // FRINTP V0.2D, v1.2D [TestCase(0x4EE18820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)] - [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.")] - [TestCase(0xEA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] + [TestCase(0x4EA18820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] // FRINTP V0.4S, v1.4S + [TestCase(0x0EA18820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] // FRINTP V0.2S, v1.2S + [TestCase(0x0EA18820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] + [TestCase(0x0EA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)] + [TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")] + [TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] public void Frintp_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1) { + Vector128 V1 = MakeVectorE0E1(A, B); + int FpcrTemp = 0x0; if(DefaultNaN) { FpcrTemp = 0x2000000; } - Vector128 V1 = MakeVectorE0E1(A, B); + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + Assert.Multiple(() => { - Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); - Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1)); }); + CompareAgainstUnicorn(); } @@ -663,36 +713,31 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")] public void Frintx_S(uint A, char RoundType, bool DefaultNaN, uint Result) { + uint Opcode = 0x1E274020; // FRINTX S0, S1 + + Vector128 V1 = MakeVectorE0(A); + int FpcrTemp = 0x0; switch(RoundType) { - case 'N': - FpcrTemp = 0x0; - break; - - case 'P': - FpcrTemp = 0x400000; - break; - - case 'M': - FpcrTemp = 0x800000; - break; - - case 'Z': - FpcrTemp = 0xC00000; - break; + case 'N': FpcrTemp = 0x0; break; + case 'P': FpcrTemp = 0x400000; break; + case 'M': FpcrTemp = 0x800000; break; + case 'Z': FpcrTemp = 0xC00000; break; } if(DefaultNaN) { FpcrTemp |= 1 << 25; } - Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(0x1E274020, V1: V1, Fpcr: FpcrTemp); - Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } - [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] + [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTX V0.2D, V1.2D [TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'N', false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)] [TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)] @@ -700,14 +745,14 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] [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, '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, 'M', false, 0x3f8000003f800000ul, 0x0000000000000000ul)] - [TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x0000000000000000ul)] + [TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTX V0.4S, V1.4S + [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)] // FRINTX V0.2S, V1.2S + [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)] [TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)] [TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'M', false, 0x0000000080000000ul, 0x0000000000000000ul)] @@ -726,45 +771,43 @@ namespace Ryujinx.Tests.Cpu [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")] public void Frintx_V(uint Opcode, ulong A, ulong B, char RoundType, bool DefaultNaN, ulong Result0, ulong Result1) { + Vector128 V1 = MakeVectorE0E1(A, B); + int FpcrTemp = 0x0; switch(RoundType) { - case 'N': - FpcrTemp = 0x0; - break; - - case 'P': - FpcrTemp = 0x400000; - break; - - case 'M': - FpcrTemp = 0x800000; - break; - - case 'Z': - FpcrTemp = 0xC00000; - break; + case 'N': FpcrTemp = 0x0; break; + case 'P': FpcrTemp = 0x400000; break; + case 'M': FpcrTemp = 0x800000; break; + case 'Z': FpcrTemp = 0xC00000; break; } if(DefaultNaN) { FpcrTemp |= 1 << 25; } - Vector128 V1 = MakeVectorE0E1(A, B); + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp); + Assert.Multiple(() => { - Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0)); - Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0)); + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0)); + Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1)); }); + CompareAgainstUnicorn(); } [TestCase(0x41200000u, 0x3EA18000u)] public void Frsqrte_S(uint A, uint Result) { + uint Opcode = 0x7EA1D820; // FRSQRTE S0, S1 + Vector128 V1 = MakeVectorE0(A); - AThreadState ThreadState = SingleOpcode(0x7EA1D820, V1: V1); - Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + + AThreadState ThreadState = SingleOpcode(Opcode, V1: V1); + + Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result)); + CompareAgainstUnicorn(); } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs b/Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs index acf7000b..a1558b05 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs @@ -24,12 +24,15 @@ namespace Ryujinx.Tests.Cpu } #endregion + private const int RndCnt = 2; + [Test, Description("FCMEQ D0, D1, D2 | FCMGE D0, D1, D2 | FCMGT D0, D1, D2")] - public void Fcmeq_Fcmge_Fcmgt_Reg_S_D([ValueSource("_doubles_")] [Random(8)] double A, - [ValueSource("_doubles_")] [Random(8)] double B, + public void Fcmeq_Fcmge_Fcmgt_Reg_S_D([ValueSource("_doubles_")] [Random(RndCnt)] double A, + [ValueSource("_doubles_")] [Random(RndCnt)] double B, [Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT { uint Opcode = 0x5E62E420 | ((EU & 1) << 29) | ((EU >> 1) << 23); + Vector128 V0 = Sse.StaticCast(Sse2.SetAllVector128(TestContext.CurrentContext.Random.NextDouble())); Vector128 V1 = Sse.StaticCast(Sse2.SetScalarVector128(A)); Vector128 V2 = Sse.StaticCast(Sse2.SetScalarVector128(B)); @@ -52,15 +55,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp)); Assert.That(VectorExtractDouble(ThreadState.V0, (byte)1), Is.Zero); }); + CompareAgainstUnicorn(); } [Test, Description("FCMEQ S0, S1, S2 | FCMGE S0, S1, S2 | FCMGT S0, S1, S2")] - public void Fcmeq_Fcmge_Fcmgt_Reg_S_S([ValueSource("_floats_")] [Random(8)] float A, - [ValueSource("_floats_")] [Random(8)] float B, + public void Fcmeq_Fcmge_Fcmgt_Reg_S_S([ValueSource("_floats_")] [Random(RndCnt)] float A, + [ValueSource("_floats_")] [Random(RndCnt)] float B, [Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT { uint Opcode = 0x5E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23); + Vector128 V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat()); Vector128 V1 = Sse.SetScalarVector128(A); Vector128 V2 = Sse.SetScalarVector128(B); @@ -85,15 +90,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(Sse41.Extract(ThreadState.V0, (byte)2), Is.Zero); Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero); }); + CompareAgainstUnicorn(); } [Test, Description("FCMEQ V0.2D, V1.2D, V2.2D | FCMGE V0.2D, V1.2D, V2.2D | FCMGT V0.2D, V1.2D, V2.2D")] - public void Fcmeq_Fcmge_Fcmgt_Reg_V_2D([ValueSource("_doubles_")] [Random(8)] double A, - [ValueSource("_doubles_")] [Random(8)] double B, + public void Fcmeq_Fcmge_Fcmgt_Reg_V_2D([ValueSource("_doubles_")] [Random(RndCnt)] double A, + [ValueSource("_doubles_")] [Random(RndCnt)] double B, [Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT { uint Opcode = 0x4E62E420 | ((EU & 1) << 29) | ((EU >> 1) << 23); + Vector128 V1 = Sse.StaticCast(Sse2.SetAllVector128(A)); Vector128 V2 = Sse.StaticCast(Sse2.SetAllVector128(B)); @@ -115,15 +122,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp)); Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)1)), Is.EquivalentTo(Exp)); }); + CompareAgainstUnicorn(); } [Test, Description("FCMEQ V0.2S, V1.2S, V2.2S | FCMGE V0.2S, V1.2S, V2.2S | FCMGT V0.2S, V1.2S, V2.2S")] - public void Fcmeq_Fcmge_Fcmgt_Reg_V_2S([ValueSource("_floats_")] [Random(8)] float A, - [ValueSource("_floats_")] [Random(8)] float B, + public void Fcmeq_Fcmge_Fcmgt_Reg_V_2S([ValueSource("_floats_")] [Random(RndCnt)] float A, + [ValueSource("_floats_")] [Random(RndCnt)] float B, [Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT { uint Opcode = 0x0E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23); + Vector128 V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat()); Vector128 V1 = Sse.SetVector128(0, 0, A, A); Vector128 V2 = Sse.SetVector128(0, 0, B, B); @@ -148,15 +157,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(Sse41.Extract(ThreadState.V0, (byte)2), Is.Zero); Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero); }); + CompareAgainstUnicorn(); } [Test, Description("FCMEQ V0.4S, V1.4S, V2.4S | FCMGE V0.4S, V1.4S, V2.4S | FCMGT V0.4S, V1.4S, V2.4S")] - public void Fcmeq_Fcmge_Fcmgt_Reg_V_4S([ValueSource("_floats_")] [Random(8)] float A, - [ValueSource("_floats_")] [Random(8)] float B, + public void Fcmeq_Fcmge_Fcmgt_Reg_V_4S([ValueSource("_floats_")] [Random(RndCnt)] float A, + [ValueSource("_floats_")] [Random(RndCnt)] float B, [Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT { uint Opcode = 0x4E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23); + Vector128 V1 = Sse.SetAllVector128(A); Vector128 V2 = Sse.SetAllVector128(B); @@ -180,15 +191,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)2)), Is.EquivalentTo(Exp)); Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)3)), Is.EquivalentTo(Exp)); }); + CompareAgainstUnicorn(); } [Test, Description("FCMGT D0, D1, #0.0 | FCMGE D0, D1, #0.0 | FCMEQ D0, D1, #0.0 | FCMLE D0, D1, #0.0 | FCMLT D0, D1, #0.0")] - public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_S_D([ValueSource("_doubles_")] [Random(8)] double A, + public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_S_D([ValueSource("_doubles_")] [Random(RndCnt)] double A, [Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE [Values(0u, 1u)] uint bit13) // "LT" { uint Opcode = 0x5EE0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12); + Vector128 V0 = Sse.StaticCast(Sse2.SetAllVector128(TestContext.CurrentContext.Random.NextDouble())); Vector128 V1 = Sse.StaticCast(Sse2.SetScalarVector128(A)); @@ -219,15 +232,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp)); Assert.That(VectorExtractDouble(ThreadState.V0, (byte)1), Is.Zero); }); + CompareAgainstUnicorn(); } [Test, Description("FCMGT S0, S1, #0.0 | FCMGE S0, S1, #0.0 | FCMEQ S0, S1, #0.0 | FCMLE S0, S1, #0.0 | FCMLT S0, S1, #0.0")] - public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_S_S([ValueSource("_floats_")] [Random(8)] float A, + public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_S_S([ValueSource("_floats_")] [Random(RndCnt)] float A, [Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE [Values(0u, 1u)] uint bit13) // "LT" { uint Opcode = 0x5EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12); + Vector128 V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat()); Vector128 V1 = Sse.SetScalarVector128(A); @@ -260,15 +275,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(Sse41.Extract(ThreadState.V0, (byte)2), Is.Zero); Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero); }); + CompareAgainstUnicorn(); } [Test, Description("FCMGT V0.2D, V1.2D, #0.0 | FCMGE V0.2D, V1.2D, #0.0 | FCMEQ V0.2D, V1.2D, #0.0 | FCMLE V0.2D, V1.2D, #0.0 | FCMLT V0.2D, V1.2D, #0.0")] - public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_2D([ValueSource("_doubles_")] [Random(8)] double A, + public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_2D([ValueSource("_doubles_")] [Random(RndCnt)] double A, [Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE [Values(0u, 1u)] uint bit13) // "LT" { uint Opcode = 0x4EE0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12); + Vector128 V1 = Sse.StaticCast(Sse2.SetAllVector128(A)); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1); @@ -298,15 +315,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp)); Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)1)), Is.EquivalentTo(Exp)); }); + CompareAgainstUnicorn(); } [Test, Description("FCMGT V0.2S, V1.2S, #0.0 | FCMGE V0.2S, V1.2S, #0.0 | FCMEQ V0.2S, V1.2S, #0.0 | FCMLE V0.2S, V1.2S, #0.0 | FCMLT V0.2S, V1.2S, #0.0")] - public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_2S([ValueSource("_floats_")] [Random(8)] float A, + public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_2S([ValueSource("_floats_")] [Random(RndCnt)] float A, [Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE [Values(0u, 1u)] uint bit13) // "LT" { uint Opcode = 0x0EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12); + Vector128 V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat()); Vector128 V1 = Sse.SetVector128(0, 0, A, A); @@ -339,15 +358,17 @@ namespace Ryujinx.Tests.Cpu Assert.That(Sse41.Extract(ThreadState.V0, (byte)2), Is.Zero); Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero); }); + CompareAgainstUnicorn(); } [Test, Description("FCMGT V0.4S, V1.4S, #0.0 | FCMGE V0.4S, V1.4S, #0.0 | FCMEQ V0.4S, V1.4S, #0.0 | FCMLE V0.4S, V1.4S, #0.0 | FCMLT V0.4S, V1.4S, #0.0")] - public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_4S([ValueSource("_floats_")] [Random(8)] float A, + public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_4S([ValueSource("_floats_")] [Random(RndCnt)] float A, [Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE [Values(0u, 1u)] uint bit13) // "LT" { uint Opcode = 0x4EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12); + Vector128 V1 = Sse.SetAllVector128(A); AThreadState ThreadState = SingleOpcode(Opcode, V1: V1); @@ -379,6 +400,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)2)), Is.EquivalentTo(Exp)); Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)3)), Is.EquivalentTo(Exp)); }); + CompareAgainstUnicorn(); } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs b/Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs index 1e58a68a..4efd8f31 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs @@ -22,6 +22,7 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4E285800; // AESD V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); + Vector128 V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH); Vector128 V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH); @@ -37,6 +38,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL)); Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH)); }); + CompareAgainstUnicorn(); } @@ -52,6 +54,7 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4E284800; // AESE V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); + Vector128 V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH); Vector128 V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH); @@ -67,6 +70,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL)); Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH)); }); + CompareAgainstUnicorn(); } @@ -80,6 +84,7 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4E287800; // AESIMC V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); + Vector128 V = MakeVectorE0E1(ValueL, ValueH); AThreadState ThreadState = SingleOpcode( @@ -100,6 +105,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH)); }); } + CompareAgainstUnicorn(); } @@ -113,6 +119,7 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4E286800; // AESMC V0.16B, V0.16B Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0); + Vector128 V = MakeVectorE0E1(ValueL, ValueH); AThreadState ThreadState = SingleOpcode( @@ -133,6 +140,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH)); }); } + CompareAgainstUnicorn(); } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs b/Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs index 7f5f05ee..3c8ad071 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs @@ -23,7 +23,8 @@ namespace Ryujinx.Tests.Cpu [TestCase((ushort)0x0001, 0x33800000u)] // 5.96046448e-8 (Smallest Subnormal) public void Fcvtl_V_f16(ushort Value, uint Result) { - uint Opcode = 0x0E217801; + uint Opcode = 0x0E217801; // FCVTL V1.4S, V0.4H + Vector128 V0 = Sse.StaticCast(Sse2.SetAllVector128(Value)); AThreadState ThreadState = SingleOpcode(Opcode, V0: V0); @@ -35,6 +36,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V1), (byte)2), Is.EqualTo(Result)); Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V1), (byte)3), Is.EqualTo(Result)); }); + CompareAgainstUnicorn(); } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs b/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs index b7633e8b..b7150db3 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs @@ -8,18 +8,10 @@ using System.Runtime.Intrinsics; namespace Ryujinx.Tests.Cpu { - using Tester; - using Tester.Types; - - [Category("SimdReg")/*, Ignore("Tested: second half of 2018.")*/] + [Category("SimdReg")] // Tested: second half of 2018. public sealed class CpuTestSimdReg : CpuTest { #if SimdReg - [SetUp] - public void SetupTester() - { - AArch64.TakeReset(false); - } #region "ValueSource" private static ulong[] _1B1H1S1D_() @@ -98,23 +90,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EE08400; // ADD D0, D0, D0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Add_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -130,23 +112,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E208400; // ADD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Add_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -162,23 +134,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E208400; // ADD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Add_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -194,23 +156,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E204000; // ADDHN V0.8B, V0.8H, V0.8H Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Addhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -226,23 +178,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E204000; // ADDHN2 V0.16B, V0.8H, V0.8H Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Addhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -258,23 +200,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E20BC00; // ADDP V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Addp_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -290,23 +222,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E20BC00; // ADDP V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Addp_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -320,23 +242,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x0E201C00; // AND V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.And_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -350,23 +262,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4E201C00; // AND V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.And_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -380,23 +282,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x0E601C00; // BIC V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Bic_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -410,23 +302,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4E601C00; // BIC V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Bic_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -440,23 +322,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x2EE01C00; // BIF V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Bif_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -470,23 +342,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x6EE01C00; // BIF V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Bif_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -500,23 +362,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x2EA01C00; // BIT V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Bit_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -530,23 +382,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x6EA01C00; // BIT V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Bit_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -560,23 +402,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x2E601C00; // BSL V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Bsl_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -590,23 +422,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x6E601C00; // BSL V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Bsl_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -620,23 +442,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x7EE08C00; // CMEQ D0, D0, D0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmeq_Reg_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -652,23 +464,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E208C00; // CMEQ V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmeq_Reg_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -684,23 +486,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E208C00; // CMEQ V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Cmeq_Reg_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -714,23 +506,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EE03C00; // CMGE D0, D0, D0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmge_Reg_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -746,23 +528,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E203C00; // CMGE V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmge_Reg_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -778,23 +550,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E203C00; // CMGE V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Cmge_Reg_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -808,23 +570,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EE03400; // CMGT D0, D0, D0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmgt_Reg_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -840,23 +592,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E203400; // CMGT V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmgt_Reg_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -872,23 +614,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E203400; // CMGT V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Cmgt_Reg_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -902,23 +634,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x7EE03400; // CMHI D0, D0, D0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmhi_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -934,23 +656,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E203400; // CMHI V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmhi_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -966,23 +678,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E203400; // CMHI V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Cmhi_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -996,23 +698,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x7EE03C00; // CMHS D0, D0, D0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmhs_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1028,23 +720,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E203C00; // CMHS V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmhs_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1060,23 +742,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E203C00; // CMHS V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Cmhs_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1090,23 +762,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5EE08C00; // CMTST D0, D0, D0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmtst_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1122,23 +784,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E208C00; // CMTST V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Cmtst_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1154,23 +806,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E208C00; // CMTST V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Cmtst_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1184,23 +826,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x2E201C00; // EOR V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Eor_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1214,23 +846,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x6E201C00; // EOR V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Eor_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1244,23 +866,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x0EE01C00; // ORN V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Orn_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1274,23 +886,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4EE01C00; // ORN V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Orn_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1304,23 +906,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x0EA01C00; // ORR V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Orr_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1334,23 +926,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x4EA01C00; // ORR V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Orr_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1366,23 +948,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E204000; // RADDHN V0.8B, V0.8H, V0.8H Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Raddhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1398,23 +970,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E204000; // RADDHN2 V0.16B, V0.8H, V0.8H Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Raddhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1430,23 +992,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E206000; // RSUBHN V0.8B, V0.8H, V0.8H Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Rsubhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1462,23 +1014,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E206000; // RSUBHN2 V0.16B, V0.8H, V0.8H Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Rsubhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1494,23 +1036,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E207C00; // SABA V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Saba_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1526,23 +1058,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E207C00; // SABA V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Saba_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1558,23 +1080,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E205000; // SABAL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Sabal_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1590,23 +1102,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E205000; // SABAL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Sabal_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1622,23 +1124,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E207400; // SABD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sabd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1654,23 +1146,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E207400; // SABD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Sabd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1686,23 +1168,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E207000; // SABDL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Sabdl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1718,23 +1190,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E207000; // SABDL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Sabdl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1750,23 +1212,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E200000; // SADDL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Saddl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SADDL{2} ., ., .")] @@ -1781,23 +1234,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E200000; // SADDL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Saddl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SADDW{2} ., ., .")] @@ -1812,23 +1256,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E201000; // SADDW V0.8H, V0.8H, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Saddw_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1844,23 +1278,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E201000; // SADDW2 V0.8H, V0.8H, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Saddw_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -1874,31 +1298,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5E004000; // SHA256H Q0, Q0, V0.4S Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); 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)); AArch64.Vpart(0, 1, new Bits(Z1)); - AArch64.Vpart(1, 0, new Bits(A0)); AArch64.Vpart(1, 1, new Bits(A1)); - AArch64.Vpart(2, 0, new Bits(B0)); AArch64.Vpart(2, 1, new Bits(B1)); - SimdFp.Sha256h_V(Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - - Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 0).ToUInt64())); - Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 1).ToUInt64())); - }); - Assert.Multiple(() => - { - Assert.That(GetVectorE0(ThreadState.V2), Is.EqualTo(AArch64.Vpart(64, 2, 0).ToUInt64())); - Assert.That(GetVectorE1(ThreadState.V2), Is.EqualTo(AArch64.Vpart(64, 2, 1).ToUInt64())); - }); CompareAgainstUnicorn(); } @@ -1912,31 +1318,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5E005000; // SHA256H2 Q0, Q0, V0.4S Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); 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)); AArch64.Vpart(0, 1, new Bits(Z1)); - AArch64.Vpart(1, 0, new Bits(A0)); AArch64.Vpart(1, 1, new Bits(A1)); - AArch64.Vpart(2, 0, new Bits(B0)); AArch64.Vpart(2, 1, new Bits(B1)); - SimdFp.Sha256h2_V(Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - - Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 0).ToUInt64())); - Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 1).ToUInt64())); - }); - Assert.Multiple(() => - { - Assert.That(GetVectorE0(ThreadState.V2), Is.EqualTo(AArch64.Vpart(64, 2, 0).ToUInt64())); - Assert.That(GetVectorE1(ThreadState.V2), Is.EqualTo(AArch64.Vpart(64, 2, 1).ToUInt64())); - }); CompareAgainstUnicorn(); } @@ -1950,31 +1338,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x5E006000; // SHA256SU1 V0.4S, V0.4S, V0.4S Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); 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)); AArch64.Vpart(0, 1, new Bits(Z1)); - AArch64.Vpart(1, 0, new Bits(A0)); AArch64.Vpart(1, 1, new Bits(A1)); - AArch64.Vpart(2, 0, new Bits(B0)); AArch64.Vpart(2, 1, new Bits(B1)); - SimdFp.Sha256su1_V(Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - Assert.Multiple(() => - { - Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 0).ToUInt64())); - Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 1).ToUInt64())); - - Assert.That(GetVectorE0(ThreadState.V2), Is.EqualTo(AArch64.Vpart(64, 2, 0).ToUInt64())); - Assert.That(GetVectorE1(ThreadState.V2), Is.EqualTo(AArch64.Vpart(64, 2, 1).ToUInt64())); - }); CompareAgainstUnicorn(); } @@ -1990,23 +1360,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E200400; // SHADD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Shadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SHADD ., ., .")] @@ -2021,23 +1382,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E200400; // SHADD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Shadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SHSUB ., ., .")] @@ -2052,23 +1404,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E202400; // SHSUB V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Shsub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SHSUB ., ., .")] @@ -2083,23 +1426,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E202400; // SHSUB V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Shsub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SMLAL{2} ., ., .")] @@ -2114,23 +1448,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E208000; // SMLAL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Smlal_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SMLAL{2} ., ., .")] @@ -2145,23 +1470,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E208000; // SMLAL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Smlal_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SMLSL{2} ., ., .")] @@ -2176,23 +1492,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E20A000; // SMLSL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Smlsl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SMLSL{2} ., ., .")] @@ -2207,23 +1514,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E20A000; // SMLSL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Smlsl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SQADD , , ")] @@ -2235,30 +1533,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x5E200C00; // SQADD B0, B0, B0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sqadd_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQADD ., ., .")] @@ -2270,30 +1555,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x0E200C00; // SQADD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sqadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQADD ., ., .")] @@ -2305,30 +1577,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x4E200C00; // SQADD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Sqadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQDMULH , , ")] @@ -2340,30 +1599,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1H1S_")] [Random(RndCnt)] ulong B, [Values(0b01u, 0b10u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x5E20B400; // SQDMULH B0, B0, B0 (RESERVED) Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sqdmulh_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQDMULH ., ., .")] @@ -2375,30 +1621,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S_")] [Random(RndCnt)] ulong B, [Values(0b01u, 0b10u)] uint size) // <4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x0E20B400; // SQDMULH V0.8B, V0.8B, V0.8B (RESERVED) Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sqdmulh_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQDMULH ., ., .")] @@ -2410,30 +1643,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S_")] [Random(RndCnt)] ulong B, [Values(0b01u, 0b10u)] uint size) // <8H, 4S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x4E20B400; // SQDMULH V0.16B, V0.16B, V0.16B (RESERVED) Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Sqdmulh_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQRDMULH , , ")] @@ -2445,30 +1665,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1H1S_")] [Random(RndCnt)] ulong B, [Values(0b01u, 0b10u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x7E20B400; // SQRDMULH B0, B0, B0 (RESERVED) Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sqrdmulh_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQRDMULH ., ., .")] @@ -2480,30 +1687,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S_")] [Random(RndCnt)] ulong B, [Values(0b01u, 0b10u)] uint size) // <4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x2E20B400; // SQRDMULH V0.8B, V0.8B, V0.8B (RESERVED) Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sqrdmulh_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQRDMULH ., ., .")] @@ -2515,30 +1709,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_4H2S_")] [Random(RndCnt)] ulong B, [Values(0b01u, 0b10u)] uint size) // <8H, 4S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x6E20B400; // SQRDMULH V0.16B, V0.16B, V0.16B (RESERVED) Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Sqrdmulh_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQSUB , , ")] @@ -2550,30 +1731,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x5E202C00; // SQSUB B0, B0, B0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sqsub_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQSUB ., ., .")] @@ -2585,30 +1753,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x0E202C00; // SQSUB V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sqsub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SQSUB ., ., .")] @@ -2620,30 +1775,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x4E202C00; // SQSUB V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Sqsub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("SRHADD ., ., .")] @@ -2658,23 +1800,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E201400; // SRHADD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Srhadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SRHADD ., ., .")] @@ -2689,23 +1822,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E201400; // SRHADD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Srhadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SSUBL{2} ., ., .")] @@ -2720,23 +1844,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E202000; // SSUBL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Ssubl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SSUBL{2} ., ., .")] @@ -2751,23 +1866,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E202000; // SSUBL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Ssubl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("SSUBW{2} ., ., .")] @@ -2782,23 +1888,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E203000; // SSUBW V0.8H, V0.8H, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Ssubw_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2814,23 +1910,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E203000; // SSUBW2 V0.8H, V0.8H, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Ssubw_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2844,23 +1930,13 @@ namespace Ryujinx.Tests.Cpu { uint Opcode = 0x7EE08400; // SUB D0, D0, D0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sub_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2876,23 +1952,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E208400; // SUB V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Sub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2908,23 +1974,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E208400; // SUB V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Sub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2940,23 +1996,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E206000; // SUBHN V0.8B, V0.8H, V0.8H Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Subhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -2972,23 +2018,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E206000; // SUBHN2 V0.16B, V0.8H, V0.8H Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Subhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3004,23 +2040,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E002800; // TRN1 V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Trn1_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3036,23 +2062,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E002800; // TRN1 V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Trn1_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3068,23 +2084,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E006800; // TRN2 V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Trn2_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3100,23 +2106,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E006800; // TRN2 V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Trn2_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3132,23 +2128,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E207C00; // UABA V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uaba_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3164,23 +2150,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E207C00; // UABA V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uaba_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3196,23 +2172,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E205000; // UABAL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Uabal_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3228,23 +2194,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E205000; // UABAL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uabal_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3260,23 +2216,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E207400; // UABD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uabd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3292,23 +2238,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E207400; // UABD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uabd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3324,23 +2260,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E207000; // UABDL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Uabdl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3356,23 +2282,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E207000; // UABDL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uabdl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3388,23 +2304,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E200000; // UADDL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Uaddl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UADDL{2} ., ., .")] @@ -3419,23 +2326,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E200000; // UADDL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uaddl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UADDW{2} ., ., .")] @@ -3450,23 +2348,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E201000; // UADDW V0.8H, V0.8H, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Uaddw_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3482,23 +2370,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E201000; // UADDW2 V0.8H, V0.8H, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uaddw_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -3514,23 +2392,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E200400; // UHADD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uhadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UHADD ., ., .")] @@ -3545,23 +2414,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E200400; // UHADD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uhadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UHSUB ., ., .")] @@ -3576,23 +2436,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E202400; // UHSUB V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uhsub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UHSUB ., ., .")] @@ -3607,23 +2458,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E202400; // UHSUB V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uhsub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UMLAL{2} ., ., .")] @@ -3638,23 +2480,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E208000; // UMLAL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Umlal_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UMLAL{2} ., ., .")] @@ -3669,23 +2502,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E208000; // UMLAL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Umlal_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UMLSL{2} ., ., .")] @@ -3700,23 +2524,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E20A000; // UMLSL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Umlsl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UMLSL{2} ., ., .")] @@ -3731,23 +2546,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E20A000; // UMLSL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Umlsl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("UQADD , , ")] @@ -3759,30 +2565,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x7E200C00; // UQADD B0, B0, B0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uqadd_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("UQADD ., ., .")] @@ -3794,30 +2587,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x2E200C00; // UQADD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uqadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("UQADD ., ., .")] @@ -3829,30 +2609,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x6E200C00; // UQADD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uqadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("UQSUB , , ")] @@ -3864,30 +2631,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x7E202C00; // UQSUB B0, B0, B0 Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uqsub_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("UQSUB ., ., .")] @@ -3899,30 +2653,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x2E202C00; // UQSUB V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uqsub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("UQSUB ., ., .")] @@ -3934,30 +2675,17 @@ namespace Ryujinx.Tests.Cpu [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong B, [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D> { - const int QCFlagBit = 27; // Cumulative saturation bit. - uint Opcode = 0x6E202C00; // UQSUB V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uqsub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); - - Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit])); + CompareAgainstUnicorn(FpsrMask: FPSR.QC); } [Test, Pairwise, Description("URHADD ., ., .")] @@ -3972,23 +2700,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E201400; // URHADD V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Urhadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("URHADD ., ., .")] @@ -4003,23 +2722,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E201400; // URHADD V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Urhadd_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("USUBL{2} ., ., .")] @@ -4034,23 +2744,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E202000; // USUBL V0.8H, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Usubl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("USUBL{2} ., ., .")] @@ -4065,23 +2766,14 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E202000; // USUBL2 V0.8H, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE1(A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Usubl_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); + CompareAgainstUnicorn(); } [Test, Pairwise, Description("USUBW{2} ., ., .")] @@ -4096,23 +2788,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x2E203000; // USUBW V0.8H, V0.8H, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); - SimdFp.Usubw_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4128,23 +2810,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x6E203000; // USUBW2 V0.8H, V0.8H, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE1(B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Usubw_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4160,23 +2832,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E001800; // UZP1 V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uzp1_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4192,23 +2854,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E001800; // UZP1 V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uzp1_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4224,23 +2876,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E005800; // UZP2 V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Uzp2_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4256,23 +2898,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E005800; // UZP2 V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Uzp2_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4288,23 +2920,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E003800; // ZIP1 V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Zip1_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4320,23 +2942,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E003800; // ZIP1 V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Zip1_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4352,23 +2964,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x0E007800; // ZIP2 V0.8B, V0.8B, V0.8B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); 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)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.V(1, new Bits(A)); - AArch64.V(2, new Bits(B)); - SimdFp.Zip2_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } @@ -4384,23 +2986,13 @@ namespace Ryujinx.Tests.Cpu uint Opcode = 0x4E007800; // ZIP2 V0.16B, V0.16B, V0.16B Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0); Opcode |= ((size & 3) << 22); - Bits Op = new Bits(Opcode); Vector128 V0 = MakeVectorE0E1(Z, Z); Vector128 V1 = MakeVectorE0E1(A, A); Vector128 V2 = MakeVectorE0E1(B, B); + AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2); - AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z)); - AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A)); - AArch64.Vpart(2, 0, new Bits(B)); AArch64.Vpart(2, 1, new Bits(B)); - SimdFp.Zip2_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]); - - Assert.Multiple(() => - { - 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())); - }); CompareAgainstUnicorn(); } #endif diff --git a/Ryujinx.Tests/Cpu/Tester/Instructions.cs b/Ryujinx.Tests/Cpu/Tester/Instructions.cs deleted file mode 100644 index e3aa4e40..00000000 --- a/Ryujinx.Tests/Cpu/Tester/Instructions.cs +++ /dev/null @@ -1,7346 +0,0 @@ -// https://github.com/LDj3SNuD/ARM_v8-A_AArch64_Instructions_Tester/blob/master/Tester/Instructions.cs - -// https://developer.arm.com/products/architecture/a-profile/exploration-tools -// ..\A64_v83A_ISA_xml_00bet6.1\ISA_v83A_A64_xml_00bet6.1_OPT\xhtml\ - -using System.Numerics; - -namespace Ryujinx.Tests.Cpu.Tester -{ - using Types; - - using static AArch64; - using static Shared; - - // index.html - internal static class Base - { -#region "Alu" - // cls_int.html - public static void Cls(bool sf, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits operand1 = X(datasize, n); - - BigInteger result = (BigInteger)CountLeadingSignBits(operand1); - - X(d, result.SubBigInteger(datasize - 1, 0)); - } - - // clz_int.html - public static void Clz(bool sf, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits operand1 = X(datasize, n); - - BigInteger result = (BigInteger)CountLeadingZeroBits(operand1); - - X(d, result.SubBigInteger(datasize - 1, 0)); - } - - // rbit_int.html - public static void Rbit(bool sf, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result = new Bits(datasize); - Bits operand = X(datasize, n); - - for (int i = 0; i <= datasize - 1; i++) - { - result[datasize - 1 - i] = operand[i]; - } - - X(d, result); - } - - // rev16_int.html - public static void Rev16(bool sf, Bits Rn, Bits Rd) - { - /* Bits opc = "01"; */ - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - int container_size = 16; - - /* Operation */ - Bits result = new Bits(datasize); - Bits operand = X(datasize, n); - - int containers = datasize / container_size; - int elements_per_container = container_size / 8; - int index = 0; - int rev_index; - - for (int c = 0; c <= containers - 1; c++) - { - rev_index = index + ((elements_per_container - 1) * 8); - - for (int e = 0; e <= elements_per_container - 1; e++) - { - result[rev_index + 7, rev_index] = operand[index + 7, index]; - - index = index + 8; - rev_index = rev_index - 8; - } - } - - X(d, result); - } - - // rev32_int.html - // (rev.html) - public static void Rev32(bool sf, Bits Rn, Bits Rd) - { - /* Bits opc = "10"; */ - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - int container_size = 32; - - /* Operation */ - Bits result = new Bits(datasize); - Bits operand = X(datasize, n); - - int containers = datasize / container_size; - int elements_per_container = container_size / 8; - int index = 0; - int rev_index; - - for (int c = 0; c <= containers - 1; c++) - { - rev_index = index + ((elements_per_container - 1) * 8); - - for (int e = 0; e <= elements_per_container - 1; e++) - { - result[rev_index + 7, rev_index] = operand[index + 7, index]; - - index = index + 8; - rev_index = rev_index - 8; - } - } - - X(d, result); - } - - // rev64_rev.html - // (rev.html) - public static void Rev64(Bits Rn, Bits Rd) - { - /* Bits opc = "11"; */ - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int container_size = 64; - - /* Operation */ - Bits result = new Bits(64); - Bits operand = X(64, n); - - int containers = 64 / container_size; - int elements_per_container = container_size / 8; - int index = 0; - int rev_index; - - for (int c = 0; c <= containers - 1; c++) - { - rev_index = index + ((elements_per_container - 1) * 8); - - for (int e = 0; e <= elements_per_container - 1; e++) - { - result[rev_index + 7, rev_index] = operand[index + 7, index]; - - index = index + 8; - rev_index = rev_index - 8; - } - } - - X(d, result); - } -#endregion - -#region "AluImm" - // add_addsub_imm.html - public static void Add_Imm(bool sf, Bits shift, Bits imm12, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits imm; - - switch (shift) - { - default: - case Bits bits when bits == "00": - imm = ZeroExtend(imm12, datasize); - break; - case Bits bits when bits == "01": - imm = ZeroExtend(Bits.Concat(imm12, Zeros(12)), datasize); - break; - /* when '1x' ReservedValue(); */ - } - - /* Operation */ - Bits result; - Bits operand1 = (n == 31 ? SP(datasize) : X(datasize, n)); - - (result, _) = AddWithCarry(datasize, operand1, imm, false); - - if (d == 31) - { - SP(result); - } - else - { - X(d, result); - } - } - - // adds_addsub_imm.html - public static void Adds_Imm(bool sf, Bits shift, Bits imm12, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits imm; - - switch (shift) - { - default: - case Bits bits when bits == "00": - imm = ZeroExtend(imm12, datasize); - break; - case Bits bits when bits == "01": - imm = ZeroExtend(Bits.Concat(imm12, Zeros(12)), datasize); - break; - /* when '1x' ReservedValue(); */ - } - - /* Operation */ - Bits result; - Bits operand1 = (n == 31 ? SP(datasize) : X(datasize, n)); - Bits nzcv; - - (result, nzcv) = AddWithCarry(datasize, operand1, imm, false); - - PSTATE.NZCV(nzcv); - - X(d, result); - } - - // and_log_imm.html - public static void And_Imm(bool sf, bool N, Bits immr, Bits imms, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits imm; - - /* if sf == '0' && N != '0' then ReservedValue(); */ - - (imm, _) = DecodeBitMasks(datasize, N, imms, immr, true); - - /* Operation */ - Bits operand1 = X(datasize, n); - - Bits result = AND(operand1, imm); - - if (d == 31) - { - SP(result); - } - else - { - X(d, result); - } - } - - // ands_log_imm.html - public static void Ands_Imm(bool sf, bool N, Bits immr, Bits imms, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits imm; - - /* if sf == '0' && N != '0' then ReservedValue(); */ - - (imm, _) = DecodeBitMasks(datasize, N, imms, immr, true); - - /* Operation */ - Bits operand1 = X(datasize, n); - - Bits result = AND(operand1, imm); - - PSTATE.NZCV(result[datasize - 1], IsZeroBit(result), false, false); - - X(d, result); - } - - // eor_log_imm.html - public static void Eor_Imm(bool sf, bool N, Bits immr, Bits imms, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits imm; - - /* if sf == '0' && N != '0' then ReservedValue(); */ - - (imm, _) = DecodeBitMasks(datasize, N, imms, immr, true); - - /* Operation */ - Bits operand1 = X(datasize, n); - - Bits result = EOR(operand1, imm); - - if (d == 31) - { - SP(result); - } - else - { - X(d, result); - } - } - - // orr_log_imm.html - public static void Orr_Imm(bool sf, bool N, Bits immr, Bits imms, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits imm; - - /* if sf == '0' && N != '0' then ReservedValue(); */ - - (imm, _) = DecodeBitMasks(datasize, N, imms, immr, true); - - /* Operation */ - Bits operand1 = X(datasize, n); - - Bits result = OR(operand1, imm); - - if (d == 31) - { - SP(result); - } - else - { - X(d, result); - } - } - - // sub_addsub_imm.html - public static void Sub_Imm(bool sf, Bits shift, Bits imm12, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits imm; - - switch (shift) - { - default: - case Bits bits when bits == "00": - imm = ZeroExtend(imm12, datasize); - break; - case Bits bits when bits == "01": - imm = ZeroExtend(Bits.Concat(imm12, Zeros(12)), datasize); - break; - /* when '1x' ReservedValue(); */ - } - - /* Operation */ - Bits result; - Bits operand1 = (n == 31 ? SP(datasize) : X(datasize, n)); - Bits operand2 = NOT(imm); - - (result, _) = AddWithCarry(datasize, operand1, operand2, true); - - if (d == 31) - { - SP(result); - } - else - { - X(d, result); - } - } - - // subs_addsub_imm.html - public static void Subs_Imm(bool sf, Bits shift, Bits imm12, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits imm; - - switch (shift) - { - default: - case Bits bits when bits == "00": - imm = ZeroExtend(imm12, datasize); - break; - case Bits bits when bits == "01": - imm = ZeroExtend(Bits.Concat(imm12, Zeros(12)), datasize); - break; - /* when '1x' ReservedValue(); */ - } - - /* Operation */ - Bits result; - Bits operand1 = (n == 31 ? SP(datasize) : X(datasize, n)); - Bits operand2 = NOT(imm); - Bits nzcv; - - (result, nzcv) = AddWithCarry(datasize, operand1, operand2, true); - - PSTATE.NZCV(nzcv); - - X(d, result); - } -#endregion - -#region "AluRs" - // adc.html - public static void Adc(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - (result, _) = AddWithCarry(datasize, operand1, operand2, PSTATE.C); - - X(d, result); - } - - // adcs.html - public static void Adcs(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - Bits nzcv; - - (result, nzcv) = AddWithCarry(datasize, operand1, operand2, PSTATE.C); - - PSTATE.NZCV(nzcv); - - X(d, result); - } - - // add_addsub_shift.html - public static void Add_Rs(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if shift == '11' then ReservedValue(); */ - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - (result, _) = AddWithCarry(datasize, operand1, operand2, false); - - X(d, result); - } - - // adds_addsub_shift.html - public static void Adds_Rs(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if shift == '11' then ReservedValue(); */ - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - Bits nzcv; - - (result, nzcv) = AddWithCarry(datasize, operand1, operand2, false); - - PSTATE.NZCV(nzcv); - - X(d, result); - } - - // and_log_shift.html - public static void And_Rs(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - Bits result = AND(operand1, operand2); - - X(d, result); - } - - // ands_log_shift.html - public static void Ands_Rs(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - Bits result = AND(operand1, operand2); - - PSTATE.NZCV(result[datasize - 1], IsZeroBit(result), false, false); - - X(d, result); - } - - // asrv.html - public static void Asrv(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /*readonly */Bits op2 = "10"; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - ShiftType shift_type = DecodeShift(op2); - - /* Operation */ - Bits operand2 = X(datasize, m); - - Bits result = ShiftReg(datasize, n, shift_type, (int)(UInt(operand2) % datasize)); // BigInteger.Modulus Operator (BigInteger, BigInteger) - - X(d, result); - } - - // bic_log_shift.html - public static void Bic(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - operand2 = NOT(operand2); - - Bits result = AND(operand1, operand2); - - X(d, result); - } - - // bics.html - public static void Bics(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - operand2 = NOT(operand2); - - Bits result = AND(operand1, operand2); - - PSTATE.NZCV(result[datasize - 1], IsZeroBit(result), false, false); - - X(d, result); - } - - // crc32.html - public static void Crc32(bool sf, Bits Rm, Bits sz, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if sf == '1' && sz != '11' then UnallocatedEncoding(); */ - /* if sf == '0' && sz == '11' then UnallocatedEncoding(); */ - - int size = 8 << (int)UInt(sz); - - /* Operation */ - /* if !HaveCRCExt() then UnallocatedEncoding(); */ - - Bits acc = X(32, n); // accumulator - Bits val = X(size, m); // input value - Bits poly = new Bits(0x04C11DB7u); - - Bits tempacc = Bits.Concat(BitReverse(acc), Zeros(size)); - Bits tempval = Bits.Concat(BitReverse(val), Zeros(32)); - - // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation - X(d, BitReverse(Poly32Mod2(EOR(tempacc, tempval), poly))); - } - - // crc32c.html - public static void Crc32c(bool sf, Bits Rm, Bits sz, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if sf == '1' && sz != '11' then UnallocatedEncoding(); */ - /* if sf == '0' && sz == '11' then UnallocatedEncoding(); */ - - int size = 8 << (int)UInt(sz); - - /* Operation */ - /* if !HaveCRCExt() then UnallocatedEncoding(); */ - - Bits acc = X(32, n); // accumulator - Bits val = X(size, m); // input value - Bits poly = new Bits(0x1EDC6F41u); - - Bits tempacc = Bits.Concat(BitReverse(acc), Zeros(size)); - Bits tempval = Bits.Concat(BitReverse(val), Zeros(32)); - - // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation - X(d, BitReverse(Poly32Mod2(EOR(tempacc, tempval), poly))); - } - - // eon.html - public static void Eon(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - operand2 = NOT(operand2); - - Bits result = EOR(operand1, operand2); - - X(d, result); - } - - // eor_log_shift.html - public static void Eor_Rs(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - Bits result = EOR(operand1, operand2); - - X(d, result); - } - - // extr.html - public static void Extr(bool sf, bool N, Bits Rm, Bits imms, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if N != sf then UnallocatedEncoding(); */ - /* if sf == '0' && imms<5> == '1' then ReservedValue(); */ - - int lsb = (int)UInt(imms); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - Bits concat = Bits.Concat(operand1, operand2); - - Bits result = concat[lsb + datasize - 1, lsb]; - - X(d, result); - } - - // lslv.html - public static void Lslv(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /*readonly */Bits op2 = "00"; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - ShiftType shift_type = DecodeShift(op2); - - /* Operation */ - Bits operand2 = X(datasize, m); - - Bits result = ShiftReg(datasize, n, shift_type, (int)(UInt(operand2) % datasize)); // BigInteger.Modulus Operator (BigInteger, BigInteger) - - X(d, result); - } - - // lsrv.html - public static void Lsrv(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /*readonly */Bits op2 = "01"; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - ShiftType shift_type = DecodeShift(op2); - - /* Operation */ - Bits operand2 = X(datasize, m); - - Bits result = ShiftReg(datasize, n, shift_type, (int)(UInt(operand2) % datasize)); // BigInteger.Modulus Operator (BigInteger, BigInteger) - - X(d, result); - } - - // orn_log_shift.html - public static void Orn(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - operand2 = NOT(operand2); - - Bits result = OR(operand1, operand2); - - X(d, result); - } - - // orr_log_shift.html - public static void Orr_Rs(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - Bits result = OR(operand1, operand2); - - X(d, result); - } - - // rorv.html - public static void Rorv(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /*readonly */Bits op2 = "11"; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - ShiftType shift_type = DecodeShift(op2); - - /* Operation */ - Bits operand2 = X(datasize, m); - - Bits result = ShiftReg(datasize, n, shift_type, (int)(UInt(operand2) % datasize)); // BigInteger.Modulus Operator (BigInteger, BigInteger) - - X(d, result); - } - - // sbc.html - public static void Sbc(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - operand2 = NOT(operand2); - - (result, _) = AddWithCarry(datasize, operand1, operand2, PSTATE.C); - - X(d, result); - } - - // sbcs.html - public static void Sbcs(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - Bits nzcv; - - operand2 = NOT(operand2); - - (result, nzcv) = AddWithCarry(datasize, operand1, operand2, PSTATE.C); - - PSTATE.NZCV(nzcv); - - X(d, result); - } - - // sdiv.html - public static void Sdiv(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - BigInteger result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - if (IsZero(operand2)) - { - result = (BigInteger)0m; - } - else - { - result = RoundTowardsZero(Real(Int(operand1, false)) / Real(Int(operand2, false))); - } - - X(d, result.SubBigInteger(datasize - 1, 0)); - } - - // sub_addsub_shift.html - public static void Sub_Rs(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if shift == '11' then ReservedValue(); */ - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - - operand2 = NOT(operand2); - - (result, _) = AddWithCarry(datasize, operand1, operand2, true); - - X(d, result); - } - - // subs_addsub_shift.html - public static void Subs_Rs(bool sf, Bits shift, Bits Rm, Bits imm6, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* if shift == '11' then ReservedValue(); */ - /* if sf == '0' && imm6<5> == '1' then ReservedValue(); */ - - ShiftType shift_type = DecodeShift(shift); - int shift_amount = (int)UInt(imm6); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = ShiftReg(datasize, m, shift_type, shift_amount); - Bits nzcv; - - operand2 = NOT(operand2); - - (result, nzcv) = AddWithCarry(datasize, operand1, operand2, true); - - PSTATE.NZCV(nzcv); - - X(d, result); - } - - // udiv.html - public static void Udiv(bool sf, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - BigInteger result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - if (IsZero(operand2)) - { - result = (BigInteger)0m; - } - else - { - result = RoundTowardsZero(Real(Int(operand1, true)) / Real(Int(operand2, true))); - } - - X(d, result.SubBigInteger(datasize - 1, 0)); - } -#endregion - -#region "AluRx" - // add_addsub_ext.html - public static void Add_Rx(bool sf, Bits Rm, Bits option, Bits imm3, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - ExtendType extend_type = DecodeRegExtend(option); - int shift = (int)UInt(imm3); - - /* if shift > 4 then ReservedValue(); */ - - /* Operation */ - Bits result; - Bits operand1 = (n == 31 ? SP(datasize) : X(datasize, n)); - Bits operand2 = ExtendReg(datasize, m, extend_type, shift); - - (result, _) = AddWithCarry(datasize, operand1, operand2, false); - - if (d == 31) - { - SP(result); - } - else - { - X(d, result); - } - } - - // adds_addsub_ext.html - public static void Adds_Rx(bool sf, Bits Rm, Bits option, Bits imm3, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - ExtendType extend_type = DecodeRegExtend(option); - int shift = (int)UInt(imm3); - - /* if shift > 4 then ReservedValue(); */ - - /* Operation */ - Bits result; - Bits operand1 = (n == 31 ? SP(datasize) : X(datasize, n)); - Bits operand2 = ExtendReg(datasize, m, extend_type, shift); - Bits nzcv; - - (result, nzcv) = AddWithCarry(datasize, operand1, operand2, false); - - PSTATE.NZCV(nzcv); - - X(d, result); - } - - // sub_addsub_ext.html - public static void Sub_Rx(bool sf, Bits Rm, Bits option, Bits imm3, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - ExtendType extend_type = DecodeRegExtend(option); - int shift = (int)UInt(imm3); - - /* if shift > 4 then ReservedValue(); */ - - /* Operation */ - Bits result; - Bits operand1 = (n == 31 ? SP(datasize) : X(datasize, n)); - Bits operand2 = ExtendReg(datasize, m, extend_type, shift); - - operand2 = NOT(operand2); - - (result, _) = AddWithCarry(datasize, operand1, operand2, true); - - if (d == 31) - { - SP(result); - } - else - { - X(d, result); - } - } - - // subs_addsub_ext.html - public static void Subs_Rx(bool sf, Bits Rm, Bits option, Bits imm3, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - ExtendType extend_type = DecodeRegExtend(option); - int shift = (int)UInt(imm3); - - /* if shift > 4 then ReservedValue(); */ - - /* Operation */ - Bits result; - Bits operand1 = (n == 31 ? SP(datasize) : X(datasize, n)); - Bits operand2 = ExtendReg(datasize, m, extend_type, shift); - Bits nzcv; - - operand2 = NOT(operand2); - - (result, nzcv) = AddWithCarry(datasize, operand1, operand2, true); - - PSTATE.NZCV(nzcv); - - X(d, result); - } -#endregion - -#region "Bfm" - // bfm.html - public static void Bfm(bool sf, bool N, Bits immr, Bits imms, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - int R; - Bits wmask; - Bits tmask; - - /* if sf == '1' && N != '1' then ReservedValue(); */ - /* if sf == '0' && (N != '0' || immr<5> != '0' || imms<5> != '0') then ReservedValue(); */ - - R = (int)UInt(immr); - (wmask, tmask) = DecodeBitMasks(datasize, N, imms, immr, false); - - /* Operation */ - Bits dst = X(datasize, d); - Bits src = X(datasize, n); - - // perform bitfield move on low bits - Bits bot = OR(AND(dst, NOT(wmask)), AND(ROR(src, R), wmask)); - - // combine extension bits and result bits - X(d, OR(AND(dst, NOT(tmask)), AND(bot, tmask))); - } - - // sbfm.html - public static void Sbfm(bool sf, bool N, Bits immr, Bits imms, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - int R; - int S; - Bits wmask; - Bits tmask; - - /* if sf == '1' && N != '1' then ReservedValue(); */ - /* if sf == '0' && (N != '0' || immr<5> != '0' || imms<5> != '0') then ReservedValue(); */ - - R = (int)UInt(immr); - S = (int)UInt(imms); - (wmask, tmask) = DecodeBitMasks(datasize, N, imms, immr, false); - - /* Operation */ - Bits src = X(datasize, n); - - // perform bitfield move on low bits - Bits bot = AND(ROR(src, R), wmask); - - // determine extension bits (sign, zero or dest register) - Bits top = Replicate(datasize, src[S]); - - // combine extension bits and result bits - X(d, OR(AND(top, NOT(tmask)), AND(bot, tmask))); - } - - // ubfm.html - public static void Ubfm(bool sf, bool N, Bits immr, Bits imms, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - int R; - Bits wmask; - Bits tmask; - - /* if sf == '1' && N != '1' then ReservedValue(); */ - /* if sf == '0' && (N != '0' || immr<5> != '0' || imms<5> != '0') then ReservedValue(); */ - - R = (int)UInt(immr); - (wmask, tmask) = DecodeBitMasks(datasize, N, imms, immr, false); - - /* Operation */ - Bits src = X(datasize, n); - - // perform bitfield move on low bits - Bits bot = AND(ROR(src, R), wmask); - - // combine extension bits and result bits - X(d, AND(bot, tmask)); - } -#endregion - -#region "CcmpImm" - // ccmn_imm.html - public static void Ccmn_Imm(bool sf, Bits imm5, Bits cond, Bits Rn, Bits nzcv) - { - /* Decode */ - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits flags = nzcv; - Bits imm = ZeroExtend(imm5, datasize); - - /* Operation */ - Bits operand1 = X(datasize, n); - - if (ConditionHolds(cond)) - { - (_, flags) = AddWithCarry(datasize, operand1, imm, false); - } - - PSTATE.NZCV(flags); - } - - // ccmp_imm.html - public static void Ccmp_Imm(bool sf, Bits imm5, Bits cond, Bits Rn, Bits nzcv) - { - /* Decode */ - int n = (int)UInt(Rn); - - int datasize = (sf ? 64 : 32); - - Bits flags = nzcv; - Bits imm = ZeroExtend(imm5, datasize); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2; - - if (ConditionHolds(cond)) - { - operand2 = NOT(imm); - (_, flags) = AddWithCarry(datasize, operand1, operand2, true); - } - - PSTATE.NZCV(flags); - } -#endregion - -#region "CcmpReg" - // ccmn_reg.html - public static void Ccmn_Reg(bool sf, Bits Rm, Bits cond, Bits Rn, Bits nzcv) - { - /* Decode */ - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - Bits flags = nzcv; - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - if (ConditionHolds(cond)) - { - (_, flags) = AddWithCarry(datasize, operand1, operand2, false); - } - - PSTATE.NZCV(flags); - } - - // ccmp_reg.html - public static void Ccmp_Reg(bool sf, Bits Rm, Bits cond, Bits Rn, Bits nzcv) - { - /* Decode */ - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - Bits flags = nzcv; - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - if (ConditionHolds(cond)) - { - operand2 = NOT(operand2); - (_, flags) = AddWithCarry(datasize, operand1, operand2, true); - } - - PSTATE.NZCV(flags); - } -#endregion - -#region "Csel" - // csel.html - public static void Csel(bool sf, Bits Rm, Bits cond, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - if (ConditionHolds(cond)) - { - result = operand1; - } - else - { - result = operand2; - } - - X(d, result); - } - - // csinc.html - public static void Csinc(bool sf, Bits Rm, Bits cond, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - if (ConditionHolds(cond)) - { - result = operand1; - } - else - { - result = operand2 + 1; - } - - X(d, result); - } - - // csinv.html - public static void Csinv(bool sf, Bits Rm, Bits cond, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - if (ConditionHolds(cond)) - { - result = operand1; - } - else - { - result = NOT(operand2); - } - - X(d, result); - } - - // csneg.html - public static void Csneg(bool sf, Bits Rm, Bits cond, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits result; - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - - if (ConditionHolds(cond)) - { - result = operand1; - } - else - { - result = NOT(operand2); - result = result + 1; - } - - X(d, result); - } -#endregion - -#region "Mov" - // movk.html - public static void Movk(bool sf, Bits hw, Bits imm16, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && hw<1> == '1' then UnallocatedEncoding(); */ - - int pos = (int)UInt(Bits.Concat(hw, "0000")); - - /* Operation */ - Bits result = X(datasize, d); - - result[pos + 15, pos] = imm16; - - X(d, result); - } - - // movn.html - public static void Movn(bool sf, Bits hw, Bits imm16, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && hw<1> == '1' then UnallocatedEncoding(); */ - - int pos = (int)UInt(Bits.Concat(hw, "0000")); - - /* Operation */ - Bits result = Zeros(datasize); - - result[pos + 15, pos] = imm16; - result = NOT(result); - - X(d, result); - } - - // movz.html - public static void Movz(bool sf, Bits hw, Bits imm16, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - - int datasize = (sf ? 64 : 32); - - /* if sf == '0' && hw<1> == '1' then UnallocatedEncoding(); */ - - int pos = (int)UInt(Bits.Concat(hw, "0000")); - - /* Operation */ - Bits result = Zeros(datasize); - - result[pos + 15, pos] = imm16; - - X(d, result); - } -#endregion - -#region "Mul" - // madd.html - public static void Madd(bool sf, Bits Rm, Bits Ra, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - int a = (int)UInt(Ra); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - Bits operand3 = X(datasize, a); - - BigInteger result = UInt(operand3) + (UInt(operand1) * UInt(operand2)); - - X(d, result.SubBigInteger(datasize - 1, 0)); - } - - // msub.html - public static void Msub(bool sf, Bits Rm, Bits Ra, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - int a = (int)UInt(Ra); - - int datasize = (sf ? 64 : 32); - - /* Operation */ - Bits operand1 = X(datasize, n); - Bits operand2 = X(datasize, m); - Bits operand3 = X(datasize, a); - - BigInteger result = UInt(operand3) - (UInt(operand1) * UInt(operand2)); - - X(d, result.SubBigInteger(datasize - 1, 0)); - } - - // smaddl.html - public static void Smaddl(Bits Rm, Bits Ra, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - int a = (int)UInt(Ra); - - /* Operation */ - Bits operand1 = X(32, n); - Bits operand2 = X(32, m); - Bits operand3 = X(64, a); - - BigInteger result = Int(operand3, false) + (Int(operand1, false) * Int(operand2, false)); - - X(d, result.SubBigInteger(63, 0)); - } - - // umaddl.html - public static void Umaddl(Bits Rm, Bits Ra, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - int a = (int)UInt(Ra); - - /* Operation */ - Bits operand1 = X(32, n); - Bits operand2 = X(32, m); - Bits operand3 = X(64, a); - - BigInteger result = Int(operand3, true) + (Int(operand1, true) * Int(operand2, true)); - - X(d, result.SubBigInteger(63, 0)); - } - - // smsubl.html - public static void Smsubl(Bits Rm, Bits Ra, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - int a = (int)UInt(Ra); - - /* Operation */ - Bits operand1 = X(32, n); - Bits operand2 = X(32, m); - Bits operand3 = X(64, a); - - BigInteger result = Int(operand3, false) - (Int(operand1, false) * Int(operand2, false)); - - X(d, result.SubBigInteger(63, 0)); - } - - // umsubl.html - public static void Umsubl(Bits Rm, Bits Ra, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - int a = (int)UInt(Ra); - - /* Operation */ - Bits operand1 = X(32, n); - Bits operand2 = X(32, m); - Bits operand3 = X(64, a); - - BigInteger result = Int(operand3, true) - (Int(operand1, true) * Int(operand2, true)); - - X(d, result.SubBigInteger(63, 0)); - } - - // smulh.html - public static void Smulh(Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* Operation */ - Bits operand1 = X(64, n); - Bits operand2 = X(64, m); - - BigInteger result = Int(operand1, false) * Int(operand2, false); - - X(d, result.SubBigInteger(127, 64)); - } - - // umulh.html - public static void Umulh(Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* Operation */ - Bits operand1 = X(64, n); - Bits operand2 = X(64, m); - - BigInteger result = Int(operand1, true) * Int(operand2, true); - - X(d, result.SubBigInteger(127, 64)); - } -#endregion - } - - // fpsimdindex.html - internal static class SimdFp - { -#region "Simd" - // abs_advsimd.html#ABS_asisdmisc_R - public static void Abs_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool neg = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - BigInteger element; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - if (neg) - { - element = -element; - } - else - { - element = Abs(element); - } - - Elem(result, e, esize, element.SubBigInteger(esize - 1, 0)); - } - - V(d, result); - } - - // abs_advsimd.html#ABS_asimdmisc_R - public static void Abs_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool neg = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - BigInteger element; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - if (neg) - { - element = -element; - } - else - { - element = Abs(element); - } - - Elem(result, e, esize, element.SubBigInteger(esize - 1, 0)); - } - - V(d, result); - } - - // addp_advsimd_pair.html - public static void Addp_S(Bits size, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize * 2; - // int elements = 2; - - ReduceOp op = ReduceOp.ReduceOp_ADD; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand = V(datasize, n); - - V(d, Reduce(op, operand, esize)); - } - - // addv_advsimd.html - public static void Addv_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '100' then ReservedValue(); */ - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - // int elements = datasize / esize; - - ReduceOp op = ReduceOp.ReduceOp_ADD; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand = V(datasize, n); - - V(d, Reduce(op, operand, esize)); - } - - // cls_advsimd.html - public static void Cls_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - CountOp countop = (U ? CountOp.CountOp_CLZ : CountOp.CountOp_CLS); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - BigInteger count; - - for (int e = 0; e <= elements - 1; e++) - { - if (countop == CountOp.CountOp_CLS) - { - count = (BigInteger)CountLeadingSignBits(Elem(operand, e, esize)); - } - else - { - count = (BigInteger)CountLeadingZeroBits(Elem(operand, e, esize)); - } - - Elem(result, e, esize, count.SubBigInteger(esize - 1, 0)); - } - - V(d, result); - } - - // clz_advsimd.html - public static void Clz_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - CountOp countop = (U ? CountOp.CountOp_CLZ : CountOp.CountOp_CLS); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - BigInteger count; - - for (int e = 0; e <= elements - 1; e++) - { - if (countop == CountOp.CountOp_CLS) - { - count = (BigInteger)CountLeadingSignBits(Elem(operand, e, esize)); - } - else - { - count = (BigInteger)CountLeadingZeroBits(Elem(operand, e, esize)); - } - - Elem(result, e, esize, count.SubBigInteger(esize - 1, 0)); - } - - V(d, result); - } - - // cmeq_advsimd_zero.html#CMEQ_asisdmisc_Z - public static void Cmeq_Zero_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - const bool op = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - CompareOp comparison; - - switch (Bits.Concat(op, U)) - { - case Bits bits when bits == "00": - comparison = CompareOp.CompareOp_GT; - break; - case Bits bits when bits == "01": - comparison = CompareOp.CompareOp_GE; - break; - default: - case Bits bits when bits == "10": - comparison = CompareOp.CompareOp_EQ; - break; - case Bits bits when bits == "11": - comparison = CompareOp.CompareOp_LE; - break; - } - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - default: - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmeq_advsimd_zero.html#CMEQ_asimdmisc_Z - public static void Cmeq_Zero_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - const bool op = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - CompareOp comparison; - - switch (Bits.Concat(op, U)) - { - case Bits bits when bits == "00": - comparison = CompareOp.CompareOp_GT; - break; - case Bits bits when bits == "01": - comparison = CompareOp.CompareOp_GE; - break; - default: - case Bits bits when bits == "10": - comparison = CompareOp.CompareOp_EQ; - break; - case Bits bits when bits == "11": - comparison = CompareOp.CompareOp_LE; - break; - } - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - default: - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmge_advsimd_zero.html#CMGE_asisdmisc_Z - public static void Cmge_Zero_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - const bool op = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - CompareOp comparison; - - switch (Bits.Concat(op, U)) - { - case Bits bits when bits == "00": - comparison = CompareOp.CompareOp_GT; - break; - default: - case Bits bits when bits == "01": - comparison = CompareOp.CompareOp_GE; - break; - case Bits bits when bits == "10": - comparison = CompareOp.CompareOp_EQ; - break; - case Bits bits when bits == "11": - comparison = CompareOp.CompareOp_LE; - break; - } - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - default: - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmge_advsimd_zero.html#CMGE_asimdmisc_Z - public static void Cmge_Zero_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - const bool op = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - CompareOp comparison; - - switch (Bits.Concat(op, U)) - { - case Bits bits when bits == "00": - comparison = CompareOp.CompareOp_GT; - break; - default: - case Bits bits when bits == "01": - comparison = CompareOp.CompareOp_GE; - break; - case Bits bits when bits == "10": - comparison = CompareOp.CompareOp_EQ; - break; - case Bits bits when bits == "11": - comparison = CompareOp.CompareOp_LE; - break; - } - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - default: - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmgt_advsimd_zero.html#CMGT_asisdmisc_Z - public static void Cmgt_Zero_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - const bool op = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - CompareOp comparison; - - switch (Bits.Concat(op, U)) - { - default: - case Bits bits when bits == "00": - comparison = CompareOp.CompareOp_GT; - break; - case Bits bits when bits == "01": - comparison = CompareOp.CompareOp_GE; - break; - case Bits bits when bits == "10": - comparison = CompareOp.CompareOp_EQ; - break; - case Bits bits when bits == "11": - comparison = CompareOp.CompareOp_LE; - break; - } - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - default: - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmgt_advsimd_zero.html#CMGT_asimdmisc_Z - public static void Cmgt_Zero_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - const bool op = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - CompareOp comparison; - - switch (Bits.Concat(op, U)) - { - default: - case Bits bits when bits == "00": - comparison = CompareOp.CompareOp_GT; - break; - case Bits bits when bits == "01": - comparison = CompareOp.CompareOp_GE; - break; - case Bits bits when bits == "10": - comparison = CompareOp.CompareOp_EQ; - break; - case Bits bits when bits == "11": - comparison = CompareOp.CompareOp_LE; - break; - } - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - default: - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmle_advsimd.html#CMLE_asisdmisc_Z - public static void Cmle_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - const bool op = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - CompareOp comparison; - - switch (Bits.Concat(op, U)) - { - case Bits bits when bits == "00": - comparison = CompareOp.CompareOp_GT; - break; - case Bits bits when bits == "01": - comparison = CompareOp.CompareOp_GE; - break; - case Bits bits when bits == "10": - comparison = CompareOp.CompareOp_EQ; - break; - default: - case Bits bits when bits == "11": - comparison = CompareOp.CompareOp_LE; - break; - } - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - default: - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmle_advsimd.html#CMLE_asimdmisc_Z - public static void Cmle_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - const bool op = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - CompareOp comparison; - - switch (Bits.Concat(op, U)) - { - case Bits bits when bits == "00": - comparison = CompareOp.CompareOp_GT; - break; - case Bits bits when bits == "01": - comparison = CompareOp.CompareOp_GE; - break; - case Bits bits when bits == "10": - comparison = CompareOp.CompareOp_EQ; - break; - default: - case Bits bits when bits == "11": - comparison = CompareOp.CompareOp_LE; - break; - } - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - default: - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmlt_advsimd.html#CMLT_asisdmisc_Z - public static void Cmlt_S(Bits size, Bits Rn, Bits Rd) - { - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - CompareOp comparison = CompareOp.CompareOp_LT; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - default: - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmlt_advsimd.html#CMLT_asimdmisc_Z - public static void Cmlt_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - CompareOp comparison = CompareOp.CompareOp_LT; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - switch (comparison) - { - case CompareOp.CompareOp_GT: - test_passed = (element > (BigInteger)0); - break; - case CompareOp.CompareOp_GE: - test_passed = (element >= (BigInteger)0); - break; - case CompareOp.CompareOp_EQ: - test_passed = (element == (BigInteger)0); - break; - case CompareOp.CompareOp_LE: - test_passed = (element <= (BigInteger)0); - break; - default: - case CompareOp.CompareOp_LT: - test_passed = (element < (BigInteger)0); - break; - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cnt_advsimd.html - public static void Cnt_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '00' then ReservedValue(); */ - - int esize = 8; - int datasize = (Q ? 128 : 64); - int elements = datasize / 8; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - BigInteger count; - - for (int e = 0; e <= elements - 1; e++) - { - count = (BigInteger)BitCount(Elem(operand, e, esize)); - - Elem(result, e, esize, count.SubBigInteger(esize - 1, 0)); - } - - V(d, result); - } - - // fcvtns_advsimd.html#FCVTNS_asisdmisc_R - public static void Fcvtns_S(Bits sz, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o2 = false; - const bool o1 = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int esize = 32 << (int)UInt(sz); - int datasize = esize; - int elements = 1; - - FPRounding rounding = FPDecodeRounding(Bits.Concat(o1, o2)); - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits element; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, esize); - - Elem(result, e, esize, FPToFixed(esize, element, 0, unsigned, FPCR, rounding)); - } - - V(d, result); - } - - // fcvtns_advsimd.html#FCVTNS_asimdmisc_R - public static void Fcvtns_V(bool Q, Bits sz, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o2 = false; - const bool o1 = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if sz:Q == '10' then ReservedValue(); */ - - int esize = 32 << (int)UInt(sz); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - FPRounding rounding = FPDecodeRounding(Bits.Concat(o1, o2)); - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits element; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, esize); - - Elem(result, e, esize, FPToFixed(esize, element, 0, unsigned, FPCR, rounding)); - } - - V(d, result); - } - - // fcvtnu_advsimd.html#FCVTNU_asisdmisc_R - public static void Fcvtnu_S(Bits sz, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o2 = false; - const bool o1 = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int esize = 32 << (int)UInt(sz); - int datasize = esize; - int elements = 1; - - FPRounding rounding = FPDecodeRounding(Bits.Concat(o1, o2)); - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits element; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, esize); - - Elem(result, e, esize, FPToFixed(esize, element, 0, unsigned, FPCR, rounding)); - } - - V(d, result); - } - - // fcvtnu_advsimd.html#FCVTNU_asimdmisc_R - public static void Fcvtnu_V(bool Q, Bits sz, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o2 = false; - const bool o1 = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if sz:Q == '10' then ReservedValue(); */ - - int esize = 32 << (int)UInt(sz); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - FPRounding rounding = FPDecodeRounding(Bits.Concat(o1, o2)); - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits element; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, esize); - - Elem(result, e, esize, FPToFixed(esize, element, 0, unsigned, FPCR, rounding)); - } - - V(d, result); - } - - // neg_advsimd.html#NEG_asisdmisc_R - public static void Neg_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool neg = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - BigInteger element; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - if (neg) - { - element = -element; - } - else - { - element = Abs(element); - } - - Elem(result, e, esize, element.SubBigInteger(esize - 1, 0)); - } - - V(d, result); - } - - // neg_advsimd.html#NEG_asimdmisc_R - public static void Neg_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool neg = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - BigInteger element; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - if (neg) - { - element = -element; - } - else - { - element = Abs(element); - } - - Elem(result, e, esize, element.SubBigInteger(esize - 1, 0)); - } - - V(d, result); - } - - // not_advsimd.html - public static void Not_V(bool Q, Bits Rn, Bits Rd) - { - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int esize = 8; - int datasize = (Q ? 128 : 64); - int elements = datasize / 8; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits element; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, esize); - - Elem(result, e, esize, NOT(element)); - } - - V(d, result); - } - - // rbit_advsimd.html - public static void Rbit_V(bool Q, Bits Rn, Bits Rd) - { - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int esize = 8; - int datasize = (Q ? 128 : 64); - int elements = datasize / 8; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits element; - Bits rev = new Bits(esize); - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, esize); - - for (int i = 0; i <= esize - 1; i++) - { - rev[esize - 1 - i] = element[i]; - } - - Elem(result, e, esize, rev); - } - - V(d, result); - } - - // rev16_advsimd.html - public static void Rev16_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o0 = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - // size=esize: B(0), H(1), S(1), D(S) - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - - // op=REVx: 64(0), 32(1), 16(2) - Bits op = Bits.Concat(o0, U); - - // => op+size: - // 64+B = 0, 64+H = 1, 64+S = 2, 64+D = X - // 32+B = 1, 32+H = 2, 32+S = X, 32+D = X - // 16+B = 2, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - // => 3-(op+size) (index bits in group) - // 64/B = 3, 64+H = 2, 64+S = 1, 64+D = X - // 32+B = 2, 32+H = 1, 32+S = X, 32+D = X - // 16+B = 1, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - - // index bits within group: 1, 2, 3 - /* if UInt(op) + UInt(size) >= 3 then UnallocatedEncoding(); */ - - int container_size; - - switch (op) - { - default: - case Bits bits when bits == "10": - container_size = 16; - break; - case Bits bits when bits == "01": - container_size = 32; - break; - case Bits bits when bits == "00": - container_size = 64; - break; - } - - int containers = datasize / container_size; - int elements_per_container = container_size / esize; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - int element = 0; - int rev_element; - - for (int c = 0; c <= containers - 1; c++) - { - rev_element = element + elements_per_container - 1; - - for (int e = 0; e <= elements_per_container - 1; e++) - { - Elem(result, rev_element, esize, Elem(operand, element, esize)); - - element = element + 1; - rev_element = rev_element - 1; - } - } - - V(d, result); - } - - // rev32_advsimd.html - public static void Rev32_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o0 = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - // size=esize: B(0), H(1), S(1), D(S) - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - - // op=REVx: 64(0), 32(1), 16(2) - Bits op = Bits.Concat(o0, U); - - // => op+size: - // 64+B = 0, 64+H = 1, 64+S = 2, 64+D = X - // 32+B = 1, 32+H = 2, 32+S = X, 32+D = X - // 16+B = 2, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - // => 3-(op+size) (index bits in group) - // 64/B = 3, 64+H = 2, 64+S = 1, 64+D = X - // 32+B = 2, 32+H = 1, 32+S = X, 32+D = X - // 16+B = 1, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - - // index bits within group: 1, 2, 3 - /* if UInt(op) + UInt(size) >= 3 then UnallocatedEncoding(); */ - - int container_size; - - switch (op) - { - case Bits bits when bits == "10": - container_size = 16; - break; - default: - case Bits bits when bits == "01": - container_size = 32; - break; - case Bits bits when bits == "00": - container_size = 64; - break; - } - - int containers = datasize / container_size; - int elements_per_container = container_size / esize; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - int element = 0; - int rev_element; - - for (int c = 0; c <= containers - 1; c++) - { - rev_element = element + elements_per_container - 1; - - for (int e = 0; e <= elements_per_container - 1; e++) - { - Elem(result, rev_element, esize, Elem(operand, element, esize)); - - element = element + 1; - rev_element = rev_element - 1; - } - } - - V(d, result); - } - - // rev64_advsimd.html - public static void Rev64_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o0 = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - // size=esize: B(0), H(1), S(1), D(S) - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - - // op=REVx: 64(0), 32(1), 16(2) - Bits op = Bits.Concat(o0, U); - - // => op+size: - // 64+B = 0, 64+H = 1, 64+S = 2, 64+D = X - // 32+B = 1, 32+H = 2, 32+S = X, 32+D = X - // 16+B = 2, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - // => 3-(op+size) (index bits in group) - // 64/B = 3, 64+H = 2, 64+S = 1, 64+D = X - // 32+B = 2, 32+H = 1, 32+S = X, 32+D = X - // 16+B = 1, 16+H = X, 16+S = X, 16+D = X - // 8+B = X, 8+H = X, 8+S = X, 8+D = X - - // index bits within group: 1, 2, 3 - /* if UInt(op) + UInt(size) >= 3 then UnallocatedEncoding(); */ - - int container_size; - - switch (op) - { - case Bits bits when bits == "10": - container_size = 16; - break; - case Bits bits when bits == "01": - container_size = 32; - break; - default: - case Bits bits when bits == "00": - container_size = 64; - break; - } - - int containers = datasize / container_size; - int elements_per_container = container_size / esize; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - - int element = 0; - int rev_element; - - for (int c = 0; c <= containers - 1; c++) - { - rev_element = element + elements_per_container - 1; - - for (int e = 0; e <= elements_per_container - 1; e++) - { - Elem(result, rev_element, esize, Elem(operand, element, esize)); - - element = element + 1; - rev_element = rev_element - 1; - } - } - - V(d, result); - } - - // sadalp_advsimd.html - public static void Sadalp_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - const bool op = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / (2 * esize); - - bool acc = (op == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand = V(datasize, n); - Bits sum; - BigInteger op1; - BigInteger op2; - - Bits result = (acc ? V(datasize, d) : Zeros(datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - op1 = Int(Elem(operand, 2 * e + 0, esize), unsigned); - op2 = Int(Elem(operand, 2 * e + 1, esize), unsigned); - - sum = (op1 + op2).SubBigInteger(2 * esize - 1, 0); - - Elem(result, e, 2 * esize, Elem(result, e, 2 * esize) + sum); - } - - V(d, result); - } - - // saddlp_advsimd.html - public static void Saddlp_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - const bool op = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / (2 * esize); - - bool acc = (op == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand = V(datasize, n); - Bits sum; - BigInteger op1; - BigInteger op2; - - Bits result = (acc ? V(datasize, d) : Zeros(datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - op1 = Int(Elem(operand, 2 * e + 0, esize), unsigned); - op2 = Int(Elem(operand, 2 * e + 1, esize), unsigned); - - sum = (op1 + op2).SubBigInteger(2 * esize - 1, 0); - - Elem(result, e, 2 * esize, Elem(result, e, 2 * esize) + sum); - } - - V(d, result); - } - - // sha256su0_advsimd.html - public static void Sha256su0_V(Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if !HaveCryptoExt() then UnallocatedEncoding(); */ - - /* Operation */ - /* CheckCryptoEnabled64(); */ - - Bits result = new Bits(128); - Bits operand1 = V(128, d); - Bits operand2 = V(128, n); - Bits T = Bits.Concat(operand2[31, 0], operand1[127, 32]); // bits(128) - Bits elt; // bits(32) - - for (int e = 0; e <= 3; e++) - { - elt = Elem(T, e, 32); - elt = EOR(EOR(ROR(elt, 7), ROR(elt, 18)), LSR(elt, 3)); - Elem(result, e, 32, elt + Elem(operand1, e, 32)); - } - - V(d, result); - } - - // sqabs_advsimd.html#SQABS_asisdmisc_R - public static void Sqabs_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool neg = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - if (neg) - { - element = -element; - } - else - { - element = Abs(element); - } - - (Bits _result, bool _sat) = SignedSatQ(element, esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqabs_advsimd.html#SQABS_asimdmisc_R - public static void Sqabs_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool neg = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - if (neg) - { - element = -element; - } - else - { - element = Abs(element); - } - - (Bits _result, bool _sat) = SignedSatQ(element, esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqneg_advsimd.html#SQNEG_asisdmisc_R - public static void Sqneg_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool neg = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - if (neg) - { - element = -element; - } - else - { - element = Abs(element); - } - - (Bits _result, bool _sat) = SignedSatQ(element, esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqneg_advsimd.html#SQNEG_asimdmisc_R - public static void Sqneg_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool neg = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - BigInteger element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = SInt(Elem(operand, e, esize)); - - if (neg) - { - element = -element; - } - else - { - element = Abs(element); - } - - (Bits _result, bool _sat) = SignedSatQ(element, esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqxtn_advsimd.html#SQXTN_asisdmisc_N - public static void Sqxtn_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int part = 0; - int elements = 1; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(2 * datasize, n); - Bits element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, 2 * esize); - - (Bits _result, bool _sat) = SatQ(Int(element, unsigned), esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - Vpart(d, part, result); - } - - // sqxtn_advsimd.html#SQXTN_asimdmisc_N - public static void Sqxtn_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(2 * datasize, n); - Bits element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, 2 * esize); - - (Bits _result, bool _sat) = SatQ(Int(element, unsigned), esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - Vpart(d, part, result); - } - - // sqxtun_advsimd.html#SQXTUN_asisdmisc_N - public static void Sqxtun_S(Bits size, Bits Rn, Bits Rd) - { - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int part = 0; - int elements = 1; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(2 * datasize, n); - Bits element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, 2 * esize); - - (Bits _result, bool _sat) = UnsignedSatQ(SInt(element), esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - Vpart(d, part, result); - } - - // sqxtun_advsimd.html#SQXTUN_asimdmisc_N - public static void Sqxtun_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(2 * datasize, n); - Bits element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, 2 * esize); - - (Bits _result, bool _sat) = UnsignedSatQ(SInt(element), esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - Vpart(d, part, result); - } - - // suqadd_advsimd.html#SUQADD_asisdmisc_R - public static void Suqadd_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits operand2 = V(datasize, d); - BigInteger op1; - BigInteger op2; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - op1 = Int(Elem(operand, e, esize), !unsigned); - op2 = Int(Elem(operand2, e, esize), unsigned); - - (Bits _result, bool _sat) = SatQ(op1 + op2, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // suqadd_advsimd.html#SUQADD_asimdmisc_R - public static void Suqadd_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits operand2 = V(datasize, d); - BigInteger op1; - BigInteger op2; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - op1 = Int(Elem(operand, e, esize), !unsigned); - op2 = Int(Elem(operand2, e, esize), unsigned); - - (Bits _result, bool _sat) = SatQ(op1 + op2, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // uadalp_advsimd.html - public static void Uadalp_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - const bool op = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / (2 * esize); - - bool acc = (op == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand = V(datasize, n); - Bits sum; - BigInteger op1; - BigInteger op2; - - Bits result = (acc ? V(datasize, d) : Zeros(datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - op1 = Int(Elem(operand, 2 * e + 0, esize), unsigned); - op2 = Int(Elem(operand, 2 * e + 1, esize), unsigned); - - sum = (op1 + op2).SubBigInteger(2 * esize - 1, 0); - - Elem(result, e, 2 * esize, Elem(result, e, 2 * esize) + sum); - } - - V(d, result); - } - - // uaddlp_advsimd.html - public static void Uaddlp_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - const bool op = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / (2 * esize); - - bool acc = (op == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand = V(datasize, n); - Bits sum; - BigInteger op1; - BigInteger op2; - - Bits result = (acc ? V(datasize, d) : Zeros(datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - op1 = Int(Elem(operand, 2 * e + 0, esize), unsigned); - op2 = Int(Elem(operand, 2 * e + 1, esize), unsigned); - - sum = (op1 + op2).SubBigInteger(2 * esize - 1, 0); - - Elem(result, e, 2 * esize, Elem(result, e, 2 * esize) + sum); - } - - V(d, result); - } - - // uqxtn_advsimd.html#UQXTN_asisdmisc_N - public static void Uqxtn_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int part = 0; - int elements = 1; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(2 * datasize, n); - Bits element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, 2 * esize); - - (Bits _result, bool _sat) = SatQ(Int(element, unsigned), esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - Vpart(d, part, result); - } - - // uqxtn_advsimd.html#UQXTN_asimdmisc_N - public static void Uqxtn_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(2 * datasize, n); - Bits element; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, 2 * esize); - - (Bits _result, bool _sat) = SatQ(Int(element, unsigned), esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - Vpart(d, part, result); - } - - // usqadd_advsimd.html#USQADD_asisdmisc_R - public static void Usqadd_S(Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits operand2 = V(datasize, d); - BigInteger op1; - BigInteger op2; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - op1 = Int(Elem(operand, e, esize), !unsigned); - op2 = Int(Elem(operand2, e, esize), unsigned); - - (Bits _result, bool _sat) = SatQ(op1 + op2, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // usqadd_advsimd.html#USQADD_asimdmisc_R - public static void Usqadd_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(datasize, n); - Bits operand2 = V(datasize, d); - BigInteger op1; - BigInteger op2; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - op1 = Int(Elem(operand, e, esize), !unsigned); - op2 = Int(Elem(operand2, e, esize), unsigned); - - (Bits _result, bool _sat) = SatQ(op1 + op2, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // xtn_advsimd.html - public static void Xtn_V(bool Q, Bits size, Bits Rn, Bits Rd) - { - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand = V(2 * datasize, n); - Bits element; - - for (int e = 0; e <= elements - 1; e++) - { - element = Elem(operand, e, 2 * esize); - - Elem(result, e, esize, element[esize - 1, 0]); - } - - Vpart(d, part, result); - } -#endregion - -#region "SimdReg" - // add_advsimd.html#ADD_asisdsame_only - public static void Add_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool sub_op = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, esize); - element2 = Elem(operand2, e, esize); - - if (sub_op) - { - Elem(result, e, esize, element1 - element2); - } - else - { - Elem(result, e, esize, element1 + element2); - } - } - - V(d, result); - } - - // add_advsimd.html#ADD_asimdsame_only - public static void Add_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool sub_op = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, esize); - element2 = Elem(operand2, e, esize); - - if (sub_op) - { - Elem(result, e, esize, element1 - element2); - } - else - { - Elem(result, e, esize, element1 + element2); - } - } - - V(d, result); - } - - // addhn_advsimd.html - public static void Addhn_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o1 = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool round = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(2 * datasize, n); - Bits operand2 = V(2 * datasize, m); - BigInteger round_const = (round ? (BigInteger)1 << (esize - 1) : 0); - Bits sum; - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, 2 * esize); - element2 = Elem(operand2, e, 2 * esize); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - sum = sum + round_const; - - Elem(result, e, esize, sum[2 * esize - 1, esize]); - } - - Vpart(d, part, result); - } - - // addp_advsimd_vec.html - public static void Addp_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits concat = Bits.Concat(operand2, operand1); - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(concat, 2 * e, esize); - element2 = Elem(concat, (2 * e) + 1, esize); - - Elem(result, e, esize, element1 + element2); - } - - V(d, result); - } - - // and_advsimd.html - public static void And_V(bool Q, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (Q ? 128 : 64); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - - Bits result = AND(operand1, operand2); - - V(d, result); - } - - // bic_advsimd_reg.html - public static void Bic_V(bool Q, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (Q ? 128 : 64); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - - operand2 = NOT(operand2); - - Bits result = AND(operand1, operand2); - - V(d, result); - } - - // bif_advsimd.html - public static void Bif_V(bool Q, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (Q ? 128 : 64); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1; - Bits operand3; - Bits operand4 = V(datasize, n); - - operand1 = V(datasize, d); - operand3 = NOT(V(datasize, m)); - - V(d, EOR(operand1, AND(EOR(operand1, operand4), operand3))); - } - - // bit_advsimd.html - public static void Bit_V(bool Q, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (Q ? 128 : 64); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1; - Bits operand3; - Bits operand4 = V(datasize, n); - - operand1 = V(datasize, d); - operand3 = V(datasize, m); - - V(d, EOR(operand1, AND(EOR(operand1, operand4), operand3))); - } - - // bsl_advsimd.html - public static void Bsl_V(bool Q, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (Q ? 128 : 64); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1; - Bits operand3; - Bits operand4 = V(datasize, n); - - operand1 = V(datasize, m); - operand3 = V(datasize, d); - - V(d, EOR(operand1, AND(EOR(operand1, operand4), operand3))); - } - - // cmeq_advsimd_reg.html#CMEQ_asisdsame_only - public static void Cmeq_Reg_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool and_test = (U == false); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits element1; - Bits element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, esize); - element2 = Elem(operand2, e, esize); - - if (and_test) - { - test_passed = !IsZero(AND(element1, element2)); - } - else - { - test_passed = (element1 == element2); - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmeq_advsimd_reg.html#CMEQ_asimdsame_only - public static void Cmeq_Reg_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool and_test = (U == false); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits element1; - Bits element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, esize); - element2 = Elem(operand2, e, esize); - - if (and_test) - { - test_passed = !IsZero(AND(element1, element2)); - } - else - { - test_passed = (element1 == element2); - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmge_advsimd_reg.html#CMGE_asisdsame_only - public static void Cmge_Reg_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool eq = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - bool cmp_eq = (eq == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - test_passed = (cmp_eq ? element1 >= element2 : element1 > element2); - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmge_advsimd_reg.html#CMGE_asimdsame_only - public static void Cmge_Reg_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool eq = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - bool cmp_eq = (eq == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - test_passed = (cmp_eq ? element1 >= element2 : element1 > element2); - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmgt_advsimd_reg.html#CMGT_asisdsame_only - public static void Cmgt_Reg_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool eq = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - bool cmp_eq = (eq == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - test_passed = (cmp_eq ? element1 >= element2 : element1 > element2); - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmgt_advsimd_reg.html#CMGT_asimdsame_only - public static void Cmgt_Reg_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool eq = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - bool cmp_eq = (eq == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - test_passed = (cmp_eq ? element1 >= element2 : element1 > element2); - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmhi_advsimd.html#CMHI_asisdsame_only - public static void Cmhi_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool eq = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - bool cmp_eq = (eq == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - test_passed = (cmp_eq ? element1 >= element2 : element1 > element2); - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmhi_advsimd.html#CMHI_asimdsame_only - public static void Cmhi_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool eq = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - bool cmp_eq = (eq == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - test_passed = (cmp_eq ? element1 >= element2 : element1 > element2); - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmhs_advsimd.html#CMHS_asisdsame_only - public static void Cmhs_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool eq = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - bool cmp_eq = (eq == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - test_passed = (cmp_eq ? element1 >= element2 : element1 > element2); - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmhs_advsimd.html#CMHS_asimdsame_only - public static void Cmhs_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool eq = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - bool cmp_eq = (eq == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - test_passed = (cmp_eq ? element1 >= element2 : element1 > element2); - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmtst_advsimd.html#CMTST_asisdsame_only - public static void Cmtst_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool and_test = (U == false); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits element1; - Bits element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, esize); - element2 = Elem(operand2, e, esize); - - if (and_test) - { - test_passed = !IsZero(AND(element1, element2)); - } - else - { - test_passed = (element1 == element2); - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // cmtst_advsimd.html#CMTST_asimdsame_only - public static void Cmtst_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool and_test = (U == false); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits element1; - Bits element2; - - bool test_passed; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, esize); - element2 = Elem(operand2, e, esize); - - if (and_test) - { - test_passed = !IsZero(AND(element1, element2)); - } - else - { - test_passed = (element1 == element2); - } - - Elem(result, e, esize, test_passed ? Ones(esize) : Zeros(esize)); - } - - V(d, result); - } - - // eor_advsimd.html - public static void Eor_V(bool Q, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (Q ? 128 : 64); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, m); - Bits operand2 = Zeros(datasize); - Bits operand3 = Ones(datasize); - Bits operand4 = V(datasize, n); - - Bits result = EOR(operand1, AND(EOR(operand2, operand4), operand3)); - - V(d, result); - } - - // orn_advsimd.html - public static void Orn_V(bool Q, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (Q ? 128 : 64); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - - operand2 = NOT(operand2); - - Bits result = OR(operand1, operand2); - - V(d, result); - } - - // orr_advsimd_reg.html - public static void Orr_V(bool Q, Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int datasize = (Q ? 128 : 64); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - - Bits result = OR(operand1, operand2); - - V(d, result); - } - - // raddhn_advsimd.html - public static void Raddhn_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o1 = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool round = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(2 * datasize, n); - Bits operand2 = V(2 * datasize, m); - BigInteger round_const = (round ? (BigInteger)1 << (esize - 1) : 0); - Bits sum; - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, 2 * esize); - element2 = Elem(operand2, e, 2 * esize); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - sum = sum + round_const; - - Elem(result, e, esize, sum[2 * esize - 1, esize]); - } - - Vpart(d, part, result); - } - - // rsubhn_advsimd.html - public static void Rsubhn_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o1 = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool round = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(2 * datasize, n); - Bits operand2 = V(2 * datasize, m); - BigInteger round_const = (round ? (BigInteger)1 << (esize - 1) : 0); - Bits sum; - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, 2 * esize); - element2 = Elem(operand2, e, 2 * esize); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - sum = sum + round_const; - - Elem(result, e, esize, sum[2 * esize - 1, esize]); - } - - Vpart(d, part, result); - } - - // saba_advsimd.html - public static void Saba_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool ac = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - bool accumulate = (ac == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - Bits absdiff; - - Bits result = (accumulate ? V(datasize, d) : Zeros(datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - absdiff = Abs(element1 - element2).SubBigInteger(esize - 1, 0); - - Elem(result, e, esize, Elem(result, e, esize) + absdiff); - } - - V(d, result); - } - - // sabal_advsimd.html - public static void Sabal_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool op = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool accumulate = (op == false); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - Bits absdiff; - - Bits result = (accumulate ? V(2 * datasize, d) : Zeros(2 * datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - absdiff = Abs(element1 - element2).SubBigInteger(2 * esize - 1, 0); - - Elem(result, e, 2 * esize, Elem(result, e, 2 * esize) + absdiff); - } - - V(d, result); - } - - // sabd_advsimd.html - public static void Sabd_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool ac = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - bool accumulate = (ac == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - Bits absdiff; - - Bits result = (accumulate ? V(datasize, d) : Zeros(datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - absdiff = Abs(element1 - element2).SubBigInteger(esize - 1, 0); - - Elem(result, e, esize, Elem(result, e, esize) + absdiff); - } - - V(d, result); - } - - // sabdl_advsimd.html - public static void Sabdl_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool op = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool accumulate = (op == false); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - Bits absdiff; - - Bits result = (accumulate ? V(2 * datasize, d) : Zeros(2 * datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - absdiff = Abs(element1 - element2).SubBigInteger(2 * esize - 1, 0); - - Elem(result, e, 2 * esize, Elem(result, e, 2 * esize) + absdiff); - } - - V(d, result); - } - - // saddl_advsimd.html - public static void Saddl_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o1 = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - Elem(result, e, 2 * esize, sum.SubBigInteger(2 * esize - 1, 0)); - } - - V(d, result); - } - - // saddw_advsimd.html - public static void Saddw_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o1 = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = V(2 * datasize, n); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, 2 * esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - Elem(result, e, 2 * esize, sum.SubBigInteger(2 * esize - 1, 0)); - } - - V(d, result); - } - - // sha256h_advsimd.html - public static void Sha256h_V(Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if !HaveCryptoExt() then UnallocatedEncoding(); */ - - /* Operation */ - /* CheckCryptoEnabled64(); */ - - Bits result = SHA256hash(V(128, d), V(128, n), V(128, m), true); - - V(d, result); - } - - // sha256h2_advsimd.html - public static void Sha256h2_V(Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if !HaveCryptoExt() then UnallocatedEncoding(); */ - - /* Operation */ - /* CheckCryptoEnabled64(); */ - - Bits result = SHA256hash(V(128, n), V(128, d), V(128, m), false); - - V(d, result); - } - - // sha256su1_advsimd.html - public static void Sha256su1_V(Bits Rm, Bits Rn, Bits Rd) - { - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if !HaveCryptoExt() then UnallocatedEncoding(); */ - - /* Operation */ - /* CheckCryptoEnabled64(); */ - - Bits result = new Bits(128); - Bits operand1 = V(128, d); - Bits operand2 = V(128, n); - Bits operand3 = V(128, m); - Bits T0 = Bits.Concat(operand3[31, 0], operand2[127, 32]); // bits(128) - Bits T1; // bits(64) - Bits elt; // bits(32) - - T1 = operand3[127, 64]; - for (int e = 0; e <= 1; e++) - { - elt = Elem(T1, e, 32); - elt = EOR(EOR(ROR(elt, 17), ROR(elt, 19)), LSR(elt, 10)); - elt = elt + Elem(operand1, e, 32) + Elem(T0, e, 32); - Elem(result, e, 32, elt); - } - - T1 = result[63, 0]; - for (int e = 2; e <= 3; e++) - { - elt = Elem(T1, e - 2, 32); - elt = EOR(EOR(ROR(elt, 17), ROR(elt, 19)), LSR(elt, 10)); - elt = elt + Elem(operand1, e, 32) + Elem(T0, e, 32); - Elem(result, e, 32, elt); - } - - V(d, result); - } - - // shadd_advsimd.html - public static void Shadd_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - sum = element1 + element2; - - Elem(result, e, esize, sum.SubBigInteger(esize, 1)); - } - - V(d, result); - } - - // shsub_advsimd.html - public static void Shsub_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger diff; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - diff = element1 - element2; - - Elem(result, e, esize, diff.SubBigInteger(esize, 1)); - } - - V(d, result); - } - - // smlal_advsimd_vec.html - public static void Smlal_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o1 = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - Bits operand3 = V(2 * datasize, d); - BigInteger element1; - BigInteger element2; - Bits product; - Bits accum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - product = (element1 * element2).SubBigInteger(2 * esize - 1, 0); - - if (sub_op) - { - accum = Elem(operand3, e, 2 * esize) - product; - } - else - { - accum = Elem(operand3, e, 2 * esize) + product; - } - - Elem(result, e, 2 * esize, accum); - } - - V(d, result); - } - - // smlsl_advsimd_vec.html - public static void Smlsl_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o1 = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - Bits operand3 = V(2 * datasize, d); - BigInteger element1; - BigInteger element2; - Bits product; - Bits accum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - product = (element1 * element2).SubBigInteger(2 * esize - 1, 0); - - if (sub_op) - { - accum = Elem(operand3, e, 2 * esize) - product; - } - else - { - accum = Elem(operand3, e, 2 * esize) + product; - } - - Elem(result, e, 2 * esize, accum); - } - - V(d, result); - } - - // sqadd_advsimd.html#SQADD_asisdsame_only - public static void Sqadd_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger sum; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - sum = element1 + element2; - - (Bits _result, bool _sat) = SatQ(sum, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqadd_advsimd.html#SQADD_asimdsame_only - public static void Sqadd_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger sum; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - sum = element1 + element2; - - (Bits _result, bool _sat) = SatQ(sum, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqdmulh_advsimd_vec.html#SQDMULH_asisdsame_only - public static void Sqdmulh_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' || size == '00' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool rounding = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger round_const = (rounding ? (BigInteger)1 << (esize - 1) : 0); - BigInteger element1; - BigInteger element2; - BigInteger product; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = SInt(Elem(operand1, e, esize)); - element2 = SInt(Elem(operand2, e, esize)); - - product = (2 * element1 * element2) + round_const; - - (Bits _result, bool _sat) = SignedSatQ(product >> esize, esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqdmulh_advsimd_vec.html#SQDMULH_asimdsame_only - public static void Sqdmulh_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' || size == '00' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool rounding = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger round_const = (rounding ? (BigInteger)1 << (esize - 1) : 0); - BigInteger element1; - BigInteger element2; - BigInteger product; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = SInt(Elem(operand1, e, esize)); - element2 = SInt(Elem(operand2, e, esize)); - - product = (2 * element1 * element2) + round_const; - - (Bits _result, bool _sat) = SignedSatQ(product >> esize, esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqrdmulh_advsimd_vec.html#SQRDMULH_asisdsame_only - public static void Sqrdmulh_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' || size == '00' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool rounding = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger round_const = (rounding ? (BigInteger)1 << (esize - 1) : 0); - BigInteger element1; - BigInteger element2; - BigInteger product; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = SInt(Elem(operand1, e, esize)); - element2 = SInt(Elem(operand2, e, esize)); - - product = (2 * element1 * element2) + round_const; - - (Bits _result, bool _sat) = SignedSatQ(product >> esize, esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqrdmulh_advsimd_vec.html#SQRDMULH_asimdsame_only - public static void Sqrdmulh_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' || size == '00' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool rounding = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger round_const = (rounding ? (BigInteger)1 << (esize - 1) : 0); - BigInteger element1; - BigInteger element2; - BigInteger product; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = SInt(Elem(operand1, e, esize)); - element2 = SInt(Elem(operand2, e, esize)); - - product = (2 * element1 * element2) + round_const; - - (Bits _result, bool _sat) = SignedSatQ(product >> esize, esize); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqsub_advsimd.html#SQSUB_asisdsame_only - public static void Sqsub_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger diff; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - diff = element1 - element2; - - (Bits _result, bool _sat) = SatQ(diff, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // sqsub_advsimd.html#SQSUB_asimdsame_only - public static void Sqsub_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger diff; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - diff = element1 - element2; - - (Bits _result, bool _sat) = SatQ(diff, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // srhadd_advsimd.html - public static void Srhadd_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - Elem(result, e, esize, (element1 + element2 + 1).SubBigInteger(esize, 1)); - } - - V(d, result); - } - - // ssubl_advsimd.html - public static void Ssubl_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o1 = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - Elem(result, e, 2 * esize, sum.SubBigInteger(2 * esize - 1, 0)); - } - - V(d, result); - } - - // ssubw_advsimd.html - public static void Ssubw_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o1 = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = V(2 * datasize, n); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, 2 * esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - Elem(result, e, 2 * esize, sum.SubBigInteger(2 * esize - 1, 0)); - } - - V(d, result); - } - - // sub_advsimd.html#SUB_asisdsame_only - public static void Sub_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size != '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool sub_op = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, esize); - element2 = Elem(operand2, e, esize); - - if (sub_op) - { - Elem(result, e, esize, element1 - element2); - } - else - { - Elem(result, e, esize, element1 + element2); - } - } - - V(d, result); - } - - // sub_advsimd.html#SUB_asimdsame_only - public static void Sub_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool sub_op = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, esize); - element2 = Elem(operand2, e, esize); - - if (sub_op) - { - Elem(result, e, esize, element1 - element2); - } - else - { - Elem(result, e, esize, element1 + element2); - } - } - - V(d, result); - } - - // subhn_advsimd.html - public static void Subhn_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = false; - const bool o1 = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool round = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(2 * datasize, n); - Bits operand2 = V(2 * datasize, m); - BigInteger round_const = (round ? (BigInteger)1 << (esize - 1) : 0); - Bits sum; - Bits element1; - Bits element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Elem(operand1, e, 2 * esize); - element2 = Elem(operand2, e, 2 * esize); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - sum = sum + round_const; - - Elem(result, e, esize, sum[2 * esize - 1, esize]); - } - - Vpart(d, part, result); - } - - // trn1_advsimd.html - public static void Trn1_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool op = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - int part = (int)UInt(op); - int pairs = elements / 2; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - - for (int p = 0; p <= pairs - 1; p++) - { - Elem(result, 2 * p + 0, esize, Elem(operand1, 2 * p + part, esize)); - Elem(result, 2 * p + 1, esize, Elem(operand2, 2 * p + part, esize)); - } - - V(d, result); - } - - // trn2_advsimd.html - public static void Trn2_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool op = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - int part = (int)UInt(op); - int pairs = elements / 2; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - - for (int p = 0; p <= pairs - 1; p++) - { - Elem(result, 2 * p + 0, esize, Elem(operand1, 2 * p + part, esize)); - Elem(result, 2 * p + 1, esize, Elem(operand2, 2 * p + part, esize)); - } - - V(d, result); - } - - // uaba_advsimd.html - public static void Uaba_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool ac = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - bool accumulate = (ac == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - Bits absdiff; - - Bits result = (accumulate ? V(datasize, d) : Zeros(datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - absdiff = Abs(element1 - element2).SubBigInteger(esize - 1, 0); - - Elem(result, e, esize, Elem(result, e, esize) + absdiff); - } - - V(d, result); - } - - // uabal_advsimd.html - public static void Uabal_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool op = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool accumulate = (op == false); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - Bits absdiff; - - Bits result = (accumulate ? V(2 * datasize, d) : Zeros(2 * datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - absdiff = Abs(element1 - element2).SubBigInteger(2 * esize - 1, 0); - - Elem(result, e, 2 * esize, Elem(result, e, 2 * esize) + absdiff); - } - - V(d, result); - } - - // uabd_advsimd.html - public static void Uabd_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool ac = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - bool accumulate = (ac == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - Bits absdiff; - - Bits result = (accumulate ? V(datasize, d) : Zeros(datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - absdiff = Abs(element1 - element2).SubBigInteger(esize - 1, 0); - - Elem(result, e, esize, Elem(result, e, esize) + absdiff); - } - - V(d, result); - } - - // uabdl_advsimd.html - public static void Uabdl_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool op = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool accumulate = (op == false); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - Bits absdiff; - - Bits result = (accumulate ? V(2 * datasize, d) : Zeros(2 * datasize)); - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - absdiff = Abs(element1 - element2).SubBigInteger(2 * esize - 1, 0); - - Elem(result, e, 2 * esize, Elem(result, e, 2 * esize) + absdiff); - } - - V(d, result); - } - - // uaddl_advsimd.html - public static void Uaddl_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o1 = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - Elem(result, e, 2 * esize, sum.SubBigInteger(2 * esize - 1, 0)); - } - - V(d, result); - } - - // uaddw_advsimd.html - public static void Uaddw_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o1 = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = V(2 * datasize, n); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, 2 * esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - Elem(result, e, 2 * esize, sum.SubBigInteger(2 * esize - 1, 0)); - } - - V(d, result); - } - - // uhadd_advsimd.html - public static void Uhadd_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - sum = element1 + element2; - - Elem(result, e, esize, sum.SubBigInteger(esize, 1)); - } - - V(d, result); - } - - // uhsub_advsimd.html - public static void Uhsub_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger diff; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - diff = element1 - element2; - - Elem(result, e, esize, diff.SubBigInteger(esize, 1)); - } - - V(d, result); - } - - // umlal_advsimd_vec.html - public static void Umlal_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o1 = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - Bits operand3 = V(2 * datasize, d); - BigInteger element1; - BigInteger element2; - Bits product; - Bits accum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - product = (element1 * element2).SubBigInteger(2 * esize - 1, 0); - - if (sub_op) - { - accum = Elem(operand3, e, 2 * esize) - product; - } - else - { - accum = Elem(operand3, e, 2 * esize) + product; - } - - Elem(result, e, 2 * esize, accum); - } - - V(d, result); - } - - // umlsl_advsimd_vec.html - public static void Umlsl_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o1 = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - Bits operand3 = V(2 * datasize, d); - BigInteger element1; - BigInteger element2; - Bits product; - Bits accum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - product = (element1 * element2).SubBigInteger(2 * esize - 1, 0); - - if (sub_op) - { - accum = Elem(operand3, e, 2 * esize) - product; - } - else - { - accum = Elem(operand3, e, 2 * esize) + product; - } - - Elem(result, e, 2 * esize, accum); - } - - V(d, result); - } - - // uqadd_advsimd.html#UQADD_asisdsame_only - public static void Uqadd_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger sum; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - sum = element1 + element2; - - (Bits _result, bool _sat) = SatQ(sum, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // uqadd_advsimd.html#UQADD_asimdsame_only - public static void Uqadd_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger sum; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - sum = element1 + element2; - - (Bits _result, bool _sat) = SatQ(sum, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // uqsub_advsimd.html#UQSUB_asisdsame_only - public static void Uqsub_S(Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Scalar */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - int esize = 8 << (int)UInt(size); - int datasize = esize; - int elements = 1; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger diff; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - diff = element1 - element2; - - (Bits _result, bool _sat) = SatQ(diff, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // uqsub_advsimd.html#UQSUB_asimdsame_only - public static void Uqsub_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode Vector */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - BigInteger diff; - bool sat; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - diff = element1 - element2; - - (Bits _result, bool _sat) = SatQ(diff, esize, unsigned); - Elem(result, e, esize, _result); - sat = _sat; - - if (sat) - { - /* FPSR.QC = '1'; */ - FPSR[27] = true; // TODO: Add named fields. - } - } - - V(d, result); - } - - // urhadd_advsimd.html - public static void Urhadd_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - BigInteger element1; - BigInteger element2; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - Elem(result, e, esize, (element1 + element2 + 1).SubBigInteger(esize, 1)); - } - - V(d, result); - } - - // usubl_advsimd.html - public static void Usubl_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o1 = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = Vpart(datasize, n, part); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - Elem(result, e, 2 * esize, sum.SubBigInteger(2 * esize - 1, 0)); - } - - V(d, result); - } - - // usubw_advsimd.html - public static void Usubw_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool U = true; - const bool o1 = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size == '11' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = 64; - int part = (int)UInt(Q); - int elements = datasize / esize; - - bool sub_op = (o1 == true); - bool unsigned = (U == true); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(2 * datasize); - Bits operand1 = V(2 * datasize, n); - Bits operand2 = Vpart(datasize, m, part); - BigInteger element1; - BigInteger element2; - BigInteger sum; - - for (int e = 0; e <= elements - 1; e++) - { - element1 = Int(Elem(operand1, e, 2 * esize), unsigned); - element2 = Int(Elem(operand2, e, esize), unsigned); - - if (sub_op) - { - sum = element1 - element2; - } - else - { - sum = element1 + element2; - } - - Elem(result, e, 2 * esize, sum.SubBigInteger(2 * esize - 1, 0)); - } - - V(d, result); - } - - // uzp1_advsimd.html - public static void Uzp1_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool op = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - int part = (int)UInt(op); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operandl = V(datasize, n); - Bits operandh = V(datasize, m); - - Bits zipped = Bits.Concat(operandh, operandl); - - for (int e = 0; e <= elements - 1; e++) - { - Elem(result, e, esize, Elem(zipped, 2 * e + part, esize)); - } - - V(d, result); - } - - // uzp2_advsimd.html - public static void Uzp2_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool op = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - int part = (int)UInt(op); - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operandl = V(datasize, n); - Bits operandh = V(datasize, m); - - Bits zipped = Bits.Concat(operandh, operandl); - - for (int e = 0; e <= elements - 1; e++) - { - Elem(result, e, esize, Elem(zipped, 2 * e + part, esize)); - } - - V(d, result); - } - - // zip1_advsimd.html - public static void Zip1_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool op = false; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - int part = (int)UInt(op); - int pairs = elements / 2; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - - int @base = part * pairs; - - for (int p = 0; p <= pairs - 1; p++) - { - Elem(result, 2 * p + 0, esize, Elem(operand1, @base + p, esize)); - Elem(result, 2 * p + 1, esize, Elem(operand2, @base + p, esize)); - } - - V(d, result); - } - - // zip2_advsimd.html - public static void Zip2_V(bool Q, Bits size, Bits Rm, Bits Rn, Bits Rd) - { - const bool op = true; - - /* Decode */ - int d = (int)UInt(Rd); - int n = (int)UInt(Rn); - int m = (int)UInt(Rm); - - /* if size:Q == '110' then ReservedValue(); */ - - int esize = 8 << (int)UInt(size); - int datasize = (Q ? 128 : 64); - int elements = datasize / esize; - int part = (int)UInt(op); - int pairs = elements / 2; - - /* Operation */ - /* CheckFPAdvSIMDEnabled64(); */ - - Bits result = new Bits(datasize); - Bits operand1 = V(datasize, n); - Bits operand2 = V(datasize, m); - - int @base = part * pairs; - - for (int p = 0; p <= pairs - 1; p++) - { - Elem(result, 2 * p + 0, esize, Elem(operand1, @base + p, esize)); - Elem(result, 2 * p + 1, esize, Elem(operand2, @base + p, esize)); - } - - V(d, result); - } -#endregion - } -} diff --git a/Ryujinx.Tests/Cpu/Tester/Pseudocode.cs b/Ryujinx.Tests/Cpu/Tester/Pseudocode.cs deleted file mode 100644 index f3777476..00000000 --- a/Ryujinx.Tests/Cpu/Tester/Pseudocode.cs +++ /dev/null @@ -1,1740 +0,0 @@ -// https://github.com/LDj3SNuD/ARM_v8-A_AArch64_Instructions_Tester/blob/master/Tester/Pseudocode.cs - -// https://developer.arm.com/products/architecture/a-profile/exploration-tools -// ..\A64_v83A_ISA_xml_00bet6.1\ISA_v83A_A64_xml_00bet6.1_OPT\xhtml\ - -// https://alastairreid.github.io/asl-lexical-syntax/ - -// | ------------------------|-------------------------------- | -// | ASL | C# | -// | ------------------------|-------------------------------- | -// | bit, bits(1); boolean | bool | -// | bits | Bits | -// | integer | BigInteger, int | -// | real | decimal; double, float | -// | ------------------------|-------------------------------- | -// | '0'; FALSE | false | -// | '1'; TRUE | true | -// | '010' | "010" | -// | DIV, MOD | /, % | -// | ------------------------|-------------------------------- | - -using System; -using System.Numerics; - -namespace Ryujinx.Tests.Cpu.Tester -{ - using Types; - - using static Shared; - - internal static class AArch64 - { -#region "exceptions/exceptions/" - /* shared_pseudocode.html#AArch64.ResetControlRegisters.1 */ - public static void ResetControlRegisters(bool cold_reset) - { - PSTATE.N = cold_reset; - PSTATE.Z = cold_reset; - PSTATE.C = cold_reset; - PSTATE.V = cold_reset; - } - - /* */ - public static void TakeReset(bool cold_reset) - { - /* assert !HighestELUsingAArch32(); */ - - // Enter the highest implemented Exception level in AArch64 state - if (HaveEL(EL3)) - { - PSTATE.EL = EL3; - } - else if (HaveEL(EL2)) - { - PSTATE.EL = EL2; - } - else - { - PSTATE.EL = EL1; - } - - // Reset the system registers and other system components - AArch64.ResetControlRegisters(cold_reset); - - // Reset all other PSTATE fields - PSTATE.SP = true; // Select stack pointer - - // All registers, bits and fields not reset by the above pseudocode or by the BranchTo() call - // below are UNKNOWN bitstrings after reset. In particular, the return information registers - // ELR_ELx and SPSR_ELx have UNKNOWN values, so that it - // is impossible to return from a reset in an architecturally defined way. - AArch64.ResetGeneralRegisters(); - AArch64.ResetSIMDFPRegisters(); - AArch64.ResetSpecialRegisters(); - } -#endregion - -#region "functions/registers/" - /* shared_pseudocode.html#AArch64.ResetGeneralRegisters.0 */ - public static void ResetGeneralRegisters() - { - for (int i = 0; i <= 30; i++) - { - /* X[i] = bits(64) UNKNOWN; */ - _R[i].SetAll(false); - } - } - - /* shared_pseudocode.html#AArch64.ResetSIMDFPRegisters.0 */ - public static void ResetSIMDFPRegisters() - { - for (int i = 0; i <= 31; i++) - { - /* V[i] = bits(128) UNKNOWN; */ - _V[i].SetAll(false); - } - } - - /* shared_pseudocode.html#AArch64.ResetSpecialRegisters.0 */ - public static void ResetSpecialRegisters() - { - // AArch64 special registers - /* SP_EL0 = bits(64) UNKNOWN; */ - SP_EL0.SetAll(false); - /* SP_EL1 = bits(64) UNKNOWN; */ - SP_EL1.SetAll(false); - - FPCR.SetAll(false); // TODO: Add named fields. - FPSR.SetAll(false); // TODO: Add named fields. - } - - // shared_pseudocode.html#impl-aarch64.SP.write.0 - public static void SP(Bits value) - { - /* int width = value.Count; */ - - /* assert width IN {32,64}; */ - - if (!PSTATE.SP) - { - SP_EL0 = ZeroExtend(64, value); - } - else - { - switch (PSTATE.EL) - { - case Bits bits when bits == EL0: - SP_EL0 = ZeroExtend(64, value); - break; - default: - case Bits bits when bits == EL1: - SP_EL1 = ZeroExtend(64, value); - break;/* - case Bits bits when bits == EL2: - SP_EL2 = ZeroExtend(64, value); - break; - case Bits bits when bits == EL3: - SP_EL3 = ZeroExtend(64, value); - break;*/ - } - } - } - - // shared_pseudocode.html#impl-aarch64.SP.read.0 - public static Bits SP(int width) - { - /* assert width IN {8,16,32,64}; */ - - if (!PSTATE.SP) - { - return SP_EL0[width - 1, 0]; - } - else - { - switch (PSTATE.EL) - { - case Bits bits when bits == EL0: - return SP_EL0[width - 1, 0]; - default: - case Bits bits when bits == EL1: - return SP_EL1[width - 1, 0];/* - case Bits bits when bits == EL2: - return SP_EL2[width - 1, 0]; - case Bits bits when bits == EL3: - return SP_EL3[width - 1, 0];*/ - } - } - } - - // shared_pseudocode.html#impl-aarch64.V.write.1 - public static void V(int n, Bits value) - { - /* int width = value.Count; */ - - /* assert n >= 0 && n <= 31; */ - /* assert width IN {8,16,32,64,128}; */ - - _V[n] = ZeroExtend(128, value); - } - - /* shared_pseudocode.html#impl-aarch64.V.read.1 */ - public static Bits V(int width, int n) - { - /* assert n >= 0 && n <= 31; */ - /* assert width IN {8,16,32,64,128}; */ - - return _V[n][width - 1, 0]; - } - - /* shared_pseudocode.html#impl-aarch64.Vpart.read.2 */ - public static Bits Vpart(int width, int n, int part) - { - /* assert n >= 0 && n <= 31; */ - /* assert part IN {0, 1}; */ - - if (part == 0) - { - /* assert width IN {8,16,32,64}; */ - return _V[n][width - 1, 0]; - } - else - { - /* assert width == 64; */ - return _V[n][(width * 2) - 1, width]; - } - } - - // shared_pseudocode.html#impl-aarch64.Vpart.write.2 - public static void Vpart(int n, int part, Bits value) - { - int width = value.Count; - - /* assert n >= 0 && n <= 31; */ - /* assert part IN {0, 1}; */ - - if (part == 0) - { - /* assert width IN {8,16,32,64}; */ - _V[n] = ZeroExtend(128, value); - } - else - { - /* assert width == 64; */ - _V[n][(width * 2) - 1, width] = value[width - 1, 0]; - } - } - - // shared_pseudocode.html#impl-aarch64.X.write.1 - public static void X(int n, Bits value) - { - /* int width = value.Count; */ - - /* assert n >= 0 && n <= 31; */ - /* assert width IN {32,64}; */ - - if (n != 31) - { - _R[n] = ZeroExtend(64, value); - } - } - - /* shared_pseudocode.html#impl-aarch64.X.read.1 */ - public static Bits X(int width, int n) - { - /* assert n >= 0 && n <= 31; */ - /* assert width IN {8,16,32,64}; */ - - if (n != 31) - { - return _R[n][width - 1, 0]; - } - else - { - return Zeros(width); - } - } -#endregion - -#region "instrs/countop/" - // shared_pseudocode.html#CountOp - public enum CountOp {CountOp_CLZ, CountOp_CLS, CountOp_CNT}; -#endregion - -#region "instrs/extendreg/" - /* shared_pseudocode.html#impl-aarch64.DecodeRegExtend.1 */ - public static ExtendType DecodeRegExtend(Bits op) - { - switch (op) - { - default: - case Bits bits when bits == "000": - return ExtendType.ExtendType_UXTB; - case Bits bits when bits == "001": - return ExtendType.ExtendType_UXTH; - case Bits bits when bits == "010": - return ExtendType.ExtendType_UXTW; - case Bits bits when bits == "011": - return ExtendType.ExtendType_UXTX; - case Bits bits when bits == "100": - return ExtendType.ExtendType_SXTB; - case Bits bits when bits == "101": - return ExtendType.ExtendType_SXTH; - case Bits bits when bits == "110": - return ExtendType.ExtendType_SXTW; - case Bits bits when bits == "111": - return ExtendType.ExtendType_SXTX; - } - } - - /* shared_pseudocode.html#impl-aarch64.ExtendReg.3 */ - public static Bits ExtendReg(int N, int reg, ExtendType type, int shift) - { - /* assert shift >= 0 && shift <= 4; */ - - Bits val = X(N, reg); - bool unsigned; - int len; - - switch (type) - { - default: - case ExtendType.ExtendType_SXTB: - unsigned = false; len = 8; - break; - case ExtendType.ExtendType_SXTH: - unsigned = false; len = 16; - break; - case ExtendType.ExtendType_SXTW: - unsigned = false; len = 32; - break; - case ExtendType.ExtendType_SXTX: - unsigned = false; len = 64; - break; - case ExtendType.ExtendType_UXTB: - unsigned = true; len = 8; - break; - case ExtendType.ExtendType_UXTH: - unsigned = true; len = 16; - break; - case ExtendType.ExtendType_UXTW: - unsigned = true; len = 32; - break; - case ExtendType.ExtendType_UXTX: - unsigned = true; len = 64; - break; - } - - // Note the extended width of the intermediate value and - // that sign extension occurs from bit , not - // from bit . This is equivalent to the instruction - // [SU]BFIZ Rtmp, Rreg, #shift, #len - // It may also be seen as a sign/zero extend followed by a shift: - // LSL(Extend(val, N, unsigned), shift); - - len = Min(len, N - shift); - return Extend(Bits.Concat(val[len - 1, 0], Zeros(shift)), N, unsigned); - } - - // shared_pseudocode.html#ExtendType - public enum ExtendType {ExtendType_SXTB, ExtendType_SXTH, ExtendType_SXTW, ExtendType_SXTX, - ExtendType_UXTB, ExtendType_UXTH, ExtendType_UXTW, ExtendType_UXTX}; -#endregion - -#region "instrs/integer/bitmasks/" - /* shared_pseudocode.html#impl-aarch64.DecodeBitMasks.4 */ - public static (Bits, Bits) DecodeBitMasks(int M, bool immN, Bits imms, Bits immr, bool immediate) - { - Bits tmask, wmask; - Bits tmask_and, wmask_and; - Bits tmask_or, wmask_or; - Bits levels; - - // Compute log2 of element size - // 2^len must be in range [2, M] - int len = HighestSetBit(Bits.Concat(immN, NOT(imms))); - /* if len < 1 then ReservedValue(); */ - /* assert M >= (1 << len); */ - - // Determine S, R and S - R parameters - levels = ZeroExtend(Ones(len), 6); - - // For logical immediates an all-ones value of S is reserved - // since it would generate a useless all-ones result (many times) - /* if immediate && (imms AND levels) == levels then ReservedValue(); */ - - BigInteger S = UInt(AND(imms, levels)); - BigInteger R = UInt(AND(immr, levels)); - BigInteger diff = S - R; // 6-bit subtract with borrow - - // Compute "top mask" - tmask_and = OR(diff.SubBigInteger(5, 0), NOT(levels)); - tmask_or = AND(diff.SubBigInteger(5, 0), levels); - - tmask = Ones(64); - tmask = OR(AND(tmask, Replicate(Bits.Concat(Replicate(tmask_and[0], 1), Ones( 1)), 32)), Replicate(Bits.Concat(Zeros( 1), Replicate(tmask_or[0], 1)), 32)); - tmask = OR(AND(tmask, Replicate(Bits.Concat(Replicate(tmask_and[1], 2), Ones( 2)), 16)), Replicate(Bits.Concat(Zeros( 2), Replicate(tmask_or[1], 2)), 16)); - tmask = OR(AND(tmask, Replicate(Bits.Concat(Replicate(tmask_and[2], 4), Ones( 4)), 8)), Replicate(Bits.Concat(Zeros( 4), Replicate(tmask_or[2], 4)), 8)); - tmask = OR(AND(tmask, Replicate(Bits.Concat(Replicate(tmask_and[3], 8), Ones( 8)), 4)), Replicate(Bits.Concat(Zeros( 8), Replicate(tmask_or[3], 8)), 4)); - tmask = OR(AND(tmask, Replicate(Bits.Concat(Replicate(tmask_and[4], 16), Ones(16)), 2)), Replicate(Bits.Concat(Zeros(16), Replicate(tmask_or[4], 16)), 2)); - tmask = OR(AND(tmask, Replicate(Bits.Concat(Replicate(tmask_and[5], 32), Ones(32)), 1)), Replicate(Bits.Concat(Zeros(32), Replicate(tmask_or[5], 32)), 1)); - - // Compute "wraparound mask" - wmask_and = OR(immr, NOT(levels)); - wmask_or = AND(immr, levels); - - wmask = Zeros(64); - wmask = OR(AND(wmask, Replicate(Bits.Concat(Ones( 1), Replicate(wmask_and[0], 1)), 32)), Replicate(Bits.Concat(Replicate(wmask_or[0], 1), Zeros( 1)), 32)); - wmask = OR(AND(wmask, Replicate(Bits.Concat(Ones( 2), Replicate(wmask_and[1], 2)), 16)), Replicate(Bits.Concat(Replicate(wmask_or[1], 2), Zeros( 2)), 16)); - wmask = OR(AND(wmask, Replicate(Bits.Concat(Ones( 4), Replicate(wmask_and[2], 4)), 8)), Replicate(Bits.Concat(Replicate(wmask_or[2], 4), Zeros( 4)), 8)); - wmask = OR(AND(wmask, Replicate(Bits.Concat(Ones( 8), Replicate(wmask_and[3], 8)), 4)), Replicate(Bits.Concat(Replicate(wmask_or[3], 8), Zeros( 8)), 4)); - wmask = OR(AND(wmask, Replicate(Bits.Concat(Ones(16), Replicate(wmask_and[4], 16)), 2)), Replicate(Bits.Concat(Replicate(wmask_or[4], 16), Zeros(16)), 2)); - wmask = OR(AND(wmask, Replicate(Bits.Concat(Ones(32), Replicate(wmask_and[5], 32)), 1)), Replicate(Bits.Concat(Replicate(wmask_or[5], 32), Zeros(32)), 1)); - - if (diff.SubBigInteger(6)) // borrow from S - R - { - wmask = AND(wmask, tmask); - } - else - { - wmask = OR(wmask, tmask); - } - - return (wmask[M - 1, 0], tmask[M - 1, 0]); - } -#endregion - -#region "instrs/integer/shiftreg/" - /* shared_pseudocode.html#impl-aarch64.DecodeShift.1 */ - public static ShiftType DecodeShift(Bits op) - { - switch (op) - { - default: - case Bits bits when bits == "00": - return ShiftType.ShiftType_LSL; - case Bits bits when bits == "01": - return ShiftType.ShiftType_LSR; - case Bits bits when bits == "10": - return ShiftType.ShiftType_ASR; - case Bits bits when bits == "11": - return ShiftType.ShiftType_ROR; - } - } - - /* shared_pseudocode.html#impl-aarch64.ShiftReg.3 */ - public static Bits ShiftReg(int N, int reg, ShiftType type, int amount) - { - Bits result = X(N, reg); - - switch (type) - { - default: - case ShiftType.ShiftType_LSL: - result = LSL(result, amount); - break; - case ShiftType.ShiftType_LSR: - result = LSR(result, amount); - break; - case ShiftType.ShiftType_ASR: - result = ASR(result, amount); - break; - case ShiftType.ShiftType_ROR: - result = ROR(result, amount); - break; - } - - return result; - } - - // shared_pseudocode.html#ShiftType - public enum ShiftType {ShiftType_LSL, ShiftType_LSR, ShiftType_ASR, ShiftType_ROR}; -#endregion - -#region "instrs/vector/arithmetic/unary/cmp/compareop/" - // shared_pseudocode.html#CompareOp - public enum CompareOp {CompareOp_GT, CompareOp_GE, CompareOp_EQ, CompareOp_LE, CompareOp_LT}; -#endregion - -#region "instrs/vector/reduce/reduceop/" - // shared_pseudocode.html#impl-aarch64.Reduce.3 - public static Bits Reduce(ReduceOp op, Bits input, int esize) - { - int N = input.Count; - - int half; - Bits hi; - Bits lo; - Bits result = new Bits(esize); - - if (N == esize) - { - return new Bits(input); // Clone. - } - - half = N / 2; - hi = Reduce(op, input[N - 1, half], esize); - lo = Reduce(op, input[half - 1, 0], esize); - - switch (op) - { - case ReduceOp.ReduceOp_FMINNUM: - /* result = FPMinNum(lo, hi, FPCR); */ - break; - case ReduceOp.ReduceOp_FMAXNUM: - /* result = FPMaxNum(lo, hi, FPCR); */ - break; - case ReduceOp.ReduceOp_FMIN: - /* result = FPMin(lo, hi, FPCR); */ - break; - case ReduceOp.ReduceOp_FMAX: - /* result = FPMax(lo, hi, FPCR); */ - break; - case ReduceOp.ReduceOp_FADD: - /* result = FPAdd(lo, hi, FPCR); */ - break; - default: - case ReduceOp.ReduceOp_ADD: - result = lo + hi; - break; - } - - return result; - } - - // shared_pseudocode.html#ReduceOp - public enum ReduceOp {ReduceOp_FMINNUM, ReduceOp_FMAXNUM, - ReduceOp_FMIN, ReduceOp_FMAX, - ReduceOp_FADD, ReduceOp_ADD}; -#endregion - } - - internal static class Shared - { - static Shared() - { - _R = new Bits[31]; - for (int i = 0; i <= 30; i++) - { - _R[i] = new Bits(64, false); - } - - _V = new Bits[32]; - for (int i = 0; i <= 31; i++) - { - _V[i] = new Bits(128, false); - } - - SP_EL0 = new Bits(64, false); - SP_EL1 = new Bits(64, false); - - FPCR = new Bits(32, false); // TODO: Add named fields. - FPSR = new Bits(32, false); // TODO: Add named fields. - - PSTATE.N = false; - PSTATE.Z = false; - PSTATE.C = false; - PSTATE.V = false; - PSTATE.EL = EL1; - PSTATE.SP = true; - } - -#region "functions/common/" - /* */ - public static Bits AND(Bits x, Bits y) - { - return x.And(y); - } - - // shared_pseudocode.html#impl-shared.ASR.2 - public static Bits ASR(Bits x, int shift) - { - int N = x.Count; - - /* assert shift >= 0; */ - - Bits result; - - if (shift == 0) - { - result = new Bits(x); // Clone. - } - else - { - (result, _) = ASR_C(x, shift); - } - - return result; - } - - // shared_pseudocode.html#impl-shared.ASR_C.2 - public static (Bits, bool) ASR_C(Bits x, int shift) - { - int N = x.Count; - - /* assert shift > 0; */ - - Bits extended_x = SignExtend(x, shift + N); - Bits result = extended_x[shift + N - 1, shift]; - bool carry_out = extended_x[shift - 1]; - - return (result, carry_out); - } - - // shared_pseudocode.html#impl-shared.Abs.1 - public static BigInteger Abs(BigInteger x) - { - return (x >= 0 ? x : -x); - } - - // shared_pseudocode.html#impl-shared.BitCount.1 - public static int BitCount(Bits x) - { - int N = x.Count; - - int result = 0; - - for (int i = 0; i <= N - 1; i++) - { - if (x[i]) - { - result = result + 1; - } - } - - return result; - } - - // shared_pseudocode.html#impl-shared.CountLeadingSignBits.1 - public static int CountLeadingSignBits(Bits x) - { - int N = x.Count; - - return CountLeadingZeroBits(EOR(x[N - 1, 1], x[N - 2, 0])); - } - - // shared_pseudocode.html#impl-shared.CountLeadingZeroBits.1 - public static int CountLeadingZeroBits(Bits x) - { - int N = x.Count; - - return (N - 1 - HighestSetBit(x)); - } - - // shared_pseudocode.html#impl-shared.Elem.read.3 - public static Bits Elem(/*in */Bits vector, int e, int size) - { - /* int N = vector.Count; */ - - /* assert e >= 0 && (e+1)*size <= N; */ - - return vector[e * size + size - 1, e * size]; - } - - // shared_pseudocode.html#impl-shared.Elem.write.3 - public static void Elem(/*out */Bits vector, int e, int size, Bits value) - { - /* int N = vector.Count; */ - - /* assert e >= 0 && (e+1)*size <= N; */ - - vector[(e + 1) * size - 1, e * size] = value; - } - - /* */ - public static Bits EOR(Bits x, Bits y) - { - return x.Xor(y); - } - - // shared_pseudocode.html#impl-shared.Extend.3 - public static Bits Extend(Bits x, int N, bool unsigned) - { - if (unsigned) - { - return ZeroExtend(x, N); - } - else - { - return SignExtend(x, N); - } - } - - /* shared_pseudocode.html#impl-shared.Extend.2 */ - public static Bits Extend(int N, Bits x, bool unsigned) - { - return Extend(x, N, unsigned); - } - - // shared_pseudocode.html#impl-shared.HighestSetBit.1 - public static int HighestSetBit(Bits x) - { - int N = x.Count; - - for (int i = N - 1; i >= 0; i--) - { - if (x[i]) - { - return i; - } - } - - return -1; - } - - // shared_pseudocode.html#impl-shared.Int.2 - public static BigInteger Int(Bits x, bool unsigned) - { - return (unsigned ? UInt(x) : SInt(x)); - } - - // shared_pseudocode.html#impl-shared.IsOnes.1 - public static bool IsOnes(Bits x) - { - int N = x.Count; - - return (x == Ones(N)); - } - - // shared_pseudocode.html#impl-shared.IsZero.1 - public static bool IsZero(Bits x) - { - int N = x.Count; - - return (x == Zeros(N)); - } - - // shared_pseudocode.html#impl-shared.IsZeroBit.1 - public static bool IsZeroBit(Bits x) - { - return IsZero(x); - } - - // shared_pseudocode.html#impl-shared.LSL.2 - public static Bits LSL(Bits x, int shift) - { - int N = x.Count; - - /* assert shift >= 0; */ - - Bits result; - - if (shift == 0) - { - result = new Bits(x); // Clone. - } - else - { - (result, _) = LSL_C(x, shift); - } - - return result; - } - - // shared_pseudocode.html#impl-shared.LSL_C.2 - public static (Bits, bool) LSL_C(Bits x, int shift) - { - int N = x.Count; - - /* assert shift > 0; */ - - Bits extended_x = Bits.Concat(x, Zeros(shift)); - Bits result = extended_x[N - 1, 0]; - bool carry_out = extended_x[N]; - - return (result, carry_out); - } - - // shared_pseudocode.html#impl-shared.LSR.2 - public static Bits LSR(Bits x, int shift) - { - int N = x.Count; - - /* assert shift >= 0; */ - - Bits result; - - if (shift == 0) - { - result = new Bits(x); // Clone. - } - else - { - (result, _) = LSR_C(x, shift); - } - - return result; - } - - // shared_pseudocode.html#impl-shared.LSR_C.2 - public static (Bits, bool) LSR_C(Bits x, int shift) - { - int N = x.Count; - - /* assert shift > 0; */ - - Bits extended_x = ZeroExtend(x, shift + N); - Bits result = extended_x[shift + N - 1, shift]; - bool carry_out = extended_x[shift - 1]; - - return (result, carry_out); - } - - // shared_pseudocode.html#impl-shared.Min.2 - public static int Min(int a, int b) - { - if (a <= b) - { - return a; - } - else - { - return b; - } - } - - /* shared_pseudocode.html#impl-shared.NOT.1 */ - public static Bits NOT(Bits x) - { - return x.Not(); - } - - // shared_pseudocode.html#impl-shared.Ones.1 - /* shared_pseudocode.html#impl-shared.Ones.0 */ - public static Bits Ones(int N) - { - return Replicate(true, N); - } - - /* */ - public static Bits OR(Bits x, Bits y) - { - return x.Or(y); - } - - /* */ - public static decimal Real(BigInteger value) - { - return (decimal)value; - } - - /* */ - public static float Real_32(BigInteger value) - { - if (value == BigInteger.Pow((BigInteger)2.0f, 1000)) - { - return float.PositiveInfinity; - } - if (value == -BigInteger.Pow((BigInteger)2.0f, 1000)) - { - return float.NegativeInfinity; - } - - return (float)value; - } - - /* */ - public static double Real_64(BigInteger value) - { - if (value == BigInteger.Pow((BigInteger)2.0, 10000)) - { - return double.PositiveInfinity; - } - if (value == -BigInteger.Pow((BigInteger)2.0, 10000)) - { - return double.NegativeInfinity; - } - - return (double)value; - } - - // shared_pseudocode.html#impl-shared.ROR.2 - public static Bits ROR(Bits x, int shift) - { - /* assert shift >= 0; */ - - Bits result; - - if (shift == 0) - { - result = new Bits(x); // Clone. - } - else - { - (result, _) = ROR_C(x, shift); - } - - return result; - } - - // shared_pseudocode.html#impl-shared.ROR_C.2 - public static (Bits, bool) ROR_C(Bits x, int shift) - { - int N = x.Count; - - /* assert shift != 0; */ - - int m = shift % N; - Bits result = OR(LSR(x, m), LSL(x, N - m)); - bool carry_out = result[N - 1]; - - return (result, carry_out); - } - - /* shared_pseudocode.html#impl-shared.Replicate.1 */ - public static Bits Replicate(int N, Bits x) - { - int M = x.Count; - - /* assert N MOD M == 0; */ - - return Replicate(x, N / M); - } - - /* shared_pseudocode.html#impl-shared.Replicate.2 */ - public static Bits Replicate(Bits x, int N) - { - int M = x.Count; - - bool[] dst = new bool[M * N]; - - for (int i = 0; i < N; i++) - { - x.CopyTo(dst, i * M); - } - - return new Bits(dst); - } - - /* shared_pseudocode.html#impl-shared.RoundDown.1 */ - public static BigInteger RoundDown(decimal x) - { - return (BigInteger)Decimal.Floor(x); - } - - /* */ - public static BigInteger RoundDown_32(float x) - { - if (float.IsPositiveInfinity(x)) - { - return BigInteger.Pow((BigInteger)2.0f, 1000); - } - if (float.IsNegativeInfinity(x)) - { - return -BigInteger.Pow((BigInteger)2.0f, 1000); - } - - return (BigInteger)MathF.Floor(x); - } - - /* */ - public static BigInteger RoundDown_64(double x) - { - if (double.IsPositiveInfinity(x)) - { - return BigInteger.Pow((BigInteger)2.0, 10000); - } - if (double.IsNegativeInfinity(x)) - { - return -BigInteger.Pow((BigInteger)2.0, 10000); - } - - return (BigInteger)Math.Floor(x); - } - - // shared_pseudocode.html#impl-shared.RoundTowardsZero.1 - public static BigInteger RoundTowardsZero(decimal x) - { - if (x == 0.0m) - { - return (BigInteger)0m; - } - else if (x >= 0.0m) - { - return RoundDown(x); - } - else - { - return RoundUp(x); - } - } - - /* shared_pseudocode.html#impl-shared.RoundUp.1 */ - public static BigInteger RoundUp(decimal x) - { - return (BigInteger)Decimal.Ceiling(x); - } - - // shared_pseudocode.html#impl-shared.SInt.1 - public static BigInteger SInt(Bits x) - { - int N = x.Count; - - BigInteger result = 0; - - for (int i = 0; i <= N - 1; i++) - { - if (x[i]) - { - result = result + BigInteger.Pow(2, i); - } - } - - if (x[N - 1]) - { - result = result - BigInteger.Pow(2, N); - } - - return result; - } - - // shared_pseudocode.html#impl-shared.SignExtend.2 - public static Bits SignExtend(Bits x, int N) - { - int M = x.Count; - - /* assert N >= M; */ - - return Bits.Concat(Replicate(x[M - 1], N - M), x); - } - - /* shared_pseudocode.html#impl-shared.SignExtend.1 */ - public static Bits SignExtend(int N, Bits x) - { - return SignExtend(x, N); - } - - // shared_pseudocode.html#impl-shared.UInt.1 - public static BigInteger UInt(Bits x) - { - int N = x.Count; - - BigInteger result = 0; - - for (int i = 0; i <= N - 1; i++) - { - if (x[i]) - { - result = result + BigInteger.Pow(2, i); - } - } - - return result; - } - - // shared_pseudocode.html#impl-shared.ZeroExtend.2 - public static Bits ZeroExtend(Bits x, int N) - { - int M = x.Count; - - /* assert N >= M; */ - - return Bits.Concat(Zeros(N - M), x); - } - - /* shared_pseudocode.html#impl-shared.ZeroExtend.1 */ - public static Bits ZeroExtend(int N, Bits x) - { - return ZeroExtend(x, N); - } - - // shared_pseudocode.html#impl-shared.Zeros.1 - /* shared_pseudocode.html#impl-shared.Zeros.0 */ - public static Bits Zeros(int N) - { - return Replicate(false, N); - } -#endregion - -#region "functions/crc/" - // shared_pseudocode.html#impl-shared.BitReverse.1 - public static Bits BitReverse(Bits data) - { - int N = data.Count; - - Bits result = new Bits(N); - - for (int i = 0; i <= N - 1; i++) - { - result[N - i - 1] = data[i]; - } - - return result; - } - - // shared_pseudocode.html#impl-shared.Poly32Mod2.2 - public static Bits Poly32Mod2(Bits _data, Bits poly) - { - int N = _data.Count; - - /* assert N > 32; */ - - Bits data = new Bits(_data); // Clone. - - for (int i = N - 1; i >= 32; i--) - { - if (data[i]) - { - data[i - 1, 0] = EOR(data[i - 1, 0], Bits.Concat(poly, Zeros(i - 32))); - } - } - - return data[31, 0]; - } -#endregion - -#region "functions/crypto/" - // shared_pseudocode.html#impl-shared.ROL.2 - public static Bits ROL(Bits x, int shift) - { - int N = x.Count; - - /* assert shift >= 0 && shift <= N; */ - - if (shift == 0) - { - return new Bits(x); // Clone. - } - - return ROR(x, N - shift); - } - - // shared_pseudocode.html#impl-shared.SHA256hash.4 - public static Bits SHA256hash(Bits _X, Bits _Y, Bits W, bool part1) - { - Bits X = new Bits(_X); // Clone. - Bits Y = new Bits(_Y); // Clone. - - Bits chs, maj, t; // bits(32) - - for (int e = 0; e <= 3; e++) - { - chs = SHAchoose(Y[31, 0], Y[63, 32], Y[95, 64]); - maj = SHAmajority(X[31, 0], X[63, 32], X[95, 64]); - - t = Y[127, 96] + SHAhashSIGMA1(Y[31, 0]) + chs + Elem(W, e, 32); - - X[127, 96] = t + X[127, 96]; - Y[127, 96] = t + SHAhashSIGMA0(X[31, 0]) + maj; - - // TODO: Implement ASL: "<,>" as C#: "Bits.Split()". - /* = ROL(Y : X, 32); */ - Bits YX = ROL(Bits.Concat(Y, X), 32); - Y = YX[255, 128]; - X = YX[127, 0]; - } - - return (part1 ? X : Y); - } - - // shared_pseudocode.html#impl-shared.SHAchoose.3 - public static Bits SHAchoose(Bits x, Bits y, Bits z) - { - return EOR(AND(EOR(y, z), x), z); - } - - // shared_pseudocode.html#impl-shared.SHAhashSIGMA0.1 - public static Bits SHAhashSIGMA0(Bits x) - { - return EOR(EOR(ROR(x, 2), ROR(x, 13)), ROR(x, 22)); - } - - // shared_pseudocode.html#impl-shared.SHAhashSIGMA1.1 - public static Bits SHAhashSIGMA1(Bits x) - { - return EOR(EOR(ROR(x, 6), ROR(x, 11)), ROR(x, 25)); - } - - // shared_pseudocode.html#impl-shared.SHAmajority.3 - public static Bits SHAmajority(Bits x, Bits y, Bits z) - { - return OR(AND(x, y), AND(OR(x, y), z)); - } -#endregion - -#region "functions/float/fpdecoderounding/" - /* shared_pseudocode.html#impl-shared.FPDecodeRounding.1 */ - public static FPRounding FPDecodeRounding(Bits rmode) - { - switch (rmode) - { - default: - case Bits bits when bits == "00": - return FPRounding.FPRounding_TIEEVEN; // N - case Bits bits when bits == "01": - return FPRounding.FPRounding_POSINF; // P - case Bits bits when bits == "10": - return FPRounding.FPRounding_NEGINF; // M - case Bits bits when bits == "11": - return FPRounding.FPRounding_ZERO; // Z - } - } -#endregion - -#region "functions/float/fpexc/" - // shared_pseudocode.html#FPExc - public enum FPExc {FPExc_InvalidOp, FPExc_DivideByZero, FPExc_Overflow, - FPExc_Underflow, FPExc_Inexact, FPExc_InputDenorm}; -#endregion - -#region "functions/float/fpprocessexception/" - // shared_pseudocode.html#impl-shared.FPProcessException.2 - public static void FPProcessException(FPExc exception, Bits _fpcr) - { - Bits fpcr = new Bits(_fpcr); // Clone. - - int cumul; - - // Determine the cumulative exception bit number - switch (exception) - { - default: - case FPExc.FPExc_InvalidOp: cumul = 0; break; - case FPExc.FPExc_DivideByZero: cumul = 1; break; - case FPExc.FPExc_Overflow: cumul = 2; break; - case FPExc.FPExc_Underflow: cumul = 3; break; - case FPExc.FPExc_Inexact: cumul = 4; break; - case FPExc.FPExc_InputDenorm: cumul = 7; break; - } - - int enable = cumul + 8; - - if (fpcr[enable]) - { - // Trapping of the exception enabled. - // It is IMPLEMENTATION DEFINED whether the enable bit may be set at all, and - // if so then how exceptions may be accumulated before calling FPTrapException() - /* IMPLEMENTATION_DEFINED "floating-point trap handling"; */ - - throw new NotImplementedException(); - }/* - else if (UsingAArch32()) - { - // Set the cumulative exception bit - FPSCR = '1'; - }*/ - else - { - // Set the cumulative exception bit - FPSR[cumul] = true; - } - } -#endregion - -#region "functions/float/fprounding/" - // shared_pseudocode.html#FPRounding - public enum FPRounding {FPRounding_TIEEVEN, FPRounding_POSINF, - FPRounding_NEGINF, FPRounding_ZERO, - FPRounding_TIEAWAY, FPRounding_ODD}; -#endregion - -#region "functions/float/fptofixed/" - /* shared_pseudocode.html#impl-shared.FPToFixed.5 */ - public static Bits FPToFixed(int M, Bits op, int fbits, bool unsigned, Bits _fpcr, FPRounding rounding) - { - int N = op.Count; - - /* assert N IN {16,32,64}; */ - /* assert M IN {16,32,64}; */ - /* assert fbits >= 0; */ - /* assert rounding != FPRounding_ODD; */ - - Bits fpcr = new Bits(_fpcr); // Clone. - - if (N == 16) - { - throw new NotImplementedException(); - } - else if (N == 32) - { - // Unpack using fpcr to determine if subnormals are flushed-to-zero - (FPType type, bool sign, float value) = FPUnpack_32(op, fpcr); - - // If NaN, set cumulative flag or take exception - if (type == FPType.FPType_SNaN || type == FPType.FPType_QNaN) - { - FPProcessException(FPExc.FPExc_InvalidOp, fpcr); - } - - // Scale by fractional bits and produce integer rounded towards minus-infinity - value = value * MathF.Pow(2.0f, fbits); - BigInteger int_result = RoundDown_32(value); - float error = value - Real_32(int_result); - - if (float.IsNaN(error)) - { - error = 0.0f; - } - - // Determine whether supplied rounding mode requires an increment - bool round_up; - - switch (rounding) - { - default: - case FPRounding.FPRounding_TIEEVEN: - round_up = (error > 0.5f || (error == 0.5f && int_result.SubBigInteger(0))); - break; - case FPRounding.FPRounding_POSINF: - round_up = (error != 0.0f); - break; - case FPRounding.FPRounding_NEGINF: - round_up = false; - break; - case FPRounding.FPRounding_ZERO: - round_up = (error != 0.0f && int_result < (BigInteger)0); - break; - case FPRounding.FPRounding_TIEAWAY: - round_up = (error > 0.5f || (error == 0.5f && int_result >= (BigInteger)0)); - break; - } - - if (round_up) - { - int_result = int_result + 1; - } - - // Generate saturated result and exceptions - (Bits result, bool overflow) = SatQ(int_result, M, unsigned); - - if (overflow) - { - FPProcessException(FPExc.FPExc_InvalidOp, fpcr); - } - else if (error != 0.0f) - { - FPProcessException(FPExc.FPExc_Inexact, fpcr); - } - - return result; - } - else /* if (N == 64) */ - { - // Unpack using fpcr to determine if subnormals are flushed-to-zero - (FPType type, bool sign, double value) = FPUnpack_64(op, fpcr); - - // If NaN, set cumulative flag or take exception - if (type == FPType.FPType_SNaN || type == FPType.FPType_QNaN) - { - FPProcessException(FPExc.FPExc_InvalidOp, fpcr); - } - - // Scale by fractional bits and produce integer rounded towards minus-infinity - value = value * Math.Pow(2.0, fbits); - BigInteger int_result = RoundDown_64(value); - double error = value - Real_64(int_result); - - if (double.IsNaN(error)) - { - error = 0.0; - } - - // Determine whether supplied rounding mode requires an increment - bool round_up; - - switch (rounding) - { - default: - case FPRounding.FPRounding_TIEEVEN: - round_up = (error > 0.5 || (error == 0.5 && int_result.SubBigInteger(0))); - break; - case FPRounding.FPRounding_POSINF: - round_up = (error != 0.0); - break; - case FPRounding.FPRounding_NEGINF: - round_up = false; - break; - case FPRounding.FPRounding_ZERO: - round_up = (error != 0.0 && int_result < (BigInteger)0); - break; - case FPRounding.FPRounding_TIEAWAY: - round_up = (error > 0.5 || (error == 0.5 && int_result >= (BigInteger)0)); - break; - } - - if (round_up) - { - int_result = int_result + 1; - } - - // Generate saturated result and exceptions - (Bits result, bool overflow) = SatQ(int_result, M, unsigned); - - if (overflow) - { - FPProcessException(FPExc.FPExc_InvalidOp, fpcr); - } - else if (error != 0.0) - { - FPProcessException(FPExc.FPExc_Inexact, fpcr); - } - - return result; - } - } -#endregion - -#region "functions/float/fptype/" - // shared_pseudocode.html#FPType - public enum FPType {FPType_Nonzero, FPType_Zero, FPType_Infinity, - FPType_QNaN, FPType_SNaN}; -#endregion - -#region "functions/float/fpunpack/" - /* shared_pseudocode.html#impl-shared.FPUnpack.2 */ - /* shared_pseudocode.html#impl-shared.FPUnpackBase.2 */ - /*public static (FPType, bool, real) FPUnpack_16(Bits fpval, Bits _fpcr) - { - int N = fpval.Count; - - // assert N == 16; - - Bits fpcr = new Bits(_fpcr); // Clone. - - fpcr[26] = false; - - return FPUnpackBase_16(fpval, fpcr); - }*/ - public static (FPType, bool, float) FPUnpack_32(Bits fpval, Bits _fpcr) - { - int N = fpval.Count; - - /* assert N == 32; */ - - Bits fpcr = new Bits(_fpcr); // Clone. - - FPType type; - float value; - - bool sign = fpval[31]; - Bits exp32 = fpval[30, 23]; - Bits frac32 = fpval[22, 0]; - - if (IsZero(exp32)) - { - // Produce zero if value is zero or flush-to-zero is selected. - if (IsZero(frac32) || fpcr[24]) - { - type = FPType.FPType_Zero; - value = 0.0f; - - // Denormalized input flushed to zero - if (!IsZero(frac32)) - { - FPProcessException(FPExc.FPExc_InputDenorm, fpcr); - } - } - else - { - type = FPType.FPType_Nonzero; - value = MathF.Pow(2.0f, -126) * (Real_32(UInt(frac32)) * MathF.Pow(2.0f, -23)); - } - } - else if (IsOnes(exp32)) - { - if (IsZero(frac32)) - { - type = FPType.FPType_Infinity; - /* value = 2.0^1000000; */ - value = MathF.Pow(2.0f, 1000); - } - else - { - type = frac32[22] ? FPType.FPType_QNaN : FPType.FPType_SNaN; - value = 0.0f; - } - } - else - { - type = FPType.FPType_Nonzero; - value = MathF.Pow(2.0f, (int)UInt(exp32) - 127) * (1.0f + Real_32(UInt(frac32)) * MathF.Pow(2.0f, -23)); - } - - if (sign) - { - value = -value; - } - - return (type, sign, value); - } - public static (FPType, bool, double) FPUnpack_64(Bits fpval, Bits _fpcr) - { - int N = fpval.Count; - - /* assert N == 64; */ - - Bits fpcr = new Bits(_fpcr); // Clone. - - FPType type; - double value; - - bool sign = fpval[63]; - Bits exp64 = fpval[62, 52]; - Bits frac64 = fpval[51, 0]; - - if (IsZero(exp64)) - { - // Produce zero if value is zero or flush-to-zero is selected. - if (IsZero(frac64) || fpcr[24]) - { - type = FPType.FPType_Zero; - value = 0.0; - - // Denormalized input flushed to zero - if (!IsZero(frac64)) - { - FPProcessException(FPExc.FPExc_InputDenorm, fpcr); - } - } - else - { - type = FPType.FPType_Nonzero; - value = Math.Pow(2.0, -1022) * (Real_64(UInt(frac64)) * Math.Pow(2.0, -52)); - } - } - else if (IsOnes(exp64)) - { - if (IsZero(frac64)) - { - type = FPType.FPType_Infinity; - /* value = 2.0^1000000; */ - value = Math.Pow(2.0, 10000); - } - else - { - type = frac64[51] ? FPType.FPType_QNaN : FPType.FPType_SNaN; - value = 0.0; - } - } - else - { - type = FPType.FPType_Nonzero; - value = Math.Pow(2.0, (int)UInt(exp64) - 1023) * (1.0 + Real_64(UInt(frac64)) * Math.Pow(2.0, -52)); - } - - if (sign) - { - value = -value; - } - - return (type, sign, value); - } - - /* shared_pseudocode.html#impl-shared.FPUnpackCV.2 */ - /* shared_pseudocode.html#impl-shared.FPUnpackBase.2 */ - /*public static (FPType, bool, real) FPUnpackCV_16(Bits fpval, Bits _fpcr) - { - int N = fpval.Count; - - // assert N == 16; - - Bits fpcr = new Bits(_fpcr); // Clone. - - fpcr[19] = false; - - return FPUnpackBase_16(fpval, fpcr); - }*/ - public static (FPType, bool, float) FPUnpackCV_32(Bits fpval, Bits _fpcr) - { - return FPUnpack_32(fpval, _fpcr); - } - public static (FPType, bool, double) FPUnpackCV_64(Bits fpval, Bits _fpcr) - { - return FPUnpack_64(fpval, _fpcr); - } -#endregion - -#region "functions/integer/" - /* shared_pseudocode.html#impl-shared.AddWithCarry.3 */ - public static (Bits, Bits) AddWithCarry(int N, Bits x, Bits y, bool carry_in) - { - BigInteger unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in); - BigInteger signed_sum = SInt(x) + SInt(y) + UInt(carry_in); - - Bits result = unsigned_sum.SubBigInteger(N - 1, 0); // same value as signed_sum - - bool n = result[N - 1]; - bool z = IsZero(result); - bool c = !(UInt(result) == unsigned_sum); - bool v = !(SInt(result) == signed_sum); - - return (result, Bits.Concat(n, z, c, v)); - } -#endregion - -#region "functions/registers/" - public static readonly Bits[] _R; - - public static readonly Bits[] _V; - - public static Bits SP_EL0; - public static Bits SP_EL1; - - public static Bits FPCR; // TODO: Add named fields. - // [ 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 22 | 21 20 | 19 | 18 17 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 ] - // [ 0 | 0 | 0 | 0 | 0 | AHP | DN | FZ | RMode | Stride | FZ16 | Len | IDE | 0 | 0 | IXE | UFE | OFE | DZE | IOE | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ] - public static Bits FPSR; // TODO: Add named fields. - // [ 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 ] - // [ N | Z | C | V | QC | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | IDC | 0 | 0 | IXC | UFC | OFC | DZC | IOC ] -#endregion - -#region "functions/system/" - // shared_pseudocode.html#impl-shared.ConditionHolds.1 - public static bool ConditionHolds(Bits cond) - { - bool result; - - // Evaluate base condition. - switch (cond[3, 1]) - { - case Bits bits when bits == "000": - result = (PSTATE.Z == true); // EQ or NE - break; - case Bits bits when bits == "001": - result = (PSTATE.C == true); // CS or CC - break; - case Bits bits when bits == "010": - result = (PSTATE.N == true); // MI or PL - break; - case Bits bits when bits == "011": - result = (PSTATE.V == true); // VS or VC - break; - case Bits bits when bits == "100": - result = (PSTATE.C == true && PSTATE.Z == false); // HI or LS - break; - case Bits bits when bits == "101": - result = (PSTATE.N == PSTATE.V); // GE or LT - break; - case Bits bits when bits == "110": - result = (PSTATE.N == PSTATE.V && PSTATE.Z == false); // GT or LE - break; - default: - case Bits bits when bits == "111": - result = true; // AL - break; - } - - // Condition flag values in the set '111x' indicate always true - // Otherwise, invert condition if necessary. - if (cond[0] == true && cond != "1111") - { - result = !result; - } - - return result; - } - - // shared_pseudocode.html#EL3 - public static readonly Bits EL3 = "11"; - // shared_pseudocode.html#EL2 - public static readonly Bits EL2 = "10"; - // shared_pseudocode.html#EL1 - public static readonly Bits EL1 = "01"; - // shared_pseudocode.html#EL0 - public static readonly Bits EL0 = "00"; - - /* shared_pseudocode.html#impl-shared.HaveEL.1 */ - public static bool HaveEL(Bits el) - { - // TODO: Implement ASL: "IN" as C#: "Bits.In()". - /* if el IN {EL1,EL0} then */ - if (el == EL1 || el == EL0) - { - return true; // EL1 and EL0 must exist - } - - /* return boolean IMPLEMENTATION_DEFINED; */ - return false; - } - - public static ProcState PSTATE; - - /* shared_pseudocode.html#ProcState */ - internal struct ProcState - { - public void NZCV(Bits nzcv) // ASL: ".<,,,>". - { - N = nzcv[3]; - Z = nzcv[2]; - C = nzcv[1]; - V = nzcv[0]; - } - - public void NZCV(bool n, bool z, bool c, bool v) // ASL: ".<,,,>". - { - N = n; - Z = z; - C = c; - V = v; - } - - public bool N; // Negative condition flag - public bool Z; // Zero condition flag - public bool C; // Carry condition flag - public bool V; // oVerflow condition flag - public Bits EL; // Exception Level - public bool SP; // Stack pointer select: 0=SP0, 1=SPx [AArch64 only] - } -#endregion - -#region "functions/vector/" - // shared_pseudocode.html#impl-shared.SatQ.3 - public static (Bits, bool) SatQ(BigInteger i, int N, bool unsigned) - { - (Bits result, bool sat) = (unsigned ? UnsignedSatQ(i, N) : SignedSatQ(i, N)); - - return (result, sat); - } - - // shared_pseudocode.html#impl-shared.SignedSatQ.2 - public static (Bits, bool) SignedSatQ(BigInteger i, int N) - { - BigInteger result; - bool saturated; - - if (i > BigInteger.Pow(2, N - 1) - 1) - { - result = BigInteger.Pow(2, N - 1) - 1; - saturated = true; - } - else if (i < -(BigInteger.Pow(2, N - 1))) - { - result = -(BigInteger.Pow(2, N - 1)); - saturated = true; - } - else - { - result = i; - saturated = false; - } - - return (result.SubBigInteger(N - 1, 0), saturated); - } - - // shared_pseudocode.html#impl-shared.UnsignedSatQ.2 - public static (Bits, bool) UnsignedSatQ(BigInteger i, int N) - { - BigInteger result; - bool saturated; - - if (i > BigInteger.Pow(2, N) - 1) - { - result = BigInteger.Pow(2, N) - 1; - saturated = true; - } - else if (i < (BigInteger)0) - { - result = (BigInteger)0; - saturated = true; - } - else - { - result = i; - saturated = false; - } - - return (result.SubBigInteger(N - 1, 0), saturated); - } -#endregion - } -} diff --git a/Ryujinx.Tests/Cpu/Tester/Types/Bits.cs b/Ryujinx.Tests/Cpu/Tester/Types/Bits.cs deleted file mode 100644 index 87cdfcd2..00000000 --- a/Ryujinx.Tests/Cpu/Tester/Types/Bits.cs +++ /dev/null @@ -1,282 +0,0 @@ -// https://github.com/LDj3SNuD/ARM_v8-A_AArch64_Instructions_Tester/blob/master/Tester/Types/Bits.cs - -// https://github.com/dotnet/corefx/blob/master/src/System.Collections/src/System/Collections/BitArray.cs - -using System; -using System.Collections; -using System.Numerics; - -namespace Ryujinx.Tests.Cpu.Tester.Types -{ - internal sealed class Bits : ICollection, IEnumerable, IEquatable - { - private BitArray bits; - - public Bits(bool[] values) => bits = new BitArray(values); - public Bits(byte[] bytes) => bits = new BitArray(bytes); - public Bits(Bits bits) => this.bits = new BitArray(bits.bits); // Clone: deep copy. - public Bits(int length) => bits = new BitArray(length); - public Bits(int length, bool defaultValue) => bits = new BitArray(length, defaultValue); - private Bits(BitArray bitArray) => bits = new BitArray(bitArray); - public Bits(ulong value) => bits = new BitArray(BitConverter.GetBytes(value)); - public Bits(uint value) => bits = new BitArray(BitConverter.GetBytes(value)); - public Bits(BigInteger value) => bits = new BitArray(value.ToByteArray()); - - private BitArray ToBitArray() => new BitArray(bits); - public ulong ToUInt64() - { - byte[] dst = new byte[8]; - - bits.CopyTo(dst, 0); - - return BitConverter.ToUInt64(dst, 0); - } - public uint ToUInt32() - { - byte[] dst = new byte[4]; - - bits.CopyTo(dst, 0); - - return BitConverter.ToUInt32(dst, 0); - } - public BigInteger ToBigInteger() - { - if (bits.Count != 64 && - bits.Count != 32 && - bits.Count != 16 && - bits.Count != 8) - { - throw new InvalidOperationException(); - } - - byte[] dst = new byte[bits.Count / 8]; - - bits.CopyTo(dst, 0); - - return new BigInteger(dst); - } - - public bool this[int index] // ASL: "<>". - { - get - { - return bits.Get(index); - } - set - { - bits.Set(index, value); - } - } - public Bits this[int highIndex, int lowIndex] // ASL: "<:>". - { - get - { - if (highIndex < lowIndex) - { - throw new IndexOutOfRangeException(); - } - - bool[] dst = new bool[highIndex - lowIndex + 1]; - - for (int i = lowIndex, n = 0; i <= highIndex; i++, n++) - { - dst[n] = bits.Get(i); - } - - return new Bits(dst); - } - set - { - if (highIndex < lowIndex) - { - throw new IndexOutOfRangeException(); - } - - for (int i = lowIndex, n = 0; i <= highIndex; i++, n++) - { - bits.Set(i, value.Get(n)); - } - } - } - - public bool IsReadOnly { get => false; } // Mutable. - public int Count { get => bits.Count; } // Not resizable. - public bool IsSynchronized { get => bits.IsSynchronized; } - public object SyncRoot { get => bits.SyncRoot; } - public Bits And(Bits value) => new Bits(new BitArray(this.bits).And(value.bits)); // Immutable. - public void CopyTo(Array array, int index) => bits.CopyTo(array, index); - public bool Get(int index) => bits.Get(index); - public IEnumerator GetEnumerator() => bits.GetEnumerator(); - //public Bits LeftShift(int count) => new Bits(new BitArray(bits).LeftShift(count)); // Immutable. - public Bits Not() => new Bits(new BitArray(bits).Not()); // Immutable. - public Bits Or(Bits value) => new Bits(new BitArray(this.bits).Or(value.bits)); // Immutable. - //public Bits RightShift(int count) => new Bits(new BitArray(bits).RightShift(count)); // Immutable. - public void Set(int index, bool value) => bits.Set(index, value); - public void SetAll(bool value) => bits.SetAll(value); - public Bits Xor(Bits value) => new Bits(new BitArray(this.bits).Xor(value.bits)); // Immutable. - - public static Bits Concat(Bits highBits, Bits lowBits) // ASL: ":". - { - if (((object)lowBits == null) || ((object)highBits == null)) - { - throw new ArgumentNullException(); - } - - bool[] dst = new bool[lowBits.Count + highBits.Count]; - - lowBits.CopyTo(dst, 0); - highBits.CopyTo(dst, lowBits.Count); - - return new Bits(dst); - } - public static Bits Concat(bool bit3, bool bit2, bool bit1, bool bit0) // ASL: ":::". - { - return new Bits(new bool[] {bit0, bit1, bit2, bit3}); - } - - public static implicit operator Bits(bool value) => new Bits(1, value); - public static implicit operator Bits(string value) - { - if (String.IsNullOrEmpty(value)) - { - throw new InvalidCastException(); - } - - bool[] dst = new bool[value.Length]; - - for (int i = value.Length - 1, n = 0; i >= 0; i--, n++) - { - if (value[i] == '1') - { - dst[n] = true; - } - else if (value[i] == '0') - { - dst[n] = false; - } - else - { - throw new InvalidCastException(); - } - } - - return new Bits(dst); - } - public static explicit operator bool(Bits bit) - { - if (((object)bit == null) || (bit.Count != 1)) - { - throw new InvalidCastException(); - } - - return bit.Get(0); - } - - public static Bits operator +(Bits left, BigInteger right) // ASL: "+". - { - if (((object)left == null) || ((object)right == null)) - { - throw new ArgumentNullException(); - } - - BigInteger dst = left.ToBigInteger() + right; - - return dst.SubBigInteger(left.Count - 1, 0); - } - public static Bits operator +(Bits left, Bits right) // ASL: "+". - { - if (((object)left == null) || ((object)right == null)) - { - throw new ArgumentNullException(); - } - - if (left.Count != right.Count) - { - throw new InvalidOperationException(); - } - - BigInteger dst = left.ToBigInteger() + right.ToBigInteger(); - - return dst.SubBigInteger(left.Count - 1, 0); - } - public static Bits operator -(Bits left, Bits right) // ASL: "-". - { - if (((object)left == null) || ((object)right == null)) - { - throw new ArgumentNullException(); - } - - if (left.Count != right.Count) - { - throw new InvalidOperationException(); - } - - BigInteger dst = left.ToBigInteger() - right.ToBigInteger(); - - return dst.SubBigInteger(left.Count - 1, 0); - } - public static bool operator ==(Bits left, Bits right) // ASL: "==". - { - if (((object)left == null) || ((object)right == null)) - { - throw new ArgumentNullException(); - } - - if (left.Count != right.Count) - { - return false; - } - - for (int i = 0; i <= left.Count - 1; i++) - { - if (left.Get(i) != right.Get(i)) - { - return false; - } - } - - return true; - } - public static bool operator !=(Bits left, Bits right) // ASL: "!=". - { - return !(left == right); - } - - public bool Equals(Bits right) // ASL: "==". - { - if ((object)right == null) - { - throw new ArgumentNullException(); - } - - Bits left = this; - - if (left.Count != right.Count) - { - return false; - } - - for (int i = 0; i <= left.Count - 1; i++) - { - if (left.Get(i) != right.Get(i)) - { - return false; - } - } - - return true; - } - public override bool Equals(object obj) - { - if (obj == null) - { - throw new ArgumentNullException(); - } - - Bits right = obj as Bits; - - return Equals(right); - } - public override int GetHashCode() => bits.GetHashCode(); - } -} diff --git a/Ryujinx.Tests/Cpu/Tester/Types/Integer.cs b/Ryujinx.Tests/Cpu/Tester/Types/Integer.cs deleted file mode 100644 index 49ba260c..00000000 --- a/Ryujinx.Tests/Cpu/Tester/Types/Integer.cs +++ /dev/null @@ -1,42 +0,0 @@ -// https://github.com/LDj3SNuD/ARM_v8-A_AArch64_Instructions_Tester/blob/master/Tester/Types/Integer.cs - -using System; -using System.Numerics; - -namespace Ryujinx.Tests.Cpu.Tester.Types -{ - internal static class Integer - { - public static Bits SubBigInteger(this BigInteger x, int highIndex, int lowIndex) // ASL: "<:>". - { - if (highIndex < lowIndex) - { - throw new IndexOutOfRangeException(); - } - - Bits src = new Bits(x); - bool[] dst = new bool[highIndex - lowIndex + 1]; - - for (int i = lowIndex, n = 0; i <= highIndex; i++, n++) - { - if (i <= src.Count - 1) - { - dst[n] = src[i]; - } - else - { - dst[n] = (x.Sign != -1 ? false : true); // Zero / Sign Extension. - } - } - - return new Bits(dst); - } - - public static bool SubBigInteger(this BigInteger x, int index) // ASL: "<>". - { - Bits dst = x.SubBigInteger(index, index); - - return (bool)dst; - } - } -}