Просмотр исходного кода

Ryujinx.Tests: Add unicorn to test framework (#389)

* Ryujinx.Tests: Add unicorn to test framework

* CpuTestSimdArithmetic: Comment out inaccurate results
Merry 7 лет назад
Родитель
Сommit
326777ca4a
31 измененных файлов с 1345 добавлено и 1 удалено
  1. 28 0
      Ryujinx.Tests.Unicorn/IndexedProperty.cs
  2. 13 0
      Ryujinx.Tests.Unicorn/MemoryPermission.cs
  3. 296 0
      Ryujinx.Tests.Unicorn/Native/ArmRegister.cs
  4. 68 0
      Ryujinx.Tests.Unicorn/Native/Interface.cs
  5. 16 0
      Ryujinx.Tests.Unicorn/Native/UnicornArch.cs
  6. 13 0
      Ryujinx.Tests.Unicorn/Native/UnicornMemoryRegion.cs
  7. 34 0
      Ryujinx.Tests.Unicorn/Native/UnicornMode.cs
  8. 18 0
      Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj
  9. 315 0
      Ryujinx.Tests.Unicorn/UnicornAArch64.cs
  10. 30 0
      Ryujinx.Tests.Unicorn/UnicornError.cs
  11. 23 0
      Ryujinx.Tests.Unicorn/UnicornException.cs
  12. 3 0
      Ryujinx.Tests.Unicorn/libs/README.md
  13. BIN
      Ryujinx.Tests.Unicorn/libs/windows/unicorn.dll
  14. 130 1
      Ryujinx.Tests/Cpu/CpuTest.cs
  15. 10 0
      Ryujinx.Tests/Cpu/CpuTestAlu.cs
  16. 20 0
      Ryujinx.Tests/Cpu/CpuTestAluImm.cs
  17. 54 0
      Ryujinx.Tests/Cpu/CpuTestAluRs.cs
  18. 28 0
      Ryujinx.Tests/Cpu/CpuTestAluRx.cs
  19. 6 0
      Ryujinx.Tests/Cpu/CpuTestBfm.cs
  20. 4 0
      Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs
  21. 4 0
      Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs
  22. 8 0
      Ryujinx.Tests/Cpu/CpuTestCsel.cs
  23. 6 0
      Ryujinx.Tests/Cpu/CpuTestMov.cs
  24. 10 0
      Ryujinx.Tests/Cpu/CpuTestMul.cs
  25. 72 0
      Ryujinx.Tests/Cpu/CpuTestSimd.cs
  26. 21 0
      Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs
  27. 10 0
      Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs
  28. 4 0
      Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs
  29. 1 0
      Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs
  30. 89 0
      Ryujinx.Tests/Cpu/CpuTestSimdReg.cs
  31. 11 0
      Ryujinx.Tests/Ryujinx.Tests.csproj

+ 28 - 0
Ryujinx.Tests.Unicorn/IndexedProperty.cs

@@ -0,0 +1,28 @@
+using System;
+
+namespace Ryujinx.Tests.Unicorn
+{
+    public class IndexedProperty<TIndex, TValue>
+    {
+        readonly Action<TIndex, TValue> SetAction;
+        readonly Func<TIndex, TValue> GetFunc;
+
+        public IndexedProperty(Func<TIndex, TValue> getFunc, Action<TIndex, TValue> setAction)
+        {
+            this.GetFunc = getFunc;
+            this.SetAction = setAction;
+        }
+
+        public TValue this[TIndex i]
+        {
+            get
+            {
+                return GetFunc(i);
+            }
+            set
+            {
+                SetAction(i, value);
+            }
+        }
+    }
+}

+ 13 - 0
Ryujinx.Tests.Unicorn/MemoryPermission.cs

@@ -0,0 +1,13 @@
+using System;
+
+namespace Ryujinx.Tests.Unicorn
+{
+    public enum MemoryPermission
+    {
+        NONE = 0,
+        READ = 1,
+        WRITE = 2,
+        EXEC = 4,
+        ALL = 7,
+    }
+}

+ 296 - 0
Ryujinx.Tests.Unicorn/Native/ArmRegister.cs

@@ -0,0 +1,296 @@
+using System;
+
+namespace Ryujinx.Tests.Unicorn.Native
+{
+    public enum ArmRegister
+    {
+        INVALID = 0,
+
+        X29,
+        X30,
+        NZCV,
+        SP,
+        WSP,
+        WZR,
+        XZR,
+        B0,
+        B1,
+        B2,
+        B3,
+        B4,
+        B5,
+        B6,
+        B7,
+        B8,
+        B9,
+        B10,
+        B11,
+        B12,
+        B13,
+        B14,
+        B15,
+        B16,
+        B17,
+        B18,
+        B19,
+        B20,
+        B21,
+        B22,
+        B23,
+        B24,
+        B25,
+        B26,
+        B27,
+        B28,
+        B29,
+        B30,
+        B31,
+        D0,
+        D1,
+        D2,
+        D3,
+        D4,
+        D5,
+        D6,
+        D7,
+        D8,
+        D9,
+        D10,
+        D11,
+        D12,
+        D13,
+        D14,
+        D15,
+        D16,
+        D17,
+        D18,
+        D19,
+        D20,
+        D21,
+        D22,
+        D23,
+        D24,
+        D25,
+        D26,
+        D27,
+        D28,
+        D29,
+        D30,
+        D31,
+        H0,
+        H1,
+        H2,
+        H3,
+        H4,
+        H5,
+        H6,
+        H7,
+        H8,
+        H9,
+        H10,
+        H11,
+        H12,
+        H13,
+        H14,
+        H15,
+        H16,
+        H17,
+        H18,
+        H19,
+        H20,
+        H21,
+        H22,
+        H23,
+        H24,
+        H25,
+        H26,
+        H27,
+        H28,
+        H29,
+        H30,
+        H31,
+        Q0,
+        Q1,
+        Q2,
+        Q3,
+        Q4,
+        Q5,
+        Q6,
+        Q7,
+        Q8,
+        Q9,
+        Q10,
+        Q11,
+        Q12,
+        Q13,
+        Q14,
+        Q15,
+        Q16,
+        Q17,
+        Q18,
+        Q19,
+        Q20,
+        Q21,
+        Q22,
+        Q23,
+        Q24,
+        Q25,
+        Q26,
+        Q27,
+        Q28,
+        Q29,
+        Q30,
+        Q31,
+        S0,
+        S1,
+        S2,
+        S3,
+        S4,
+        S5,
+        S6,
+        S7,
+        S8,
+        S9,
+        S10,
+        S11,
+        S12,
+        S13,
+        S14,
+        S15,
+        S16,
+        S17,
+        S18,
+        S19,
+        S20,
+        S21,
+        S22,
+        S23,
+        S24,
+        S25,
+        S26,
+        S27,
+        S28,
+        S29,
+        S30,
+        S31,
+        W0,
+        W1,
+        W2,
+        W3,
+        W4,
+        W5,
+        W6,
+        W7,
+        W8,
+        W9,
+        W10,
+        W11,
+        W12,
+        W13,
+        W14,
+        W15,
+        W16,
+        W17,
+        W18,
+        W19,
+        W20,
+        W21,
+        W22,
+        W23,
+        W24,
+        W25,
+        W26,
+        W27,
+        W28,
+        W29,
+        W30,
+        X0,
+        X1,
+        X2,
+        X3,
+        X4,
+        X5,
+        X6,
+        X7,
+        X8,
+        X9,
+        X10,
+        X11,
+        X12,
+        X13,
+        X14,
+        X15,
+        X16,
+        X17,
+        X18,
+        X19,
+        X20,
+        X21,
+        X22,
+        X23,
+        X24,
+        X25,
+        X26,
+        X27,
+        X28,
+
+        V0,
+        V1,
+        V2,
+        V3,
+        V4,
+        V5,
+        V6,
+        V7,
+        V8,
+        V9,
+        V10,
+        V11,
+        V12,
+        V13,
+        V14,
+        V15,
+        V16,
+        V17,
+        V18,
+        V19,
+        V20,
+        V21,
+        V22,
+        V23,
+        V24,
+        V25,
+        V26,
+        V27,
+        V28,
+        V29,
+        V30,
+        V31,
+
+        //> pseudo registers
+        PC,            // program counter register
+
+        CPACR_EL1,
+        ESR,
+
+        //> thread registers
+        TPIDR_EL0,
+        TPIDRRO_EL0,
+        TPIDR_EL1,
+
+        PSTATE,        // PSTATE pseudoregister
+
+        //> floating point control and status registers
+        FPCR,
+        FPSR,
+
+        ENDING,        // <-- mark the end of the list of registers
+
+        //> alias registers
+
+        IP0 =   X16,
+        IP1 =   X17,
+        FP =    X29,
+        LR =    X30,
+    }
+}

+ 68 - 0
Ryujinx.Tests.Unicorn/Native/Interface.cs

@@ -0,0 +1,68 @@
+using System;
+using System.Runtime.InteropServices;
+using Ryujinx.Tests.Unicorn;
+
+namespace Ryujinx.Tests.Unicorn.Native
+{
+    public class Interface
+    {
+        public static void Checked(UnicornError error)
+        {
+            if (error != UnicornError.UC_ERR_OK)
+            {
+                throw new UnicornException(error);
+            }
+        }
+
+        public static void MarshalArrayOf<T>(IntPtr input, int length, out T[] output)
+        {
+            var size = Marshal.SizeOf(typeof(T));
+            output = new T[length];
+
+            for (int i = 0; i < length; i++)
+            {
+                IntPtr item = new IntPtr(input.ToInt64() + i * size);
+                output[i] = Marshal.PtrToStructure<T>(item);
+            }
+         }
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern uint uc_version(out uint major, out uint minor);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_open(uint arch, uint mode, out IntPtr uc);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_close(IntPtr uc);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern IntPtr uc_strerror(UnicornError err);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_reg_write(IntPtr uc, int regid, byte[] value);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_reg_read(IntPtr uc, int regid, byte[] value);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_mem_write(IntPtr uc, ulong address, byte[] bytes, ulong size);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_mem_read(IntPtr uc, ulong address, byte[] bytes, ulong size);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_emu_start(IntPtr uc, ulong begin, ulong until, ulong timeout, ulong count);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_mem_map(IntPtr uc, ulong address, ulong size, uint perms);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_mem_unmap(IntPtr uc, ulong address, ulong size);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_mem_protect(IntPtr uc, ulong address, ulong size, uint perms);
+
+        [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)]
+        public static extern UnicornError uc_mem_regions(IntPtr uc, out IntPtr regions, out uint count);
+    }
+}

