forked from Mirror/Ryujinx
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:
parent
76a3172f17
commit
ca1e37a295
22 changed files with 1354 additions and 15384 deletions
|
@ -33,9 +33,10 @@ namespace Ryujinx.Tests.Cpu
|
||||||
static CpuTest()
|
static CpuTest()
|
||||||
{
|
{
|
||||||
UnicornAvailable = UnicornAArch64.IsAvailable();
|
UnicornAvailable = UnicornAArch64.IsAvailable();
|
||||||
|
|
||||||
if (!UnicornAvailable)
|
if (!UnicornAvailable)
|
||||||
{
|
{
|
||||||
Console.WriteLine("WARNING: Could not find unicorn");
|
Console.WriteLine("WARNING: Could not find Unicorn.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +80,12 @@ namespace Ryujinx.Tests.Cpu
|
||||||
protected void Opcode(uint Opcode)
|
protected void Opcode(uint Opcode)
|
||||||
{
|
{
|
||||||
Thread.Memory.WriteUInt32(Position, Opcode);
|
Thread.Memory.WriteUInt32(Position, Opcode);
|
||||||
|
|
||||||
if (UnicornAvailable)
|
if (UnicornAvailable)
|
||||||
{
|
{
|
||||||
UnicornEmu.MemoryWrite32((ulong)Position, Opcode);
|
UnicornEmu.MemoryWrite32((ulong)Position, Opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Position += 4;
|
Position += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,14 +100,18 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Thread.ThreadState.X1 = X1;
|
Thread.ThreadState.X1 = X1;
|
||||||
Thread.ThreadState.X2 = X2;
|
Thread.ThreadState.X2 = X2;
|
||||||
Thread.ThreadState.X3 = X3;
|
Thread.ThreadState.X3 = X3;
|
||||||
|
|
||||||
Thread.ThreadState.X31 = X31;
|
Thread.ThreadState.X31 = X31;
|
||||||
|
|
||||||
Thread.ThreadState.V0 = V0;
|
Thread.ThreadState.V0 = V0;
|
||||||
Thread.ThreadState.V1 = V1;
|
Thread.ThreadState.V1 = V1;
|
||||||
Thread.ThreadState.V2 = V2;
|
Thread.ThreadState.V2 = V2;
|
||||||
|
|
||||||
Thread.ThreadState.Overflow = Overflow;
|
Thread.ThreadState.Overflow = Overflow;
|
||||||
Thread.ThreadState.Carry = Carry;
|
Thread.ThreadState.Carry = Carry;
|
||||||
Thread.ThreadState.Zero = Zero;
|
Thread.ThreadState.Zero = Zero;
|
||||||
Thread.ThreadState.Negative = Negative;
|
Thread.ThreadState.Negative = Negative;
|
||||||
|
|
||||||
Thread.ThreadState.Fpcr = Fpcr;
|
Thread.ThreadState.Fpcr = Fpcr;
|
||||||
Thread.ThreadState.Fpsr = Fpsr;
|
Thread.ThreadState.Fpsr = Fpsr;
|
||||||
|
|
||||||
|
@ -114,14 +121,18 @@ namespace Ryujinx.Tests.Cpu
|
||||||
UnicornEmu.X[1] = X1;
|
UnicornEmu.X[1] = X1;
|
||||||
UnicornEmu.X[2] = X2;
|
UnicornEmu.X[2] = X2;
|
||||||
UnicornEmu.X[3] = X3;
|
UnicornEmu.X[3] = X3;
|
||||||
|
|
||||||
UnicornEmu.SP = X31;
|
UnicornEmu.SP = X31;
|
||||||
|
|
||||||
UnicornEmu.Q[0] = V0;
|
UnicornEmu.Q[0] = V0;
|
||||||
UnicornEmu.Q[1] = V1;
|
UnicornEmu.Q[1] = V1;
|
||||||
UnicornEmu.Q[2] = V2;
|
UnicornEmu.Q[2] = V2;
|
||||||
|
|
||||||
UnicornEmu.OverflowFlag = Overflow;
|
UnicornEmu.OverflowFlag = Overflow;
|
||||||
UnicornEmu.CarryFlag = Carry;
|
UnicornEmu.CarryFlag = Carry;
|
||||||
UnicornEmu.ZeroFlag = Zero;
|
UnicornEmu.ZeroFlag = Zero;
|
||||||
UnicornEmu.NegativeFlag = Negative;
|
UnicornEmu.NegativeFlag = Negative;
|
||||||
|
|
||||||
UnicornEmu.Fpcr = Fpcr;
|
UnicornEmu.Fpcr = Fpcr;
|
||||||
UnicornEmu.Fpsr = Fpsr;
|
UnicornEmu.Fpsr = Fpsr;
|
||||||
}
|
}
|
||||||
|
@ -144,10 +155,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AThreadState GetThreadState()
|
protected AThreadState GetThreadState() => Thread.ThreadState;
|
||||||
{
|
|
||||||
return Thread.ThreadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AThreadState SingleOpcode(uint Opcode,
|
protected AThreadState SingleOpcode(uint Opcode,
|
||||||
ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0,
|
ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0,
|
||||||
|
@ -166,7 +174,28 @@ namespace Ryujinx.Tests.Cpu
|
||||||
return GetThreadState();
|
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)
|
if (!UnicornAvailable)
|
||||||
{
|
{
|
||||||
|
@ -204,7 +233,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Assert.That(Thread.ThreadState.X28, Is.EqualTo(UnicornEmu.X[28]));
|
Assert.That(Thread.ThreadState.X28, Is.EqualTo(UnicornEmu.X[28]));
|
||||||
Assert.That(Thread.ThreadState.X29, Is.EqualTo(UnicornEmu.X[29]));
|
Assert.That(Thread.ThreadState.X29, Is.EqualTo(UnicornEmu.X[29]));
|
||||||
Assert.That(Thread.ThreadState.X30, Is.EqualTo(UnicornEmu.X[30]));
|
Assert.That(Thread.ThreadState.X30, Is.EqualTo(UnicornEmu.X[30]));
|
||||||
|
|
||||||
Assert.That(Thread.ThreadState.X31, Is.EqualTo(UnicornEmu.SP));
|
Assert.That(Thread.ThreadState.X31, Is.EqualTo(UnicornEmu.SP));
|
||||||
|
|
||||||
Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0]));
|
Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0]));
|
||||||
Assert.That(Thread.ThreadState.V1, Is.EqualTo(UnicornEmu.Q[1]));
|
Assert.That(Thread.ThreadState.V1, Is.EqualTo(UnicornEmu.Q[1]));
|
||||||
Assert.That(Thread.ThreadState.V2, Is.EqualTo(UnicornEmu.Q[2]));
|
Assert.That(Thread.ThreadState.V2, Is.EqualTo(UnicornEmu.Q[2]));
|
||||||
|
@ -238,8 +269,10 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Assert.That(Thread.ThreadState.V30, Is.EqualTo(UnicornEmu.Q[30]));
|
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.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.Fpcr, Is.EqualTo(UnicornEmu.Fpcr));
|
||||||
Assert.That(Thread.ThreadState.Fpsr & 0x08000000, Is.EqualTo(UnicornEmu.Fpsr & 0x08000000));
|
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.Overflow, Is.EqualTo(UnicornEmu.OverflowFlag));
|
||||||
Assert.That(Thread.ThreadState.Carry, Is.EqualTo(UnicornEmu.CarryFlag));
|
Assert.That(Thread.ThreadState.Carry, Is.EqualTo(UnicornEmu.CarryFlag));
|
||||||
Assert.That(Thread.ThreadState.Zero, Is.EqualTo(UnicornEmu.ZeroFlag));
|
Assert.That(Thread.ThreadState.Zero, Is.EqualTo(UnicornEmu.ZeroFlag));
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//#define Alu
|
#define Alu
|
||||||
|
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
|
|
||||||
|
@ -6,334 +6,185 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
using Tester;
|
[Category("Alu")] // Tested: second half of 2018.
|
||||||
using Tester.Types;
|
|
||||||
|
|
||||||
[Category("Alu"), Ignore("Tested: second half of 2018.")]
|
|
||||||
public sealed class CpuTestAlu : CpuTest
|
public sealed class CpuTestAlu : CpuTest
|
||||||
{
|
{
|
||||||
#if Alu
|
#if Alu
|
||||||
[SetUp]
|
private const int RndCnt = 2;
|
||||||
public void SetupTester()
|
|
||||||
{
|
|
||||||
AArch64.TakeReset(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test, Description("CLS <Xd>, <Xn>")]
|
[Test, Pairwise, Description("CLS <Xd>, <Xn>")]
|
||||||
public void Cls_64bit([Values(0u, 31u)] uint Rd,
|
public void Cls_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC01400; // CLS X0, X0
|
uint Opcode = 0xDAC01400; // CLS X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("CLS <Wd>, <Wn>")]
|
[Test, Pairwise, Description("CLS <Wd>, <Wn>")]
|
||||||
public void Cls_32bit([Values(0u, 31u)] uint Rd,
|
public void Cls_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC01400; // CLS W0, W0
|
uint Opcode = 0x5AC01400; // CLS W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
||||||
|
|
||||||
if (Rd != 31)
|
CompareAgainstUnicorn();
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("CLZ <Xd>, <Xn>")]
|
[Test, Pairwise, Description("CLZ <Xd>, <Xn>")]
|
||||||
public void Clz_64bit([Values(0u, 31u)] uint Rd,
|
public void Clz_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC01000; // CLZ X0, X0
|
uint Opcode = 0xDAC01000; // CLZ X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("CLZ <Wd>, <Wn>")]
|
[Test, Pairwise, Description("CLZ <Wd>, <Wn>")]
|
||||||
public void Clz_32bit([Values(0u, 31u)] uint Rd,
|
public void Clz_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC01000; // CLZ W0, W0
|
uint Opcode = 0x5AC01000; // CLZ W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("RBIT <Xd>, <Xn>")]
|
[Test, Pairwise, Description("RBIT <Xd>, <Xn>")]
|
||||||
public void Rbit_64bit([Values(0u, 31u)] uint Rd,
|
public void Rbit_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC00000; // RBIT X0, X0
|
uint Opcode = 0xDAC00000; // RBIT X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("RBIT <Wd>, <Wn>")]
|
[Test, Pairwise, Description("RBIT <Wd>, <Wn>")]
|
||||||
public void Rbit_32bit([Values(0u, 31u)] uint Rd,
|
public void Rbit_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC00000; // RBIT W0, W0
|
uint Opcode = 0x5AC00000; // RBIT W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("REV16 <Xd>, <Xn>")]
|
[Test, Pairwise, Description("REV16 <Xd>, <Xn>")]
|
||||||
public void Rev16_64bit([Values(0u, 31u)] uint Rd,
|
public void Rev16_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC00400; // REV16 X0, X0
|
uint Opcode = 0xDAC00400; // REV16 X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("REV16 <Wd>, <Wn>")]
|
[Test, Pairwise, Description("REV16 <Wd>, <Wn>")]
|
||||||
public void Rev16_32bit([Values(0u, 31u)] uint Rd,
|
public void Rev16_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC00400; // REV16 W0, W0
|
uint Opcode = 0x5AC00400; // REV16 W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("REV32 <Xd>, <Xn>")]
|
[Test, Pairwise, Description("REV32 <Xd>, <Xn>")]
|
||||||
public void Rev32_64bit([Values(0u, 31u)] uint Rd,
|
public void Rev32_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC00800; // REV32 X0, X0
|
uint Opcode = 0xDAC00800; // REV32 X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("REV <Wd>, <Wn>")]
|
[Test, Pairwise, Description("REV <Wd>, <Wn>")]
|
||||||
public void Rev32_32bit([Values(0u, 31u)] uint Rd,
|
public void Rev32_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(256)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC00800; // REV W0, W0
|
uint Opcode = 0x5AC00800; // REV W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("REV64 <Xd>, <Xn>")]
|
[Test, Pairwise, Description("REV64 <Xd>, <Xn>")]
|
||||||
public void Rev64_64bit([Values(0u, 31u)] uint Rd,
|
public void Rev64_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(256)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC00C00; // REV64 X0, X0
|
uint Opcode = 0xDAC00C00; // REV64 X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//#define AluImm
|
#define AluImm
|
||||||
|
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
|
|
||||||
|
@ -6,824 +6,448 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
using Tester;
|
[Category("AluImm")] // Tested: second half of 2018.
|
||||||
using Tester.Types;
|
|
||||||
|
|
||||||
[Category("AluImm"), Ignore("Tested: second half of 2018.")]
|
|
||||||
public sealed class CpuTestAluImm : CpuTest
|
public sealed class CpuTestAluImm : CpuTest
|
||||||
{
|
{
|
||||||
#if AluImm
|
#if AluImm
|
||||||
[SetUp]
|
private const int RndCnt = 2;
|
||||||
public void SetupTester()
|
private const int RndCntImm = 2;
|
||||||
{
|
private const int RndCntImms = 2;
|
||||||
AArch64.TakeReset(false);
|
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,
|
public void Add_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x91000000; // ADD X0, X0, #0, LSL #0
|
uint Opcode = 0x91000000; // ADD X0, X0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
AThreadState ThreadState;
|
AThreadState ThreadState;
|
||||||
|
|
||||||
if (Rn != 31)
|
if (Rn != 31)
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
||||||
|
|
||||||
AArch64.X((int)Rn, new Bits(Xn_SP));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
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();
|
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,
|
public void Add_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x11000000; // ADD W0, W0, #0, LSL #0
|
uint Opcode = 0x11000000; // ADD W0, W0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
AThreadState ThreadState;
|
AThreadState ThreadState;
|
||||||
|
|
||||||
if (Rn != 31)
|
if (Rn != 31)
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
||||||
|
|
||||||
AArch64.X((int)Rn, new Bits(Wn_WSP));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
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();
|
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,
|
public void Adds_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xB1000000; // ADDS X0, X0, #0, LSL #0
|
uint Opcode = 0xB1000000; // ADDS X0, X0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
AThreadState ThreadState;
|
AThreadState ThreadState;
|
||||||
|
|
||||||
if (Rn != 31)
|
if (Rn != 31)
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
||||||
|
|
||||||
AArch64.X((int)Rn, new Bits(Xn_SP));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
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();
|
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,
|
public void Adds_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x31000000; // ADDS W0, W0, #0, LSL #0
|
uint Opcode = 0x31000000; // ADDS W0, W0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
AThreadState ThreadState;
|
AThreadState ThreadState;
|
||||||
|
|
||||||
if (Rn != 31)
|
if (Rn != 31)
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
||||||
|
|
||||||
AArch64.X((int)Rn, new Bits(Wn_WSP));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
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();
|
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,
|
public void And_N1_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
|
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x92400000; // AND X0, X0, #0x1
|
uint Opcode = 0x92400000; // AND X0, X0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void And_N0_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x92000000; // AND X0, X0, #0x100000001
|
uint Opcode = 0x92000000; // AND X0, X0, #0x100000001
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void And_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x12000000; // AND W0, W0, #0x1
|
uint Opcode = 0x12000000; // AND W0, W0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
||||||
public void Ands_N1_64bit([Values(0u, 31u)] uint Rd,
|
public void Ands_N1_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
|
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xF2400000; // ANDS X0, X0, #0x1
|
uint Opcode = 0xF2400000; // ANDS X0, X0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
||||||
public void Ands_N0_64bit([Values(0u, 31u)] uint Rd,
|
public void Ands_N0_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xF2000000; // ANDS X0, X0, #0x100000001
|
uint Opcode = 0xF2000000; // ANDS X0, X0, #0x100000001
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("ANDS <Wd>, <Wn>, #<imm>")]
|
[Test, Pairwise, Description("ANDS <Wd>, <Wn>, #<imm>")]
|
||||||
public void Ands_32bit([Values(0u, 31u)] uint Rd,
|
public void Ands_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x72000000; // ANDS W0, W0, #0x1
|
uint Opcode = 0x72000000; // ANDS W0, W0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
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,
|
public void Eor_N1_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
|
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD2400000; // EOR X0, X0, #0x1
|
uint Opcode = 0xD2400000; // EOR X0, X0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void Eor_N0_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD2000000; // EOR X0, X0, #0x100000001
|
uint Opcode = 0xD2000000; // EOR X0, X0, #0x100000001
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("EOR <Wd>, <Wn>, #<imm>")]
|
[Test, Pairwise, Description("EOR <Wd>, <Wn>, #<imm>")]
|
||||||
public void Eor_32bit([Values(0u, 31u)] uint Rd,
|
public void Eor_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x52000000; // EOR W0, W0, #0x1
|
uint Opcode = 0x52000000; // EOR W0, W0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
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,
|
public void Orr_N1_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
|
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xB2400000; // ORR X0, X0, #0x1
|
uint Opcode = 0xB2400000; // ORR X0, X0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void Orr_N0_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xB2000000; // ORR X0, X0, #0x100000001
|
uint Opcode = 0xB2000000; // ORR X0, X0, #0x100000001
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void Orr_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x32000000; // ORR W0, W0, #0x1
|
uint Opcode = 0x32000000; // ORR W0, W0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
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,
|
public void Sub_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD1000000; // SUB X0, X0, #0, LSL #0
|
uint Opcode = 0xD1000000; // SUB X0, X0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
AThreadState ThreadState;
|
AThreadState ThreadState;
|
||||||
|
|
||||||
if (Rn != 31)
|
if (Rn != 31)
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
||||||
|
|
||||||
AArch64.X((int)Rn, new Bits(Xn_SP));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
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();
|
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,
|
public void Sub_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x51000000; // SUB W0, W0, #0, LSL #0
|
uint Opcode = 0x51000000; // SUB W0, W0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
AThreadState ThreadState;
|
AThreadState ThreadState;
|
||||||
|
|
||||||
if (Rn != 31)
|
if (Rn != 31)
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
||||||
|
|
||||||
AArch64.X((int)Rn, new Bits(Wn_WSP));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
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();
|
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,
|
public void Subs_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xF1000000; // SUBS X0, X0, #0, LSL #0
|
uint Opcode = 0xF1000000; // SUBS X0, X0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
AThreadState ThreadState;
|
AThreadState ThreadState;
|
||||||
|
|
||||||
if (Rn != 31)
|
if (Rn != 31)
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
||||||
|
|
||||||
AArch64.X((int)Rn, new Bits(Xn_SP));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
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();
|
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,
|
public void Subs_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x71000000; // SUBS W0, W0, #0, LSL #0
|
uint Opcode = 0x71000000; // SUBS W0, W0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
Bits Op = new Bits(Opcode);
|
|
||||||
|
|
||||||
AThreadState ThreadState;
|
AThreadState ThreadState;
|
||||||
|
|
||||||
if (Rn != 31)
|
if (Rn != 31)
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
||||||
|
|
||||||
AArch64.X((int)Rn, new Bits(Wn_WSP));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
//#define Bfm
|
#define Bfm
|
||||||
|
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
|
|
||||||
|
@ -6,212 +6,127 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
using Tester;
|
[Category("Bfm")] // Tested: second half of 2018.
|
||||||
using Tester.Types;
|
|
||||||
|
|
||||||
[Category("Bfm"), Ignore("Tested: second half of 2018.")]
|
|
||||||
public sealed class CpuTestBfm : CpuTest
|
public sealed class CpuTestBfm : CpuTest
|
||||||
{
|
{
|
||||||
#if Bfm
|
#if Bfm
|
||||||
[SetUp]
|
private const int RndCnt = 2;
|
||||||
public void SetupTester()
|
private const int RndCntImmr = 2;
|
||||||
{
|
private const int RndCntImms = 2;
|
||||||
AArch64.TakeReset(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test, Description("BFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
[Test, Pairwise, Description("BFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||||
public void Bfm_64bit([Values(0u, 31u)] uint Rd,
|
public void Bfm_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Random(2)] ulong _Xd,
|
[Random(RndCnt)] ulong _Xd,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr,
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms)
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xB3400000; // BFM X0, X0, #0, #0
|
uint Opcode = 0xB3400000; // BFM X0, X0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void Bfm_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Random(2)] uint _Wd,
|
[Random(RndCnt)] uint _Wd,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr,
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms)
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x33000000; // BFM W0, W0, #0, #0
|
uint Opcode = 0x33000000; // BFM W0, W0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X1: Wn, X31: _W31);
|
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();
|
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,
|
public void Sbfm_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr,
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms)
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x93400000; // SBFM X0, X0, #0, #0
|
uint Opcode = 0x93400000; // SBFM X0, X0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void Sbfm_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr,
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms)
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x13000000; // SBFM W0, W0, #0, #0
|
uint Opcode = 0x13000000; // SBFM W0, W0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
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,
|
public void Ubfm_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr,
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint imms)
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD3400000; // UBFM X0, X0, #0, #0
|
uint Opcode = 0xD3400000; // UBFM X0, X0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void Ubfm_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr,
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint imms)
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x53000000; // UBFM W0, W0, #0, #0
|
uint Opcode = 0x53000000; // UBFM W0, W0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//#define CcmpImm
|
#define CcmpImm
|
||||||
|
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
|
|
||||||
|
@ -6,25 +6,20 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
using Tester;
|
[Category("CcmpImm")] // Tested: second half of 2018.
|
||||||
using Tester.Types;
|
|
||||||
|
|
||||||
[Category("CcmpImm"), Ignore("Tested: second half of 2018.")]
|
|
||||||
public sealed class CpuTestCcmpImm : CpuTest
|
public sealed class CpuTestCcmpImm : CpuTest
|
||||||
{
|
{
|
||||||
#if CcmpImm
|
#if CcmpImm
|
||||||
[SetUp]
|
private const int RndCnt = 2;
|
||||||
public void SetupTester()
|
private const int RndCntImm = 2;
|
||||||
{
|
private const int RndCntNzcv = 2;
|
||||||
AArch64.TakeReset(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test, Description("CCMN <Xn>, #<imm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMN <Xn>, #<imm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmn_64bit([Values(1u, 31u)] uint Rn,
|
public void Ccmn_64bit([Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm,
|
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||||
[Random(0u, 15u, 1)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
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);
|
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void Ccmn_32bit([Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm,
|
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||||
[Random(0u, 15u, 1)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
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);
|
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
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,
|
public void Ccmp_64bit([Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm,
|
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||||
[Random(0u, 15u, 1)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
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);
|
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
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();
|
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,
|
public void Ccmp_32bit([Values(1u, 31u)] uint Rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0u, 31u)] [Random(0u, 31u, 3)] uint imm,
|
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||||
[Random(0u, 15u, 1)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
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);
|
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//#define CcmpReg
|
#define CcmpReg
|
||||||
|
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
|
|
||||||
|
@ -6,27 +6,21 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
using Tester;
|
[Category("CcmpReg")] // Tested: second half of 2018.
|
||||||
using Tester.Types;
|
|
||||||
|
|
||||||
[Category("CcmpReg"), Ignore("Tested: second half of 2018.")]
|
|
||||||
public sealed class CpuTestCcmpReg : CpuTest
|
public sealed class CpuTestCcmpReg : CpuTest
|
||||||
{
|
{
|
||||||
#if CcmpReg
|
#if CcmpReg
|
||||||
[SetUp]
|
private const int RndCnt = 2;
|
||||||
public void SetupTester()
|
private const int RndCntNzcv = 2;
|
||||||
{
|
|
||||||
AArch64.TakeReset(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test, Description("CCMN <Xn>, <Xm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMN <Xn>, <Xm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmn_64bit([Values(1u, 31u)] uint Rn,
|
public void Ccmn_64bit([Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||||
[Random(0u, 15u, 1)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -37,32 +31,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
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();
|
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,
|
public void Ccmn_32bit([Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||||
[Random(0u, 15u, 1)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -73,32 +55,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
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();
|
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,
|
public void Ccmp_64bit([Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||||
[Random(0u, 15u, 1)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -109,32 +79,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
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();
|
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,
|
public void Ccmp_32bit([Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||||
[Random(0u, 15u, 1)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -145,21 +103,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//#define Csel
|
#define Csel
|
||||||
|
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
|
|
||||||
|
@ -6,27 +6,20 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
using Tester;
|
[Category("Csel")] // Tested: second half of 2018.
|
||||||
using Tester.Types;
|
|
||||||
|
|
||||||
[Category("Csel"), Ignore("Tested: second half of 2018.")]
|
|
||||||
public sealed class CpuTestCsel : CpuTest
|
public sealed class CpuTestCsel : CpuTest
|
||||||
{
|
{
|
||||||
#if Csel
|
#if Csel
|
||||||
[SetUp]
|
private const int RndCnt = 2;
|
||||||
public void SetupTester()
|
|
||||||
{
|
|
||||||
AArch64.TakeReset(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test, Description("CSEL <Xd>, <Xn>, <Xm>, <cond>")]
|
[Test, Pairwise, Description("CSEL <Xd>, <Xn>, <Xm>, <cond>")]
|
||||||
public void Csel_64bit([Values(0u, 31u)] uint Rd,
|
public void Csel_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[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,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -37,34 +30,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12);
|
Opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
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();
|
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,
|
public void Csel_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[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,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -75,34 +54,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12);
|
Opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
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();
|
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,
|
public void Csinc_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[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,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -113,34 +78,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12);
|
Opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
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();
|
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,
|
public void Csinc_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[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,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -151,34 +102,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12);
|
Opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
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();
|
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,
|
public void Csinv_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[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,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -189,34 +126,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12);
|
Opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
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();
|
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,
|
public void Csinv_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[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,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -227,34 +150,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12);
|
Opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
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();
|
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,
|
public void Csneg_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[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,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -265,34 +174,20 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12);
|
Opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
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();
|
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,
|
public void Csneg_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[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,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
|
@ -303,23 +198,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= ((cond & 15) << 12);
|
Opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode(0xD65F03C0);
|
Opcode(0xD65F03C0);
|
||||||
ExecuteOpcodes();
|
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.
|
[TestCase(-20d, -5d)] // 18 integer solutions.
|
||||||
|
@ -137,7 +137,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode(0xD65F03C0);
|
Opcode(0xD65F03C0);
|
||||||
ExecuteOpcodes();
|
ExecuteOpcodes();
|
||||||
|
|
||||||
Assert.That(VectorExtractDouble(GetThreadState().V0, 0), Is.EqualTo(16d));
|
Assert.That(VectorExtractDouble(GetThreadState().V0, (byte)0), Is.EqualTo(16d));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -163,27 +163,27 @@ namespace Ryujinx.Tests.Cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
0x0000000000000000: MOV W4, W0
|
0x0000000000001000: MOV W4, W0
|
||||||
0x0000000000000004: CBZ W0, #0x3C
|
0x0000000000001004: CBZ W0, #0x3C
|
||||||
0x0000000000000008: CMP W0, #1
|
0x0000000000001008: CMP W0, #1
|
||||||
0x000000000000000C: B.LS #0x48
|
0x000000000000100C: B.LS #0x48
|
||||||
0x0000000000000010: MOVZ W2, #0x2
|
0x0000000000001010: MOVZ W2, #0x2
|
||||||
0x0000000000000014: MOVZ X1, #0x1
|
0x0000000000001014: MOVZ X1, #0x1
|
||||||
0x0000000000000018: MOVZ X3, #0
|
0x0000000000001018: MOVZ X3, #0
|
||||||
0x000000000000001C: ADD X0, X3, X1
|
0x000000000000101C: ADD X0, X3, X1
|
||||||
0x0000000000000020: ADD W2, W2, #1
|
0x0000000000001020: ADD W2, W2, #1
|
||||||
0x0000000000000024: MOV X3, X1
|
0x0000000000001024: MOV X3, X1
|
||||||
0x0000000000000028: MOV X1, X0
|
0x0000000000001028: MOV X1, X0
|
||||||
0x000000000000002C: CMP W4, W2
|
0x000000000000102C: CMP W4, W2
|
||||||
0x0000000000000030: B.HS #0x1C
|
0x0000000000001030: B.HS #0x1C
|
||||||
0x0000000000000034: BRK #0
|
0x0000000000001034: BRK #0
|
||||||
0x0000000000000038: RET
|
0x0000000000001038: RET
|
||||||
0x000000000000003C: MOVZ X0, #0
|
0x000000000000103C: MOVZ X0, #0
|
||||||
0x0000000000000040: BRK #0
|
0x0000000000001040: BRK #0
|
||||||
0x0000000000000044: RET
|
0x0000000000001044: RET
|
||||||
0x0000000000000048: MOVZ X0, #0x1
|
0x0000000000001048: MOVZ X0, #0x1
|
||||||
0x000000000000004C: BRK #0
|
0x000000000000104C: BRK #0
|
||||||
0x0000000000000050: RET
|
0x0000000000001050: RET
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SetThreadState(X0: A);
|
SetThreadState(X0: A);
|
||||||
|
@ -219,11 +219,11 @@ namespace Ryujinx.Tests.Cpu
|
||||||
const ulong Result = 5;
|
const ulong Result = 5;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
0x0000000000000000: MOV X0, #2
|
0x0000000000001000: MOV X0, #2
|
||||||
0x0000000000000004: MOV X1, #3
|
0x0000000000001004: MOV X1, #3
|
||||||
0x0000000000000008: ADD X0, X0, X1
|
0x0000000000001008: ADD X0, X0, X1
|
||||||
0x000000000000000C: BRK #0
|
0x000000000000100C: BRK #0
|
||||||
0x0000000000000010: RET
|
0x0000000000001010: RET
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Opcode(0xD2800040);
|
Opcode(0xD2800040);
|
||||||
|
@ -238,11 +238,11 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
0x0000000000000000: MOV X0, #3
|
0x0000000000001000: MOV X0, #3
|
||||||
0x0000000000000004: MOV X1, #2
|
0x0000000000001004: MOV X1, #2
|
||||||
0x0000000000000008: ADD X0, X0, X1
|
0x0000000000001008: ADD X0, X0, X1
|
||||||
0x000000000000000C: BRK #0
|
0x000000000000100C: BRK #0
|
||||||
0x0000000000000010: RET
|
0x0000000000001010: RET
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Opcode(0xD2800060);
|
Opcode(0xD2800060);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//#define Mov
|
#define Mov
|
||||||
|
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
|
|
||||||
|
@ -6,23 +6,16 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
using Tester;
|
[Category("Mov")] // Tested: second half of 2018.
|
||||||
using Tester.Types;
|
|
||||||
|
|
||||||
[Category("Mov"), Ignore("Tested: second half of 2018.")]
|
|
||||||
public sealed class CpuTestMov : CpuTest
|
public sealed class CpuTestMov : CpuTest
|
||||||
{
|
{
|
||||||
#if Mov
|
#if Mov
|
||||||
[SetUp]
|
private const int RndCntImm = 2;
|
||||||
public void SetupTester()
|
|
||||||
{
|
|
||||||
AArch64.TakeReset(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test, Description("MOVK <Xd>, #<imm>{, LSL #<shift>}")]
|
[Test, Pairwise, Description("MOVK <Xd>, #<imm>{, LSL #<shift>}")]
|
||||||
public void Movk_64bit([Values(0u, 31u)] uint Rd,
|
public void Movk_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Random(12)] ulong _Xd,
|
[Random(RndCntImm)] ulong _Xd,
|
||||||
[Values(0u, 65535u)] [Random(0u, 65535u, 10)] uint imm,
|
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||||
[Values(0u, 16u, 32u, 48u)] uint shift)
|
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xF2800000; // MOVK X0, #0, LSL #0
|
uint Opcode = 0xF2800000; // MOVK X0, #0, LSL #0
|
||||||
|
@ -30,29 +23,16 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X31: _X31);
|
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();
|
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,
|
public void Movk_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Random(12)] uint _Wd,
|
[Random(RndCntImm)] uint _Wd,
|
||||||
[Values(0u, 65535u)] [Random(0u, 65535u, 10)] uint imm,
|
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||||
[Values(0u, 16u)] uint shift)
|
[Values(0u, 16u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x72800000; // MOVK W0, #0, LSL #0
|
uint Opcode = 0x72800000; // MOVK W0, #0, LSL #0
|
||||||
|
@ -60,28 +40,15 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X31: _W31);
|
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();
|
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,
|
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)
|
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x92800000; // MOVN X0, #0, LSL #0
|
uint Opcode = 0x92800000; // MOVN X0, #0, LSL #0
|
||||||
|
@ -89,27 +56,15 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);
|
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();
|
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,
|
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)
|
[Values(0u, 16u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x12800000; // MOVN W0, #0, LSL #0
|
uint Opcode = 0x12800000; // MOVN W0, #0, LSL #0
|
||||||
|
@ -117,27 +72,15 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X31: _W31);
|
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();
|
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,
|
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)
|
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD2800000; // MOVZ X0, #0, LSL #0
|
uint Opcode = 0xD2800000; // MOVZ X0, #0, LSL #0
|
||||||
|
@ -145,27 +88,15 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);
|
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();
|
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,
|
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)
|
[Values(0u, 16u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x52800000; // MOVZ W0, #0, LSL #0
|
uint Opcode = 0x52800000; // MOVZ W0, #0, LSL #0
|
||||||
|
@ -173,21 +104,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X31: _W31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//#define Mul
|
#define Mul
|
||||||
|
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
|
|
||||||
|
@ -6,378 +6,223 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
using Tester;
|
[Category("Mul")] // Tested: second half of 2018.
|
||||||
using Tester.Types;
|
|
||||||
|
|
||||||
[Category("Mul"), Ignore("Tested: second half of 2018.")]
|
|
||||||
public sealed class CpuTestMul : CpuTest
|
public sealed class CpuTestMul : CpuTest
|
||||||
{
|
{
|
||||||
#if Mul
|
#if Mul
|
||||||
[SetUp]
|
private const int RndCnt = 2;
|
||||||
public void SetupTester()
|
|
||||||
{
|
|
||||||
AArch64.TakeReset(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test, Description("MADD <Xd>, <Xn>, <Xm>, <Xa>")]
|
[Test, Pairwise, Description("MADD <Xd>, <Xn>, <Xm>, <Xa>")]
|
||||||
public void Madd_64bit([Values(0u, 31u)] uint Rd,
|
public void Madd_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint Ra,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B000000; // MADD X0, X0, X0, X0
|
uint Opcode = 0x9B000000; // MADD X0, X0, X0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31);
|
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();
|
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,
|
public void Madd_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint Ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wa)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1B000000; // MADD W0, W0, W0, W0
|
uint Opcode = 0x1B000000; // MADD W0, W0, W0, W0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31);
|
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();
|
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,
|
public void Msub_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint Ra,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B008000; // MSUB X0, X0, X0, X0
|
uint Opcode = 0x9B008000; // MSUB X0, X0, X0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31);
|
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();
|
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,
|
public void Msub_32bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint Ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wa)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1B008000; // MSUB W0, W0, W0, W0
|
uint Opcode = 0x1B008000; // MSUB W0, W0, W0, W0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31);
|
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();
|
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,
|
public void Smaddl_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint Ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B200000; // SMADDL X0, W0, W0, X0
|
uint Opcode = 0x9B200000; // SMADDL X0, W0, W0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
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();
|
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,
|
public void Umaddl_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint Ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9BA00000; // UMADDL X0, W0, W0, X0
|
uint Opcode = 0x9BA00000; // UMADDL X0, W0, W0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
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();
|
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,
|
public void Smsubl_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint Ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B208000; // SMSUBL X0, W0, W0, X0
|
uint Opcode = 0x9B208000; // SMSUBL X0, W0, W0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
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();
|
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,
|
public void Umsubl_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint Ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9BA08000; // UMSUBL X0, W0, W0, X0
|
uint Opcode = 0x9BA08000; // UMSUBL X0, W0, W0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("SMULH <Xd>, <Xn>, <Xm>")]
|
[Test, Pairwise, Description("SMULH <Xd>, <Xn>, <Xm>")]
|
||||||
public void Smulh_64bit([Values(0u, 31u)] uint Rd,
|
public void Smulh_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xm)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B407C00; // SMULH X0, X0, X0
|
uint Opcode = 0x9B407C00; // SMULH X0, X0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("UMULH <Xd>, <Xn>, <Xm>")]
|
[Test, Pairwise, Description("UMULH <Xd>, <Xn>, <Xm>")]
|
||||||
public void Umulh_64bit([Values(0u, 31u)] uint Rd,
|
public void Umulh_64bit([Values(0u, 31u)] uint Rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint Rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint Rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xm)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9BC07C00; // UMULH X0, X0, X0
|
uint Opcode = 0x9BC07C00; // UMULH X0, X0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,7 +9,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
public class CpuTestSimdArithmetic : CpuTest
|
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, 0x0000000000000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x1E224820u, 0x0000000080000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
|
[TestCase(0x1E224820u, 0x0000000080000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
|
||||||
[TestCase(0x1E224820u, 0x0000000080000000ul, 0x000000003DCCCCCDul, 0x000000003DCCCCCDul)]
|
[TestCase(0x1E224820u, 0x0000000080000000ul, 0x000000003DCCCCCDul, 0x000000003DCCCCCDul)]
|
||||||
|
@ -22,17 +22,19 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x1E224820u, 0x000000007F800001ul, 0x000000007FC00042ul, 0x000000007FC00001ul)]
|
[TestCase(0x1E224820u, 0x000000007F800001ul, 0x000000007FC00042ul, 0x000000007FC00001ul)]
|
||||||
[TestCase(0x1E224820u, 0x000000007FC00042ul, 0x000000007F800001ul, 0x000000007FC00001ul)]
|
[TestCase(0x1E224820u, 0x000000007FC00042ul, 0x000000007F800001ul, 0x000000007FC00001ul)]
|
||||||
[TestCase(0x1E224820u, 0x000000007FC0000Aul, 0x000000007FC0000Bul, 0x000000007FC0000Aul)]
|
[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, 0x0000000000000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x1E624820u, 0x8000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)]
|
[TestCase(0x1E624820u, 0x8000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)]
|
||||||
[TestCase(0x1E624820u, 0x8000000000000000ul, 0x3FF3333333333333ul, 0x3FF3333333333333ul)]
|
[TestCase(0x1E624820u, 0x8000000000000000ul, 0x3FF3333333333333ul, 0x3FF3333333333333ul)]
|
||||||
public void Fmax_S(uint Opcode, ulong A, ulong B, ulong Result)
|
public void Fmax_S(uint Opcode, ulong A, ulong B, ulong Result)
|
||||||
{
|
{
|
||||||
// FMAX S0, S1, S2
|
Vector128<float> V1 = MakeVectorE0(A);
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode,
|
Vector128<float> V2 = MakeVectorE0(B);
|
||||||
V1: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, A)),
|
|
||||||
V2: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, B)));
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
||||||
Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast<float, ulong>(ThreadState.V0), 0));
|
|
||||||
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,19 +53,23 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC0000Au, 0x7FC0000Au, 0x7FC0000Bu, 0x7FC0000Bu, 0x7FC0000Au, 0x7FC0000Au)]
|
[TestCase(0x7FC0000Au, 0x7FC0000Au, 0x7FC0000Bu, 0x7FC0000Bu, 0x7FC0000Au, 0x7FC0000Au)]
|
||||||
public void Fmax_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1)
|
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> V1 = MakeVectorE0E1(A, B);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(C, D);
|
Vector128<float> V2 = MakeVectorE0E1(C, D);
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(0x1E225820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
|
[TestCase(0x1E225820u, 0x0000000000000000ul, 0x0000000080000000ul, 0x0000000080000000ul)] // FMIN S0, S1, S2
|
||||||
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x0000000000000000ul, 0x0000000080000000ul)]
|
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x0000000000000000ul, 0x0000000080000000ul)]
|
||||||
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
|
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x0000000080000000ul, 0x0000000080000000ul)]
|
||||||
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x000000003DCCCCCDul, 0x0000000080000000ul)]
|
[TestCase(0x1E225820u, 0x0000000080000000ul, 0x000000003DCCCCCDul, 0x0000000080000000ul)]
|
||||||
|
@ -76,17 +82,19 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x1E225820u, 0x000000007F800001ul, 0x000000007FC00042ul, 0x000000007FC00001ul)]
|
[TestCase(0x1E225820u, 0x000000007F800001ul, 0x000000007FC00042ul, 0x000000007FC00001ul)]
|
||||||
[TestCase(0x1E225820u, 0x000000007FC00042ul, 0x000000007F800001ul, 0x000000007FC00001ul)]
|
[TestCase(0x1E225820u, 0x000000007FC00042ul, 0x000000007F800001ul, 0x000000007FC00001ul)]
|
||||||
[TestCase(0x1E225820u, 0x000000007FC0000Aul, 0x000000007FC0000Bul, 0x000000007FC0000Aul)]
|
[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, 0x0000000000000000ul, 0x8000000000000000ul)]
|
||||||
[TestCase(0x1E625820u, 0x8000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)]
|
[TestCase(0x1E625820u, 0x8000000000000000ul, 0x8000000000000000ul, 0x8000000000000000ul)]
|
||||||
[TestCase(0x1E625820u, 0x8000000000000000ul, 0x3FF3333333333333ul, 0x8000000000000000ul)]
|
[TestCase(0x1E625820u, 0x8000000000000000ul, 0x3FF3333333333333ul, 0x8000000000000000ul)]
|
||||||
public void Fmin_S(uint Opcode, ulong A, ulong B, ulong Result)
|
public void Fmin_S(uint Opcode, ulong A, ulong B, ulong Result)
|
||||||
{
|
{
|
||||||
// FMIN S0, S1, S2
|
Vector128<float> V1 = MakeVectorE0(A);
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode,
|
Vector128<float> V2 = MakeVectorE0(B);
|
||||||
V1: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, A)),
|
|
||||||
V2: Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, B)));
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
||||||
Assert.AreEqual(Result, Sse41.Extract(Sse.StaticCast<float, ulong>(ThreadState.V0), 0));
|
|
||||||
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,15 +113,19 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC0000Au, 0x7FC0000Au, 0x7FC0000Bu, 0x7FC0000Bu, 0x7FC0000Au, 0x7FC0000Au)]
|
[TestCase(0x7FC0000Au, 0x7FC0000Au, 0x7FC0000Bu, 0x7FC0000Bu, 0x7FC0000Au, 0x7FC0000Au)]
|
||||||
public void Fmin_V(uint A, uint B, uint C, uint D, uint Result0, uint Result1)
|
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> V1 = MakeVectorE0E1(A, B);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(C, D);
|
Vector128<float> V2 = MakeVectorE0E1(C, D);
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +137,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
V0: Sse.SetVector128(0, B, 0, 0));
|
V0: Sse.SetVector128(0, B, 0, 0));
|
||||||
|
|
||||||
Assert.That(Sse41.Extract(ThreadState.V6, (byte)0), Is.EqualTo(A * B));
|
Assert.That(Sse41.Extract(ThreadState.V6, (byte)0), Is.EqualTo(A * B));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,21 +150,27 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x007FF000u, 0x7E800000u)]
|
[TestCase(0x007FF000u, 0x7E800000u)]
|
||||||
public void Frecpe_S(uint A, uint Result)
|
public void Frecpe_S(uint A, uint Result)
|
||||||
{
|
{
|
||||||
|
uint Opcode = 0x5EA1D820; // FRECPE S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
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();
|
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)
|
public void Frecps_S([Random(10)] double A, [Random(10)] double B)
|
||||||
{
|
{
|
||||||
AThreadState ThreadState = SingleOpcode(0x5E62FC20,
|
AThreadState ThreadState = SingleOpcode(0x5E62FC20,
|
||||||
V1: MakeVectorE0(A),
|
V1: MakeVectorE0(A),
|
||||||
V2: MakeVectorE0(B));
|
V2: MakeVectorE0(B));
|
||||||
|
|
||||||
Assert.That(VectorExtractDouble(ThreadState.V0, 0), Is.EqualTo(2 - (A * B)));
|
Assert.That(VectorExtractDouble(ThreadState.V0, (byte)0), Is.EqualTo(2 - (A * B)));
|
||||||
//CompareAgainstUnicorn(); // Not accurate enough
|
|
||||||
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("FRECPS V4.4S, V2.4S, V0.4S")]
|
[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)2), Is.EqualTo(Result));
|
||||||
Assert.That(Sse41.Extract(ThreadState.V4, (byte)3), Is.EqualTo(Result));
|
Assert.That(Sse41.Extract(ThreadState.V4, (byte)3), Is.EqualTo(Result));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +197,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
||||||
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
||||||
[TestCase(0x40733333u, false, 0x40800000u)]
|
[TestCase(0x40733333u, false, 0x40800000u)]
|
||||||
[TestCase(0x3fc00000u, false, 0x40000000u)]
|
[TestCase(0x3FC00000u, false, 0x40000000u)]
|
||||||
[TestCase(0x40200000u, false, 0x40400000u)]
|
[TestCase(0x40200000u, false, 0x40400000u)]
|
||||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||||
|
@ -213,42 +233,53 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frinta_S(uint A, bool DefaultNaN, uint Result)
|
public void Frinta_S(uint A, bool DefaultNaN, uint Result)
|
||||||
{
|
{
|
||||||
|
uint Opcode = 0x1E264020; // FRINTA S0, S1
|
||||||
|
|
||||||
|
Vector128<float> V1 = MakeVectorE0(A);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int FpcrTemp = 0x0;
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
FpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
|
||||||
AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
|
||||||
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x6E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
[TestCase(0x6E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x3f80000040000000ul)]
|
[TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTX V0.4S, V1.4S
|
||||||
[TestCase(0x6E219820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
[TestCase(0x6E219820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTX V0.2S, V1.2S
|
||||||
[TestCase(0x2E219820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E219820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)] // FRINTA V0.2S, V1.2S
|
||||||
[TestCase(0x2E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 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)
|
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;
|
int FpcrTemp = 0x0;
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
FpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,36 +325,31 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frinti_S(uint A, char RoundType, bool DefaultNaN, uint Result)
|
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;
|
int FpcrTemp = 0x0;
|
||||||
switch(RoundType)
|
switch(RoundType)
|
||||||
{
|
{
|
||||||
case 'N':
|
case 'N': FpcrTemp = 0x0; break;
|
||||||
FpcrTemp = 0x0;
|
case 'P': FpcrTemp = 0x400000; break;
|
||||||
break;
|
case 'M': FpcrTemp = 0x800000; break;
|
||||||
|
case 'Z': FpcrTemp = 0xC00000; break;
|
||||||
case 'P':
|
|
||||||
FpcrTemp = 0x400000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'M':
|
|
||||||
FpcrTemp = 0x800000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Z':
|
|
||||||
FpcrTemp = 0xC00000;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp |= 1 << 25;
|
FpcrTemp |= 1 << 25;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
|
||||||
AThreadState ThreadState = SingleOpcode(0x1E27C020, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
|
||||||
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'N', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
[TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, '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, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||||
[TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
[TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||||
[TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
[TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||||
[TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x3f80000040000000ul)]
|
[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, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||||
[TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
[TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
|
||||||
[TestCase(0x6EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
[TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
|
||||||
[TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x0000000000000000ul)]
|
[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, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
[TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2EA19820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
[TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
[TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
[TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'M', 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.")]
|
[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)
|
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;
|
int FpcrTemp = 0x0;
|
||||||
switch(RoundType)
|
switch(RoundType)
|
||||||
{
|
{
|
||||||
case 'N':
|
case 'N': FpcrTemp = 0x0; break;
|
||||||
FpcrTemp = 0x0;
|
case 'P': FpcrTemp = 0x400000; break;
|
||||||
break;
|
case 'M': FpcrTemp = 0x800000; break;
|
||||||
|
case 'Z': FpcrTemp = 0xC00000; break;
|
||||||
case 'P':
|
|
||||||
FpcrTemp = 0x400000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'M':
|
|
||||||
FpcrTemp = 0x800000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Z':
|
|
||||||
FpcrTemp = 0xC00000;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp |= 1 << 25;
|
FpcrTemp |= 1 << 25;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +413,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
||||||
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
||||||
[TestCase(0x40733333u, false, 0x40400000u)]
|
[TestCase(0x40733333u, false, 0x40400000u)]
|
||||||
[TestCase(0x3fc00000u, false, 0x3F800000u)]
|
[TestCase(0x3FC00000u, false, 0x3F800000u)]
|
||||||
[TestCase(0x40200000u, false, 0x40000000u)]
|
[TestCase(0x40200000u, false, 0x40000000u)]
|
||||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||||
|
@ -430,47 +449,58 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frintm_S(uint A, bool DefaultNaN, uint Result)
|
public void Frintm_S(uint A, bool DefaultNaN, uint Result)
|
||||||
{
|
{
|
||||||
|
uint Opcode = 0x1E254020; // FRINTM S0, S1
|
||||||
|
|
||||||
|
Vector128<float> V1 = MakeVectorE0(A);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int FpcrTemp = 0x0;
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
FpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
|
||||||
AThreadState ThreadState = SingleOpcode(0x1E254020, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
|
||||||
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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(0x4E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||||
[TestCase(0x4E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
[TestCase(0x4E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)] // FRINTM V0.4S, V1.4S
|
||||||
[TestCase(0xE219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F8000003F800000ul, 0x0000000000000000ul)] // FRINTM V0.2S, V1.2S
|
||||||
[TestCase(0xE219820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E219820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0xE219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0xE219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0xE219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 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)
|
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;
|
int FpcrTemp = 0x0;
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
FpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Ignore("Wrong opcode.")]
|
||||||
[TestCase(0x3FE66666u, false, 0x40000000u)]
|
[TestCase(0x3FE66666u, false, 0x40000000u)]
|
||||||
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
[TestCase(0x3F99999Au, false, 0x3F800000u)]
|
||||||
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
[TestCase(0x404CCCCDu, false, 0x40400000u)]
|
||||||
[TestCase(0x40733333u, false, 0x40800000u)]
|
[TestCase(0x40733333u, false, 0x40800000u)]
|
||||||
[TestCase(0x3fc00000u, false, 0x40000000u)]
|
[TestCase(0x3FC00000u, false, 0x40000000u)]
|
||||||
[TestCase(0x40200000u, false, 0x40400000u)]
|
[TestCase(0x40200000u, false, 0x40400000u)]
|
||||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||||
|
@ -506,42 +536,52 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frintn_S(uint A, bool DefaultNaN, uint Result)
|
public void Frintn_S(uint A, bool DefaultNaN, uint Result)
|
||||||
{
|
{
|
||||||
|
uint Opcode = 0x1E264020; // FRINTA S0, S1
|
||||||
|
|
||||||
|
Vector128<float> V1 = MakeVectorE0(A);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int FpcrTemp = 0x0;
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
FpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
|
||||||
AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
|
||||||
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x4E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
[TestCase(0x4E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x4E218820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x3f80000040000000ul)]
|
[TestCase(0x4E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTN V0.4S, V1.4S
|
||||||
[TestCase(0x4E218820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
[TestCase(0x4E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||||
[TestCase(0xE218820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x3f80000040000000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTN V0.2S, V1.2S
|
||||||
[TestCase(0xE218820u, 0x3fc000003fc00000ul, 0x3fc000003fc00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0xE218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0xE218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0xE218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0xE218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 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)
|
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;
|
int FpcrTemp = 0x0;
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
FpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,7 +589,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x3F99999Au, false, 0x40000000u)]
|
[TestCase(0x3F99999Au, false, 0x40000000u)]
|
||||||
[TestCase(0x404CCCCDu, false, 0x40800000u)]
|
[TestCase(0x404CCCCDu, false, 0x40800000u)]
|
||||||
[TestCase(0x40733333u, false, 0x40800000u)]
|
[TestCase(0x40733333u, false, 0x40800000u)]
|
||||||
[TestCase(0x3fc00000u, false, 0x40000000u)]
|
[TestCase(0x3FC00000u, false, 0x40000000u)]
|
||||||
[TestCase(0x40200000u, false, 0x40400000u)]
|
[TestCase(0x40200000u, false, 0x40400000u)]
|
||||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||||
[TestCase(0x00000000u, false, 0x00000000u)]
|
[TestCase(0x00000000u, false, 0x00000000u)]
|
||||||
|
@ -585,39 +625,49 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frintp_S(uint A, bool DefaultNaN, uint Result)
|
public void Frintp_S(uint A, bool DefaultNaN, uint Result)
|
||||||
{
|
{
|
||||||
|
uint Opcode = 0x1E24C020; // FRINTP S0, S1
|
||||||
|
|
||||||
|
Vector128<float> V1 = MakeVectorE0(A);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int FpcrTemp = 0x0;
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
FpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
|
||||||
AThreadState ThreadState = SingleOpcode(0x1E24C020, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
|
||||||
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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(0x4EE18820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x4EA18820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
[TestCase(0x4EA18820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] // FRINTP V0.4S, v1.4S
|
||||||
[TestCase(0xEA18820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
[TestCase(0x0EA18820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] // FRINTP V0.2S, v1.2S
|
||||||
[TestCase(0xEA18820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
[TestCase(0x0EA18820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0xEA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
[TestCase(0x0EA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0xEA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0xEA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 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)
|
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;
|
int FpcrTemp = 0x0;
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
FpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,36 +713,31 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frintx_S(uint A, char RoundType, bool DefaultNaN, uint Result)
|
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;
|
int FpcrTemp = 0x0;
|
||||||
switch(RoundType)
|
switch(RoundType)
|
||||||
{
|
{
|
||||||
case 'N':
|
case 'N': FpcrTemp = 0x0; break;
|
||||||
FpcrTemp = 0x0;
|
case 'P': FpcrTemp = 0x400000; break;
|
||||||
break;
|
case 'M': FpcrTemp = 0x800000; break;
|
||||||
|
case 'Z': FpcrTemp = 0xC00000; break;
|
||||||
case 'P':
|
|
||||||
FpcrTemp = 0x400000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'M':
|
|
||||||
FpcrTemp = 0x800000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Z':
|
|
||||||
FpcrTemp = 0xC00000;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp |= 1 << 25;
|
FpcrTemp |= 1 << 25;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
|
||||||
AThreadState ThreadState = SingleOpcode(0x1E274020, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
Assert.AreEqual(Result, GetVectorE0(ThreadState.V0));
|
|
||||||
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'N', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
[TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
|
||||||
[TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, '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, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||||
[TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
[TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||||
[TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
[TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
|
||||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x3f80000040000000ul)]
|
[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, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)]
|
||||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
[TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
|
||||||
[TestCase(0x6E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x3f8000003f800000ul)]
|
[TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
|
||||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'N', false, 0x3f80000040000000ul, 0x0000000000000000ul)]
|
[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, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'M', false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2E219820u, 0x3f99999a3fe66666ul, 0x3f99999a3fe66666ul, 'Z', false, 0x3f8000003f800000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'M', 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.")]
|
[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)
|
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;
|
int FpcrTemp = 0x0;
|
||||||
switch(RoundType)
|
switch(RoundType)
|
||||||
{
|
{
|
||||||
case 'N':
|
case 'N': FpcrTemp = 0x0; break;
|
||||||
FpcrTemp = 0x0;
|
case 'P': FpcrTemp = 0x400000; break;
|
||||||
break;
|
case 'M': FpcrTemp = 0x800000; break;
|
||||||
|
case 'Z': FpcrTemp = 0xC00000; break;
|
||||||
case 'P':
|
|
||||||
FpcrTemp = 0x400000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'M':
|
|
||||||
FpcrTemp = 0x800000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Z':
|
|
||||||
FpcrTemp = 0xC00000;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if(DefaultNaN)
|
if(DefaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp |= 1 << 25;
|
FpcrTemp |= 1 << 25;
|
||||||
}
|
}
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(Result0, GetVectorE0(ThreadState.V0));
|
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
||||||
Assert.AreEqual(Result1, GetVectorE1(ThreadState.V0));
|
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(0x41200000u, 0x3EA18000u)]
|
[TestCase(0x41200000u, 0x3EA18000u)]
|
||||||
public void Frsqrte_S(uint A, uint Result)
|
public void Frsqrte_S(uint A, uint Result)
|
||||||
{
|
{
|
||||||
|
uint Opcode = 0x7EA1D820; // FRSQRTE S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
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();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,15 @@ namespace Ryujinx.Tests.Cpu
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
[Test, Description("FCMEQ D0, D1, D2 | FCMGE D0, D1, D2 | FCMGT D0, D1, D2")]
|
[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,
|
public void Fcmeq_Fcmge_Fcmgt_Reg_S_D([ValueSource("_doubles_")] [Random(RndCnt)] double A,
|
||||||
[ValueSource("_doubles_")] [Random(8)] double B,
|
[ValueSource("_doubles_")] [Random(RndCnt)] double B,
|
||||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5E62E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
uint Opcode = 0x5E62E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||||
|
|
||||||
Vector128<float> V0 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(TestContext.CurrentContext.Random.NextDouble()));
|
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> V1 = Sse.StaticCast<double, float>(Sse2.SetScalarVector128(A));
|
||||||
Vector128<float> V2 = Sse.StaticCast<double, float>(Sse2.SetScalarVector128(B));
|
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(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp));
|
||||||
Assert.That(VectorExtractDouble(ThreadState.V0, (byte)1), Is.Zero);
|
Assert.That(VectorExtractDouble(ThreadState.V0, (byte)1), Is.Zero);
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("FCMEQ S0, S1, S2 | FCMGE S0, S1, S2 | FCMGT S0, S1, S2")]
|
[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,
|
public void Fcmeq_Fcmge_Fcmgt_Reg_S_S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||||
[ValueSource("_floats_")] [Random(8)] float B,
|
[ValueSource("_floats_")] [Random(RndCnt)] float B,
|
||||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
uint Opcode = 0x5E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||||
|
|
||||||
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
||||||
Vector128<float> V1 = Sse.SetScalarVector128(A);
|
Vector128<float> V1 = Sse.SetScalarVector128(A);
|
||||||
Vector128<float> V2 = Sse.SetScalarVector128(B);
|
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)2), Is.Zero);
|
||||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("FCMEQ V0.2D, V1.2D, V2.2D | FCMGE V0.2D, V1.2D, V2.2D | FCMGT V0.2D, V1.2D, V2.2D")]
|
[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,
|
public void Fcmeq_Fcmge_Fcmgt_Reg_V_2D([ValueSource("_doubles_")] [Random(RndCnt)] double A,
|
||||||
[ValueSource("_doubles_")] [Random(8)] double B,
|
[ValueSource("_doubles_")] [Random(RndCnt)] double B,
|
||||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E62E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
uint Opcode = 0x4E62E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||||
|
|
||||||
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(A));
|
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(A));
|
||||||
Vector128<float> V2 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(B));
|
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)0)), Is.EquivalentTo(Exp));
|
||||||
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)1)), Is.EquivalentTo(Exp));
|
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)1)), Is.EquivalentTo(Exp));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("FCMEQ V0.2S, V1.2S, V2.2S | FCMGE V0.2S, V1.2S, V2.2S | FCMGT V0.2S, V1.2S, V2.2S")]
|
[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,
|
public void Fcmeq_Fcmge_Fcmgt_Reg_V_2S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||||
[ValueSource("_floats_")] [Random(8)] float B,
|
[ValueSource("_floats_")] [Random(RndCnt)] float B,
|
||||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||||
{
|
{
|
||||||
uint Opcode = 0x0E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
uint Opcode = 0x0E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||||
|
|
||||||
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
||||||
Vector128<float> V1 = Sse.SetVector128(0, 0, A, A);
|
Vector128<float> V1 = Sse.SetVector128(0, 0, A, A);
|
||||||
Vector128<float> V2 = Sse.SetVector128(0, 0, B, B);
|
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)2), Is.Zero);
|
||||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("FCMEQ V0.4S, V1.4S, V2.4S | FCMGE V0.4S, V1.4S, V2.4S | FCMGT V0.4S, V1.4S, V2.4S")]
|
[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,
|
public void Fcmeq_Fcmge_Fcmgt_Reg_V_4S([ValueSource("_floats_")] [Random(RndCnt)] float A,
|
||||||
[ValueSource("_floats_")] [Random(8)] float B,
|
[ValueSource("_floats_")] [Random(RndCnt)] float B,
|
||||||
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
[Values(0u, 1u, 3u)] uint EU) // EQ, GE, GT
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
uint Opcode = 0x4E22E420 | ((EU & 1) << 29) | ((EU >> 1) << 23);
|
||||||
|
|
||||||
Vector128<float> V1 = Sse.SetAllVector128(A);
|
Vector128<float> V1 = Sse.SetAllVector128(A);
|
||||||
Vector128<float> V2 = Sse.SetAllVector128(B);
|
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)2)), Is.EquivalentTo(Exp));
|
||||||
Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)3)), Is.EquivalentTo(Exp));
|
Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)3)), Is.EquivalentTo(Exp));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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")]
|
[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, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||||
[Values(0u, 1u)] uint bit13) // "LT"
|
[Values(0u, 1u)] uint bit13) // "LT"
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5EE0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
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> V0 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(TestContext.CurrentContext.Random.NextDouble()));
|
||||||
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetScalarVector128(A));
|
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(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)0)), Is.EquivalentTo(Exp));
|
||||||
Assert.That(VectorExtractDouble(ThreadState.V0, (byte)1), Is.Zero);
|
Assert.That(VectorExtractDouble(ThreadState.V0, (byte)1), Is.Zero);
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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")]
|
[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, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||||
[Values(0u, 1u)] uint bit13) // "LT"
|
[Values(0u, 1u)] uint bit13) // "LT"
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
uint Opcode = 0x5EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||||
|
|
||||||
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
||||||
Vector128<float> V1 = Sse.SetScalarVector128(A);
|
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)2), Is.Zero);
|
||||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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")]
|
[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, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||||
[Values(0u, 1u)] uint bit13) // "LT"
|
[Values(0u, 1u)] uint bit13) // "LT"
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4EE0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
uint Opcode = 0x4EE0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||||
|
|
||||||
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(A));
|
Vector128<float> V1 = Sse.StaticCast<double, float>(Sse2.SetAllVector128(A));
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1);
|
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)0)), Is.EquivalentTo(Exp));
|
||||||
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)1)), Is.EquivalentTo(Exp));
|
Assert.That(BitConverter.GetBytes(VectorExtractDouble(ThreadState.V0, (byte)1)), Is.EquivalentTo(Exp));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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")]
|
[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, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||||
[Values(0u, 1u)] uint bit13) // "LT"
|
[Values(0u, 1u)] uint bit13) // "LT"
|
||||||
{
|
{
|
||||||
uint Opcode = 0x0EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
uint Opcode = 0x0EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||||
|
|
||||||
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
Vector128<float> V0 = Sse.SetAllVector128(TestContext.CurrentContext.Random.NextFloat());
|
||||||
Vector128<float> V1 = Sse.SetVector128(0, 0, A, A);
|
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)2), Is.Zero);
|
||||||
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
Assert.That(Sse41.Extract(ThreadState.V0, (byte)3), Is.Zero);
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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")]
|
[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, 2u, 3u)] uint opU, // GT, GE, EQ, LE
|
||||||
[Values(0u, 1u)] uint bit13) // "LT"
|
[Values(0u, 1u)] uint bit13) // "LT"
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
uint Opcode = 0x4EA0C820 | (((opU & 1) & ~bit13) << 29) | (bit13 << 13) | (((opU >> 1) & ~bit13) << 12);
|
||||||
|
|
||||||
Vector128<float> V1 = Sse.SetAllVector128(A);
|
Vector128<float> V1 = Sse.SetAllVector128(A);
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V1: V1);
|
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)2)), Is.EquivalentTo(Exp));
|
||||||
Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)3)), Is.EquivalentTo(Exp));
|
Assert.That(BitConverter.GetBytes(Sse41.Extract(ThreadState.V0, (byte)3)), Is.EquivalentTo(Exp));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E285800; // AESD V0.16B, V0.16B
|
uint Opcode = 0x4E285800; // AESD V0.16B, V0.16B
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
|
Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
|
Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
|
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
|
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +54,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E284800; // AESE V0.16B, V0.16B
|
uint Opcode = 0x4E284800; // AESE V0.16B, V0.16B
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
|
Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
|
Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
|
||||||
|
|
||||||
|
@ -67,6 +70,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
|
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
|
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +84,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E287800; // AESIMC V0.16B, V0.16B
|
uint Opcode = 0x4E287800; // AESIMC V0.16B, V0.16B
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
|
Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(
|
AThreadState ThreadState = SingleOpcode(
|
||||||
|
@ -100,6 +105,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
|
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +119,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E286800; // AESMC V0.16B, V0.16B
|
uint Opcode = 0x4E286800; // AESMC V0.16B, V0.16B
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
||||||
|
|
||||||
Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
|
Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(
|
AThreadState ThreadState = SingleOpcode(
|
||||||
|
@ -133,6 +140,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
|
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase((ushort)0x0001, 0x33800000u)] // 5.96046448e-8 (Smallest Subnormal)
|
[TestCase((ushort)0x0001, 0x33800000u)] // 5.96046448e-8 (Smallest Subnormal)
|
||||||
public void Fcvtl_V_f16(ushort Value, uint Result)
|
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));
|
Vector128<float> V0 = Sse.StaticCast<ushort, float>(Sse2.SetAllVector128(Value));
|
||||||
|
|
||||||
AThreadState ThreadState = SingleOpcode(Opcode, V0: V0);
|
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)2), Is.EqualTo(Result));
|
||||||
Assert.That(Sse41.Extract(Sse.StaticCast<float, uint>(ThreadState.V1), (byte)3), Is.EqualTo(Result));
|
Assert.That(Sse41.Extract(Sse.StaticCast<float, uint>(ThreadState.V1), (byte)3), Is.EqualTo(Result));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue