diff --git a/Ryujinx.Tests.Unicorn/IndexedProperty.cs b/Ryujinx.Tests.Unicorn/IndexedProperty.cs new file mode 100644 index 00000000..946620c6 --- /dev/null +++ b/Ryujinx.Tests.Unicorn/IndexedProperty.cs @@ -0,0 +1,28 @@ +using System; + +namespace Ryujinx.Tests.Unicorn +{ + public class IndexedProperty + { + readonly Action SetAction; + readonly Func GetFunc; + + public IndexedProperty(Func getFunc, Action setAction) + { + this.GetFunc = getFunc; + this.SetAction = setAction; + } + + public TValue this[TIndex i] + { + get + { + return GetFunc(i); + } + set + { + SetAction(i, value); + } + } + } +} diff --git a/Ryujinx.Tests.Unicorn/MemoryPermission.cs b/Ryujinx.Tests.Unicorn/MemoryPermission.cs new file mode 100644 index 00000000..d79b2add --- /dev/null +++ b/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, + } +} diff --git a/Ryujinx.Tests.Unicorn/Native/ArmRegister.cs b/Ryujinx.Tests.Unicorn/Native/ArmRegister.cs new file mode 100644 index 00000000..3554480c --- /dev/null +++ b/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, + } +} diff --git a/Ryujinx.Tests.Unicorn/Native/Interface.cs b/Ryujinx.Tests.Unicorn/Native/Interface.cs new file mode 100644 index 00000000..a6563220 --- /dev/null +++ b/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(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(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); + } +} diff --git a/Ryujinx.Tests.Unicorn/Native/UnicornArch.cs b/Ryujinx.Tests.Unicorn/Native/UnicornArch.cs new file mode 100644 index 00000000..be088366 --- /dev/null +++ b/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, + } +} diff --git a/Ryujinx.Tests.Unicorn/Native/UnicornMemoryRegion.cs b/Ryujinx.Tests.Unicorn/Native/UnicornMemoryRegion.cs new file mode 100644 index 00000000..7ee34a74 --- /dev/null +++ b/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 + } +} diff --git a/Ryujinx.Tests.Unicorn/Native/UnicornMode.cs b/Ryujinx.Tests.Unicorn/Native/UnicornMode.cs new file mode 100644 index 00000000..950583bd --- /dev/null +++ b/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 + } +} diff --git a/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj b/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj new file mode 100644 index 00000000..ee7c103d --- /dev/null +++ b/Ryujinx.Tests.Unicorn/Ryujinx.Tests.Unicorn.csproj @@ -0,0 +1,18 @@ + + + + netcoreapp2.1 + win10-x64;osx-x64;linux-x64 + true + + + + false + + + + + + + + diff --git a/Ryujinx.Tests.Unicorn/UnicornAArch64.cs b/Ryujinx.Tests.Unicorn/UnicornAArch64.cs new file mode 100644 index 00000000..1cd3671f --- /dev/null +++ b/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 X + { + get + { + return new IndexedProperty( + (int i) => GetX(i), + (int i, ulong value) => SetX(i, value)); + } + } + + public IndexedProperty> Q + { + get + { + return new IndexedProperty>( + (int i) => GetQ(i), + (int i, Vector128 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 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 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 GetQ(int index) + { + Contract.Requires(index <= 31, "invalid vector"); + + return GetVector(Q_registers[index]); + } + + public void SetQ(int index, Vector128 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(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; + } + } + } +} \ No newline at end of file diff --git a/Ryujinx.Tests.Unicorn/UnicornError.cs b/Ryujinx.Tests.Unicorn/UnicornError.cs new file mode 100644 index 00000000..db56c615 --- /dev/null +++ b/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 + } +} diff --git a/Ryujinx.Tests.Unicorn/UnicornException.cs b/Ryujinx.Tests.Unicorn/UnicornException.cs new file mode 100644 index 00000000..3cb69370 --- /dev/null +++ b/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)); + } + } + } +} diff --git a/Ryujinx.Tests.Unicorn/libs/README.md b/Ryujinx.Tests.Unicorn/libs/README.md new file mode 100644 index 00000000..bb370164 --- /dev/null +++ b/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 diff --git a/Ryujinx.Tests.Unicorn/libs/windows/unicorn.dll b/Ryujinx.Tests.Unicorn/libs/windows/unicorn.dll new file mode 100644 index 00000000..0e3cea58 Binary files /dev/null and b/Ryujinx.Tests.Unicorn/libs/windows/unicorn.dll differ diff --git a/Ryujinx.Tests/Cpu/CpuTest.cs b/Ryujinx.Tests/Cpu/CpuTest.cs index 4ac05f1b..6e013aa0 100644 --- a/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/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 MakeVectorE0(double E0) { if (!Sse2.IsSupported) diff --git a/Ryujinx.Tests/Cpu/CpuTestAlu.cs b/Ryujinx.Tests/Cpu/CpuTestAlu.cs index c89cb646..3a47dbee 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAlu.cs +++ b/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 , ")] @@ -101,6 +102,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("CLZ , ")] @@ -129,6 +131,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("RBIT , ")] @@ -157,6 +160,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("RBIT , ")] @@ -185,6 +189,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("REV16 , ")] @@ -213,6 +218,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("REV16 , ")] @@ -241,6 +247,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("REV32 , ")] @@ -269,6 +276,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("REV , ")] @@ -297,6 +305,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("REV64 , ")] @@ -325,6 +334,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } #endif } diff --git a/Ryujinx.Tests/Cpu/CpuTestAluImm.cs b/Ryujinx.Tests/Cpu/CpuTestAluImm.cs index d436d65f..b648a337 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluImm.cs +++ b/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 , , #{, }")] @@ -105,6 +106,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("ADDS , , #{, }")] @@ -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 , , #{, }")] @@ -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 , , #")] @@ -240,6 +244,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("AND , , #")] @@ -273,6 +278,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("AND , , #")] @@ -306,6 +312,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("ANDS , , #")] @@ -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 , , #")] @@ -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 , , #")] @@ -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 , , #")] @@ -450,6 +460,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("EOR , , #")] @@ -483,6 +494,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("EOR , , #")] @@ -516,6 +528,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("ORR , , #")] @@ -549,6 +562,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("ORR , , #")] @@ -582,6 +596,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("ORR , , #")] @@ -615,6 +630,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , #{, }")] @@ -659,6 +675,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , #{, }")] @@ -703,6 +720,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("SUBS , , #{, }")] @@ -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 , , #{, }")] @@ -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 } diff --git a/Ryujinx.Tests/Cpu/CpuTestAluRs.cs b/Ryujinx.Tests/Cpu/CpuTestAluRs.cs index 880794cf..49c82b74 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluRs.cs +++ b/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 , , ")] @@ -85,6 +86,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("ADCS , , ")] @@ -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 , , ")] @@ -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 , , {, #}")] @@ -200,6 +204,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("ADD , , {, #}")] @@ -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 , , {, #}")] @@ -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 , , {, #}")] @@ -352,6 +360,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("AND , , {, #}")] @@ -387,6 +396,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("ANDS , , {, #}")] @@ -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 , , {, #}")] @@ -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 , , ")] @@ -501,6 +513,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("ASRV , , ")] @@ -533,6 +546,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("BIC , , {, #}")] @@ -568,6 +582,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("BIC , , {, #}")] @@ -603,6 +618,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("BICS , , {, #}")] @@ -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 , , {, #}")] @@ -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 , , ")] @@ -718,6 +736,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CRC32W , , ")] @@ -749,6 +768,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CRC32H , , ")] @@ -780,6 +800,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CRC32B , , ")] @@ -811,6 +832,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CRC32CX , , ")] @@ -844,6 +866,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CRC32CW , , ")] @@ -875,6 +898,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CRC32CH , , ")] @@ -906,6 +930,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CRC32CB , , ")] @@ -937,6 +962,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("EON , , {, #}")] @@ -972,6 +998,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("EON , , {, #}")] @@ -1007,6 +1034,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("EOR , , {, #}")] @@ -1042,6 +1070,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("EOR , , {, #}")] @@ -1077,6 +1106,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("EXTR , , , #")] @@ -1111,6 +1141,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("EXTR , , , #")] @@ -1145,6 +1176,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("LSLV , , ")] @@ -1177,6 +1209,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("LSLV , , ")] @@ -1209,6 +1242,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("LSRV , , ")] @@ -1241,6 +1275,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("LSRV , , ")] @@ -1273,6 +1308,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("ORN , , {, #}")] @@ -1308,6 +1344,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("ORN , , {, #}")] @@ -1343,6 +1380,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("ORR , , {, #}")] @@ -1378,6 +1416,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("ORR , , {, #}")] @@ -1413,6 +1452,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("RORV , , ")] @@ -1445,6 +1485,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("RORV , , ")] @@ -1477,6 +1518,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("SBC , , ")] @@ -1511,6 +1553,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("SBC , , ")] @@ -1545,6 +1588,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("SBCS , , ")] @@ -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 , , ")] @@ -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 , , ")] @@ -1657,6 +1703,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("SDIV , , ")] @@ -1689,6 +1736,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , {, #}")] @@ -1724,6 +1772,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , {, #}")] @@ -1759,6 +1808,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("SUBS , , {, #}")] @@ -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 , , {, #}")] @@ -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 , , ")] @@ -1873,6 +1925,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("UDIV , , ")] @@ -1905,6 +1958,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } #endif } diff --git a/Ryujinx.Tests/Cpu/CpuTestAluRx.cs b/Ryujinx.Tests/Cpu/CpuTestAluRx.cs index d6cf8dc4..41fd580a 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAluRx.cs +++ b/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 , , {, {#}}")] @@ -116,6 +117,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("ADD , , {, {#}}")] @@ -166,6 +168,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("ADD , , {, {#}}")] @@ -216,6 +219,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("ADD , , {, {#}}")] @@ -266,6 +270,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("ADD , , {, {#}}")] @@ -316,6 +321,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("ADD , , {, {#}}")] @@ -366,6 +372,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("ADDS , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -729,6 +743,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , {, {#}}")] @@ -779,6 +794,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , {, {#}}")] @@ -829,6 +845,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , {, {#}}")] @@ -879,6 +896,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , {, {#}}")] @@ -929,6 +947,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , {, {#}}")] @@ -979,6 +998,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("SUB , , {, {#}}")] @@ -1029,6 +1049,7 @@ namespace Ryujinx.Tests.Cpu Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP)); } + CompareAgainstUnicorn(); } [Test, Description("SUBS , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 , , {, {#}}")] @@ -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 } diff --git a/Ryujinx.Tests/Cpu/CpuTestBfm.cs b/Ryujinx.Tests/Cpu/CpuTestBfm.cs index 0a2f9ad3..c5be5788 100644 --- a/Ryujinx.Tests/Cpu/CpuTestBfm.cs +++ b/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 , , #, #")] @@ -83,6 +84,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("SBFM , , #, #")] @@ -114,6 +116,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("SBFM , , #, #")] @@ -145,6 +148,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("UBFM , , #, #")] @@ -176,6 +180,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("UBFM , , #, #")] @@ -207,6 +212,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } #endif } diff --git a/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs b/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs index 7ba44ed9..245b04c0 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCcmpImm.cs +++ b/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 , #, #, ")] @@ -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 , #, #, ")] @@ -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 , #, #, ")] @@ -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 } diff --git a/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs b/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs index 82556464..8c4e503e 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCcmpReg.cs +++ b/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 , , #, ")] @@ -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 , , #, ")] @@ -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 , , #, ")] @@ -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 } diff --git a/Ryujinx.Tests/Cpu/CpuTestCsel.cs b/Ryujinx.Tests/Cpu/CpuTestCsel.cs index fef56fee..d532a12c 100644 --- a/Ryujinx.Tests/Cpu/CpuTestCsel.cs +++ b/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 , , , ")] @@ -91,6 +92,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CSINC , , , ")] @@ -128,6 +130,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("CSINC , , , ")] @@ -165,6 +168,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CSINV , , , ")] @@ -202,6 +206,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("CSINV , , , ")] @@ -239,6 +244,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("CSNEG , , , ")] @@ -276,6 +282,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("CSNEG , , , ")] @@ -313,6 +320,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } #endif } diff --git a/Ryujinx.Tests/Cpu/CpuTestMov.cs b/Ryujinx.Tests/Cpu/CpuTestMov.cs index db544f86..a8bf33ef 100644 --- a/Ryujinx.Tests/Cpu/CpuTestMov.cs +++ b/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 , #{, LSL #}")] @@ -75,6 +76,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("MOVN , #{, LSL #}")] @@ -102,6 +104,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("MOVN , #{, LSL #}")] @@ -129,6 +132,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("MOVZ , #{, LSL #}")] @@ -156,6 +160,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("MOVZ , #{, LSL #}")] @@ -183,6 +188,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } #endif } diff --git a/Ryujinx.Tests/Cpu/CpuTestMul.cs b/Ryujinx.Tests/Cpu/CpuTestMul.cs index 19b8ecd0..2e8aa76f 100644 --- a/Ryujinx.Tests/Cpu/CpuTestMul.cs +++ b/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 , , , ")] @@ -89,6 +90,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("MSUB , , , ")] @@ -125,6 +127,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("MSUB , , , ")] @@ -161,6 +164,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31)); } + CompareAgainstUnicorn(); } [Test, Description("SMADDL , , , ")] @@ -197,6 +201,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("UMADDL , , , ")] @@ -233,6 +238,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("SMSUBL , , , ")] @@ -269,6 +275,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("UMSUBL , , , ")] @@ -305,6 +312,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("SMULH , , ")] @@ -337,6 +345,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } [Test, Description("UMULH , , ")] @@ -369,6 +378,7 @@ namespace Ryujinx.Tests.Cpu { Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31)); } + CompareAgainstUnicorn(); } #endif } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimd.cs b/Ryujinx.Tests/Cpu/CpuTestSimd.cs index d1832ce8..dbf6b3c2 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimd.cs +++ b/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 ., .")] @@ -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 ., .")] @@ -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 , .")] @@ -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 , .")] @@ -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 , .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 , , #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 ., ., #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 ., ., #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 , , #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 ., ., #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 ., ., #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 , , #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 ., ., #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 ., ., #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 , , #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 ., ., #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 ., ., #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 , , #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 ., ., #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 ., ., #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 ., .")] @@ -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 ., .")] @@ -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 , ")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 .4S, .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 , ")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 , ")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 , ")] @@ -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} ., .")] @@ -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} ., .")] @@ -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 , ")] @@ -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} ., .")] @@ -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} ., .")] @@ -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 , ")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 ., .")] @@ -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 , ")] @@ -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} ., .")] @@ -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} ., .")] @@ -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 , ")] @@ -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 ., .")] @@ -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 ., .")] @@ -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} ., .")] @@ -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} ., .")] @@ -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 } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs b/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs index 53e15542..e9fd462e 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdArithmetic.cs @@ -33,6 +33,7 @@ namespace Ryujinx.Tests.Cpu V1: Sse.StaticCast(Sse2.SetVector128(0, A)), V2: Sse.StaticCast(Sse2.SetVector128(0, B))); Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast(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(Sse2.SetVector128(0, A)), V2: Sse.StaticCast(Sse2.SetVector128(0, B))); Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast(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 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 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 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 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 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 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 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 V1 = MakeVectorE0(A); AThreadState ThreadState = SingleOpcode(0x7EA1D820, V1: V1); Assert.AreEqual(Result, GetVectorE0(ThreadState.V0)); + CompareAgainstUnicorn(); } } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs b/Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs index 41f5113d..acf7000b 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdCmp.cs +++ b/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(); } } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs b/Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs index cce0db63..1e58a68a 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdCrypto.cs +++ b/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 .16B, .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 .16B, .16B")] @@ -98,6 +100,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH)); }); } + CompareAgainstUnicorn(); } [Test, Description("AESMC .16B, .16B")] @@ -130,6 +133,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH)); }); } + CompareAgainstUnicorn(); } } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs b/Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs index 2d021616..7f5f05ee 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdCvt.cs @@ -35,6 +35,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V1), (byte)2), Is.EqualTo(Result)); Assert.That(Sse41.Extract(Sse.StaticCast(ThreadState.V1), (byte)3), Is.EqualTo(Result)); }); + CompareAgainstUnicorn(); } } } diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs b/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs index 2ca91b37..782e5921 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdReg.cs +++ b/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 ., ., .")] @@ -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 ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 , , ")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 , , ")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 , , ")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 , , ")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 , , ")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 , , ")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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 , , .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 , , .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 .4S, .4S, .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 ., ., .")] @@ -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} ., ., .")] @@ -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 , , ")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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} ., ., .")] @@ -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 ., ., .")] @@ -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} ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 ., ., .")] @@ -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 } diff --git a/Ryujinx.Tests/Ryujinx.Tests.csproj b/Ryujinx.Tests/Ryujinx.Tests.csproj index a68b34e9..27c2bf78 100644 --- a/Ryujinx.Tests/Ryujinx.Tests.csproj +++ b/Ryujinx.Tests/Ryujinx.Tests.csproj @@ -5,6 +5,10 @@ win10-x64;osx-x64;linux-x64 Exe false + + windows + osx + linux @@ -20,6 +24,13 @@ + + + + + + +