+ 16 - 0
Ryujinx.Tests.Unicorn/Native/UnicornArch.cs

@@ -0,0 +1,16 @@
+using System;
+
+namespace Ryujinx.Tests.Unicorn.Native
+{
+    public enum UnicornArch
+    {
+        UC_ARCH_ARM = 1,    // ARM architecture (including Thumb, Thumb-2)
+        UC_ARCH_ARM64,      // ARM-64, also called AArch64
+        UC_ARCH_MIPS,       // Mips architecture
+        UC_ARCH_X86,        // X86 architecture (including x86 & x86-64)
+        UC_ARCH_PPC,        // PowerPC architecture (currently unsupported)
+        UC_ARCH_SPARC,      // Sparc architecture
+        UC_ARCH_M68K,       // M68K architecture
+        UC_ARCH_MAX,
+    }
+}

+ 13 - 0
Ryujinx.Tests.Unicorn/Native/UnicornMemoryRegion.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Tests.Unicorn.Native
+{
+    [StructLayout(LayoutKind.Sequential)]
+    public struct UnicornMemoryRegion
+    {
+        public UInt64 begin; // begin address of the region (inclusive)
+        public UInt64 end;   // end address of the region (inclusive)
+        public UInt32 perms; // memory permissions of the region
+    }
+}

+ 34 - 0
Ryujinx.Tests.Unicorn/Native/UnicornMode.cs

@@ -0,0 +1,34 @@
+using System;
+
+namespace Ryujinx.Tests.Unicorn.Native
+{
+    public enum UnicornMode
+    {
+        UC_MODE_LITTLE_ENDIAN = 0,    // little-endian mode (default mode)
+        UC_MODE_BIG_ENDIAN = 1 << 30, // big-endian mode
+        // arm / arm64
+        UC_MODE_ARM = 0,              // ARM mode
+        UC_MODE_THUMB = 1 << 4,       // THUMB mode (including Thumb-2)
+        UC_MODE_MCLASS = 1 << 5,      // ARM's Cortex-M series (currently unsupported)
+        UC_MODE_V8 = 1 << 6,          // ARMv8 A32 encodings for ARM (currently unsupported)
+        // mips
+        UC_MODE_MICRO = 1 << 4,       // MicroMips mode (currently unsupported)
+        UC_MODE_MIPS3 = 1 << 5,       // Mips III ISA (currently unsupported)
+        UC_MODE_MIPS32R6 = 1 << 6,    // Mips32r6 ISA (currently unsupported)
+        UC_MODE_MIPS32 = 1 << 2,      // Mips32 ISA
+        UC_MODE_MIPS64 = 1 << 3,      // Mips64 ISA
+        // x86 / x64
+        UC_MODE_16 = 1 << 1,          // 16-bit mode
+        UC_MODE_32 = 1 << 2,          // 32-bit mode
+        UC_MODE_64 = 1 << 3,          // 64-bit mode
+        // ppc
+        UC_MODE_PPC32 = 1 << 2,       // 32-bit mode (currently unsupported)
+        UC_MODE_PPC64 = 1 << 3,       // 64-bit mode (currently unsupported)
+        UC_MODE_QPX = 1 << 4,         // Quad Processing eXtensions mode (currently unsupported)
+        // sparc
+        UC_MODE_SPARC32 = 1 << 2,     // 32-bit mode
+        UC_MODE_SPARC64 = 1 << 3,     // 64-bit mode
+        UC_MODE_V9 = 1 << 4,          // SparcV9 mode (currently unsupported)
+        // m68k
+    }
+}

+ 18 - 0
Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj

@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+    <RuntimeIdentifiers>win10-x64;osx-x64;linux-x64</RuntimeIdentifiers>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+
+  <PropertyGroup>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
+    <PackageReference Include="System.Runtime.Intrinsics.Experimental" Version="4.5.0-rc1" />
+  </ItemGroup>
+
+</Project>

+ 315 - 0
Ryujinx.Tests.Unicorn/UnicornAArch64.cs

