Remove old Tester, update Tests (some reworks). (#400)
* Delete Bits.cs * Delete Integer.cs * Delete Instructions.cs * Delete Pseudocode.cs * Add files via upload * Add mnemonic. * Literals all uppercase. * Nit. * Allow FPSR control. * Allow FPSR control. * Allow FPSR control.
This commit is contained in:
@@ -33,9 +33,10 @@ namespace Ryujinx.Tests.Cpu
|
||||
static CpuTest()
|
||||
{
|
||||
UnicornAvailable = UnicornAArch64.IsAvailable();
|
||||
|
||||
if (!UnicornAvailable)
|
||||
{
|
||||
Console.WriteLine("WARNING: Could not find unicorn");
|
||||
Console.WriteLine("WARNING: Could not find Unicorn.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
public void Setup()
|
||||
{
|
||||
Position = 0x1000;
|
||||
Size = 0x1000;
|
||||
Size = 0x1000;
|
||||
|
||||
EntryPoint = Position;
|
||||
|
||||
@@ -79,10 +80,12 @@ namespace Ryujinx.Tests.Cpu
|
||||
protected void Opcode(uint Opcode)
|
||||
{
|
||||
Thread.Memory.WriteUInt32(Position, Opcode);
|
||||
|
||||
if (UnicornAvailable)
|
||||
{
|
||||
UnicornEmu.MemoryWrite32((ulong)Position, Opcode);
|
||||
}
|
||||
|
||||
Position += 4;
|
||||
}
|
||||
|
||||
@@ -97,14 +100,18 @@ namespace Ryujinx.Tests.Cpu
|
||||
Thread.ThreadState.X1 = X1;
|
||||
Thread.ThreadState.X2 = X2;
|
||||
Thread.ThreadState.X3 = X3;
|
||||
|
||||
Thread.ThreadState.X31 = X31;
|
||||
|
||||
Thread.ThreadState.V0 = V0;
|
||||
Thread.ThreadState.V1 = V1;
|
||||
Thread.ThreadState.V2 = V2;
|
||||
|
||||
Thread.ThreadState.Overflow = Overflow;
|
||||
Thread.ThreadState.Carry = Carry;
|
||||
Thread.ThreadState.Zero = Zero;
|
||||
Thread.ThreadState.Carry = Carry;
|
||||
Thread.ThreadState.Zero = Zero;
|
||||
Thread.ThreadState.Negative = Negative;
|
||||
|
||||
Thread.ThreadState.Fpcr = Fpcr;
|
||||
Thread.ThreadState.Fpsr = Fpsr;
|
||||
|
||||
@@ -114,14 +121,18 @@ namespace Ryujinx.Tests.Cpu
|
||||
UnicornEmu.X[1] = X1;
|
||||
UnicornEmu.X[2] = X2;
|
||||
UnicornEmu.X[3] = X3;
|
||||
|
||||
UnicornEmu.SP = X31;
|
||||
|
||||
UnicornEmu.Q[0] = V0;
|
||||
UnicornEmu.Q[1] = V1;
|
||||
UnicornEmu.Q[2] = V2;
|
||||
|
||||
UnicornEmu.OverflowFlag = Overflow;
|
||||
UnicornEmu.CarryFlag = Carry;
|
||||
UnicornEmu.ZeroFlag = Zero;
|
||||
UnicornEmu.CarryFlag = Carry;
|
||||
UnicornEmu.ZeroFlag = Zero;
|
||||
UnicornEmu.NegativeFlag = Negative;
|
||||
|
||||
UnicornEmu.Fpcr = Fpcr;
|
||||
UnicornEmu.Fpsr = Fpsr;
|
||||
}
|
||||
@@ -144,10 +155,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
}
|
||||
}
|
||||
|
||||
protected AThreadState GetThreadState()
|
||||
{
|
||||
return Thread.ThreadState;
|
||||
}
|
||||
protected AThreadState GetThreadState() => Thread.ThreadState;
|
||||
|
||||
protected AThreadState SingleOpcode(uint Opcode,
|
||||
ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0,
|
||||
@@ -166,23 +174,44 @@ namespace Ryujinx.Tests.Cpu
|
||||
return GetThreadState();
|
||||
}
|
||||
|
||||
protected void CompareAgainstUnicorn()
|
||||
[Flags]
|
||||
protected enum FPSR
|
||||
{
|
||||
None = 0,
|
||||
|
||||
/// <summary>Invalid Operation cumulative floating-point exception bit.</summary>
|
||||
IOC = 1 << 0,
|
||||
/// <summary>Divide by Zero cumulative floating-point exception bit.</summary>
|
||||
DZC = 1 << 1,
|
||||
/// <summary>Overflow cumulative floating-point exception bit.</summary>
|
||||
OFC = 1 << 2,
|
||||
/// <summary>Underflow cumulative floating-point exception bit.</summary>
|
||||
UFC = 1 << 3,
|
||||
/// <summary>Inexact cumulative floating-point exception bit.</summary>
|
||||
IXC = 1 << 4,
|
||||
/// <summary>Input Denormal cumulative floating-point exception bit.</summary>
|
||||
IDC = 1 << 7,
|
||||
/// <summary>Cumulative saturation bit.</summary>
|
||||
QC = 1 << 27
|
||||
}
|
||||
|
||||
protected void CompareAgainstUnicorn(FPSR FpsrMask = FPSR.None)
|
||||
{
|
||||
if (!UnicornAvailable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.That(Thread.ThreadState.X0, Is.EqualTo(UnicornEmu.X[0]));
|
||||
Assert.That(Thread.ThreadState.X1, Is.EqualTo(UnicornEmu.X[1]));
|
||||
Assert.That(Thread.ThreadState.X2, Is.EqualTo(UnicornEmu.X[2]));
|
||||
Assert.That(Thread.ThreadState.X3, Is.EqualTo(UnicornEmu.X[3]));
|
||||
Assert.That(Thread.ThreadState.X4, Is.EqualTo(UnicornEmu.X[4]));
|
||||
Assert.That(Thread.ThreadState.X5, Is.EqualTo(UnicornEmu.X[5]));
|
||||
Assert.That(Thread.ThreadState.X6, Is.EqualTo(UnicornEmu.X[6]));
|
||||
Assert.That(Thread.ThreadState.X7, Is.EqualTo(UnicornEmu.X[7]));
|
||||
Assert.That(Thread.ThreadState.X8, Is.EqualTo(UnicornEmu.X[8]));
|
||||
Assert.That(Thread.ThreadState.X9, Is.EqualTo(UnicornEmu.X[9]));
|
||||
Assert.That(Thread.ThreadState.X0, Is.EqualTo(UnicornEmu.X[0]));
|
||||
Assert.That(Thread.ThreadState.X1, Is.EqualTo(UnicornEmu.X[1]));
|
||||
Assert.That(Thread.ThreadState.X2, Is.EqualTo(UnicornEmu.X[2]));
|
||||
Assert.That(Thread.ThreadState.X3, Is.EqualTo(UnicornEmu.X[3]));
|
||||
Assert.That(Thread.ThreadState.X4, Is.EqualTo(UnicornEmu.X[4]));
|
||||
Assert.That(Thread.ThreadState.X5, Is.EqualTo(UnicornEmu.X[5]));
|
||||
Assert.That(Thread.ThreadState.X6, Is.EqualTo(UnicornEmu.X[6]));
|
||||
Assert.That(Thread.ThreadState.X7, Is.EqualTo(UnicornEmu.X[7]));
|
||||
Assert.That(Thread.ThreadState.X8, Is.EqualTo(UnicornEmu.X[8]));
|
||||
Assert.That(Thread.ThreadState.X9, Is.EqualTo(UnicornEmu.X[9]));
|
||||
Assert.That(Thread.ThreadState.X10, Is.EqualTo(UnicornEmu.X[10]));
|
||||
Assert.That(Thread.ThreadState.X11, Is.EqualTo(UnicornEmu.X[11]));
|
||||
Assert.That(Thread.ThreadState.X12, Is.EqualTo(UnicornEmu.X[12]));
|
||||
@@ -204,17 +233,19 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(Thread.ThreadState.X28, Is.EqualTo(UnicornEmu.X[28]));
|
||||
Assert.That(Thread.ThreadState.X29, Is.EqualTo(UnicornEmu.X[29]));
|
||||
Assert.That(Thread.ThreadState.X30, Is.EqualTo(UnicornEmu.X[30]));
|
||||
|
||||
Assert.That(Thread.ThreadState.X31, Is.EqualTo(UnicornEmu.SP));
|
||||
Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0]));
|
||||
Assert.That(Thread.ThreadState.V1, Is.EqualTo(UnicornEmu.Q[1]));
|
||||
Assert.That(Thread.ThreadState.V2, Is.EqualTo(UnicornEmu.Q[2]));
|
||||
Assert.That(Thread.ThreadState.V3, Is.EqualTo(UnicornEmu.Q[3]));
|
||||
Assert.That(Thread.ThreadState.V4, Is.EqualTo(UnicornEmu.Q[4]));
|
||||
Assert.That(Thread.ThreadState.V5, Is.EqualTo(UnicornEmu.Q[5]));
|
||||
Assert.That(Thread.ThreadState.V6, Is.EqualTo(UnicornEmu.Q[6]));
|
||||
Assert.That(Thread.ThreadState.V7, Is.EqualTo(UnicornEmu.Q[7]));
|
||||
Assert.That(Thread.ThreadState.V8, Is.EqualTo(UnicornEmu.Q[8]));
|
||||
Assert.That(Thread.ThreadState.V9, Is.EqualTo(UnicornEmu.Q[9]));
|
||||
|
||||
Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0]));
|
||||
Assert.That(Thread.ThreadState.V1, Is.EqualTo(UnicornEmu.Q[1]));
|
||||
Assert.That(Thread.ThreadState.V2, Is.EqualTo(UnicornEmu.Q[2]));
|
||||
Assert.That(Thread.ThreadState.V3, Is.EqualTo(UnicornEmu.Q[3]));
|
||||
Assert.That(Thread.ThreadState.V4, Is.EqualTo(UnicornEmu.Q[4]));
|
||||
Assert.That(Thread.ThreadState.V5, Is.EqualTo(UnicornEmu.Q[5]));
|
||||
Assert.That(Thread.ThreadState.V6, Is.EqualTo(UnicornEmu.Q[6]));
|
||||
Assert.That(Thread.ThreadState.V7, Is.EqualTo(UnicornEmu.Q[7]));
|
||||
Assert.That(Thread.ThreadState.V8, Is.EqualTo(UnicornEmu.Q[8]));
|
||||
Assert.That(Thread.ThreadState.V9, Is.EqualTo(UnicornEmu.Q[9]));
|
||||
Assert.That(Thread.ThreadState.V10, Is.EqualTo(UnicornEmu.Q[10]));
|
||||
Assert.That(Thread.ThreadState.V11, Is.EqualTo(UnicornEmu.Q[11]));
|
||||
Assert.That(Thread.ThreadState.V12, Is.EqualTo(UnicornEmu.Q[12]));
|
||||
@@ -238,11 +269,13 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(Thread.ThreadState.V30, Is.EqualTo(UnicornEmu.Q[30]));
|
||||
Assert.That(Thread.ThreadState.V31, Is.EqualTo(UnicornEmu.Q[31]));
|
||||
Assert.That(Thread.ThreadState.V31, Is.EqualTo(UnicornEmu.Q[31]));
|
||||
Assert.That(Thread.ThreadState.Fpcr, Is.EqualTo(UnicornEmu.Fpcr));
|
||||
Assert.That(Thread.ThreadState.Fpsr & 0x08000000, Is.EqualTo(UnicornEmu.Fpsr & 0x08000000));
|
||||
|
||||
Assert.That(Thread.ThreadState.Fpcr, Is.EqualTo(UnicornEmu.Fpcr));
|
||||
Assert.That(Thread.ThreadState.Fpsr & (int)FpsrMask, Is.EqualTo(UnicornEmu.Fpsr & (int)FpsrMask));
|
||||
|
||||
Assert.That(Thread.ThreadState.Overflow, Is.EqualTo(UnicornEmu.OverflowFlag));
|
||||
Assert.That(Thread.ThreadState.Carry, Is.EqualTo(UnicornEmu.CarryFlag));
|
||||
Assert.That(Thread.ThreadState.Zero, Is.EqualTo(UnicornEmu.ZeroFlag));
|
||||
Assert.That(Thread.ThreadState.Carry, Is.EqualTo(UnicornEmu.CarryFlag));
|
||||
Assert.That(Thread.ThreadState.Zero, Is.EqualTo(UnicornEmu.ZeroFlag));
|
||||
Assert.That(Thread.ThreadState.Negative, Is.EqualTo(UnicornEmu.NegativeFlag));
|
||||
}
|
||||
|
||||
|
||||
+37
-186
@@ -1,4 +1,4 @@
|
||||
//#define Alu
|
||||
#define Alu
|
||||
|
||||
using ChocolArm64.State;
|
||||
|
||||
@@ -6,334 +6,185 @@ using NUnit.Framework;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
using Tester;
|
||||
using Tester.Types;
|
||||
|
||||
[Category("Alu"), Ignore("Tested: second half of 2018.")]
|
||||
[Category("Alu")] // Tested: second half of 2018.
|
||||
public sealed class CpuTestAlu : CpuTest
|
||||
{
|
||||
#if Alu
|
||||
[SetUp]
|
||||
public void SetupTester()
|
||||
{
|
||||
AArch64.TakeReset(false);
|
||||
}
|
||||
private const int RndCnt = 2;
|
||||
|
||||
[Test, Description("CLS <Xd>, <Xn>")]
|
||||
[Test, Pairwise, Description("CLS <Xd>, <Xn>")]
|
||||
public void Cls_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||
{
|
||||
uint Opcode = 0xDAC01400; // CLS X0, X0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Cls(Op[31], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CLS <Wd>, <Wn>")]
|
||||
[Test, Pairwise, Description("CLS <Wd>, <Wn>")]
|
||||
public void Cls_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||
{
|
||||
uint Opcode = 0x5AC01400; // CLS W0, W0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Cls(Op[31], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CLZ <Xd>, <Xn>")]
|
||||
[Test, Pairwise, Description("CLZ <Xd>, <Xn>")]
|
||||
public void Clz_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||
{
|
||||
uint Opcode = 0xDAC01000; // CLZ X0, X0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Clz(Op[31], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CLZ <Wd>, <Wn>")]
|
||||
[Test, Pairwise, Description("CLZ <Wd>, <Wn>")]
|
||||
public void Clz_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||
{
|
||||
uint Opcode = 0x5AC01000; // CLZ W0, W0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Clz(Op[31], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("RBIT <Xd>, <Xn>")]
|
||||
[Test, Pairwise, Description("RBIT <Xd>, <Xn>")]
|
||||
public void Rbit_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||
{
|
||||
uint Opcode = 0xDAC00000; // RBIT X0, X0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Rbit(Op[31], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("RBIT <Wd>, <Wn>")]
|
||||
[Test, Pairwise, Description("RBIT <Wd>, <Wn>")]
|
||||
public void Rbit_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||
{
|
||||
uint Opcode = 0x5AC00000; // RBIT W0, W0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Rbit(Op[31], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("REV16 <Xd>, <Xn>")]
|
||||
[Test, Pairwise, Description("REV16 <Xd>, <Xn>")]
|
||||
public void Rev16_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||
{
|
||||
uint Opcode = 0xDAC00400; // REV16 X0, X0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Rev16(Op[31], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("REV16 <Wd>, <Wn>")]
|
||||
[Test, Pairwise, Description("REV16 <Wd>, <Wn>")]
|
||||
public void Rev16_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||
{
|
||||
uint Opcode = 0x5AC00400; // REV16 W0, W0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Rev16(Op[31], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("REV32 <Xd>, <Xn>")]
|
||||
[Test, Pairwise, Description("REV32 <Xd>, <Xn>")]
|
||||
public void Rev32_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||
{
|
||||
uint Opcode = 0xDAC00800; // REV32 X0, X0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Rev32(Op[31], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("REV <Wd>, <Wn>")]
|
||||
[Test, Pairwise, Description("REV <Wd>, <Wn>")]
|
||||
public void Rev32_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||
{
|
||||
uint Opcode = 0x5AC00800; // REV W0, W0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Rev32(Op[31], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("REV64 <Xd>, <Xn>")]
|
||||
[Test, Pairwise, Description("REV64 <Xd>, <Xn>")]
|
||||
public void Rev64_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||
{
|
||||
uint Opcode = 0xDAC00C00; // REV64 X0, X0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Rev64(Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//#define AluImm
|
||||
#define AluImm
|
||||
|
||||
using ChocolArm64.State;
|
||||
|
||||
@@ -6,824 +6,448 @@ using NUnit.Framework;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
using Tester;
|
||||
using Tester.Types;
|
||||
|
||||
[Category("AluImm"), Ignore("Tested: second half of 2018.")]
|
||||
[Category("AluImm")] // Tested: second half of 2018.
|
||||
public sealed class CpuTestAluImm : CpuTest
|
||||
{
|
||||
#if AluImm
|
||||
[SetUp]
|
||||
public void SetupTester()
|
||||
{
|
||||
AArch64.TakeReset(false);
|
||||
}
|
||||
private const int RndCnt = 2;
|
||||
private const int RndCntImm = 2;
|
||||
private const int RndCntImms = 2;
|
||||
private const int RndCntImmr = 2;
|
||||
|
||||
[Test, Description("ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||
[Test, Pairwise, Description("ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||
public void Add_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||
{
|
||||
uint Opcode = 0x91000000; // ADD X0, X0, #0, LSL #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AThreadState ThreadState;
|
||||
|
||||
if (Rn != 31)
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn_SP));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
||||
|
||||
AArch64.SP(new Bits(Xn_SP));
|
||||
}
|
||||
|
||||
Base.Add_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong SP = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||
[Test, Pairwise, Description("ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||
public void Add_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||
{
|
||||
uint Opcode = 0x11000000; // ADD W0, W0, #0, LSL #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AThreadState ThreadState;
|
||||
|
||||
if (Rn != 31)
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn_WSP));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
||||
|
||||
AArch64.SP(new Bits(Wn_WSP));
|
||||
}
|
||||
|
||||
Base.Add_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint WSP = AArch64.SP(32).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||
[Test, Pairwise, Description("ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||
public void Adds_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||
{
|
||||
uint Opcode = 0xB1000000; // ADDS X0, X0, #0, LSL #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AThreadState ThreadState;
|
||||
|
||||
if (Rn != 31)
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn_SP));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
||||
|
||||
AArch64.SP(new Bits(Xn_SP));
|
||||
}
|
||||
|
||||
Base.Adds_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong _X31 = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||
[Test, Pairwise, Description("ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||
public void Adds_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||
{
|
||||
uint Opcode = 0x31000000; // ADDS W0, W0, #0, LSL #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AThreadState ThreadState;
|
||||
|
||||
if (Rn != 31)
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn_WSP));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
||||
|
||||
AArch64.SP(new Bits(Wn_WSP));
|
||||
}
|
||||
|
||||
Base.Adds_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint _W31 = AArch64.SP(32).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("AND <Xd|SP>, <Xn>, #<imm>")]
|
||||
[Test, Pairwise, Description("AND <Xd|SP>, <Xn>, #<imm>")]
|
||||
public void And_N1_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0x92400000; // AND X0, X0, #0x1
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong SP = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("AND <Xd|SP>, <Xn>, #<imm>")]
|
||||
[Test, Pairwise, Description("AND <Xd|SP>, <Xn>, #<imm>")]
|
||||
public void And_N0_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0x92000000; // AND X0, X0, #0x100000001
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong SP = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("AND <Wd|WSP>, <Wn>, #<imm>")]
|
||||
[Test, Pairwise, Description("AND <Wd|WSP>, <Wn>, #<imm>")]
|
||||
public void And_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0x12000000; // AND W0, W0, #0x1
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint WSP = AArch64.SP(32).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
||||
[Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
||||
public void Ands_N1_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0xF2400000; // ANDS X0, X0, #0x1
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
||||
[Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
||||
public void Ands_N0_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0xF2000000; // ANDS X0, X0, #0x100000001
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ANDS <Wd>, <Wn>, #<imm>")]
|
||||
[Test, Pairwise, Description("ANDS <Wd>, <Wn>, #<imm>")]
|
||||
public void Ands_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0x72000000; // ANDS W0, W0, #0x1
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
|
||||
[Test, Pairwise, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
|
||||
public void Eor_N1_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0xD2400000; // EOR X0, X0, #0x1
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong SP = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
|
||||
[Test, Pairwise, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
|
||||
public void Eor_N0_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0xD2000000; // EOR X0, X0, #0x100000001
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong SP = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("EOR <Wd>, <Wn>, #<imm>")]
|
||||
[Test, Pairwise, Description("EOR <Wd>, <Wn>, #<imm>")]
|
||||
public void Eor_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0x52000000; // EOR W0, W0, #0x1
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint WSP = AArch64.SP(32).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
|
||||
[Test, Pairwise, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
|
||||
public void Orr_N1_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0xB2400000; // ORR X0, X0, #0x1
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong SP = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
|
||||
[Test, Pairwise, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
|
||||
public void Orr_N0_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0xB2000000; // ORR X0, X0, #0x100000001
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong SP = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("ORR <Wd|WSP>, <Wn>, #<imm>")]
|
||||
[Test, Pairwise, Description("ORR <Wd|WSP>, <Wn>, #<imm>")]
|
||||
public void Orr_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||
{
|
||||
uint Opcode = 0x32000000; // ORR W0, W0, #0x1
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint WSP = AArch64.SP(32).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||
[Test, Pairwise, Description("SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||
public void Sub_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||
{
|
||||
uint Opcode = 0xD1000000; // SUB X0, X0, #0, LSL #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AThreadState ThreadState;
|
||||
|
||||
if (Rn != 31)
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn_SP));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
||||
|
||||
AArch64.SP(new Bits(Xn_SP));
|
||||
}
|
||||
|
||||
Base.Sub_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong SP = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||
[Test, Pairwise, Description("SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||
public void Sub_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||
{
|
||||
uint Opcode = 0x51000000; // SUB W0, W0, #0, LSL #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AThreadState ThreadState;
|
||||
|
||||
if (Rn != 31)
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn_WSP));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
||||
|
||||
AArch64.SP(new Bits(Wn_WSP));
|
||||
}
|
||||
|
||||
Base.Sub_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint WSP = AArch64.SP(32).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||
[Test, Pairwise, Description("SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||
public void Subs_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||
{
|
||||
uint Opcode = 0xF1000000; // SUBS X0, X0, #0, LSL #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AThreadState ThreadState;
|
||||
|
||||
if (Rn != 31)
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn_SP));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
||||
|
||||
AArch64.SP(new Bits(Xn_SP));
|
||||
}
|
||||
|
||||
Base.Subs_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong _X31 = AArch64.SP(64).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||
[Test, Pairwise, Description("SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||
public void Subs_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||
{
|
||||
uint Opcode = 0x71000000; // SUBS W0, W0, #0, LSL #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AThreadState ThreadState;
|
||||
|
||||
if (Rn != 31)
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn_WSP));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
||||
|
||||
AArch64.SP(new Bits(Wn_WSP));
|
||||
}
|
||||
|
||||
Base.Subs_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint _W31 = AArch64.SP(32).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
|
||||
+248
-1089
File diff suppressed because it is too large
Load Diff
+101
-724
File diff suppressed because it is too large
Load Diff
+37
-122
@@ -1,4 +1,4 @@
|
||||
//#define Bfm
|
||||
#define Bfm
|
||||
|
||||
using ChocolArm64.State;
|
||||
|
||||
@@ -6,212 +6,127 @@ using NUnit.Framework;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
using Tester;
|
||||
using Tester.Types;
|
||||
|
||||
[Category("Bfm"), Ignore("Tested: second half of 2018.")]
|
||||
[Category("Bfm")] // Tested: second half of 2018.
|
||||
public sealed class CpuTestBfm : CpuTest
|
||||
{
|
||||
#if Bfm
|
||||
[SetUp]
|
||||
public void SetupTester()
|
||||
{
|
||||
AArch64.TakeReset(false);
|
||||
}
|
||||
private const int RndCnt = 2;
|
||||
private const int RndCntImmr = 2;
|
||||
private const int RndCntImms = 2;
|
||||
|
||||
[Test, Description("BFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||
[Test, Pairwise, Description("BFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||
public void Bfm_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Random(2)] ulong _Xd,
|
||||
[Random(RndCnt)] ulong _Xd,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||
{
|
||||
uint Opcode = 0xB3400000; // BFM X0, X0, #0, #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rd, new Bits(_Xd));
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Bfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("BFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||
[Test, Pairwise, Description("BFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||
public void Bfm_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Random(2)] uint _Wd,
|
||||
[Random(RndCnt)] uint _Wd,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||
{
|
||||
uint Opcode = 0x33000000; // BFM W0, W0, #0, #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X1: Wn, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rd, new Bits(_Wd));
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Bfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SBFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||
[Test, Pairwise, Description("SBFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||
public void Sbfm_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||
{
|
||||
uint Opcode = 0x93400000; // SBFM X0, X0, #0, #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Sbfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SBFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||
[Test, Pairwise, Description("SBFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||
public void Sbfm_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||
{
|
||||
uint Opcode = 0x13000000; // SBFM W0, W0, #0, #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Sbfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("UBFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||
[Test, Pairwise, Description("UBFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||
public void Ubfm_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||
{
|
||||
uint Opcode = 0xD3400000; // UBFM X0, X0, #0, #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Ubfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("UBFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||
[Test, Pairwise, Description("UBFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||
public void Ubfm_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||
{
|
||||
uint Opcode = 0x53000000; // UBFM W0, W0, #0, #0
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Ubfm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//#define CcmpImm
|
||||
#define CcmpImm
|
||||
|
||||
using ChocolArm64.State;
|
||||
|
||||
@@ -6,25 +6,20 @@ using NUnit.Framework;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
using Tester;
|
||||
using Tester.Types;
|
||||
|
||||
[Category("CcmpImm"), Ignore("Tested: second half of 2018.")]
|
||||
[Category("CcmpImm")] // Tested: second half of 2018.
|
||||
public sealed class CpuTestCcmpImm : CpuTest
|
||||
{
|
||||
#if CcmpImm
|
||||
[SetUp]
|
||||
public void SetupTester()
|
||||
{
|
||||
AArch64.TakeReset(false);
|
||||
}
|
||||
private const int RndCnt = 2;
|
||||
private const int RndCntImm = 2;
|
||||
private const int RndCntNzcv = 2;
|
||||
|
||||
[Test, Description("CCMN <Xn>, #<imm>, #<nzcv>, <cond>")]
|
||||
[Test, Pairwise, Description("CCMN <Xn>, #<imm>, #<nzcv>, <cond>")]
|
||||
public void Ccmn_64bit([Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
||||
[Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm,
|
||||
[Random(0u, 15u, 1)] uint nzcv,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -35,29 +30,18 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Ccmn_Imm(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[3, 0]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CCMN <Wn>, #<imm>, #<nzcv>, <cond>")]
|
||||
[Test, Pairwise, Description("CCMN <Wn>, #<imm>, #<nzcv>, <cond>")]
|
||||
public void Ccmn_32bit([Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
||||
[Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm,
|
||||
[Random(0u, 15u, 1)] uint nzcv,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -68,29 +52,18 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Ccmn_Imm(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[3, 0]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CCMP <Xn>, #<imm>, #<nzcv>, <cond>")]
|
||||
[Test, Pairwise, Description("CCMP <Xn>, #<imm>, #<nzcv>, <cond>")]
|
||||
public void Ccmp_64bit([Values(1u, 31u)] uint Rn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
||||
[Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm,
|
||||
[Random(0u, 15u, 1)] uint nzcv,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -101,29 +74,18 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
||||
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
Base.Ccmp_Imm(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[3, 0]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CCMP <Wn>, #<imm>, #<nzcv>, <cond>")]
|
||||
[Test, Pairwise, Description("CCMP <Wn>, #<imm>, #<nzcv>, <cond>")]
|
||||
public void Ccmp_32bit([Values(1u, 31u)] uint Rn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
||||
[Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm,
|
||||
[Random(0u, 15u, 1)] uint nzcv,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -134,20 +96,9 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
Base.Ccmp_Imm(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[3, 0]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//#define CcmpReg
|
||||
#define CcmpReg
|
||||
|
||||
using ChocolArm64.State;
|
||||
|
||||
@@ -6,27 +6,21 @@ using NUnit.Framework;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
using Tester;
|
||||
using Tester.Types;
|
||||
|
||||
[Category("CcmpReg"), Ignore("Tested: second half of 2018.")]
|
||||
[Category("CcmpReg")] // Tested: second half of 2018.
|
||||
public sealed class CpuTestCcmpReg : CpuTest
|
||||
{
|
||||
#if CcmpReg
|
||||
[SetUp]
|
||||
public void SetupTester()
|
||||
{
|
||||
AArch64.TakeReset(false);
|
||||
}
|
||||
private const int RndCnt = 2;
|
||||
private const int RndCntNzcv = 2;
|
||||
|
||||
[Test, Description("CCMN <Xn>, <Xm>, #<nzcv>, <cond>")]
|
||||
[Test, Pairwise, Description("CCMN <Xn>, <Xm>, #<nzcv>, <cond>")]
|
||||
public void Ccmn_64bit([Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
|
||||
[Random(0u, 15u, 1)] uint nzcv,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -37,32 +31,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
||||
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
Base.Ccmn_Reg(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[3, 0]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CCMN <Wn>, <Wm>, #<nzcv>, <cond>")]
|
||||
[Test, Pairwise, Description("CCMN <Wn>, <Wm>, #<nzcv>, <cond>")]
|
||||
public void Ccmn_32bit([Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
|
||||
[Random(0u, 15u, 1)] uint nzcv,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -73,32 +55,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
||||
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
Base.Ccmn_Reg(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[3, 0]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CCMP <Xn>, <Xm>, #<nzcv>, <cond>")]
|
||||
[Test, Pairwise, Description("CCMP <Xn>, <Xm>, #<nzcv>, <cond>")]
|
||||
public void Ccmp_64bit([Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
|
||||
[Random(0u, 15u, 1)] uint nzcv,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -109,32 +79,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
||||
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
Base.Ccmp_Reg(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[3, 0]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CCMP <Wn>, <Wm>, #<nzcv>, <cond>")]
|
||||
[Test, Pairwise, Description("CCMP <Wn>, <Wm>, #<nzcv>, <cond>")]
|
||||
public void Ccmp_32bit([Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
|
||||
[Random(0u, 15u, 1)] uint nzcv,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -145,21 +103,9 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
||||
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
Base.Ccmp_Reg(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[3, 0]);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
|
||||
Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
|
||||
Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
|
||||
Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
|
||||
});
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//#define Csel
|
||||
#define Csel
|
||||
|
||||
using ChocolArm64.State;
|
||||
|
||||
@@ -6,27 +6,20 @@ using NUnit.Framework;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
using Tester;
|
||||
using Tester.Types;
|
||||
|
||||
[Category("Csel"), Ignore("Tested: second half of 2018.")]
|
||||
[Category("Csel")] // Tested: second half of 2018.
|
||||
public sealed class CpuTestCsel : CpuTest
|
||||
{
|
||||
#if Csel
|
||||
[SetUp]
|
||||
public void SetupTester()
|
||||
{
|
||||
AArch64.TakeReset(false);
|
||||
}
|
||||
private const int RndCnt = 2;
|
||||
|
||||
[Test, Description("CSEL <Xd>, <Xn>, <Xm>, <cond>")]
|
||||
[Test, Pairwise, Description("CSEL <Xd>, <Xn>, <Xm>, <cond>")]
|
||||
public void Csel_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -37,34 +30,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
Base.Csel(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CSEL <Wd>, <Wn>, <Wm>, <cond>")]
|
||||
[Test, Pairwise, Description("CSEL <Wd>, <Wn>, <Wm>, <cond>")]
|
||||
public void Csel_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -75,34 +54,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
Base.Csel(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CSINC <Xd>, <Xn>, <Xm>, <cond>")]
|
||||
[Test, Pairwise, Description("CSINC <Xd>, <Xn>, <Xm>, <cond>")]
|
||||
public void Csinc_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -113,34 +78,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
Base.Csinc(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CSINC <Wd>, <Wn>, <Wm>, <cond>")]
|
||||
[Test, Pairwise, Description("CSINC <Wd>, <Wn>, <Wm>, <cond>")]
|
||||
public void Csinc_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -151,34 +102,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
Base.Csinc(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CSINV <Xd>, <Xn>, <Xm>, <cond>")]
|
||||
[Test, Pairwise, Description("CSINV <Xd>, <Xn>, <Xm>, <cond>")]
|
||||
public void Csinv_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -189,34 +126,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
Base.Csinv(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CSINV <Wd>, <Wn>, <Wm>, <cond>")]
|
||||
[Test, Pairwise, Description("CSINV <Wd>, <Wn>, <Wm>, <cond>")]
|
||||
public void Csinv_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -227,34 +150,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
Base.Csinv(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CSNEG <Xd>, <Xn>, <Xm>, <cond>")]
|
||||
[Test, Pairwise, Description("CSNEG <Xd>, <Xn>, <Xm>, <cond>")]
|
||||
public void Csneg_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -265,34 +174,20 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
Base.Csneg(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("CSNEG <Wd>, <Wn>, <Wm>, <cond>")]
|
||||
[Test, Pairwise, Description("CSNEG <Wd>, <Wn>, <Wm>, <cond>")]
|
||||
public void Csneg_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||
@@ -303,23 +198,9 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= ((cond & 15) << 12);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
Base.Csneg(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode(0xD65F03C0);
|
||||
ExecuteOpcodes();
|
||||
|
||||
Assert.That(Sse41.Extract(GetThreadState().V0, 0), Is.EqualTo(16f));
|
||||
Assert.That(Sse41.Extract(GetThreadState().V0, (byte)0), Is.EqualTo(16f));
|
||||
}
|
||||
|
||||
[TestCase(-20d, -5d)] // 18 integer solutions.
|
||||
@@ -137,7 +137,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode(0xD65F03C0);
|
||||
ExecuteOpcodes();
|
||||
|
||||
Assert.That(VectorExtractDouble(GetThreadState().V0, 0), Is.EqualTo(16d));
|
||||
Assert.That(VectorExtractDouble(GetThreadState().V0, (byte)0), Is.EqualTo(16d));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -163,27 +163,27 @@ namespace Ryujinx.Tests.Cpu
|
||||
}
|
||||
|
||||
/*
|
||||
0x0000000000000000: MOV W4, W0
|
||||
0x0000000000000004: CBZ W0, #0x3C
|
||||
0x0000000000000008: CMP W0, #1
|
||||
0x000000000000000C: B.LS #0x48
|
||||
0x0000000000000010: MOVZ W2, #0x2
|
||||
0x0000000000000014: MOVZ X1, #0x1
|
||||
0x0000000000000018: MOVZ X3, #0
|
||||
0x000000000000001C: ADD X0, X3, X1
|
||||
0x0000000000000020: ADD W2, W2, #1
|
||||
0x0000000000000024: MOV X3, X1
|
||||
0x0000000000000028: MOV X1, X0
|
||||
0x000000000000002C: CMP W4, W2
|
||||
0x0000000000000030: B.HS #0x1C
|
||||
0x0000000000000034: BRK #0
|
||||
0x0000000000000038: RET
|
||||
0x000000000000003C: MOVZ X0, #0
|
||||
0x0000000000000040: BRK #0
|
||||
0x0000000000000044: RET
|
||||
0x0000000000000048: MOVZ X0, #0x1
|
||||
0x000000000000004C: BRK #0
|
||||
0x0000000000000050: RET
|
||||
0x0000000000001000: MOV W4, W0
|
||||
0x0000000000001004: CBZ W0, #0x3C
|
||||
0x0000000000001008: CMP W0, #1
|
||||
0x000000000000100C: B.LS #0x48
|
||||
0x0000000000001010: MOVZ W2, #0x2
|
||||
0x0000000000001014: MOVZ X1, #0x1
|
||||
0x0000000000001018: MOVZ X3, #0
|
||||
0x000000000000101C: ADD X0, X3, X1
|
||||
0x0000000000001020: ADD W2, W2, #1
|
||||
0x0000000000001024: MOV X3, X1
|
||||
0x0000000000001028: MOV X1, X0
|
||||
0x000000000000102C: CMP W4, W2
|
||||
0x0000000000001030: B.HS #0x1C
|
||||
0x0000000000001034: BRK #0
|
||||
0x0000000000001038: RET
|
||||
0x000000000000103C: MOVZ X0, #0
|
||||
0x0000000000001040: BRK #0
|
||||
0x0000000000001044: RET
|
||||
0x0000000000001048: MOVZ X0, #0x1
|
||||
0x000000000000104C: BRK #0
|
||||
0x0000000000001050: RET
|
||||
*/
|
||||
|
||||
SetThreadState(X0: A);
|
||||
@@ -219,11 +219,11 @@ namespace Ryujinx.Tests.Cpu
|
||||
const ulong Result = 5;
|
||||
|
||||
/*
|
||||
0x0000000000000000: MOV X0, #2
|
||||
0x0000000000000004: MOV X1, #3
|
||||
0x0000000000000008: ADD X0, X0, X1
|
||||
0x000000000000000C: BRK #0
|
||||
0x0000000000000010: RET
|
||||
0x0000000000001000: MOV X0, #2
|
||||
0x0000000000001004: MOV X1, #3
|
||||
0x0000000000001008: ADD X0, X0, X1
|
||||
0x000000000000100C: BRK #0
|
||||
0x0000000000001010: RET
|
||||
*/
|
||||
|
||||
Opcode(0xD2800040);
|
||||
@@ -238,11 +238,11 @@ namespace Ryujinx.Tests.Cpu
|
||||
Reset();
|
||||
|
||||
/*
|
||||
0x0000000000000000: MOV X0, #3
|
||||
0x0000000000000004: MOV X1, #2
|
||||
0x0000000000000008: ADD X0, X0, X1
|
||||
0x000000000000000C: BRK #0
|
||||
0x0000000000000010: RET
|
||||
0x0000000000001000: MOV X0, #3
|
||||
0x0000000000001004: MOV X1, #2
|
||||
0x0000000000001008: ADD X0, X0, X1
|
||||
0x000000000000100C: BRK #0
|
||||
0x0000000000001010: RET
|
||||
*/
|
||||
|
||||
Opcode(0xD2800060);
|
||||
|
||||
+23
-104
@@ -1,4 +1,4 @@
|
||||
//#define Mov
|
||||
#define Mov
|
||||
|
||||
using ChocolArm64.State;
|
||||
|
||||
@@ -6,23 +6,16 @@ using NUnit.Framework;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
using Tester;
|
||||
using Tester.Types;
|
||||
|
||||
[Category("Mov"), Ignore("Tested: second half of 2018.")]
|
||||
[Category("Mov")] // Tested: second half of 2018.
|
||||
public sealed class CpuTestMov : CpuTest
|
||||
{
|
||||
#if Mov
|
||||
[SetUp]
|
||||
public void SetupTester()
|
||||
{
|
||||
AArch64.TakeReset(false);
|
||||
}
|
||||
private const int RndCntImm = 2;
|
||||
|
||||
[Test, Description("MOVK <Xd>, #<imm>{, LSL #<shift>}")]
|
||||
[Test, Pairwise, Description("MOVK <Xd>, #<imm>{, LSL #<shift>}")]
|
||||
public void Movk_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Random(12)] ulong _Xd,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, 10)] uint imm,
|
||||
[Random(RndCntImm)] ulong _Xd,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||
{
|
||||
uint Opcode = 0xF2800000; // MOVK X0, #0, LSL #0
|
||||
@@ -30,29 +23,16 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rd, new Bits(_Xd));
|
||||
Base.Movk(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("MOVK <Wd>, #<imm>{, LSL #<shift>}")]
|
||||
[Test, Pairwise, Description("MOVK <Wd>, #<imm>{, LSL #<shift>}")]
|
||||
public void Movk_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Random(12)] uint _Wd,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, 10)] uint imm,
|
||||
[Random(RndCntImm)] uint _Wd,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||
[Values(0u, 16u)] uint shift)
|
||||
{
|
||||
uint Opcode = 0x72800000; // MOVK W0, #0, LSL #0
|
||||
@@ -60,28 +40,15 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rd, new Bits(_Wd));
|
||||
Base.Movk(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("MOVN <Xd>, #<imm>{, LSL #<shift>}")]
|
||||
[Test, Pairwise, Description("MOVN <Xd>, #<imm>{, LSL #<shift>}")]
|
||||
public void Movn_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||
{
|
||||
uint Opcode = 0x92800000; // MOVN X0, #0, LSL #0
|
||||
@@ -89,27 +56,15 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
Base.Movn(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("MOVN <Wd>, #<imm>{, LSL #<shift>}")]
|
||||
[Test, Pairwise, Description("MOVN <Wd>, #<imm>{, LSL #<shift>}")]
|
||||
public void Movn_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||
[Values(0u, 16u)] uint shift)
|
||||
{
|
||||
uint Opcode = 0x12800000; // MOVN W0, #0, LSL #0
|
||||
@@ -117,27 +72,15 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
Base.Movn(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("MOVZ <Xd>, #<imm>{, LSL #<shift>}")]
|
||||
[Test, Pairwise, Description("MOVZ <Xd>, #<imm>{, LSL #<shift>}")]
|
||||
public void Movz_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||
{
|
||||
uint Opcode = 0xD2800000; // MOVZ X0, #0, LSL #0
|
||||
@@ -145,27 +88,15 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
Base.Movz(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("MOVZ <Wd>, #<imm>{, LSL #<shift>}")]
|
||||
[Test, Pairwise, Description("MOVZ <Wd>, #<imm>{, LSL #<shift>}")]
|
||||
public void Movz_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm,
|
||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||
[Values(0u, 16u)] uint shift)
|
||||
{
|
||||
uint Opcode = 0x52800000; // MOVZ W0, #0, LSL #0
|
||||
@@ -173,21 +104,9 @@ namespace Ryujinx.Tests.Cpu
|
||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
Base.Movz(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
|
||||
+51
-206
@@ -1,4 +1,4 @@
|
||||
//#define Mul
|
||||
#define Mul
|
||||
|
||||
using ChocolArm64.State;
|
||||
|
||||
@@ -6,378 +6,223 @@ using NUnit.Framework;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
using Tester;
|
||||
using Tester.Types;
|
||||
|
||||
[Category("Mul"), Ignore("Tested: second half of 2018.")]
|
||||
[Category("Mul")] // Tested: second half of 2018.
|
||||
public sealed class CpuTestMul : CpuTest
|
||||
{
|
||||
#if Mul
|
||||
[SetUp]
|
||||
public void SetupTester()
|
||||
{
|
||||
AArch64.TakeReset(false);
|
||||
}
|
||||
private const int RndCnt = 2;
|
||||
|
||||
[Test, Description("MADD <Xd>, <Xn>, <Xm>, <Xa>")]
|
||||
[Test, Pairwise, Description("MADD <Xd>, <Xn>, <Xm>, <Xa>")]
|
||||
public void Madd_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(3u, 31u)] uint Ra,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||
{
|
||||
uint Opcode = 0x9B000000; // MADD X0, X0, X0, X0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
AArch64.X((int)Ra, new Bits(Xa));
|
||||
Base.Madd(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("MADD <Wd>, <Wn>, <Wm>, <Wa>")]
|
||||
[Test, Pairwise, Description("MADD <Wd>, <Wn>, <Wm>, <Wa>")]
|
||||
public void Madd_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(3u, 31u)] uint Ra,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wa)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wa)
|
||||
{
|
||||
uint Opcode = 0x1B000000; // MADD W0, W0, W0, W0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
AArch64.X((int)Ra, new Bits(Wa));
|
||||
Base.Madd(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("MSUB <Xd>, <Xn>, <Xm>, <Xa>")]
|
||||
[Test, Pairwise, Description("MSUB <Xd>, <Xn>, <Xm>, <Xa>")]
|
||||
public void Msub_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(3u, 31u)] uint Ra,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||
{
|
||||
uint Opcode = 0x9B008000; // MSUB X0, X0, X0, X0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
AArch64.X((int)Ra, new Bits(Xa));
|
||||
Base.Msub(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("MSUB <Wd>, <Wn>, <Wm>, <Wa>")]
|
||||
[Test, Pairwise, Description("MSUB <Wd>, <Wn>, <Wm>, <Wa>")]
|
||||
public void Msub_32bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(3u, 31u)] uint Ra,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wa)
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wa)
|
||||
{
|
||||
uint Opcode = 0x1B008000; // MSUB W0, W0, W0, W0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
AArch64.X((int)Ra, new Bits(Wa));
|
||||
Base.Msub(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
|
||||
uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
|
||||
|
||||
Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||
[Test, Pairwise, Description("SMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||
public void Smaddl_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(3u, 31u)] uint Ra,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||
{
|
||||
uint Opcode = 0x9B200000; // SMADDL X0, W0, W0, X0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
AArch64.X((int)Ra, new Bits(Xa));
|
||||
Base.Smaddl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("UMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||
[Test, Pairwise, Description("UMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||
public void Umaddl_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(3u, 31u)] uint Ra,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||
{
|
||||
uint Opcode = 0x9BA00000; // UMADDL X0, W0, W0, X0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
AArch64.X((int)Ra, new Bits(Xa));
|
||||
Base.Umaddl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||
[Test, Pairwise, Description("SMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||
public void Smsubl_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(3u, 31u)] uint Ra,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||
{
|
||||
uint Opcode = 0x9B208000; // SMSUBL X0, W0, W0, X0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
AArch64.X((int)Ra, new Bits(Xa));
|
||||
Base.Smsubl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("UMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||
[Test, Pairwise, Description("UMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||
public void Umsubl_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(3u, 31u)] uint Ra,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||
{
|
||||
uint Opcode = 0x9BA08000; // UMSUBL X0, W0, W0, X0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Wn));
|
||||
AArch64.X((int)Rm, new Bits(Wm));
|
||||
AArch64.X((int)Ra, new Bits(Xa));
|
||||
Base.Umsubl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("SMULH <Xd>, <Xn>, <Xm>")]
|
||||
[Test, Pairwise, Description("SMULH <Xd>, <Xn>, <Xm>")]
|
||||
public void Smulh_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xm)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm)
|
||||
{
|
||||
uint Opcode = 0x9B407C00; // SMULH X0, X0, X0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
Base.Smulh(Op[20, 16], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("UMULH <Xd>, <Xn>, <Xm>")]
|
||||
[Test, Pairwise, Description("UMULH <Xd>, <Xn>, <Xm>")]
|
||||
public void Umulh_64bit([Values(0u, 31u)] uint Rd,
|
||||
[Values(1u, 31u)] uint Rn,
|
||||
[Values(2u, 31u)] uint Rm,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xn,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xm)
|
||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm)
|
||||
{
|
||||
uint Opcode = 0x9BC07C00; // UMULH X0, X0, X0
|
||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
||||
|
||||
if (Rd != 31)
|
||||
{
|
||||
Bits Op = new Bits(Opcode);
|
||||
|
||||
AArch64.X((int)Rn, new Bits(Xn));
|
||||
AArch64.X((int)Rm, new Bits(Xm));
|
||||
Base.Umulh(Op[20, 16], Op[9, 5], Op[4, 0]);
|
||||
ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
|
||||
|
||||
Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
|
||||
}
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
|
||||
+135
-923
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
public class CpuTestSimdArithmetic : CpuTest
|
||||
{
|
||||
[TestCase(0x1E224820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x1E224820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000000000000ul)] // FMAX S0, S1, S2
|
||||
[TestCase(0x1E224820u, 0x0000000080000000ul, 0x0000000000000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x1E224820u, 0x0000000080000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
|
||||
[TestCase(0x1E224820u, 0x0000000080000000ul, 0x000000003DCCCCCDul, 0x000000003DCCCCCDul)]
|
||||
@@ -22,17 +22,19 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x1E224820u, 0x000000007F800001ul, 0x000000007FC00042ul, 0x000000007FC00001ul)]
|
||||
[TestCase(0x1E224820u, 0x000000007FC00042ul, 0x000000007F800001ul, 0x000000007FC00001ul)]
|
||||
[TestCase(0x1E224820u, 0x000000007FC0000Aul, 0x000000007FC0000Bul, 0x000000007FC0000Aul)]
|
||||
[TestCase(0x1E624820u, 0x0000000000000000ul, 0x8000000000000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x1E624820u, 0x0000000000000000ul, 0x8000000000000000ul, 0x0000000000000000ul)] // FMAX D0, D1, D2
|
||||
[TestCase(0x1E624820u, 0x8000000000000000ul, 0x0000000000000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x1E624820u, 0x8000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)]
|
||||
[TestCase(0x1E624820u, 0x8000000000000000ul, 0x3FF3333333333333ul, 0x3FF3333333333333ul)]
|
||||
public void Fmax_S(uint Opcode, ulong A, ulong B, ulong Result)
|
||||
{
|
||||
// FMAX S0, S1, S2
|
||||
AThreadState ThreadState = SingleOpcode(Opcode,
|
||||
V1: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, A)),
|
||||
V2: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, B)));
|
||||
Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast<float, ulong>(ThreadState.V0), 0));
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
Vector128<float> V2 = MakeVectorE0(B);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -51,19 +53,23 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x7FC0000Au, 0x7FC0000Au, 0x7FC0000Bu, 0x7FC0000Bu, 0x7FC0000Au, 0x7FC0000Au)]
|
||||
public void Fmax_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1)
|
||||
{
|
||||
uint Opcode = 0x4E22F420;
|
||||
uint Opcode = 0x4E22F420; // FMAX V0.4S, V1.4S, V2.4S
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
Vector128<float> V2 = MakeVectorE0E1(C, D);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[TestCase(0x1E225820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
|
||||
[TestCase(0x1E225820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000080000000ul)] // FMIN S0, S1, S2
|
||||
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x0000000000000000ul, 0x0000000080000000ul)]
|
||||
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
|
||||
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x000000003DCCCCCDul, 0x0000000080000000ul)]
|
||||
@@ -76,17 +82,19 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x1E225820u, 0x000000007F800001ul, 0x000000007FC00042ul, 0x000000007FC00001ul)]
|
||||
[TestCase(0x1E225820u, 0x000000007FC00042ul, 0x000000007F800001ul, 0x000000007FC00001ul)]
|
||||
[TestCase(0x1E225820u, 0x000000007FC0000Aul, 0x000000007FC0000Bul, 0x000000007FC0000Aul)]
|
||||
[TestCase(0x1E625820u, 0x0000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)]
|
||||
[TestCase(0x1E625820u, 0x0000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)] // FMIN D0, D1, D2
|
||||
[TestCase(0x1E625820u, 0x8000000000000000ul, 0x0000000000000000ul, 0x8000000000000000ul)]
|
||||
[TestCase(0x1E625820u, 0x8000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)]
|
||||
[TestCase(0x1E625820u, 0x8000000000000000ul, 0x3FF3333333333333ul, 0x8000000000000000ul)]
|
||||
public void Fmin_S(uint Opcode, ulong A, ulong B, ulong Result)
|
||||
{
|
||||
// FMIN S0, S1, S2
|
||||
AThreadState ThreadState = SingleOpcode(Opcode,
|
||||
V1: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, A)),
|
||||
V2: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, B)));
|
||||
Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast<float, ulong>(ThreadState.V0), 0));
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
Vector128<float> V2 = MakeVectorE0(B);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -105,15 +113,19 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x7FC0000Au, 0x7FC0000Au, 0x7FC0000Bu, 0x7FC0000Bu, 0x7FC0000Au, 0x7FC0000Au)]
|
||||
public void Fmin_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1)
|
||||
{
|
||||
uint Opcode = 0x4EA2F420;
|
||||
uint Opcode = 0x4EA2F420; // FMIN V0.4S, V1.4S, V2.4S
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
Vector128<float> V2 = MakeVectorE0E1(C, D);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -125,6 +137,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
V0: Sse.SetVector128(0, B, 0, 0));
|
||||
|
||||
Assert.That(Sse41.Extract(ThreadState.V6, (byte)0), Is.EqualTo(A * B));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -137,21 +150,27 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x007FF000u, 0x7E800000u)]
|
||||
public void Frecpe_S(uint A, uint Result)
|
||||
{
|
||||
uint Opcode = 0x5EA1D820; // FRECPE S0, S1
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
AThreadState ThreadState = SingleOpcode(0x5EA1D820, V1: V1);
|
||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FRECPS D0, D1, D2")]
|
||||
[Test, Description("FRECPS D0, D1, D2"), Ignore("Not accurate enough.")]
|
||||
public void Frecps_S([Random(10)] double A, [Random(10)] double B)
|
||||
{
|
||||
AThreadState ThreadState = SingleOpcode(0x5E62FC20,
|
||||
V1: MakeVectorE0(A),
|
||||
V2: MakeVectorE0(B));
|
||||
|
||||
Assert.That(VectorExtractDouble(ThreadState.V0, 0), Is.EqualTo(2 - (A * B)));
|
||||
//CompareAgainstUnicorn(); // Not accurate enough
|
||||
Assert.That(VectorExtractDouble(ThreadState.V0, (byte)0), Is.EqualTo(2 - (A * B)));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FRECPS V4.4S, V2.4S, V0.4S")]
|
||||
@@ -170,6 +189,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(Sse41.Extract(ThreadState.V4, (byte)2), Is.EqualTo(Result));
|
||||
Assert.That(Sse41.Extract(ThreadState.V4, (byte)3), Is.EqualTo(Result));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -177,7 +197,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
||||
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
||||
[TestCase(0x40733333u, false, 0x40800000u)]
|
||||
[TestCase(0x3fc00000u, false, 0x40000000u)]
|
||||
[TestCase(0x3FC00000u, false, 0x40000000u)]
|
||||
[TestCase(0x40200000u, false, 0x40400000u)]
|
||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||
@@ -213,42 +233,53 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||
public void Frinta_S(uint A, bool DefaultNaN, uint Result)
|
||||
{
|
||||
uint Opcode = 0x1E264020; // FRINTA S0, S1
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp = 0x2000000;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp);
|
||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[TestCase(0x6E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[Ignore("Wrong opcodes.")]
|
||||
[TestCase(0x6E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTA V0.2D, V1.2D
|
||||
[TestCase(0x6E618820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x6E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x3f80000040000000ul)]
|
||||
[TestCase(0x6E219820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTX V0.4S, V1.4S
|
||||
[TestCase(0x6E219820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTX V0.2S, V1.2S
|
||||
[TestCase(0x2E219820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] // FRINTA V0.2S, V1.2S
|
||||
[TestCase(0x2E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
public void Frinta_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1)
|
||||
{
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp = 0x2000000;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -294,36 +325,31 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||
public void Frinti_S(uint A, char RoundType, bool DefaultNaN, uint Result)
|
||||
{
|
||||
uint Opcode = 0x1E27C020; // FRINTI S0, S1
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
switch(RoundType)
|
||||
{
|
||||
case 'N':
|
||||
FpcrTemp = 0x0;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
FpcrTemp = 0x400000;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
FpcrTemp = 0x800000;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
FpcrTemp = 0xC00000;
|
||||
break;
|
||||
case 'N': FpcrTemp = 0x0; break;
|
||||
case 'P': FpcrTemp = 0x400000; break;
|
||||
case 'M': FpcrTemp = 0x800000; break;
|
||||
case 'Z': FpcrTemp = 0xC00000; break;
|
||||
}
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp |= 1 << 25;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
AThreadState ThreadState = SingleOpcode(0x1E27C020, V1: V1, Fpcr: FpcrTemp);
|
||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTI V0.2D, V1.2D
|
||||
[TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'N', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
@@ -331,14 +357,14 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x3f80000040000000ul)]
|
||||
[TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
||||
[TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
||||
[TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTI V0.4S, V1.4S
|
||||
[TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
|
||||
[TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
|
||||
[TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTI V0.2S, V1.2S
|
||||
[TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'M', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
@@ -357,36 +383,29 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
public void Frinti_V(uint Opcode, ulong A, ulong B, char RoundType, bool DefaultNaN, ulong Result0, ulong Result1)
|
||||
{
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
switch(RoundType)
|
||||
{
|
||||
case 'N':
|
||||
FpcrTemp = 0x0;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
FpcrTemp = 0x400000;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
FpcrTemp = 0x800000;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
FpcrTemp = 0xC00000;
|
||||
break;
|
||||
case 'N': FpcrTemp = 0x0; break;
|
||||
case 'P': FpcrTemp = 0x400000; break;
|
||||
case 'M': FpcrTemp = 0x800000; break;
|
||||
case 'Z': FpcrTemp = 0xC00000; break;
|
||||
}
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp |= 1 << 25;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -394,7 +413,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
||||
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
||||
[TestCase(0x40733333u, false, 0x40400000u)]
|
||||
[TestCase(0x3fc00000u, false, 0x3F800000u)]
|
||||
[TestCase(0x3FC00000u, false, 0x3F800000u)]
|
||||
[TestCase(0x40200000u, false, 0x40000000u)]
|
||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||
@@ -430,47 +449,58 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||
public void Frintm_S(uint A, bool DefaultNaN, uint Result)
|
||||
{
|
||||
uint Opcode = 0x1E254020; // FRINTM S0, S1
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp = 0x2000000;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
AThreadState ThreadState = SingleOpcode(0x1E254020, V1: V1, Fpcr: FpcrTemp);
|
||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[TestCase(0x4E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x4E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTM V0.2D, V1.2D
|
||||
[TestCase(0x4E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x4E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
||||
[TestCase(0xE219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xE219820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xE219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xE219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0xE219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0x4E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)] // FRINTM V0.4S, V1.4S
|
||||
[TestCase(0x0E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F8000003F800000ul, 0x0000000000000000ul)] // FRINTM V0.2S, V1.2S
|
||||
[TestCase(0x0E219820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x0E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
public void Frintm_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1)
|
||||
{
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp = 0x2000000;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Ignore("Wrong opcode.")]
|
||||
[TestCase(0x3FE66666u, false, 0x40000000u)]
|
||||
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
||||
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
||||
[TestCase(0x40733333u, false, 0x40800000u)]
|
||||
[TestCase(0x3fc00000u, false, 0x40000000u)]
|
||||
[TestCase(0x3FC00000u, false, 0x40000000u)]
|
||||
[TestCase(0x40200000u, false, 0x40400000u)]
|
||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||
@@ -506,42 +536,52 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||
public void Frintn_S(uint A, bool DefaultNaN, uint Result)
|
||||
{
|
||||
uint Opcode = 0x1E264020; // FRINTA S0, S1
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp = 0x2000000;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp);
|
||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[TestCase(0x4E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x4E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTN V0.2D, V1.2D
|
||||
[TestCase(0x4E618820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x4E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x4E218820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x3f80000040000000ul)]
|
||||
[TestCase(0x4E218820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0xE218820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xE218820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xE218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xE218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xE218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0xE218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0x4E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTN V0.4S, V1.4S
|
||||
[TestCase(0x4E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0x0E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTN V0.2S, V1.2S
|
||||
[TestCase(0x0E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x0E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x0E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
public void Frintn_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1)
|
||||
{
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp = 0x2000000;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -549,7 +589,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x3F99999Au, false, 0x40000000u)]
|
||||
[TestCase(0x404CCCCDu, false, 0x40800000u)]
|
||||
[TestCase(0x40733333u, false, 0x40800000u)]
|
||||
[TestCase(0x3fc00000u, false, 0x40000000u)]
|
||||
[TestCase(0x3FC00000u, false, 0x40000000u)]
|
||||
[TestCase(0x40200000u, false, 0x40400000u)]
|
||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||
@@ -585,39 +625,49 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||
public void Frintp_S(uint A, bool DefaultNaN, uint Result)
|
||||
{
|
||||
uint Opcode = 0x1E24C020; // FRINTP S0, S1
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp = 0x2000000;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
AThreadState ThreadState = SingleOpcode(0x1E24C020, V1: V1, Fpcr: FpcrTemp);
|
||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[TestCase(0x4EE18820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x4EE18820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x4000000000000000ul, 0x4000000000000000ul)] // FRINTP V0.2D, v1.2D
|
||||
[TestCase(0x4EE18820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x4EA18820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0xEA18820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xEA18820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xEA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0xEA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0xEA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0x4EA18820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] // FRINTP V0.4S, v1.4S
|
||||
[TestCase(0x0EA18820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] // FRINTP V0.2S, v1.2S
|
||||
[TestCase(0x0EA18820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x0EA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
[TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
public void Frintp_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1)
|
||||
{
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp = 0x2000000;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -663,36 +713,31 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||
public void Frintx_S(uint A, char RoundType, bool DefaultNaN, uint Result)
|
||||
{
|
||||
uint Opcode = 0x1E274020; // FRINTX S0, S1
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
switch(RoundType)
|
||||
{
|
||||
case 'N':
|
||||
FpcrTemp = 0x0;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
FpcrTemp = 0x400000;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
FpcrTemp = 0x800000;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
FpcrTemp = 0xC00000;
|
||||
break;
|
||||
case 'N': FpcrTemp = 0x0; break;
|
||||
case 'P': FpcrTemp = 0x400000; break;
|
||||
case 'M': FpcrTemp = 0x800000; break;
|
||||
case 'Z': FpcrTemp = 0xC00000; break;
|
||||
}
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp |= 1 << 25;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
AThreadState ThreadState = SingleOpcode(0x1E274020, V1: V1, Fpcr: FpcrTemp);
|
||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTX V0.2D, V1.2D
|
||||
[TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'N', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
[TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||
@@ -700,14 +745,14 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x3f80000040000000ul)]
|
||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTX V0.4S, V1.4S
|
||||
[TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||
[TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
|
||||
[TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
|
||||
[TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTX V0.2S, V1.2S
|
||||
[TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
[TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'M', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||
@@ -726,45 +771,43 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||
public void Frintx_V(uint Opcode, ulong A, ulong B, char RoundType, bool DefaultNaN, ulong Result0, ulong Result1)
|
||||
{
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
int FpcrTemp = 0x0;
|
||||
switch(RoundType)
|
||||
{
|
||||
case 'N':
|
||||
FpcrTemp = 0x0;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
FpcrTemp = 0x400000;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
FpcrTemp = 0x800000;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
FpcrTemp = 0xC00000;
|
||||
break;
|
||||
case 'N': FpcrTemp = 0x0; break;
|
||||
case 'P': FpcrTemp = 0x400000; break;
|
||||
case 'M': FpcrTemp = 0x800000; break;
|
||||
case 'Z': FpcrTemp = 0xC00000; break;
|
||||
}
|
||||
if(DefaultNaN)
|
||||
{
|
||||
FpcrTemp |= 1 << 25;
|
||||
}
|
||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[TestCase(0x41200000u, 0x3EA18000u)]
|
||||
public void Frsqrte_S(uint A, uint Result)
|
||||
{
|
||||
uint Opcode = 0x7EA1D820; // FRSQRTE S0, S1
|
||||
|
||||
Vector128<float> V1 = MakeVectorE0(A);
|
||||
AThreadState ThreadState = SingleOpcode(0x7EA1D820, V1: V1);
|
||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1);
|
||||
|
||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,15 @@ namespace Ryujinx.Tests.Cpu
|
||||
}
|
||||
#endregion
|
||||
|
||||
private const int RndCnt = 2;
|
||||
|
||||
[Test, Description("FCMEQ D0, D1, D2 | FCMGE D0, D1, D2 | FCMGT D0, D1, D2")]
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_S_D([ValueSource("_doubles_")] [Random(8)] double A,
|
||||
[ValueSource("_doubles_")] [Random(8)] double B,
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_S_D([ValueSource("_doubles_")] [Random(RndCnt)] double A,
|
||||
[ValueSource("_doubles_")] [Random(RndCnt)] double B,
|
||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||
{
|
||||
uint Opcode = 0x5E62E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||
|
||||
Vector128<float> V0 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(TestContext.CurrentContext.Random.NextDouble()));
|
||||
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetScalarVector128(A));
|
||||
Vector128<float> V2 = Sse.StaticCast<double, float>(Sse2.SetScalarVector128(B));
|
||||
@@ -52,15 +55,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp));
|
||||
Assert.That(VectorExtractDouble(ThreadState.V0, (byte)1), Is.Zero);
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMEQ S0, S1, S2 | FCMGE S0, S1, S2 | FCMGT S0, S1, S2")]
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_S_S([ValueSource("_floats_")] [Random(8)] float A,
|
||||
[ValueSource("_floats_")] [Random(8)] float B,
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_S_S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||
[ValueSource("_floats_")] [Random(RndCnt)] float B,
|
||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||
{
|
||||
uint Opcode = 0x5E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||
|
||||
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
||||
Vector128<float> V1 = Sse.SetScalarVector128(A);
|
||||
Vector128<float> V2 = Sse.SetScalarVector128(B);
|
||||
@@ -85,15 +90,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)2), Is.Zero);
|
||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMEQ V0.2D, V1.2D, V2.2D | FCMGE V0.2D, V1.2D, V2.2D | FCMGT V0.2D, V1.2D, V2.2D")]
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_V_2D([ValueSource("_doubles_")] [Random(8)] double A,
|
||||
[ValueSource("_doubles_")] [Random(8)] double B,
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_V_2D([ValueSource("_doubles_")] [Random(RndCnt)] double A,
|
||||
[ValueSource("_doubles_")] [Random(RndCnt)] double B,
|
||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||
{
|
||||
uint Opcode = 0x4E62E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||
|
||||
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(A));
|
||||
Vector128<float> V2 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(B));
|
||||
|
||||
@@ -115,15 +122,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp));
|
||||
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)1)), Is.EquivalentTo(Exp));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMEQ V0.2S, V1.2S, V2.2S | FCMGE V0.2S, V1.2S, V2.2S | FCMGT V0.2S, V1.2S, V2.2S")]
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_V_2S([ValueSource("_floats_")] [Random(8)] float A,
|
||||
[ValueSource("_floats_")] [Random(8)] float B,
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_V_2S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||
[ValueSource("_floats_")] [Random(RndCnt)] float B,
|
||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||
{
|
||||
uint Opcode = 0x0E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||
|
||||
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
||||
Vector128<float> V1 = Sse.SetVector128(0, 0, A, A);
|
||||
Vector128<float> V2 = Sse.SetVector128(0, 0, B, B);
|
||||
@@ -148,15 +157,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)2), Is.Zero);
|
||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMEQ V0.4S, V1.4S, V2.4S | FCMGE V0.4S, V1.4S, V2.4S | FCMGT V0.4S, V1.4S, V2.4S")]
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_V_4S([ValueSource("_floats_")] [Random(8)] float A,
|
||||
[ValueSource("_floats_")] [Random(8)] float B,
|
||||
public void Fcmeq_Fcmge_Fcmgt_Reg_V_4S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||
[ValueSource("_floats_")] [Random(RndCnt)] float B,
|
||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||
{
|
||||
uint Opcode = 0x4E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||
|
||||
Vector128<float> V1 = Sse.SetAllVector128(A);
|
||||
Vector128<float> V2 = Sse.SetAllVector128(B);
|
||||
|
||||
@@ -180,15 +191,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)2)), Is.EquivalentTo(Exp));
|
||||
Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)3)), Is.EquivalentTo(Exp));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMGT D0, D1, #0.0 | FCMGE D0, D1, #0.0 | FCMEQ D0, D1, #0.0 | FCMLE D0, D1, #0.0 | FCMLT D0, D1, #0.0")]
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_S_D([ValueSource("_doubles_")] [Random(8)] double A,
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_S_D([ValueSource("_doubles_")] [Random(RndCnt)] double A,
|
||||
[Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||
[Values(0u, 1u)] uint bit13) // "LT"
|
||||
{
|
||||
uint Opcode = 0x5EE0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||
|
||||
Vector128<float> V0 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(TestContext.CurrentContext.Random.NextDouble()));
|
||||
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetScalarVector128(A));
|
||||
|
||||
@@ -219,15 +232,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp));
|
||||
Assert.That(VectorExtractDouble(ThreadState.V0, (byte)1), Is.Zero);
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMGT S0, S1, #0.0 | FCMGE S0, S1, #0.0 | FCMEQ S0, S1, #0.0 | FCMLE S0, S1, #0.0 | FCMLT S0, S1, #0.0")]
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_S_S([ValueSource("_floats_")] [Random(8)] float A,
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_S_S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||
[Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||
[Values(0u, 1u)] uint bit13) // "LT"
|
||||
{
|
||||
uint Opcode = 0x5EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||
|
||||
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
||||
Vector128<float> V1 = Sse.SetScalarVector128(A);
|
||||
|
||||
@@ -260,15 +275,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)2), Is.Zero);
|
||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMGT V0.2D, V1.2D, #0.0 | FCMGE V0.2D, V1.2D, #0.0 | FCMEQ V0.2D, V1.2D, #0.0 | FCMLE V0.2D, V1.2D, #0.0 | FCMLT V0.2D, V1.2D, #0.0")]
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_2D([ValueSource("_doubles_")] [Random(8)] double A,
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_2D([ValueSource("_doubles_")] [Random(RndCnt)] double A,
|
||||
[Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||
[Values(0u, 1u)] uint bit13) // "LT"
|
||||
{
|
||||
uint Opcode = 0x4EE0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||
|
||||
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(A));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1);
|
||||
@@ -298,15 +315,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp));
|
||||
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)1)), Is.EquivalentTo(Exp));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMGT V0.2S, V1.2S, #0.0 | FCMGE V0.2S, V1.2S, #0.0 | FCMEQ V0.2S, V1.2S, #0.0 | FCMLE V0.2S, V1.2S, #0.0 | FCMLT V0.2S, V1.2S, #0.0")]
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_2S([ValueSource("_floats_")] [Random(8)] float A,
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_2S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||
[Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||
[Values(0u, 1u)] uint bit13) // "LT"
|
||||
{
|
||||
uint Opcode = 0x0EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||
|
||||
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
||||
Vector128<float> V1 = Sse.SetVector128(0, 0, A, A);
|
||||
|
||||
@@ -339,15 +358,17 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)2), Is.Zero);
|
||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
[Test, Description("FCMGT V0.4S, V1.4S, #0.0 | FCMGE V0.4S, V1.4S, #0.0 | FCMEQ V0.4S, V1.4S, #0.0 | FCMLE V0.4S, V1.4S, #0.0 | FCMLT V0.4S, V1.4S, #0.0")]
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_4S([ValueSource("_floats_")] [Random(8)] float A,
|
||||
public void Fcmgt_Fcmge_Fcmeq_Fcmle_Fcmlt_Zero_V_4S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||
[Values(0u, 1u, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||
[Values(0u, 1u)] uint bit13) // "LT"
|
||||
{
|
||||
uint Opcode = 0x4EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||
|
||||
Vector128<float> V1 = Sse.SetAllVector128(A);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1);
|
||||
@@ -379,6 +400,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)2)), Is.EquivalentTo(Exp));
|
||||
Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)3)), Is.EquivalentTo(Exp));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
uint Opcode = 0x4E285800; // AESD V0.16B, V0.16B
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
|
||||
Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
|
||||
|
||||
@@ -37,6 +38,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
|
||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -52,6 +54,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
uint Opcode = 0x4E284800; // AESE V0.16B, V0.16B
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
|
||||
Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
|
||||
|
||||
@@ -67,6 +70,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
|
||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -80,6 +84,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
uint Opcode = 0x4E287800; // AESIMC V0.16B, V0.16B
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(
|
||||
@@ -100,6 +105,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
|
||||
});
|
||||
}
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
|
||||
@@ -113,6 +119,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
uint Opcode = 0x4E286800; // AESMC V0.16B, V0.16B
|
||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||
|
||||
Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(
|
||||
@@ -133,6 +140,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
|
||||
});
|
||||
}
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ namespace Ryujinx.Tests.Cpu
|
||||
[TestCase((ushort)0x0001, 0x33800000u)] // 5.96046448e-8 (Smallest Subnormal)
|
||||
public void Fcvtl_V_f16(ushort Value, uint Result)
|
||||
{
|
||||
uint Opcode = 0x0E217801;
|
||||
uint Opcode = 0x0E217801; // FCVTL V1.4S, V0.4H
|
||||
|
||||
Vector128<float> V0 = Sse.StaticCast<ushort, float>(Sse2.SetAllVector128(Value));
|
||||
|
||||
AThreadState ThreadState = SingleOpcode(Opcode, V0: V0);
|
||||
@@ -35,6 +36,7 @@ namespace Ryujinx.Tests.Cpu
|
||||
Assert.That(Sse41.Extract(Sse.StaticCast<float, uint>(ThreadState.V1), (byte)2), Is.EqualTo(Result));
|
||||
Assert.That(Sse41.Extract(Sse.StaticCast<float, uint>(ThreadState.V1), (byte)3), Is.EqualTo(Result));
|
||||
});
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
}
|
||||
|
||||
+182
-1590
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,282 +0,0 @@
|
||||
// https://github.com/LDj3SNuD/ARM_v8-A_AArch64_Instructions_Tester/blob/master/Tester/Types/Bits.cs
|
||||
|
||||
// https://github.com/dotnet/corefx/blob/master/src/System.Collections/src/System/Collections/BitArray.cs
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu.Tester.Types
|
||||
{
|
||||
internal sealed class Bits : ICollection, IEnumerable, IEquatable<Bits>
|
||||
{
|
||||
private BitArray bits;
|
||||
|
||||
public Bits(bool[] values) => bits = new BitArray(values);
|
||||
public Bits(byte[] bytes) => bits = new BitArray(bytes);
|
||||
public Bits(Bits bits) => this.bits = new BitArray(bits.bits); // Clone: deep copy.
|
||||
public Bits(int length) => bits = new BitArray(length);
|
||||
public Bits(int length, bool defaultValue) => bits = new BitArray(length, defaultValue);
|
||||
private Bits(BitArray bitArray) => bits = new BitArray(bitArray);
|
||||
public Bits(ulong value) => bits = new BitArray(BitConverter.GetBytes(value));
|
||||
public Bits(uint value) => bits = new BitArray(BitConverter.GetBytes(value));
|
||||
public Bits(BigInteger value) => bits = new BitArray(value.ToByteArray());
|
||||
|
||||
private BitArray ToBitArray() => new BitArray(bits);
|
||||
public ulong ToUInt64()
|
||||
{
|
||||
byte[] dst = new byte[8];
|
||||
|
||||
bits.CopyTo(dst, 0);
|
||||
|
||||
return BitConverter.ToUInt64(dst, 0);
|
||||
}
|
||||
public uint ToUInt32()
|
||||
{
|
||||
byte[] dst = new byte[4];
|
||||
|
||||
bits.CopyTo(dst, 0);
|
||||
|
||||
return BitConverter.ToUInt32(dst, 0);
|
||||
}
|
||||
public BigInteger ToBigInteger()
|
||||
{
|
||||
if (bits.Count != 64 &&
|
||||
bits.Count != 32 &&
|
||||
bits.Count != 16 &&
|
||||
bits.Count != 8)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
byte[] dst = new byte[bits.Count / 8];
|
||||
|
||||
bits.CopyTo(dst, 0);
|
||||
|
||||
return new BigInteger(dst);
|
||||
}
|
||||
|
||||
public bool this[int index] // ASL: "<>".
|
||||
{
|
||||
get
|
||||
{
|
||||
return bits.Get(index);
|
||||
}
|
||||
set
|
||||
{
|
||||
bits.Set(index, value);
|
||||
}
|
||||
}
|
||||
public Bits this[int highIndex, int lowIndex] // ASL: "<:>".
|
||||
{
|
||||
get
|
||||
{
|
||||
if (highIndex < lowIndex)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
bool[] dst = new bool[highIndex - lowIndex + 1];
|
||||
|
||||
for (int i = lowIndex, n = 0; i <= highIndex; i++, n++)
|
||||
{
|
||||
dst[n] = bits.Get(i);
|
||||
}
|
||||
|
||||
return new Bits(dst);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (highIndex < lowIndex)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
for (int i = lowIndex, n = 0; i <= highIndex; i++, n++)
|
||||
{
|
||||
bits.Set(i, value.Get(n));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly { get => false; } // Mutable.
|
||||
public int Count { get => bits.Count; } // Not resizable.
|
||||
public bool IsSynchronized { get => bits.IsSynchronized; }
|
||||
public object SyncRoot { get => bits.SyncRoot; }
|
||||
public Bits And(Bits value) => new Bits(new BitArray(this.bits).And(value.bits)); // Immutable.
|
||||
public void CopyTo(Array array, int index) => bits.CopyTo(array, index);
|
||||
public bool Get(int index) => bits.Get(index);
|
||||
public IEnumerator GetEnumerator() => bits.GetEnumerator();
|
||||
//public Bits LeftShift(int count) => new Bits(new BitArray(bits).LeftShift(count)); // Immutable.
|
||||
public Bits Not() => new Bits(new BitArray(bits).Not()); // Immutable.
|
||||
public Bits Or(Bits value) => new Bits(new BitArray(this.bits).Or(value.bits)); // Immutable.
|
||||
//public Bits RightShift(int count) => new Bits(new BitArray(bits).RightShift(count)); // Immutable.
|
||||
public void Set(int index, bool value) => bits.Set(index, value);
|
||||
public void SetAll(bool value) => bits.SetAll(value);
|
||||
public Bits Xor(Bits value) => new Bits(new BitArray(this.bits).Xor(value.bits)); // Immutable.
|
||||
|
||||
public static Bits Concat(Bits highBits, Bits lowBits) // ASL: ":".
|
||||
{
|
||||
if (((object)lowBits == null) || ((object)highBits == null))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
bool[] dst = new bool[lowBits.Count + highBits.Count];
|
||||
|
||||
lowBits.CopyTo(dst, 0);
|
||||
highBits.CopyTo(dst, lowBits.Count);
|
||||
|
||||
return new Bits(dst);
|
||||
}
|
||||
public static Bits Concat(bool bit3, bool bit2, bool bit1, bool bit0) // ASL: ":::".
|
||||
{
|
||||
return new Bits(new bool[] {bit0, bit1, bit2, bit3});
|
||||
}
|
||||
|
||||
public static implicit operator Bits(bool value) => new Bits(1, value);
|
||||
public static implicit operator Bits(string value)
|
||||
{
|
||||
if (String.IsNullOrEmpty(value))
|
||||
{
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
|
||||
bool[] dst = new bool[value.Length];
|
||||
|
||||
for (int i = value.Length - 1, n = 0; i >= 0; i--, n++)
|
||||
{
|
||||
if (value[i] == '1')
|
||||
{
|
||||
dst[n] = true;
|
||||
}
|
||||
else if (value[i] == '0')
|
||||
{
|
||||
dst[n] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
}
|
||||
|
||||
return new Bits(dst);
|
||||
}
|
||||
public static explicit operator bool(Bits bit)
|
||||
{
|
||||
if (((object)bit == null) || (bit.Count != 1))
|
||||
{
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
|
||||
return bit.Get(0);
|
||||
}
|
||||
|
||||
public static Bits operator +(Bits left, BigInteger right) // ASL: "+".
|
||||
{
|
||||
if (((object)left == null) || ((object)right == null))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
BigInteger dst = left.ToBigInteger() + right;
|
||||
|
||||
return dst.SubBigInteger(left.Count - 1, 0);
|
||||
}
|
||||
public static Bits operator +(Bits left, Bits right) // ASL: "+".
|
||||
{
|
||||
if (((object)left == null) || ((object)right == null))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
if (left.Count != right.Count)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
BigInteger dst = left.ToBigInteger() + right.ToBigInteger();
|
||||
|
||||
return dst.SubBigInteger(left.Count - 1, 0);
|
||||
}
|
||||
public static Bits operator -(Bits left, Bits right) // ASL: "-".
|
||||
{
|
||||
if (((object)left == null) || ((object)right == null))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
if (left.Count != right.Count)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
BigInteger dst = left.ToBigInteger() - right.ToBigInteger();
|
||||
|
||||
return dst.SubBigInteger(left.Count - 1, 0);
|
||||
}
|
||||
public static bool operator ==(Bits left, Bits right) // ASL: "==".
|
||||
{
|
||||
if (((object)left == null) || ((object)right == null))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
if (left.Count != right.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= left.Count - 1; i++)
|
||||
{
|
||||
if (left.Get(i) != right.Get(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public static bool operator !=(Bits left, Bits right) // ASL: "!=".
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public bool Equals(Bits right) // ASL: "==".
|
||||
{
|
||||
if ((object)right == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
Bits left = this;
|
||||
|
||||
if (left.Count != right.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= left.Count - 1; i++)
|
||||
{
|
||||
if (left.Get(i) != right.Get(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
Bits right = obj as Bits;
|
||||
|
||||
return Equals(right);
|
||||
}
|
||||
public override int GetHashCode() => bits.GetHashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// https://github.com/LDj3SNuD/ARM_v8-A_AArch64_Instructions_Tester/blob/master/Tester/Types/Integer.cs
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu.Tester.Types
|
||||
{
|
||||
internal static class Integer
|
||||
{
|
||||
public static Bits SubBigInteger(this BigInteger x, int highIndex, int lowIndex) // ASL: "<:>".
|
||||
{
|
||||
if (highIndex < lowIndex)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
Bits src = new Bits(x);
|
||||
bool[] dst = new bool[highIndex - lowIndex + 1];
|
||||
|
||||
for (int i = lowIndex, n = 0; i <= highIndex; i++, n++)
|
||||
{
|
||||
if (i <= src.Count - 1)
|
||||
{
|
||||
dst[n] = src[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[n] = (x.Sign != -1 ? false : true); // Zero / Sign Extension.
|
||||
}
|
||||
}
|
||||
|
||||
return new Bits(dst);
|
||||
}
|
||||
|
||||
public static bool SubBigInteger(this BigInteger x, int index) // ASL: "<>".
|
||||
{
|
||||
Bits dst = x.SubBigInteger(index, index);
|
||||
|
||||
return (bool)dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user