Convert misc CPU tests to xUnit

This commit is contained in:
TSR Berry 2023-07-09 00:05:26 +02:00
parent b16a539468
commit 7acf80b93d
No known key found for this signature in database
GPG key ID: 52353C0A4CCA15E2
2 changed files with 178 additions and 142 deletions

View file

@ -1,5 +1,8 @@
// #define Misc
#define Misc
using ARMeilleure.State;
using System;
using System.Collections.Generic;
using Xunit;
namespace Ryujinx.Tests.Cpu
@ -43,7 +46,7 @@ namespace Ryujinx.Tests.Cpu
for (int cnt = 1; cnt <= RndCnt; cnt++)
{
ulong grbg = TestContext.CurrentContext.Random.NextUInt();
ulong grbg = Random.Shared.NextUInt();
ulong rnd1 = GenNormalS();
ulong rnd2 = GenSubnormalS();
@ -60,15 +63,44 @@ namespace Ryujinx.Tests.Cpu
private static readonly bool _noNaNs = false;
#region "AluImm & Csel"
[Test, Pairwise]
public void Adds_Csinc_64bit([Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
[Values(0u, 4095u)] uint imm,
[Values(0b00u, 0b01u)] uint shift, // <LSL #0, LSL #12>
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u)] uint cond) // GT, LE>
private static readonly ulong[] _testDataXn =
{
0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
private static readonly uint[] _testDataWn =
{
0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu,
};
private static readonly uint[] _testDataImm =
{
0u, 4095u,
};
private static readonly uint[] _testDataShift =
{
0b00u, 0b01u,
};
private static readonly uint[] _testDataCond =
{
0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u, // GT, LE>
};
public static readonly MatrixTheoryData<ulong, uint, uint, uint> TestMatrixData_64bit = new(_testDataXn, _testDataImm, _testDataShift, _testDataCond);
public static readonly MatrixTheoryData<uint, uint, uint, uint> TestMatrixData_32bit = new(_testDataWn, _testDataImm, _testDataShift, _testDataCond);
public static readonly RangeTheoryData<uint> TestRangeData = new(0u, 92u, 1u);
[Theory]
[MemberData(nameof(TestMatrixData_64bit))]
public void Adds_Csinc_64bit(ulong xn, uint imm, uint shift, uint cond)
{
uint opCmn = 0xB100001F; // ADDS X31, X0, #0, LSL #0 -> CMN X0, #0, LSL #0
uint opCset = 0x9A9F07E0; // CSINC X0, X31, X31, EQ -> CSET X0, NE
@ -85,15 +117,9 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void Adds_Csinc_32bit([Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] uint wn,
[Values(0u, 4095u)] uint imm,
[Values(0b00u, 0b01u)] uint shift, // <LSL #0, LSL #12>
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u)] uint cond) // GT, LE>
[Theory]
[MemberData(nameof(TestMatrixData_32bit))]
public void Adds_Csinc_32bit(uint wn, uint imm, uint shift, uint cond)
{
uint opCmn = 0x3100001F; // ADDS W31, W0, #0, LSL #0 -> CMN W0, #0, LSL #0
uint opCset = 0x1A9F07E0; // CSINC W0, W31, W31, EQ -> CSET W0, NE
@ -110,15 +136,9 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void Subs_Csinc_64bit([Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
[Values(0u, 4095u)] uint imm,
[Values(0b00u, 0b01u)] uint shift, // <LSL #0, LSL #12>
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u)] uint cond) // GT, LE>
[Theory]
[MemberData(nameof(TestMatrixData_64bit))]
public void Subs_Csinc_64bit(ulong xn, uint imm, uint shift, uint cond)
{
uint opCmp = 0xF100001F; // SUBS X31, X0, #0, LSL #0 -> CMP X0, #0, LSL #0
uint opCset = 0x9A9F07E0; // CSINC X0, X31, X31, EQ -> CSET X0, NE
@ -135,15 +155,9 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise]
public void Subs_Csinc_32bit([Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] uint wn,
[Values(0u, 4095u)] uint imm,
[Values(0b00u, 0b01u)] uint shift, // <LSL #0, LSL #12>
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u)] uint cond) // GT, LE>
[Theory]
[MemberData(nameof(TestMatrixData_32bit))]
public void Subs_Csinc_32bit(uint wn, uint imm, uint shift, uint cond)
{
uint opCmp = 0x7100001F; // SUBS W31, W0, #0, LSL #0 -> CMP W0, #0, LSL #0
uint opCset = 0x1A9F07E0; // CSINC W0, W31, W31, EQ -> CSET W0, NE
@ -162,9 +176,9 @@ namespace Ryujinx.Tests.Cpu
#endregion
// Roots.
[Explicit]
[TestCase(0xFFFFFFFDu)]
[TestCase(0x00000005u)]
[Theory]
[InlineData(0xFFFFFFFDu)]
[InlineData(0x00000005u)]
public void Misc1(uint a)
{
// ((a + 3) * (a - 5)) / ((a + 5) * (a - 3)) = 0
@ -191,29 +205,29 @@ namespace Ryujinx.Tests.Cpu
Opcode(0xD65F03C0);
ExecuteOpcodes();
Assert.That(GetContext().GetX(0), Is.Zero);
Assert.Equal(0ul, GetContext().GetX(0));
}
// 18 integer solutions.
[Explicit]
[TestCase(-20f, -5f)]
[TestCase(-12f, -6f)]
[TestCase(-12f, 3f)]
[TestCase(-8f, -8f)]
[TestCase(-6f, -12f)]
[TestCase(-5f, -20f)]
[TestCase(-4f, 2f)]
[TestCase(-3f, 12f)]
[TestCase(-2f, 4f)]
[TestCase(2f, -4f)]
[TestCase(3f, -12f)]
[TestCase(4f, -2f)]
[TestCase(5f, 20f)]
[TestCase(6f, 12f)]
[TestCase(8f, 8f)]
[TestCase(12f, -3f)]
[TestCase(12f, 6f)]
[TestCase(20f, 5f)]
[Theory]
[InlineData(-20f, -5f)]
[InlineData(-12f, -6f)]
[InlineData(-12f, 3f)]
[InlineData(-8f, -8f)]
[InlineData(-6f, -12f)]
[InlineData(-5f, -20f)]
[InlineData(-4f, 2f)]
[InlineData(-3f, 12f)]
[InlineData(-2f, 4f)]
[InlineData(2f, -4f)]
[InlineData(3f, -12f)]
[InlineData(4f, -2f)]
[InlineData(5f, 20f)]
[InlineData(6f, 12f)]
[InlineData(8f, 8f)]
[InlineData(12f, -3f)]
[InlineData(12f, 6f)]
[InlineData(20f, 5f)]
public void Misc2(float a, float b)
{
// 1 / ((1 / a + 1 / b) ^ 2) = 16
@ -238,29 +252,29 @@ namespace Ryujinx.Tests.Cpu
Opcode(0xD65F03C0);
ExecuteOpcodes();
Assert.That(GetContext().GetV(0).As<float>(), Is.EqualTo(16f));
Assert.Equal(16f, GetContext().GetV(0).As<float>());
}
// 18 integer solutions.
[Explicit]
[TestCase(-20d, -5d)]
[TestCase(-12d, -6d)]
[TestCase(-12d, 3d)]
[TestCase(-8d, -8d)]
[TestCase(-6d, -12d)]
[TestCase(-5d, -20d)]
[TestCase(-4d, 2d)]
[TestCase(-3d, 12d)]
[TestCase(-2d, 4d)]
[TestCase(2d, -4d)]
[TestCase(3d, -12d)]
[TestCase(4d, -2d)]
[TestCase(5d, 20d)]
[TestCase(6d, 12d)]
[TestCase(8d, 8d)]
[TestCase(12d, -3d)]
[TestCase(12d, 6d)]
[TestCase(20d, 5d)]
[Theory]
[InlineData(-20d, -5d)]
[InlineData(-12d, -6d)]
[InlineData(-12d, 3d)]
[InlineData(-8d, -8d)]
[InlineData(-6d, -12d)]
[InlineData(-5d, -20d)]
[InlineData(-4d, 2d)]
[InlineData(-3d, 12d)]
[InlineData(-2d, 4d)]
[InlineData(2d, -4d)]
[InlineData(3d, -12d)]
[InlineData(4d, -2d)]
[InlineData(5d, 20d)]
[InlineData(6d, 12d)]
[InlineData(8d, 8d)]
[InlineData(12d, -3d)]
[InlineData(12d, 6d)]
[InlineData(20d, 5d)]
public void Misc3(double a, double b)
{
// 1 / ((1 / a + 1 / b) ^ 2) = 16
@ -285,11 +299,12 @@ namespace Ryujinx.Tests.Cpu
Opcode(0xD65F03C0);
ExecuteOpcodes();
Assert.That(GetContext().GetV(0).As<double>(), Is.EqualTo(16d));
Assert.Equal(16d, GetContext().GetV(0).As<double>());
}
[Test, Ignore("The Tester supports only one return point.")]
public void MiscF([Range(0u, 92u, 1u)] uint a)
[Theory(Skip = "The Tester supports only one return point.")]
[MemberData(nameof(TestRangeData))]
public void MiscF(uint a)
{
static ulong Fn(uint n)
{
@ -352,11 +367,11 @@ namespace Ryujinx.Tests.Cpu
Opcode(0xD65F03C0);
ExecuteOpcodes();
Assert.That(GetContext().GetX(0), Is.EqualTo(Fn(a)));
Assert.Equal(Fn(a), GetContext().GetX(0));
}
[Explicit]
[Test]
// This test used to be skipped unless explicitly executed
[Fact]
public void MiscR()
{
const ulong Result = 5;
@ -374,7 +389,7 @@ namespace Ryujinx.Tests.Cpu
Opcode(0xD65F03C0);
ExecuteOpcodes();
Assert.That(GetContext().GetX(0), Is.EqualTo(Result));
Assert.Equal(Result, GetContext().GetX(0));
Reset();
@ -391,57 +406,67 @@ namespace Ryujinx.Tests.Cpu
Opcode(0xD65F03C0);
ExecuteOpcodes();
Assert.That(GetContext().GetX(0), Is.EqualTo(Result));
Assert.Equal(Result, GetContext().GetX(0));
}
[Explicit]
[TestCase(0ul)]
[TestCase(1ul)]
[TestCase(2ul)]
[TestCase(42ul)]
// This test used to be skipped unless explicitly executed
[Theory]
[InlineData(0ul)]
[InlineData(1ul)]
[InlineData(2ul)]
[InlineData(42ul)]
public void SanityCheck(ulong a)
{
uint opcode = 0xD503201F; // NOP
ExecutionContext context = SingleOpcode(opcode, x0: a);
Assert.That(context.GetX(0), Is.EqualTo(a));
Assert.Equal(a, context.GetX(0));
}
[Explicit]
[Test, Pairwise]
public void Misc4([ValueSource(nameof(_1S_F_))] ulong a,
[ValueSource(nameof(_1S_F_))] ulong b,
[ValueSource(nameof(_1S_F_))] ulong c,
[Values(0ul, 1ul, 2ul, 3ul)] ulong displacement)
private static readonly ulong[] _testDataMisc4Displacement =
{
if (!BitConverter.IsLittleEndian)
{
Assert.Ignore();
}
0ul, 1ul, 2ul, 3ul,
};
public static readonly MatrixTheoryData<ulong, ulong, ulong, ulong> TestDataMisc4 = new(_1S_F_(), _1S_F_(), _1S_F_(), _testDataMisc4Displacement);
// This test used to be skipped unless explicitly executed
[SkippableTheory]
[MemberData(nameof(TestDataMisc4))]
public void Misc4(ulong a, ulong b, ulong c, ulong displacement)
{
Skip.IfNot(BitConverter.IsLittleEndian);
byte[] data = new byte[1];
for (ulong gapOffset = 0; gapOffset < displacement; gapOffset++)
{
SetWorkingMemory(gapOffset, TestContext.CurrentContext.Random.NextByte());
Random.Shared.NextBytes(data);
SetWorkingMemory(gapOffset, data[0]);
}
SetWorkingMemory(0x0 + displacement, BitConverter.GetBytes((uint)b));
SetWorkingMemory(0x4 + displacement, BitConverter.GetBytes((uint)c));
SetWorkingMemory(0x8 + displacement, TestContext.CurrentContext.Random.NextByte());
SetWorkingMemory(0x9 + displacement, TestContext.CurrentContext.Random.NextByte());
SetWorkingMemory(0xA + displacement, TestContext.CurrentContext.Random.NextByte());
SetWorkingMemory(0xB + displacement, TestContext.CurrentContext.Random.NextByte());
Random.Shared.NextBytes(data);
SetWorkingMemory(0x8 + displacement, data[0]);
Random.Shared.NextBytes(data);
SetWorkingMemory(0x9 + displacement, data[0]);
Random.Shared.NextBytes(data);
SetWorkingMemory(0xA + displacement, data[0]);
Random.Shared.NextBytes(data);
SetWorkingMemory(0xB + displacement, data[0]);
SetContext(
x0: DataBaseAddress + displacement,
v0: MakeVectorE0E1(a, TestContext.CurrentContext.Random.NextULong()),
v1: MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong()),
v2: MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong()),
overflow: TestContext.CurrentContext.Random.NextBool(),
carry: TestContext.CurrentContext.Random.NextBool(),
zero: TestContext.CurrentContext.Random.NextBool(),
negative: TestContext.CurrentContext.Random.NextBool());
v0: MakeVectorE0E1(a, Random.Shared.NextULong()),
v1: MakeVectorE0E1(Random.Shared.NextULong(), Random.Shared.NextULong()),
v2: MakeVectorE0E1(Random.Shared.NextULong(), Random.Shared.NextULong()),
overflow: Random.Shared.NextBool(),
carry: Random.Shared.NextBool(),
zero: Random.Shared.NextBool(),
negative: Random.Shared.NextBool());
Opcode(0xBD400001); // LDR S1, [X0,#0]
Opcode(0xBD400402); // LDR S2, [X0,#4]
@ -455,17 +480,20 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Explicit]
[Test]
public void Misc5([ValueSource(nameof(_1S_F_))] ulong a)
public static readonly EnumerableTheoryData<ulong> TestDataMisc5 = new(_1S_F_());
// This test used to be skipped unless explicitly executed
[Theory]
[MemberData(nameof(TestDataMisc5))]
public void Misc5(ulong a)
{
SetContext(
v0: MakeVectorE0E1(a, TestContext.CurrentContext.Random.NextULong()),
v1: MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong()),
overflow: TestContext.CurrentContext.Random.NextBool(),
carry: TestContext.CurrentContext.Random.NextBool(),
zero: TestContext.CurrentContext.Random.NextBool(),
negative: TestContext.CurrentContext.Random.NextBool());
v0: MakeVectorE0E1(a, Random.Shared.NextULong()),
v1: MakeVectorE0E1(Random.Shared.NextULong(), Random.Shared.NextULong()),
overflow: Random.Shared.NextBool(),
carry: Random.Shared.NextBool(),
zero: Random.Shared.NextBool(),
negative: Random.Shared.NextBool());
Opcode(0x1E202008); // FCMP S0, #0.0
Opcode(0x1E2E1001); // FMOV S1, #1.0