@@ -0,0 +1,315 @@
+using System;
+using System.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace Ryujinx.Tests.Unicorn
+{
+    public class UnicornAArch64
+    {
+        internal readonly IntPtr uc;
+
+        public IndexedProperty<int, ulong> X
+        {
+            get
+            {
+                return new IndexedProperty<int, ulong>(
+                    (int i) => GetX(i),
+                    (int i, ulong value) => SetX(i, value));
+            }
+        }
+
+        public IndexedProperty<int, Vector128<float>> Q
+        {
+            get
+            {
+                return new IndexedProperty<int, Vector128<float>>(
+                    (int i) => GetQ(i),
+                    (int i, Vector128<float> value) => SetQ(i, value));
+            }
+        }
+
+        public ulong LR
+        {
+            get { return GetRegister(Native.ArmRegister.LR); }
+            set { SetRegister(Native.ArmRegister.LR, value); }
+        }
+
+        public ulong SP
+        {
+            get { return GetRegister(Native.ArmRegister.SP); }
+            set { SetRegister(Native.ArmRegister.SP, value); }
+        }
+
+        public ulong PC
+        {
+            get { return GetRegister(Native.ArmRegister.PC); }
+            set { SetRegister(Native.ArmRegister.PC, value); }
+        }
+
+        public uint Pstate
+        {
+            get { return (uint)GetRegister(Native.ArmRegister.PSTATE); }
+            set { SetRegister(Native.ArmRegister.PSTATE, (uint)value); }
+        }
+
+        public int Fpcr
+        {
+            get { return (int)GetRegister(Native.ArmRegister.FPCR); }
+            set { SetRegister(Native.ArmRegister.FPCR, (uint)value); }
+        }
+
+        public int Fpsr
+        {
+            get { return (int)GetRegister(Native.ArmRegister.FPSR); }
+            set { SetRegister(Native.ArmRegister.FPSR, (uint)value); }
+        }
+
+        public bool OverflowFlag
+        {
+            get { return (Pstate & 0x10000000u) != 0; }
+            set { Pstate = (Pstate & ~0x10000000u) | (value ? 0x10000000u : 0u); }
+        }
+
+        public bool CarryFlag
+        {
+            get { return (Pstate & 0x20000000u) != 0; }
+            set { Pstate = (Pstate & ~0x20000000u) | (value ? 0x20000000u : 0u); }
+        }
+
+        public bool ZeroFlag
+        {
+            get { return (Pstate & 0x40000000u) != 0; }
+            set { Pstate = (Pstate & ~0x40000000u) | (value ? 0x40000000u : 0u); }
+        }
+
+        public bool NegativeFlag
+        {
+            get { return (Pstate & 0x80000000u) != 0; }
+            set { Pstate = (Pstate & ~0x80000000u) | (value ? 0x80000000u : 0u); }
+        }
+
+        public UnicornAArch64()
+        {
+            Native.Interface.Checked(Native.Interface.uc_open((uint)Native.UnicornArch.UC_ARCH_ARM64, (uint)Native.UnicornMode.UC_MODE_LITTLE_ENDIAN, out uc));
+            SetRegister(Native.ArmRegister.CPACR_EL1, 0x00300000);
+        }
+
+        ~UnicornAArch64()
+        {
+            Native.Interface.Checked(Native.Interface.uc_close(uc));
+        }
+
+        public void RunForCount(ulong count)
+        {
+            Native.Interface.Checked(Native.Interface.uc_emu_start(uc, this.PC, 0xFFFFFFFFFFFFFFFFu, 0, count));
+        }
+
+        public void Step()
+        {
+            RunForCount(1);
+        }
+
+        internal static Native.ArmRegister[] X_registers = new Native.ArmRegister[31]
+        {
+            Native.ArmRegister.X0,
+            Native.ArmRegister.X1,
+            Native.ArmRegister.X2,
+            Native.ArmRegister.X3,
+            Native.ArmRegister.X4,
+            Native.ArmRegister.X5,
+            Native.ArmRegister.X6,
+            Native.ArmRegister.X7,
+            Native.ArmRegister.X8,
+            Native.ArmRegister.X9,
+            Native.ArmRegister.X10,
+            Native.ArmRegister.X11,
+            Native.ArmRegister.X12,
+            Native.ArmRegister.X13,
+            Native.ArmRegister.X14,
+            Native.ArmRegister.X15,
+            Native.ArmRegister.X16,
+            Native.ArmRegister.X17,
+            Native.ArmRegister.X18,
+            Native.ArmRegister.X19,
+            Native.ArmRegister.X20,
+            Native.ArmRegister.X21,
+            Native.ArmRegister.X22,
+            Native.ArmRegister.X23,
+            Native.ArmRegister.X24,
+            Native.ArmRegister.X25,
+            Native.ArmRegister.X26,
+            Native.ArmRegister.X27,
+            Native.ArmRegister.X28,
+            Native.ArmRegister.X29,
+            Native.ArmRegister.X30,
+        };
+
+        internal static Native.ArmRegister[] Q_registers = new Native.ArmRegister[32]
+        {
+            Native.ArmRegister.Q0,
+            Native.ArmRegister.Q1,
+            Native.ArmRegister.Q2,
+            Native.ArmRegister.Q3,
+            Native.ArmRegister.Q4,
+            Native.ArmRegister.Q5,
+            Native.ArmRegister.Q6,
+            Native.ArmRegister.Q7,
+            Native.ArmRegister.Q8,
+            Native.ArmRegister.Q9,
+            Native.ArmRegister.Q10,
+            Native.ArmRegister.Q11,
+            Native.ArmRegister.Q12,
+            Native.ArmRegister.Q13,
+            Native.ArmRegister.Q14,
+            Native.ArmRegister.Q15,
+            Native.ArmRegister.Q16,
+            Native.ArmRegister.Q17,
+            Native.ArmRegister.Q18,
+            Native.ArmRegister.Q19,
+            Native.ArmRegister.Q20,
+            Native.ArmRegister.Q21,
+            Native.ArmRegister.Q22,
+            Native.ArmRegister.Q23,
+            Native.ArmRegister.Q24,
+            Native.ArmRegister.Q25,
+            Native.ArmRegister.Q26,
+            Native.ArmRegister.Q27,
+            Native.ArmRegister.Q28,
+            Native.ArmRegister.Q29,
+            Native.ArmRegister.Q30,
+            Native.ArmRegister.Q31,
+        };
+
+        internal ulong GetRegister(Native.ArmRegister register)
+        {
+            byte[] value_bytes = new byte[8];
+            Native.Interface.Checked(Native.Interface.uc_reg_read(uc, (int)register, value_bytes));
+            return (ulong)BitConverter.ToInt64(value_bytes, 0);
+        }
+
+        internal void SetRegister(Native.ArmRegister register, ulong value)
+        {
+            byte[] value_bytes = BitConverter.GetBytes(value);
+            Native.Interface.Checked(Native.Interface.uc_reg_write(uc, (int)register, value_bytes));
+        }
+
+        internal Vector128<float> GetVector(Native.ArmRegister register)
+        {
+            byte[] value_bytes = new byte[16];
+            Native.Interface.Checked(Native.Interface.uc_reg_read(uc, (int)register, value_bytes));
+            unsafe
+            {
+                fixed (byte* p = &value_bytes[0])
+                {
+                    return Sse.LoadVector128((float*)p);
+                }
+            }
+        }
+
+        internal void SetVector(Native.ArmRegister register, Vector128<float> value)
+        {
+            byte[] value_bytes = new byte[16];
+            unsafe
+            {
+                fixed (byte* p = &value_bytes[0])
+                {
+                    Sse.Store((float*)p, value);
+                }
+            }
+            Native.Interface.Checked(Native.Interface.uc_reg_write(uc, (int)register, value_bytes));
+        }
+
+        public ulong GetX(int index)
+        {
+            Contract.Requires(index <= 30, "invalid register");
+
+            return GetRegister(X_registers[index]);
+        }
+
+        public void SetX(int index, ulong value)
+        {
+            Contract.Requires(index <= 30, "invalid register");
+
+            SetRegister(X_registers[index], value);
+        }
+
+        public Vector128<float> GetQ(int index)
+        {
+            Contract.Requires(index <= 31, "invalid vector");
+
+            return GetVector(Q_registers[index]);
+        }
+
+        public void SetQ(int index, Vector128<float> value)
+        {
+            Contract.Requires(index <= 31, "invalid vector");
+
+            SetVector(Q_registers[index], value);
+        }
+
+        public byte[] MemoryRead(ulong address, ulong size)
+        {
+            byte[] value = new byte[size];
+            Native.Interface.Checked(Native.Interface.uc_mem_read(uc, address, value, size));
+            return value;
+        }
+
+        public byte   MemoryRead8 (ulong address) { return MemoryRead(address, 1)[0]; }
+        public UInt16 MemoryRead16(ulong address) { return (UInt16)BitConverter.ToInt16(MemoryRead(address, 2), 0); }
+        public UInt32 MemoryRead32(ulong address) { return (UInt32)BitConverter.ToInt32(MemoryRead(address, 4), 0); }
+        public UInt64 MemoryRead64(ulong address) { return (UInt64)BitConverter.ToInt64(MemoryRead(address, 8), 0); }
+
+        public void MemoryWrite(ulong address, byte[] value)
+        {
+            Native.Interface.Checked(Native.Interface.uc_mem_write(uc, address, value, (ulong)value.Length));
+        }
+
+        public void MemoryWrite8 (ulong address, byte value)   { MemoryWrite(address, new byte[]{value}); }
+        public void MemoryWrite16(ulong address, Int16 value)  { MemoryWrite(address, BitConverter.GetBytes(value)); }
+        public void MemoryWrite16(ulong address, UInt16 value) { MemoryWrite(address, BitConverter.GetBytes(value)); }
+        public void MemoryWrite32(ulong address, Int32 value)  { MemoryWrite(address, BitConverter.GetBytes(value)); }
+        public void MemoryWrite32(ulong address, UInt32 value) { MemoryWrite(address, BitConverter.GetBytes(value)); }
+        public void MemoryWrite64(ulong address, Int64 value)  { MemoryWrite(address, BitConverter.GetBytes(value)); }
+        public void MemoryWrite64(ulong address, UInt64 value) { MemoryWrite(address, BitConverter.GetBytes(value)); }
+
+        public void MemoryMap(ulong address, ulong size, MemoryPermission permissions)
+        {
+            Native.Interface.Checked(Native.Interface.uc_mem_map(uc, address, size, (uint)permissions));
+        }
+
+        public void MemoryUnmap(ulong address, ulong size)
+        {
+            Native.Interface.Checked(Native.Interface.uc_mem_unmap(uc, address, size));
+        }
+
+        public void MemoryProtect(ulong address, ulong size, MemoryPermission permissions)
+        {
+            Native.Interface.Checked(Native.Interface.uc_mem_protect(uc, address, size, (uint)permissions));
+        }
+
+        public void DumpMemoryInformation()
+        {
+            Native.Interface.Checked(Native.Interface.uc_mem_regions(uc, out IntPtr regions_raw, out uint length));
+            Native.Interface.MarshalArrayOf<Native.UnicornMemoryRegion>(regions_raw, (int)length, out var regions);
+            foreach (var region in regions)
+            {
+                Console.WriteLine("region: begin {0:X16} end {1:X16} perms {2:X8}", region.begin, region.end, region.perms);
+            }
+        }
+
+        public static bool IsAvailable()
+        {
+            try
+            {
+                Native.Interface.uc_version(out uint major, out uint minor);
+                return true;
+            }
+            catch (DllNotFoundException)
+            {
+                return false;
+            }
+        }
+    }
+}

