diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2019-03-23 19:50:19 +0100 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2019-03-23 15:50:19 -0300 |
| commit | c106ae994425e384a9ad8d6d00747af71e8475a6 (patch) | |
| tree | a40b30d78cff602f68597493f71118ff7fe47826 /Ryujinx.Tests/Cpu | |
| parent | 1b2e430e887fc2eac372c46255c18ecceb032fd1 (diff) | |
Add Tbl_V Sse opt. with Tests. (#651)
* Add v4, v5, v30, v31 required for Tbl_V Tests.
* Add Tests for Tbl_V.
* Add Tbl_V Sse opt..
* Nit.
* Small opt. on comparison constant vector.
* Nit.
* Add EmitLd/Stvectmp2/3.
* Nit.
Diffstat (limited to 'Ryujinx.Tests/Cpu')
| -rw-r--r-- | Ryujinx.Tests/Cpu/CpuTest.cs | 50 | ||||
| -rw-r--r-- | Ryujinx.Tests/Cpu/CpuTestSimdTbl.cs | 315 |
2 files changed, 348 insertions, 17 deletions
diff --git a/Ryujinx.Tests/Cpu/CpuTest.cs b/Ryujinx.Tests/Cpu/CpuTest.cs index 47feb573..b147cf44 100644 --- a/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/Ryujinx.Tests/Cpu/CpuTest.cs @@ -93,10 +93,14 @@ namespace Ryujinx.Tests.Cpu } protected void SetThreadState(ulong x0 = 0, ulong x1 = 0, ulong x2 = 0, ulong x3 = 0, ulong x31 = 0, - Vector128<float> v0 = default(Vector128<float>), - Vector128<float> v1 = default(Vector128<float>), - Vector128<float> v2 = default(Vector128<float>), - Vector128<float> v3 = default(Vector128<float>), + Vector128<float> v0 = default(Vector128<float>), + Vector128<float> v1 = default(Vector128<float>), + Vector128<float> v2 = default(Vector128<float>), + Vector128<float> v3 = default(Vector128<float>), + Vector128<float> v4 = default(Vector128<float>), + Vector128<float> v5 = default(Vector128<float>), + Vector128<float> v30 = default(Vector128<float>), + Vector128<float> v31 = default(Vector128<float>), bool overflow = false, bool carry = false, bool zero = false, bool negative = false, int fpcr = 0x0, int fpsr = 0x0) { @@ -107,10 +111,14 @@ namespace Ryujinx.Tests.Cpu _thread.ThreadState.X31 = x31; - _thread.ThreadState.V0 = v0; - _thread.ThreadState.V1 = v1; - _thread.ThreadState.V2 = v2; - _thread.ThreadState.V3 = v3; + _thread.ThreadState.V0 = v0; + _thread.ThreadState.V1 = v1; + _thread.ThreadState.V2 = v2; + _thread.ThreadState.V3 = v3; + _thread.ThreadState.V4 = v4; + _thread.ThreadState.V5 = v5; + _thread.ThreadState.V30 = v30; + _thread.ThreadState.V31 = v31; _thread.ThreadState.Overflow = overflow; _thread.ThreadState.Carry = carry; @@ -129,10 +137,14 @@ namespace Ryujinx.Tests.Cpu _unicornEmu.SP = x31; - _unicornEmu.Q[0] = v0; - _unicornEmu.Q[1] = v1; - _unicornEmu.Q[2] = v2; - _unicornEmu.Q[3] = v3; + _unicornEmu.Q[0] = v0; + _unicornEmu.Q[1] = v1; + _unicornEmu.Q[2] = v2; + _unicornEmu.Q[3] = v3; + _unicornEmu.Q[4] = v4; + _unicornEmu.Q[5] = v5; + _unicornEmu.Q[30] = v30; + _unicornEmu.Q[31] = v31; _unicornEmu.OverflowFlag = overflow; _unicornEmu.CarryFlag = carry; @@ -165,17 +177,21 @@ namespace Ryujinx.Tests.Cpu protected CpuThreadState SingleOpcode(uint opcode, ulong x0 = 0, ulong x1 = 0, ulong x2 = 0, ulong x3 = 0, ulong x31 = 0, - Vector128<float> v0 = default(Vector128<float>), - Vector128<float> v1 = default(Vector128<float>), - Vector128<float> v2 = default(Vector128<float>), - Vector128<float> v3 = default(Vector128<float>), + Vector128<float> v0 = default(Vector128<float>), + Vector128<float> v1 = default(Vector128<float>), + Vector128<float> v2 = default(Vector128<float>), + Vector128<float> v3 = default(Vector128<float>), + Vector128<float> v4 = default(Vector128<float>), + Vector128<float> v5 = default(Vector128<float>), + Vector128<float> v30 = default(Vector128<float>), + Vector128<float> v31 = default(Vector128<float>), bool overflow = false, bool carry = false, bool zero = false, bool negative = false, int fpcr = 0x0, int fpsr = 0x0) { Opcode(opcode); Opcode(0xD4200000); // BRK #0 Opcode(0xD65F03C0); // RET - SetThreadState(x0, x1, x2, x3, x31, v0, v1, v2, v3, overflow, carry, zero, negative, fpcr, fpsr); + SetThreadState(x0, x1, x2, x3, x31, v0, v1, v2, v3, v4, v5, v30, v31, overflow, carry, zero, negative, fpcr, fpsr); ExecuteOpcodes(); return GetThreadState(); diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdTbl.cs b/Ryujinx.Tests/Cpu/CpuTestSimdTbl.cs new file mode 100644 index 00000000..69195af2 --- /dev/null +++ b/Ryujinx.Tests/Cpu/CpuTestSimdTbl.cs @@ -0,0 +1,315 @@ +#define SimdTbl + +using NUnit.Framework; + +using System.Collections.Generic; +using System.Runtime.Intrinsics; + +namespace Ryujinx.Tests.Cpu +{ + [Category("SimdTbl")] + public sealed class CpuTestSimdTbl : CpuTest + { +#if SimdTbl + +#region "Helper methods" + private static ulong GenIdxsForTbls(int regs) + { + const byte idxInRngMin = (byte)0; + byte idxInRngMax = (byte)((16 * regs) - 1); + byte idxOutRngMin = (byte) (16 * regs); + const byte idxOutRngMax = (byte)255; + + ulong idxs = 0ul; + + for (int cnt = 1; cnt <= 8; cnt++) + { + ulong idxInRng = (ulong)TestContext.CurrentContext.Random.NextByte(idxInRngMin, idxInRngMax); + ulong idxOutRng = (ulong)TestContext.CurrentContext.Random.NextByte(idxOutRngMin, idxOutRngMax); + + ulong idx = TestContext.CurrentContext.Random.NextBool() ? idxInRng : idxOutRng; + + idxs = (idxs << 8) | idx; + } + + return idxs; + } +#endregion + +#region "ValueSource (Types)" + private static ulong[] _8B_() + { + return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful, + 0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul }; + } + + private static IEnumerable<ulong> _GenIdxsForTbl1_() + { + yield return 0x0000000000000000ul; + yield return 0x7F7F7F7F7F7F7F7Ful; + yield return 0x8080808080808080ul; + yield return 0xFFFFFFFFFFFFFFFFul; + + for (int cnt = 1; cnt <= RndCntIdxs; cnt++) + { + yield return GenIdxsForTbls(regs: 1); + } + } + + private static IEnumerable<ulong> _GenIdxsForTbl2_() + { + yield return 0x0000000000000000ul; + yield return 0x7F7F7F7F7F7F7F7Ful; + yield return 0x8080808080808080ul; + yield return 0xFFFFFFFFFFFFFFFFul; + + for (int cnt = 1; cnt <= RndCntIdxs; cnt++) + { + yield return GenIdxsForTbls(regs: 2); + } + } + + private static IEnumerable<ulong> _GenIdxsForTbl3_() + { + yield return 0x0000000000000000ul; + yield return 0x7F7F7F7F7F7F7F7Ful; + yield return 0x8080808080808080ul; + yield return 0xFFFFFFFFFFFFFFFFul; + + for (int cnt = 1; cnt <= RndCntIdxs; cnt++) + { + yield return GenIdxsForTbls(regs: 3); + } + } + + private static IEnumerable<ulong> _GenIdxsForTbl4_() + { + yield return 0x0000000000000000ul; + yield return 0x7F7F7F7F7F7F7F7Ful; + yield return 0x8080808080808080ul; + yield return 0xFFFFFFFFFFFFFFFFul; + + for (int cnt = 1; cnt <= RndCntIdxs; cnt++) + { + yield return GenIdxsForTbls(regs: 4); + } + } +#endregion + +#region "ValueSource (Opcodes)" + private static uint[] _SingleRegTbl_V_8B_16B_() + { + return new uint[] + { + 0x0E000000u, // TBL V0.8B, { V0.16B }, V0.8B + }; + } + + private static uint[] _TwoRegTbl_V_8B_16B_() + { + return new uint[] + { + 0x0E002000u, // TBL V0.8B, { V0.16B, V1.16B }, V0.8B + }; + } + + private static uint[] _ThreeRegTbl_V_8B_16B_() + { + return new uint[] + { + 0x0E004000u, // TBL V0.8B, { V0.16B, V1.16B, V2.16B }, V0.8B + }; + } + + private static uint[] _FourRegTbl_V_8B_16B_() + { + return new uint[] + { + 0x0E006000u, // TBL V0.8B, { V0.16B, V1.16B, V2.16B, V3.16B }, V0.8B + }; + } +#endregion + + private const int RndCntTbls = 2; + private const int RndCntIdxs = 2; + + [Test, Pairwise, Description("TBL <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>")] + public void SingleRegTbl_V_8B_16B([ValueSource("_SingleRegTbl_V_8B_16B_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u)] uint rn, + [Values(2u)] uint rm, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table0, + [ValueSource("_GenIdxsForTbl1_")] ulong indexes, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + { + opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= ((q & 1) << 30); + + ulong z = TestContext.CurrentContext.Random.NextULong(); + Vector128<float> v0 = MakeVectorE0E1(z, z); + Vector128<float> v1 = MakeVectorE0E1(table0, table0); + Vector128<float> v2 = MakeVectorE0E1(indexes, q == 1u ? indexes : 0ul); + + SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise, Description("TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>")] + public void TwoRegTbl_V_8B_16B([ValueSource("_TwoRegTbl_V_8B_16B_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u)] uint rn, + [Values(3u)] uint rm, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table0, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table1, + [ValueSource("_GenIdxsForTbl2_")] ulong indexes, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + { + opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= ((q & 1) << 30); + + ulong z = TestContext.CurrentContext.Random.NextULong(); + Vector128<float> v0 = MakeVectorE0E1(z, z); + Vector128<float> v1 = MakeVectorE0E1(table0, table0); + Vector128<float> v2 = MakeVectorE0E1(table1, table1); + Vector128<float> v3 = MakeVectorE0E1(indexes, q == 1u ? indexes : 0ul); + + SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v3: v3); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise, Description("TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>")] + public void Mod_TwoRegTbl_V_8B_16B([ValueSource("_TwoRegTbl_V_8B_16B_")] uint opcodes, + [Values(30u, 1u)] uint rd, + [Values(31u)] uint rn, + [Values(1u, 30u)] uint rm, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table0, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table1, + [ValueSource("_GenIdxsForTbl2_")] ulong indexes, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + { + opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= ((q & 1) << 30); + + ulong z = TestContext.CurrentContext.Random.NextULong(); + Vector128<float> v30 = MakeVectorE0E1(z, z); + Vector128<float> v31 = MakeVectorE0E1(table0, table0); + Vector128<float> v0 = MakeVectorE0E1(table1, table1); + Vector128<float> v1 = MakeVectorE0E1(indexes, indexes); + + SingleOpcode(opcodes, v0: v0, v1: v1, v30: v30, v31: v31); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise, Description("TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>")] + public void ThreeRegTbl_V_8B_16B([ValueSource("_ThreeRegTbl_V_8B_16B_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u)] uint rn, + [Values(4u)] uint rm, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table0, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table1, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table2, + [ValueSource("_GenIdxsForTbl3_")] ulong indexes, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + { + opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= ((q & 1) << 30); + + ulong z = TestContext.CurrentContext.Random.NextULong(); + Vector128<float> v0 = MakeVectorE0E1(z, z); + Vector128<float> v1 = MakeVectorE0E1(table0, table0); + Vector128<float> v2 = MakeVectorE0E1(table1, table1); + Vector128<float> v3 = MakeVectorE0E1(table2, table2); + Vector128<float> v4 = MakeVectorE0E1(indexes, q == 1u ? indexes : 0ul); + + SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v3: v3, v4: v4); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise, Description("TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>")] + public void Mod_ThreeRegTbl_V_8B_16B([ValueSource("_ThreeRegTbl_V_8B_16B_")] uint opcodes, + [Values(30u, 2u)] uint rd, + [Values(31u)] uint rn, + [Values(2u, 30u)] uint rm, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table0, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table1, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table2, + [ValueSource("_GenIdxsForTbl3_")] ulong indexes, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + { + opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= ((q & 1) << 30); + + ulong z = TestContext.CurrentContext.Random.NextULong(); + Vector128<float> v30 = MakeVectorE0E1(z, z); + Vector128<float> v31 = MakeVectorE0E1(table0, table0); + Vector128<float> v0 = MakeVectorE0E1(table1, table1); + Vector128<float> v1 = MakeVectorE0E1(table2, table2); + Vector128<float> v2 = MakeVectorE0E1(indexes, indexes); + + SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v30: v30, v31: v31); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise, Description("TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>")] + public void FourRegTbl_V_8B_16B([ValueSource("_FourRegTbl_V_8B_16B_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u)] uint rn, + [Values(5u)] uint rm, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table0, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table1, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table2, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table3, + [ValueSource("_GenIdxsForTbl4_")] ulong indexes, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + { + opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= ((q & 1) << 30); + + ulong z = TestContext.CurrentContext.Random.NextULong(); + Vector128<float> v0 = MakeVectorE0E1(z, z); + Vector128<float> v1 = MakeVectorE0E1(table0, table0); + Vector128<float> v2 = MakeVectorE0E1(table1, table1); + Vector128<float> v3 = MakeVectorE0E1(table2, table2); + Vector128<float> v4 = MakeVectorE0E1(table3, table3); + Vector128<float> v5 = MakeVectorE0E1(indexes, q == 1u ? indexes : 0ul); + + SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v3: v3, v4: v4, v5: v5); + + CompareAgainstUnicorn(); + } + + [Test, Pairwise, Description("TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>")] + public void Mod_FourRegTbl_V_8B_16B([ValueSource("_FourRegTbl_V_8B_16B_")] uint opcodes, + [Values(30u, 3u)] uint rd, + [Values(31u)] uint rn, + [Values(3u, 30u)] uint rm, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table0, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table1, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table2, + [ValueSource("_8B_")] [Random(RndCntTbls)] ulong table3, + [ValueSource("_GenIdxsForTbl4_")] ulong indexes, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + { + opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0); + opcodes |= ((q & 1) << 30); + + ulong z = TestContext.CurrentContext.Random.NextULong(); + Vector128<float> v30 = MakeVectorE0E1(z, z); + Vector128<float> v31 = MakeVectorE0E1(table0, table0); + Vector128<float> v0 = MakeVectorE0E1(table1, table1); + Vector128<float> v1 = MakeVectorE0E1(table2, table2); + Vector128<float> v2 = MakeVectorE0E1(table3, table3); + Vector128<float> v3 = MakeVectorE0E1(indexes, indexes); + + SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v3: v3, v30: v30, v31: v31); + + CompareAgainstUnicorn(); + } +#endif + } +} |
