CpuTestSimdRegElem.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #define SimdRegElem
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. using System.Runtime.Intrinsics;
  5. namespace Ryujinx.Tests.Cpu
  6. {
  7. [Category("SimdRegElem")] // Tested: second half of 2018.
  8. public sealed class CpuTestSimdRegElem : CpuTest
  9. {
  10. #if SimdRegElem
  11. #region "ValueSource"
  12. private static ulong[] _2S_()
  13. {
  14. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
  15. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  16. }
  17. private static ulong[] _4H_()
  18. {
  19. return new ulong[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
  20. 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
  21. }
  22. #endregion
  23. private const int RndCnt = 2;
  24. [Test, Pairwise, Description("MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]")]
  25. public void Mla_Ve_4H_8H([Values(0u)] uint Rd,
  26. [Values(1u, 0u)] uint Rn,
  27. [Values(2u, 0u)] uint Rm,
  28. [ValueSource("_4H_")] [Random(RndCnt)] ulong Z,
  29. [ValueSource("_4H_")] [Random(RndCnt)] ulong A,
  30. [ValueSource("_4H_")] [Random(RndCnt)] ulong B,
  31. [Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint Index,
  32. [Values(0b0u, 0b1u)] uint Q) // <4H, 8H>
  33. {
  34. uint H = (Index & 4) >> 2;
  35. uint L = (Index & 2) >> 1;
  36. uint M = (Index & 1) >> 0;
  37. uint Opcode = 0x2F400000; // MLA V0.4H, V0.4H, V0.H[0]
  38. Opcode |= ((Rm & 15) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  39. Opcode |= (L << 21) | (M << 20) | (H << 11);
  40. Opcode |= ((Q & 1) << 30);
  41. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  42. Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
  43. Vector128<float> V2 = MakeVectorE0E1(B, B * H);
  44. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  45. CompareAgainstUnicorn();
  46. }
  47. [Test, Pairwise, Description("MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]")]
  48. public void Mla_Ve_2S_4S([Values(0u)] uint Rd,
  49. [Values(1u, 0u)] uint Rn,
  50. [Values(2u, 0u)] uint Rm,
  51. [ValueSource("_2S_")] [Random(RndCnt)] ulong Z,
  52. [ValueSource("_2S_")] [Random(RndCnt)] ulong A,
  53. [ValueSource("_2S_")] [Random(RndCnt)] ulong B,
  54. [Values(0u, 1u, 2u, 3u)] uint Index,
  55. [Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
  56. {
  57. uint H = (Index & 2) >> 1;
  58. uint L = (Index & 1) >> 0;
  59. uint Opcode = 0x2F800000; // MLA V0.2S, V0.2S, V0.S[0]
  60. Opcode |= ((Rm & 15) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  61. Opcode |= (L << 21) | (H << 11);
  62. Opcode |= ((Q & 1) << 30);
  63. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  64. Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
  65. Vector128<float> V2 = MakeVectorE0E1(B, B * H);
  66. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  67. CompareAgainstUnicorn();
  68. }
  69. [Test, Pairwise, Description("MLS <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]")]
  70. public void Mls_Ve_4H_8H([Values(0u)] uint Rd,
  71. [Values(1u, 0u)] uint Rn,
  72. [Values(2u, 0u)] uint Rm,
  73. [ValueSource("_4H_")] [Random(RndCnt)] ulong Z,
  74. [ValueSource("_4H_")] [Random(RndCnt)] ulong A,
  75. [ValueSource("_4H_")] [Random(RndCnt)] ulong B,
  76. [Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint Index,
  77. [Values(0b0u, 0b1u)] uint Q) // <4H, 8H>
  78. {
  79. uint H = (Index & 4) >> 2;
  80. uint L = (Index & 2) >> 1;
  81. uint M = (Index & 1) >> 0;
  82. uint Opcode = 0x2F404000; // MLS V0.4H, V0.4H, V0.H[0]
  83. Opcode |= ((Rm & 15) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  84. Opcode |= (L << 21) | (M << 20) | (H << 11);
  85. Opcode |= ((Q & 1) << 30);
  86. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  87. Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
  88. Vector128<float> V2 = MakeVectorE0E1(B, B * H);
  89. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  90. CompareAgainstUnicorn();
  91. }
  92. [Test, Pairwise, Description("MLS <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]")]
  93. public void Mls_Ve_2S_4S([Values(0u)] uint Rd,
  94. [Values(1u, 0u)] uint Rn,
  95. [Values(2u, 0u)] uint Rm,
  96. [ValueSource("_2S_")] [Random(RndCnt)] ulong Z,
  97. [ValueSource("_2S_")] [Random(RndCnt)] ulong A,
  98. [ValueSource("_2S_")] [Random(RndCnt)] ulong B,
  99. [Values(0u, 1u, 2u, 3u)] uint Index,
  100. [Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
  101. {
  102. uint H = (Index & 2) >> 1;
  103. uint L = (Index & 1) >> 0;
  104. uint Opcode = 0x2F804000; // MLS V0.2S, V0.2S, V0.S[0]
  105. Opcode |= ((Rm & 15) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  106. Opcode |= (L << 21) | (H << 11);
  107. Opcode |= ((Q & 1) << 30);
  108. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  109. Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
  110. Vector128<float> V2 = MakeVectorE0E1(B, B * H);
  111. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  112. CompareAgainstUnicorn();
  113. }
  114. #endif
  115. }
  116. }