+ 30 - 0
Ryujinx.Tests.Unicorn/UnicornError.cs

@@ -0,0 +1,30 @@
+using System;
+
+namespace Ryujinx.Tests.Unicorn
+{
+    public enum UnicornError
+    {
+        UC_ERR_OK = 0,             // No error: everything was fine
+        UC_ERR_NOMEM,              // Out-Of-Memory error: uc_open(), uc_emulate()
+        UC_ERR_ARCH,               // Unsupported architecture: uc_open()
+        UC_ERR_HANDLE,             // Invalid handle
+        UC_ERR_MODE,               // Invalid/unsupported mode: uc_open()
+        UC_ERR_VERSION,            // Unsupported version (bindings)
+        UC_ERR_READ_UNMAPPED,      // Quit emulation due to READ on unmapped memory: uc_emu_start()
+        UC_ERR_WRITE_UNMAPPED,     // Quit emulation due to WRITE on unmapped memory: uc_emu_start()
+        UC_ERR_FETCH_UNMAPPED,     // Quit emulation due to FETCH on unmapped memory: uc_emu_start()
+        UC_ERR_HOOK,               // Invalid hook type: uc_hook_add()
+        UC_ERR_INSN_INVALID,       // Quit emulation due to invalid instruction: uc_emu_start()
+        UC_ERR_MAP,                // Invalid memory mapping: uc_mem_map()
+        UC_ERR_WRITE_PROT,         // Quit emulation due to UC_MEM_WRITE_PROT violation: uc_emu_start()
+        UC_ERR_READ_PROT,          // Quit emulation due to UC_MEM_READ_PROT violation: uc_emu_start()
+        UC_ERR_FETCH_PROT,         // Quit emulation due to UC_MEM_FETCH_PROT violation: uc_emu_start()
+        UC_ERR_ARG,                // Inavalid argument provided to uc_xxx function (See specific function API)
+        UC_ERR_READ_UNALIGNED,     // Unaligned read
+        UC_ERR_WRITE_UNALIGNED,    // Unaligned write
+        UC_ERR_FETCH_UNALIGNED,    // Unaligned fetch
+        UC_ERR_HOOK_EXIST,         // hook for this event already existed
+        UC_ERR_RESOURCE,           // Insufficient resource: uc_emu_start()
+        UC_ERR_EXCEPTION           // Unhandled CPU exception
+    }
+}

+ 23 - 0
Ryujinx.Tests.Unicorn/UnicornException.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Tests.Unicorn
+{
+    public class UnicornException : Exception
+    {
+        public readonly UnicornError Error;
+
+        internal UnicornException(UnicornError error)
+        {
+            Error = error;
+        }
+
+        public override string Message
+        {
+            get
+            {
+                return Marshal.PtrToStringAnsi(Native.Interface.uc_strerror(Error));
+            }
+        }
+    }
+}

+ 3 - 0
Ryujinx.Tests.Unicorn/libs/README.md

@@ -0,0 +1,3 @@
+The pre-compiled dynamic libraries in this directory are licenced under the GPLv2.
+
+The source code for windows/unicorn.dll is available at: https://github.com/MerryMage/UnicornDotNet/tree/299451c02d9c810d2feca51f5e9cb6d8b2f38960

BIN
Ryujinx.Tests.Unicorn/libs/windows/unicorn.dll


+ 130 - 1
Ryujinx.Tests/Cpu/CpuTest.cs

@@ -4,6 +4,8 @@ using ChocolArm64.State;
 
 using NUnit.Framework;
 
+using Ryujinx.Tests.Unicorn;
+
 using System;
 using System.Runtime.InteropServices;
 using System.Runtime.Intrinsics;
@@ -25,10 +27,22 @@ namespace Ryujinx.Tests.Cpu
         private AMemory Memory;
         private AThread Thread;
 
+        private static bool UnicornAvailable;
+        private UnicornAArch64 UnicornEmu;
+
+        static CpuTest()
+        {
+            UnicornAvailable = UnicornAArch64.IsAvailable();
+            if (!UnicornAvailable)
+            {
+                Console.WriteLine("WARNING: Could not find unicorn");
+            }
+        }
+
         [SetUp]
         public void Setup()
         {
-            Position = 0x0;
+            Position = 0x1000;
             Size = 0x1000;
 
             EntryPoint = Position;
@@ -38,6 +52,13 @@ namespace Ryujinx.Tests.Cpu
             Memory = new AMemory(RamPointer);
             Memory.Map(Position, 0, Size);
             Thread = new AThread(Translator, Memory, EntryPoint);
+
+            if (UnicornAvailable)
+            {
+                UnicornEmu = new UnicornAArch64();
+                UnicornEmu.MemoryMap((ulong)Position, (ulong)Size, MemoryPermission.READ | MemoryPermission.EXEC);
+                UnicornEmu.PC = (ulong)EntryPoint;
+            }
         }
 
         [TearDown]
@@ -46,6 +67,7 @@ namespace Ryujinx.Tests.Cpu
             Marshal.FreeHGlobal(RamPointer);
             Memory = null;
             Thread = null;
+            UnicornEmu = null;
         }
 
         protected void Reset()
@@ -57,6 +79,10 @@ namespace Ryujinx.Tests.Cpu
         protected void Opcode(uint Opcode)
         {
             Thread.Memory.WriteUInt32(Position, Opcode);
+            if (UnicornAvailable)
+            {
+                UnicornEmu.MemoryWrite32((ulong)Position, Opcode);
+            }
             Position += 4;
         }
 
@@ -81,6 +107,24 @@ namespace Ryujinx.Tests.Cpu
             Thread.ThreadState.Negative = Negative;
             Thread.ThreadState.Fpcr = Fpcr;
             Thread.ThreadState.Fpsr = Fpsr;
+
+            if (UnicornAvailable)
+            {
+                UnicornEmu.X[0] = X0;
+                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.NegativeFlag = Negative;
+                UnicornEmu.Fpcr = Fpcr;
+                UnicornEmu.Fpsr = Fpsr;
+            }
         }
 
         protected void ExecuteOpcodes()
@@ -93,6 +137,11 @@ namespace Ryujinx.Tests.Cpu
                 Thread.Execute();
                 Wait.WaitOne();
             }
+
+            if (UnicornAvailable)
+            {
+                UnicornEmu.RunForCount((ulong)(Position - EntryPoint - 8) / 4);
+            }
         }
 
         protected AThreadState GetThreadState()
@@ -117,6 +166,86 @@ namespace Ryujinx.Tests.Cpu
             return GetThreadState();
         }
 