View file

@ -1,5 +1,8 @@
// #define Misc32
#define Misc32
using ARMeilleure.State;
using System;
using System.Collections.Generic;
using Xunit;
namespace Ryujinx.Tests.Cpu
@ -43,7 +46,7 @@ namespace Ryujinx.Tests.Cpu
for (int cnt = 1; cnt <= RndCnt; cnt++)
{
ulong grbg = TestContext.CurrentContext.Random.NextUInt();
ulong grbg = Random.Shared.NextUInt();
ulong rnd1 = GenNormalS();
ulong rnd2 = GenSubnormalS();
@ -59,28 +62,33 @@ namespace Ryujinx.Tests.Cpu
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Test, Pairwise]
public void Vmsr_Vcmp_Vmrs([ValueSource(nameof(_1S_F_))] ulong a,
[ValueSource(nameof(_1S_F_))] ulong b,
[Values] bool mode1,
[Values] bool mode2,
[Values] bool mode3)
private static readonly bool[] _testData_bool =
{
false,
true,
};
public static readonly MatrixTheoryData<ulong, ulong, bool, bool, bool> TestData = new(_1S_F_(), _1S_F_(), _testData_bool, _testData_bool, _testData_bool);
[Theory]
[MemberData(nameof(TestData))]
public void Vmsr_Vcmp_Vmrs(ulong a, ulong b, bool mode1, bool mode2, bool mode3)
{
V128 v4 = MakeVectorE0(a);
V128 v5 = MakeVectorE0(b);
uint r0 = mode1
? TestContext.CurrentContext.Random.NextUInt(0xf) << 28
: TestContext.CurrentContext.Random.NextUInt();
? Random.Shared.NextUInt(0xf) << 28
: Random.Shared.NextUInt();
bool v = mode3 && TestContext.CurrentContext.Random.NextBool();
bool c = mode3 && TestContext.CurrentContext.Random.NextBool();
bool z = mode3 && TestContext.CurrentContext.Random.NextBool();
bool n = mode3 && TestContext.CurrentContext.Random.NextBool();
bool v = mode3 && Random.Shared.NextBool();
bool c = mode3 && Random.Shared.NextBool();
bool z = mode3 && Random.Shared.NextBool();
bool n = mode3 && Random.Shared.NextBool();
int fpscr = mode1
? (int)TestContext.CurrentContext.Random.NextUInt()
: (int)TestContext.CurrentContext.Random.NextUInt(0xf) << 28;
? (int)Random.Shared.NextUInt()
: (int)Random.Shared.NextUInt(0xf) << 28;
SetContext(r0: r0, v4: v4, v5: v5, overflow: v, carry: c, zero: z, negative: n, fpscr: fpscr);