aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Tests/Cpu/CpuTestMisc.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Tests/Cpu/CpuTestMisc.cs')
-rw-r--r--Ryujinx.Tests/Cpu/CpuTestMisc.cs123
1 files changed, 123 insertions, 0 deletions
diff --git a/Ryujinx.Tests/Cpu/CpuTestMisc.cs b/Ryujinx.Tests/Cpu/CpuTestMisc.cs
index 9b31e68e..9c067f4e 100644
--- a/Ryujinx.Tests/Cpu/CpuTestMisc.cs
+++ b/Ryujinx.Tests/Cpu/CpuTestMisc.cs
@@ -4,15 +4,67 @@ using ARMeilleure.State;
using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+
namespace Ryujinx.Tests.Cpu
{
[Category("Misc")]
public sealed class CpuTestMisc : CpuTest
{
#if Misc
+
+#region "ValueSource (Types)"
+ private static IEnumerable<ulong> _1S_F_()
+ {
+ yield return 0x00000000FF7FFFFFul; // -Max Normal (float.MinValue)
+ yield return 0x0000000080800000ul; // -Min Normal
+ yield return 0x00000000807FFFFFul; // -Max Subnormal
+ yield return 0x0000000080000001ul; // -Min Subnormal (-float.Epsilon)
+ yield return 0x000000007F7FFFFFul; // +Max Normal (float.MaxValue)
+ yield return 0x0000000000800000ul; // +Min Normal
+ yield return 0x00000000007FFFFFul; // +Max Subnormal
+ yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
+
+ if (!NoZeros)
+ {
+ yield return 0x0000000080000000ul; // -Zero
+ yield return 0x0000000000000000ul; // +Zero
+ }
+
+ if (!NoInfs)
+ {
+ yield return 0x00000000FF800000ul; // -Infinity
+ yield return 0x000000007F800000ul; // +Infinity
+ }
+
+ if (!NoNaNs)
+ {
+ yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
+ yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
+ yield return 0x000000007FC00000ul; // +QNaN (all zeros payload) (-float.NaN) (DefaultNaN)
+ yield return 0x000000007FBFFFFFul; // +SNaN (all ones payload)
+ }
+
+ for (int cnt = 1; cnt <= RndCnt; cnt++)
+ {
+ ulong grbg = TestContext.CurrentContext.Random.NextUInt();
+ ulong rnd1 = GenNormalS();
+ ulong rnd2 = GenSubnormalS();
+
+ yield return (grbg << 32) | rnd1;
+ yield return (grbg << 32) | rnd2;
+ }
+ }
+#endregion
+
private const int RndCnt = 2;
private const int RndCntImm = 2;
+ private static readonly bool NoZeros = false;
+ private static readonly bool NoInfs = false;
+ private static readonly bool NoNaNs = false;
+
#region "AluImm & Csel"
[Test, Pairwise]
public void Adds_Csinc_64bit([Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
@@ -357,6 +409,77 @@ namespace Ryujinx.Tests.Cpu
Assert.That(context.GetX(0), Is.EqualTo(a));
}
+
+ [Explicit]
+ [Test, Pairwise]
+ public void Misc4([ValueSource("_1S_F_")] ulong a,
+ [ValueSource("_1S_F_")] ulong b,
+ [ValueSource("_1S_F_")] ulong c,
+ [Values(0ul, 1ul, 2ul, 3ul)] ulong displacement)
+ {
+ if (!BitConverter.IsLittleEndian)
+ {
+ Assert.Ignore();
+ }
+
+ for (ulong gapOffset = 0; gapOffset < displacement; gapOffset++)
+ {
+ SetWorkingMemory(gapOffset, TestContext.CurrentContext.Random.NextByte());
+ }
+
+ 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());
+
+ 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());
+
+ Opcode(0xBD400001); // LDR S1, [X0,#0]
+ Opcode(0xBD400402); // LDR S2, [X0,#4]
+ Opcode(0x1E215801); // FMIN S1, S0, S1
+ Opcode(0x1E222000); // FCMP S0, S2
+ Opcode(0x1E214C40); // FCSEL S0, S2, S1, MI
+ Opcode(0xBD000800); // STR S0, [X0,#8]
+ Opcode(0xD65F03C0); // RET
+ ExecuteOpcodes();
+
+ CompareAgainstUnicorn();
+ }
+
+ [Explicit]
+ [Test]
+ public void Misc5([ValueSource("_1S_F_")] 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());
+
+ Opcode(0x1E202008); // FCMP S0, #0.0
+ Opcode(0x1E2E1001); // FMOV S1, #1.0
+ Opcode(0x1E215800); // FMIN S0, S0, S1
+ Opcode(0x1E2703E1); // FMOV S1, WZR
+ Opcode(0x1E204C20); // FCSEL S0, S1, S0, MI
+ Opcode(0xD65F03C0); // RET
+ ExecuteOpcodes();
+
+ CompareAgainstUnicorn();
+ }
#endif
}
}