+        protected void CompareAgainstUnicorn()
+        {
+            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.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]));
+            Assert.That(Thread.ThreadState.X13, Is.EqualTo(UnicornEmu.X[13]));
+            Assert.That(Thread.ThreadState.X14, Is.EqualTo(UnicornEmu.X[14]));
+            Assert.That(Thread.ThreadState.X15, Is.EqualTo(UnicornEmu.X[15]));
+            Assert.That(Thread.ThreadState.X16, Is.EqualTo(UnicornEmu.X[16]));
+            Assert.That(Thread.ThreadState.X17, Is.EqualTo(UnicornEmu.X[17]));
+            Assert.That(Thread.ThreadState.X18, Is.EqualTo(UnicornEmu.X[18]));
+            Assert.That(Thread.ThreadState.X19, Is.EqualTo(UnicornEmu.X[19]));
+            Assert.That(Thread.ThreadState.X20, Is.EqualTo(UnicornEmu.X[20]));
+            Assert.That(Thread.ThreadState.X21, Is.EqualTo(UnicornEmu.X[21]));
+            Assert.That(Thread.ThreadState.X22, Is.EqualTo(UnicornEmu.X[22]));
+            Assert.That(Thread.ThreadState.X23, Is.EqualTo(UnicornEmu.X[23]));
+            Assert.That(Thread.ThreadState.X24, Is.EqualTo(UnicornEmu.X[24]));
+            Assert.That(Thread.ThreadState.X25, Is.EqualTo(UnicornEmu.X[25]));
+            Assert.That(Thread.ThreadState.X26, Is.EqualTo(UnicornEmu.X[26]));
+            Assert.That(Thread.ThreadState.X27, Is.EqualTo(UnicornEmu.X[27]));
+            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.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]));
+            Assert.That(Thread.ThreadState.V13, Is.EqualTo(UnicornEmu.Q[13]));
+            Assert.That(Thread.ThreadState.V14, Is.EqualTo(UnicornEmu.Q[14]));
+            Assert.That(Thread.ThreadState.V15, Is.EqualTo(UnicornEmu.Q[15]));
+            Assert.That(Thread.ThreadState.V16, Is.EqualTo(UnicornEmu.Q[16]));
+            Assert.That(Thread.ThreadState.V17, Is.EqualTo(UnicornEmu.Q[17]));
+            Assert.That(Thread.ThreadState.V18, Is.EqualTo(UnicornEmu.Q[18]));
+            Assert.That(Thread.ThreadState.V19, Is.EqualTo(UnicornEmu.Q[19]));
+            Assert.That(Thread.ThreadState.V20, Is.EqualTo(UnicornEmu.Q[20]));
+            Assert.That(Thread.ThreadState.V21, Is.EqualTo(UnicornEmu.Q[21]));
+            Assert.That(Thread.ThreadState.V22, Is.EqualTo(UnicornEmu.Q[22]));
+            Assert.That(Thread.ThreadState.V23, Is.EqualTo(UnicornEmu.Q[23]));
+            Assert.That(Thread.ThreadState.V24, Is.EqualTo(UnicornEmu.Q[24]));
+            Assert.That(Thread.ThreadState.V25, Is.EqualTo(UnicornEmu.Q[25]));
+            Assert.That(Thread.ThreadState.V26, Is.EqualTo(UnicornEmu.Q[26]));
+            Assert.That(Thread.ThreadState.V27, Is.EqualTo(UnicornEmu.Q[27]));
+            Assert.That(Thread.ThreadState.V28, Is.EqualTo(UnicornEmu.Q[28]));
+            Assert.That(Thread.ThreadState.V29, Is.EqualTo(UnicornEmu.Q[29]));
+            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.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.Negative, Is.EqualTo(UnicornEmu.NegativeFlag));
+        }
+
         protected static Vector128<float> MakeVectorE0(double E0)
         {
             if (!Sse2.IsSupported)

+ 10 - 0
Ryujinx.Tests/Cpu/CpuTestAlu.cs

@@ -45,6 +45,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CLS <Wd>, <Wn>")]
@@ -101,6 +102,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CLZ <Wd>, <Wn>")]
@@ -129,6 +131,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("RBIT <Xd>, <Xn>")]
@@ -157,6 +160,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("RBIT <Wd>, <Wn>")]
@@ -185,6 +189,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("REV16 <Xd>, <Xn>")]
@@ -213,6 +218,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("REV16 <Wd>, <Wn>")]
@@ -241,6 +247,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("REV32 <Xd>, <Xn>")]
@@ -269,6 +276,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("REV <Wd>, <Wn>")]
@@ -297,6 +305,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("REV64 <Xd>, <Xn>")]
@@ -325,6 +334,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 20 - 0
Ryujinx.Tests/Cpu/CpuTestAluImm.cs

@@ -61,6 +61,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
@@ -105,6 +106,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
@@ -156,6 +158,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
@@ -207,6 +210,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("AND <Xd|SP>, <Xn>, #<imm>")]
@@ -240,6 +244,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("AND <Xd|SP>, <Xn>, #<imm>")]
@@ -273,6 +278,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("AND <Wd|WSP>, <Wn>, #<imm>")]
@@ -306,6 +312,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ANDS <Xd>, <Xn>, #<imm>")]
@@ -343,6 +350,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ANDS <Xd>, <Xn>, #<imm>")]
@@ -380,6 +388,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ANDS <Wd>, <Wn>, #<imm>")]
@@ -417,6 +426,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
@@ -450,6 +460,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
@@ -483,6 +494,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EOR <Wd>, <Wn>, #<imm>")]
@@ -516,6 +528,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
@@ -549,6 +562,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
@@ -582,6 +596,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ORR <Wd|WSP>, <Wn>, #<imm>")]
@@ -615,6 +630,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
@@ -659,6 +675,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
@@ -703,6 +720,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
@@ -754,6 +772,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
@@ -805,6 +824,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 54 - 0
Ryujinx.Tests/Cpu/CpuTestAluRs.cs

@@ -51,6 +51,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADC <Wd>, <Wn>, <Wm>")]
@@ -85,6 +86,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADCS <Xd>, <Xn>, <Xm>")]
@@ -125,6 +127,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADCS <Wd>, <Wn>, <Wm>")]
@@ -165,6 +168,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -200,6 +204,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -234,6 +239,7 @@ namespace Ryujinx.Tests.Cpu
             else
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
+                CompareAgainstUnicorn();
             }
         }
 
@@ -276,6 +282,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -317,6 +324,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("AND <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -352,6 +360,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("AND <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -387,6 +396,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ANDS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -428,6 +438,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ANDS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -469,6 +480,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ASRV <Xd>, <Xn>, <Xm>")]
@@ -501,6 +513,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ASRV <Wd>, <Wn>, <Wm>")]
@@ -533,6 +546,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("BIC <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -568,6 +582,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("BIC <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -603,6 +618,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("BICS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -644,6 +660,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("BICS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -685,6 +702,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CRC32X <Wd>, <Wn>, <Xm>")]
@@ -718,6 +736,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CRC32W <Wd>, <Wn>, <Wm>")]
@@ -749,6 +768,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CRC32H <Wd>, <Wn>, <Wm>")]
@@ -780,6 +800,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CRC32B <Wd>, <Wn>, <Wm>")]
@@ -811,6 +832,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CRC32CX <Wd>, <Wn>, <Xm>")]
@@ -844,6 +866,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CRC32CW <Wd>, <Wn>, <Wm>")]
@@ -875,6 +898,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CRC32CH <Wd>, <Wn>, <Wm>")]
@@ -906,6 +930,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CRC32CB <Wd>, <Wn>, <Wm>")]
@@ -937,6 +962,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EON <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -972,6 +998,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EON <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -1007,6 +1034,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EOR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -1042,6 +1070,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EOR <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -1077,6 +1106,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EXTR <Xd>, <Xn>, <Xm>, #<lsb>")]
@@ -1111,6 +1141,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("EXTR <Wd>, <Wn>, <Wm>, #<lsb>")]
@@ -1145,6 +1176,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("LSLV <Xd>, <Xn>, <Xm>")]
@@ -1177,6 +1209,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("LSLV <Wd>, <Wn>, <Wm>")]
@@ -1209,6 +1242,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("LSRV <Xd>, <Xn>, <Xm>")]
@@ -1241,6 +1275,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("LSRV <Wd>, <Wn>, <Wm>")]
@@ -1273,6 +1308,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ORN <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -1308,6 +1344,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ORN <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -1343,6 +1380,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ORR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -1378,6 +1416,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ORR <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -1413,6 +1452,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("RORV <Xd>, <Xn>, <Xm>")]
@@ -1445,6 +1485,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("RORV <Wd>, <Wn>, <Wm>")]
@@ -1477,6 +1518,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SBC <Xd>, <Xn>, <Xm>")]
@@ -1511,6 +1553,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SBC <Wd>, <Wn>, <Wm>")]
@@ -1545,6 +1588,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SBCS <Xd>, <Xn>, <Xm>")]
@@ -1585,6 +1629,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SBCS <Wd>, <Wn>, <Wm>")]
@@ -1625,6 +1670,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SDIV <Xd>, <Xn>, <Xm>")]
@@ -1657,6 +1703,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SDIV <Wd>, <Wn>, <Wm>")]
@@ -1689,6 +1736,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -1724,6 +1772,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -1759,6 +1808,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
@@ -1800,6 +1850,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
@@ -1841,6 +1892,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UDIV <Xd>, <Xn>, <Xm>")]
@@ -1873,6 +1925,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UDIV <Wd>, <Wn>, <Wm>")]
@@ -1905,6 +1958,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 28 - 0
Ryujinx.Tests/Cpu/CpuTestAluRx.cs

