diff options
Diffstat (limited to 'src/Ryujinx.Tests/Cpu/CpuTestMisc32.cs')
| -rw-r--r-- | src/Ryujinx.Tests/Cpu/CpuTestMisc32.cs | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/Ryujinx.Tests/Cpu/CpuTestMisc32.cs b/src/Ryujinx.Tests/Cpu/CpuTestMisc32.cs new file mode 100644 index 00000000..e6115013 --- /dev/null +++ b/src/Ryujinx.Tests/Cpu/CpuTestMisc32.cs @@ -0,0 +1,111 @@ +#define Misc32 + +using ARMeilleure.State; +using NUnit.Framework; +using System.Collections.Generic; + +namespace Ryujinx.Tests.Cpu +{ + [Category("Misc32")] + public sealed class CpuTestMisc32 : CpuTest32 + { +#if Misc32 + +#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 static readonly bool NoZeros = false; + 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) + { + V128 v4 = MakeVectorE0(a); + V128 v5 = MakeVectorE0(b); + + uint r0 = mode1 + ? TestContext.CurrentContext.Random.NextUInt(0xf) << 28 + : TestContext.CurrentContext.Random.NextUInt(); + + bool v = mode3 ? TestContext.CurrentContext.Random.NextBool() : false; + bool c = mode3 ? TestContext.CurrentContext.Random.NextBool() : false; + bool z = mode3 ? TestContext.CurrentContext.Random.NextBool() : false; + bool n = mode3 ? TestContext.CurrentContext.Random.NextBool() : false; + + int fpscr = mode1 + ? (int)TestContext.CurrentContext.Random.NextUInt() + : (int)TestContext.CurrentContext.Random.NextUInt(0xf) << 28; + + SetContext(r0: r0, v4: v4, v5: v5, overflow: v, carry: c, zero: z, negative: n, fpscr: fpscr); + + if (mode1) + { + Opcode(0xEEE10A10); // VMSR FPSCR, R0 + } + Opcode(0xEEB48A4A); // VCMP.F32 S16, S20 + if (mode2) + { + Opcode(0xEEF10A10); // VMRS R0, FPSCR + Opcode(0xE200020F); // AND R0, #0xF0000000 // R0 &= "Fpsr.Nzcv". + } + if (mode3) + { + Opcode(0xEEF1FA10); // VMRS APSR_NZCV, FPSCR + } + Opcode(0xE12FFF1E); // BX LR + + ExecuteOpcodes(); + + CompareAgainstUnicorn(fpsrMask: Fpsr.Nzcv); + } +#endif + } +} |