@@ -66,6 +66,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -116,6 +117,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -166,6 +168,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -216,6 +219,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -266,6 +270,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -316,6 +321,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -366,6 +372,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Xd>, <Xn|SP>, <X><m>{, <extend> {#<amount>}}")]
@@ -410,6 +417,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -455,6 +463,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -500,6 +509,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -545,6 +555,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -590,6 +601,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -635,6 +647,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -680,6 +693,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Xd|SP>, <Xn|SP>, <X><m>{, <extend> {#<amount>}}")]
@@ -729,6 +743,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -779,6 +794,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -829,6 +845,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Xd|SP>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -879,6 +896,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -929,6 +947,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -979,6 +998,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -1029,6 +1049,7 @@ namespace Ryujinx.Tests.Cpu
 
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Xd>, <Xn|SP>, <X><m>{, <extend> {#<amount>}}")]
@@ -1073,6 +1094,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -1118,6 +1140,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -1163,6 +1186,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Xd>, <Xn|SP>, <W><m>{, <extend> {#<amount>}}")]
@@ -1208,6 +1232,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -1253,6 +1278,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -1298,6 +1324,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}")]
@@ -1343,6 +1370,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 6 - 0
Ryujinx.Tests/Cpu/CpuTestBfm.cs

@@ -50,6 +50,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("BFM <Wd>, <Wn>, #<immr>, #<imms>")]
@@ -83,6 +84,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SBFM <Xd>, <Xn>, #<immr>, #<imms>")]
@@ -114,6 +116,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SBFM <Wd>, <Wn>, #<immr>, #<imms>")]
@@ -145,6 +148,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UBFM <Xd>, <Xn>, #<immr>, #<imms>")]
@@ -176,6 +180,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UBFM <Wd>, <Wn>, #<immr>, #<imms>")]
@@ -207,6 +212,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 4 - 0
Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs

@@ -49,6 +49,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CCMN <Wn>, #<imm>, #<nzcv>, <cond>")]
@@ -81,6 +82,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CCMP <Xn>, #<imm>, #<nzcv>, <cond>")]
@@ -113,6 +115,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CCMP <Wn>, #<imm>, #<nzcv>, <cond>")]
@@ -145,6 +148,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 4 - 0
Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs

@@ -52,6 +52,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CCMN <Wn>, <Wm>, #<nzcv>, <cond>")]
@@ -87,6 +88,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CCMP <Xn>, <Xm>, #<nzcv>, <cond>")]
@@ -122,6 +124,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CCMP <Wn>, <Wm>, #<nzcv>, <cond>")]
@@ -157,6 +160,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(ThreadState.Carry,    Is.EqualTo(Shared.PSTATE.C));
                 Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
             });
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 8 - 0
Ryujinx.Tests/Cpu/CpuTestCsel.cs

@@ -54,6 +54,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CSEL <Wd>, <Wn>, <Wm>, <cond>")]
@@ -91,6 +92,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CSINC <Xd>, <Xn>, <Xm>, <cond>")]
@@ -128,6 +130,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CSINC <Wd>, <Wn>, <Wm>, <cond>")]
@@ -165,6 +168,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CSINV <Xd>, <Xn>, <Xm>, <cond>")]
@@ -202,6 +206,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CSINV <Wd>, <Wn>, <Wm>, <cond>")]
@@ -239,6 +244,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CSNEG <Xd>, <Xn>, <Xm>, <cond>")]
@@ -276,6 +282,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("CSNEG <Wd>, <Wn>, <Wm>, <cond>")]
@@ -313,6 +320,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 6 - 0
Ryujinx.Tests/Cpu/CpuTestMov.cs

@@ -46,6 +46,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("MOVK <Wd>, #<imm>{, LSL #<shift>}")]
@@ -75,6 +76,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("MOVN <Xd>, #<imm>{, LSL #<shift>}")]
@@ -102,6 +104,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("MOVN <Wd>, #<imm>{, LSL #<shift>}")]
@@ -129,6 +132,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("MOVZ <Xd>, #<imm>{, LSL #<shift>}")]
@@ -156,6 +160,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("MOVZ <Wd>, #<imm>{, LSL #<shift>}")]
@@ -183,6 +188,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 10 - 0
Ryujinx.Tests/Cpu/CpuTestMul.cs

@@ -53,6 +53,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("MADD <Wd>, <Wn>, <Wm>, <Wa>")]
@@ -89,6 +90,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("MSUB <Xd>, <Xn>, <Xm>, <Xa>")]
@@ -125,6 +127,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("MSUB <Wd>, <Wn>, <Wm>, <Wa>")]
@@ -161,6 +164,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
@@ -197,6 +201,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
@@ -233,6 +238,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
@@ -269,6 +275,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
@@ -305,6 +312,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SMULH <Xd>, <Xn>, <Xm>")]
@@ -337,6 +345,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UMULH <Xd>, <Xn>, <Xm>")]
@@ -369,6 +378,7 @@ namespace Ryujinx.Tests.Cpu
             {
                 Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
             }
+            CompareAgainstUnicorn();
         }
 #endif
     }

+ 72 - 0
Ryujinx.Tests/Cpu/CpuTestSimd.cs

@@ -112,6 +112,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("ABS <Vd>.<T>, <Vn>.<T>")]
@@ -139,6 +140,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("ABS <Vd>.<T>, <Vn>.<T>")]
@@ -166,6 +168,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("ADDP <V><d>, <Vn>.<T>")]
@@ -191,6 +194,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("ADDV <V><d>, <Vn>.<T>")]
@@ -218,6 +222,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("ADDV <V><d>, <Vn>.<T>")]
@@ -245,6 +250,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CLS <Vd>.<T>, <Vn>.<T>")]
@@ -272,6 +278,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CLS <Vd>.<T>, <Vn>.<T>")]
@@ -299,6 +306,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CLZ <Vd>.<T>, <Vn>.<T>")]
@@ -326,6 +334,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CLZ <Vd>.<T>, <Vn>.<T>")]
@@ -353,6 +362,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMEQ <V><d>, <V><n>, #0")]
@@ -378,6 +388,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMEQ <Vd>.<T>, <Vn>.<T>, #0")]
@@ -405,6 +416,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMEQ <Vd>.<T>, <Vn>.<T>, #0")]
@@ -432,6 +444,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMGE <V><d>, <V><n>, #0")]
@@ -457,6 +470,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMGE <Vd>.<T>, <Vn>.<T>, #0")]
@@ -484,6 +498,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMGE <Vd>.<T>, <Vn>.<T>, #0")]
@@ -511,6 +526,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMGT <V><d>, <V><n>, #0")]
@@ -536,6 +552,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMGT <Vd>.<T>, <Vn>.<T>, #0")]
@@ -563,6 +580,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMGT <Vd>.<T>, <Vn>.<T>, #0")]
@@ -590,6 +608,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMLE <V><d>, <V><n>, #0")]
@@ -615,6 +634,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMLE <Vd>.<T>, <Vn>.<T>, #0")]
@@ -642,6 +662,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMLE <Vd>.<T>, <Vn>.<T>, #0")]
@@ -669,6 +690,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMLT <V><d>, <V><n>, #0")]
@@ -694,6 +716,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMLT <Vd>.<T>, <Vn>.<T>, #0")]
@@ -721,6 +744,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CMLT <Vd>.<T>, <Vn>.<T>, #0")]
@@ -748,6 +772,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CNT <Vd>.<T>, <Vn>.<T>")]
@@ -773,6 +798,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("CNT <Vd>.<T>, <Vn>.<T>")]
@@ -798,6 +824,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("NEG <V><d>, <V><n>")]
@@ -823,6 +850,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("NEG <Vd>.<T>, <Vn>.<T>")]
@@ -850,6 +878,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("NEG <Vd>.<T>, <Vn>.<T>")]
@@ -877,6 +906,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("NOT <Vd>.<T>, <Vn>.<T>")]
@@ -902,6 +932,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("NOT <Vd>.<T>, <Vn>.<T>")]
@@ -927,6 +958,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("RBIT <Vd>.<T>, <Vn>.<T>")]
@@ -952,6 +984,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("RBIT <Vd>.<T>, <Vn>.<T>")]
@@ -977,6 +1010,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("REV16 <Vd>.<T>, <Vn>.<T>")]
@@ -1002,6 +1036,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("REV16 <Vd>.<T>, <Vn>.<T>")]
@@ -1027,6 +1062,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("REV32 <Vd>.<T>, <Vn>.<T>")]
@@ -1054,6 +1090,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("REV32 <Vd>.<T>, <Vn>.<T>")]
@@ -1081,6 +1118,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("REV64 <Vd>.<T>, <Vn>.<T>")]
@@ -1108,6 +1146,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("REV64 <Vd>.<T>, <Vn>.<T>")]
@@ -1135,6 +1174,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("SADALP <Vd>.<Ta>, <Vn>.<Tb>")]
@@ -1162,6 +1202,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("SADALP <Vd>.<Ta>, <Vn>.<Tb>")]
@@ -1189,6 +1230,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("SADDLP <Vd>.<Ta>, <Vn>.<Tb>")]
@@ -1216,6 +1258,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("SADDLP <Vd>.<Ta>, <Vn>.<Tb>")]
@@ -1243,6 +1286,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SHA256SU0 <Vd>.4S, <Vn>.4S")]
@@ -1273,6 +1317,7 @@ namespace Ryujinx.Tests.Cpu
                 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();
         }
 
         [Test, Description("SQABS <V><d>, <V><n>")]
@@ -1304,6 +1349,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQABS <Vd>.<T>, <Vn>.<T>")]
@@ -1335,6 +1381,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQABS <Vd>.<T>, <Vn>.<T>")]
@@ -1366,6 +1413,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQNEG <V><d>, <V><n>")]
@@ -1397,6 +1445,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQNEG <Vd>.<T>, <Vn>.<T>")]
@@ -1428,6 +1477,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQNEG <Vd>.<T>, <Vn>.<T>")]
@@ -1459,6 +1509,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQXTN <Vb><d>, <Va><n>")]
@@ -1490,6 +1541,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
@@ -1521,6 +1573,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
@@ -1552,6 +1605,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQXTUN <Vb><d>, <Va><n>")]
@@ -1583,6 +1637,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQXTUN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
@@ -1614,6 +1669,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SQXTUN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
@@ -1645,6 +1701,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUQADD <V><d>, <V><n>")]
@@ -1676,6 +1733,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUQADD <Vd>.<T>, <Vn>.<T>")]
@@ -1707,6 +1765,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("SUQADD <Vd>.<T>, <Vn>.<T>")]
@@ -1738,6 +1797,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UADALP <Vd>.<Ta>, <Vn>.<Tb>")]
@@ -1765,6 +1825,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("UADALP <Vd>.<Ta>, <Vn>.<Tb>")]
@@ -1792,6 +1853,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("UADDLP <Vd>.<Ta>, <Vn>.<Tb>")]
@@ -1819,6 +1881,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("UADDLP <Vd>.<Ta>, <Vn>.<Tb>")]
@@ -1846,6 +1909,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("UQXTN <Vb><d>, <Va><n>")]
@@ -1877,6 +1941,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
@@ -1908,6 +1973,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("UQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
@@ -1939,6 +2005,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("USQADD <V><d>, <V><n>")]
@@ -1970,6 +2037,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("USQADD <Vd>.<T>, <Vn>.<T>")]
@@ -2001,6 +2069,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("USQADD <Vd>.<T>, <Vn>.<T>")]
@@ -2032,6 +2101,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
             });
             Assert.That(ThreadState.Fpsr, Is.EqualTo((int)Shared.FPSR.ToUInt32()));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("XTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
@@ -2059,6 +2129,7 @@ namespace Ryujinx.Tests.Cpu
                 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, Description("XTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
@@ -2086,6 +2157,7 @@ namespace Ryujinx.Tests.Cpu
                 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
     }

+ 21 - 0
Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs

@@ -33,6 +33,7 @@ namespace Ryujinx.Tests.Cpu
                 V1: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, A)),
                 V2: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, B)));
             Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast<float, ulong>(ThreadState.V0), 0));
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x80000000u, 0x80000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u)]
@@ -59,6 +60,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                 Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
             });
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x1E225820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
@@ -85,6 +87,7 @@ namespace Ryujinx.Tests.Cpu
                 V1: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, A)),
                 V2: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, B)));
             Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast<float, ulong>(ThreadState.V0), 0));
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x80000000u, 0x80000000u, 0x00000000u, 0x00000000u, 0x80000000u, 0x80000000u)]
@@ -111,6 +114,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                 Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("FMUL S6, S1, V0.S[2]")]
@@ -121,6 +125,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();
         }
 
         [TestCase(0x00000000u, 0x7F800000u)]
@@ -135,6 +140,7 @@ namespace Ryujinx.Tests.Cpu
             Vector128<float> V1 = MakeVectorE0(A);
             AThreadState ThreadState = SingleOpcode(0x5EA1D820, V1: V1);
             Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("FRECPS D0, D1, D2")]
@@ -145,6 +151,7 @@ namespace Ryujinx.Tests.Cpu
                 V2: MakeVectorE0(B));
 
             Assert.That(VectorExtractDouble(ThreadState.V0, 0), Is.EqualTo(2 - (A * B)));
+            //CompareAgainstUnicorn(); // Not accurate enough
         }
 
         [Test, Description("FRECPS V4.4S, V2.4S, V0.4S")]
@@ -163,6 +170,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();
         }
 
         [TestCase(0x3FE66666u, false, 0x40000000u)]
@@ -213,6 +221,7 @@ namespace Ryujinx.Tests.Cpu
             Vector128<float> V1 = MakeVectorE0(A);
             AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp);
             Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x6E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
@@ -240,6 +249,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                 Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
             });
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x3FE66666u, 'N', false, 0x40000000u)]
@@ -310,6 +320,7 @@ namespace Ryujinx.Tests.Cpu
             Vector128<float> V1 = MakeVectorE0(A);
             AThreadState ThreadState = SingleOpcode(0x1E27C020, V1: V1, Fpcr: FpcrTemp);
             Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
@@ -376,6 +387,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                 Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
             });
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x3FE66666u, false, 0x3F800000u)]
@@ -426,6 +438,7 @@ namespace Ryujinx.Tests.Cpu
             Vector128<float> V1 = MakeVectorE0(A);
             AThreadState ThreadState = SingleOpcode(0x1E254020, V1: V1, Fpcr: FpcrTemp);
             Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x4E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
@@ -450,6 +463,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                 Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
             });
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x3FE66666u, false, 0x40000000u)]
@@ -500,6 +514,7 @@ namespace Ryujinx.Tests.Cpu
             Vector128<float> V1 = MakeVectorE0(A);
             AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp);
             Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x4E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
@@ -527,6 +542,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                 Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
             });
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x3FE66666u, false, 0x40000000u)]
@@ -577,6 +593,7 @@ namespace Ryujinx.Tests.Cpu
             Vector128<float> V1 = MakeVectorE0(A);
             AThreadState ThreadState = SingleOpcode(0x1E24C020, V1: V1, Fpcr: FpcrTemp);
             Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x4EE18820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
@@ -601,6 +618,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                 Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
             });
+            CompareAgainstUnicorn();
         }
 
     	[TestCase(0x3FE66666u, 'N', false, 0x40000000u)]
@@ -671,6 +689,7 @@ namespace Ryujinx.Tests.Cpu
         	Vector128<float> V1 = MakeVectorE0(A);
         	AThreadState ThreadState = SingleOpcode(0x1E274020, V1: V1, Fpcr: FpcrTemp);
         	Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
@@ -737,6 +756,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
                 Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
             });
+            CompareAgainstUnicorn();
         }
 
         [TestCase(0x41200000u, 0x3EA18000u)]
@@ -745,6 +765,7 @@ namespace Ryujinx.Tests.Cpu
             Vector128<float> V1 = MakeVectorE0(A);
             AThreadState ThreadState = SingleOpcode(0x7EA1D820, V1: V1);
             Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
+            CompareAgainstUnicorn();
         }
     }
 }

+ 10 - 0
Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs

@@ -52,6 +52,7 @@ 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")]
@@ -84,6 +85,7 @@ 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")]
@@ -113,6 +115,7 @@ 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")]
@@ -145,6 +148,7 @@ 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")]
@@ -176,6 +180,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();
         }
 
         [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")]
@@ -214,6 +219,7 @@ 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")]
@@ -254,6 +260,7 @@ 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")]
@@ -291,6 +298,7 @@ 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")]
@@ -331,6 +339,7 @@ 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")]
@@ -370,6 +379,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();
         }
     }
 }

+ 4 - 0
Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs

@@ -37,6 +37,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
                 Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("AESE <Vd>.16B, <Vn>.16B")]
@@ -66,6 +67,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
                 Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
             });
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("AESIMC <Vd>.16B, <Vn>.16B")]
@@ -98,6 +100,7 @@ namespace Ryujinx.Tests.Cpu
                     Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
                 });
             }
+            CompareAgainstUnicorn();
         }
 
         [Test, Description("AESMC <Vd>.16B, <Vn>.16B")]
@@ -130,6 +133,7 @@ namespace Ryujinx.Tests.Cpu
                     Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
                 });
             }
+            CompareAgainstUnicorn();
         }
     }
 }

+ 1 - 0
Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs

@@ -35,6 +35,7 @@ namespace Ryujinx.Tests.Cpu
                 Assert.That(Sse41.Extract(Sse.StaticCast<float, uint>(ThreadState.V1), (byte)2), Is.EqualTo(Result));
                 Assert.That(Sse41.Extract(Sse.StaticCast<float, uint>(ThreadState.V1), (byte)3), Is.EqualTo(Result));
             });
+            CompareAgainstUnicorn();
         }
     }
 }

+ 89 - 0
Ryujinx.Tests/Cpu/CpuTestSimdReg.cs

@@ -115,6 +115,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -146,6 +147,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -177,6 +179,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
@@ -208,6 +211,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
@@ -239,6 +243,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -270,6 +275,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -301,6 +307,7 @@ namespace Ryujinx.Tests.Cpu
                 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("AND <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -330,6 +337,7 @@ namespace Ryujinx.Tests.Cpu
                 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("AND <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -359,6 +367,7 @@ namespace Ryujinx.Tests.Cpu
                 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("BIC <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -388,6 +397,7 @@ namespace Ryujinx.Tests.Cpu
                 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("BIC <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -417,6 +427,7 @@ namespace Ryujinx.Tests.Cpu
                 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("BIF <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -446,6 +457,7 @@ namespace Ryujinx.Tests.Cpu
                 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("BIF <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -475,6 +487,7 @@ namespace Ryujinx.Tests.Cpu
                 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("BIT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -504,6 +517,7 @@ namespace Ryujinx.Tests.Cpu
                 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("BIT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -533,6 +547,7 @@ namespace Ryujinx.Tests.Cpu
                 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("BSL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -562,6 +577,7 @@ namespace Ryujinx.Tests.Cpu
                 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("BSL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -591,6 +607,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMEQ <V><d>, <V><n>, <V><m>")]
@@ -620,6 +637,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMEQ <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -651,6 +669,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMEQ <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -682,6 +701,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMGE <V><d>, <V><n>, <V><m>")]
@@ -711,6 +731,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -742,6 +763,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMGE <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -773,6 +795,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMGT <V><d>, <V><n>, <V><m>")]
@@ -802,6 +825,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -833,6 +857,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMGT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -864,6 +889,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMHI <V><d>, <V><n>, <V><m>")]
@@ -893,6 +919,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMHI <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -924,6 +951,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMHI <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -955,6 +983,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMHS <V><d>, <V><n>, <V><m>")]
@@ -984,6 +1013,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMHS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1015,6 +1045,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMHS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1046,6 +1077,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMTST <V><d>, <V><n>, <V><m>")]
@@ -1075,6 +1107,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMTST <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1106,6 +1139,7 @@ namespace Ryujinx.Tests.Cpu
                 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("CMTST <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1137,6 +1171,7 @@ namespace Ryujinx.Tests.Cpu
                 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("EOR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1166,6 +1201,7 @@ namespace Ryujinx.Tests.Cpu
                 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("EOR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1195,6 +1231,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ORN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1224,6 +1261,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ORN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1253,6 +1291,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ORR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1282,6 +1321,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ORR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1311,6 +1351,7 @@ namespace Ryujinx.Tests.Cpu
                 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("RADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
@@ -1342,6 +1383,7 @@ namespace Ryujinx.Tests.Cpu
                 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("RADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
@@ -1373,6 +1415,7 @@ namespace Ryujinx.Tests.Cpu
                 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("RSUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
@@ -1404,6 +1447,7 @@ namespace Ryujinx.Tests.Cpu
                 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("RSUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
@@ -1435,6 +1479,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SABA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1466,6 +1511,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SABA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1497,6 +1543,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SABAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>")]
@@ -1528,6 +1575,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SABAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>")]
@@ -1559,6 +1607,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1590,6 +1639,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -1621,6 +1671,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SABDL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>")]
@@ -1652,6 +1703,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SABDL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>")]
@@ -1683,6 +1735,7 @@ namespace Ryujinx.Tests.Cpu
                 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} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>")]
@@ -1714,6 +1767,7 @@ namespace Ryujinx.Tests.Cpu
                 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} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>")]
@@ -1745,6 +1799,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SHA256H <Qd>, <Qn>, <Vm>.4S")]
@@ -1782,6 +1837,7 @@ namespace Ryujinx.Tests.Cpu
                 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();
         }
 
         [Test, Pairwise, Description("SHA256H2 <Qd>, <Qn>, <Vm>.4S")]
@@ -1819,6 +1875,7 @@ namespace Ryujinx.Tests.Cpu
                 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();
         }
 
         [Test, Pairwise, Description("SHA256SU1 <Vd>.4S, <Vn>.4S, <Vm>.4S")]
@@ -1856,6 +1913,7 @@ namespace Ryujinx.Tests.Cpu
                 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();
         }
 
         [Test, Pairwise, Description("SHADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2493,6 +2551,7 @@ namespace Ryujinx.Tests.Cpu
                 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} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>")]
@@ -2524,6 +2583,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SUB <V><d>, <V><n>, <V><m>")]
@@ -2553,6 +2613,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2584,6 +2645,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2615,6 +2677,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
@@ -2646,6 +2709,7 @@ namespace Ryujinx.Tests.Cpu
                 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("SUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
@@ -2677,6 +2741,7 @@ namespace Ryujinx.Tests.Cpu
                 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("TRN1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2708,6 +2773,7 @@ namespace Ryujinx.Tests.Cpu
                 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("TRN1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2739,6 +2805,7 @@ namespace Ryujinx.Tests.Cpu
                 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("TRN2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2770,6 +2837,7 @@ namespace Ryujinx.Tests.Cpu
                 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("TRN2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2801,6 +2869,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UABA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2832,6 +2901,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UABA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2863,6 +2933,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UABAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>")]
@@ -2894,6 +2965,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UABAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>")]
@@ -2925,6 +2997,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2956,6 +3029,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -2987,6 +3061,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UABDL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>")]
@@ -3018,6 +3093,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UABDL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>")]
@@ -3049,6 +3125,7 @@ namespace Ryujinx.Tests.Cpu
                 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} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>")]
@@ -3080,6 +3157,7 @@ namespace Ryujinx.Tests.Cpu
                 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} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>")]
@@ -3111,6 +3189,7 @@ namespace Ryujinx.Tests.Cpu
                 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 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3538,6 +3617,7 @@ namespace Ryujinx.Tests.Cpu
                 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} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>")]
@@ -3569,6 +3649,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UZP1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3600,6 +3681,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UZP1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3631,6 +3713,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UZP2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3662,6 +3745,7 @@ namespace Ryujinx.Tests.Cpu
                 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("UZP2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3693,6 +3777,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ZIP1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3724,6 +3809,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ZIP1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3755,6 +3841,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ZIP2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3786,6 +3873,7 @@ namespace Ryujinx.Tests.Cpu
                 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("ZIP2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
@@ -3817,6 +3905,7 @@ namespace Ryujinx.Tests.Cpu
                 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
     }

+ 11 - 0
Ryujinx.Tests/Ryujinx.Tests.csproj

@@ -5,6 +5,10 @@
     <RuntimeIdentifiers>win10-x64;osx-x64;linux-x64</RuntimeIdentifiers>
     <OutputType>Exe</OutputType>
     <IsPackable>false</IsPackable>
+
+    <TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">windows</TargetOS>
+    <TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">osx</TargetOS>
+    <TargetOS Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">linux</TargetOS>
   </PropertyGroup>
 
   <PropertyGroup>
@@ -20,6 +24,13 @@
 
   <ItemGroup>
     <ProjectReference Include="..\ChocolArm64\ChocolArm64.csproj" />
+    <ProjectReference Include="..\Ryujinx.Tests.Unicorn\Ryujinx.Tests.Unicorn.csproj" />
   </ItemGroup>
 
+  <Target Name="CopyUnicorn" AfterTargets="Build">
+    <Copy SourceFiles="..\Ryujinx.Tests.Unicorn\libs\$(TargetOS)\unicorn.dll" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
+    <Copy SourceFiles="..\Ryujinx.Tests.Unicorn\libs\$(TargetOS)\libunicorn.dylib" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
+    <Copy SourceFiles="..\Ryujinx.Tests.Unicorn\libs\$(TargetOS)\libunicorn.so" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
+  </Target>
+
 </Project>