CpuTestSimdRegElem.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #define SimdRegElem
  2. using ARMeilleure.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. [Category("SimdRegElem")]
  7. public sealed class CpuTestSimdRegElem : CpuTest
  8. {
  9. #if SimdRegElem
  10. #region "ValueSource (Types)"
  11. private static ulong[] _2S_()
  12. {
  13. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
  14. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  15. }
  16. private static ulong[] _4H_()
  17. {
  18. return new ulong[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
  19. 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
  20. }
  21. #endregion
  22. #region "ValueSource (Opcodes)"
  23. private static uint[] _Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H_()
  24. {
  25. return new uint[]
  26. {
  27. 0x2F400000u, // MLA V0.4H, V0.4H, V0.H[0]
  28. 0x2F404000u, // MLS V0.4H, V0.4H, V0.H[0]
  29. 0x0F408000u, // MUL V0.4H, V0.4H, V0.H[0]
  30. 0x0F40C000u, // SQDMULH V0.4H, V0.4H, V0.H[0]
  31. 0x0F40D000u // SQRDMULH V0.4H, V0.4H, V0.H[0]
  32. };
  33. }
  34. private static uint[] _Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_2S_4S_()
  35. {
  36. return new uint[]
  37. {
  38. 0x2F800000u, // MLA V0.2S, V0.2S, V0.S[0]
  39. 0x2F804000u, // MLS V0.2S, V0.2S, V0.S[0]
  40. 0x0F808000u, // MUL V0.2S, V0.2S, V0.S[0]
  41. 0x0F80C000u, // SQDMULH V0.2S, V0.2S, V0.S[0]
  42. 0x0F80D000u // SQRDMULH V0.2S, V0.2S, V0.S[0]
  43. };
  44. }
  45. private static uint[] _SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S_()
  46. {
  47. return new uint[]
  48. {
  49. 0x0F402000u, // SMLAL V0.4S, V0.4H, V0.H[0]
  50. 0x0F406000u, // SMLSL V0.4S, V0.4H, V0.H[0]
  51. 0x0F40A000u, // SMULL V0.4S, V0.4H, V0.H[0]
  52. 0x2F402000u, // UMLAL V0.4S, V0.4H, V0.H[0]
  53. 0x2F406000u, // UMLSL V0.4S, V0.4H, V0.H[0]
  54. 0x2F40A000u // UMULL V0.4S, V0.4H, V0.H[0]
  55. };
  56. }
  57. private static uint[] _SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D_()
  58. {
  59. return new uint[]
  60. {
  61. 0x0F802000u, // SMLAL V0.2D, V0.2S, V0.S[0]
  62. 0x0F806000u, // SMLSL V0.2D, V0.2S, V0.S[0]
  63. 0x0F80A000u, // SMULL V0.2D, V0.2S, V0.S[0]
  64. 0x2F802000u, // UMLAL V0.2D, V0.2S, V0.S[0]
  65. 0x2F806000u, // UMLSL V0.2D, V0.2S, V0.S[0]
  66. 0x2F80A000u // UMULL V0.2D, V0.2S, V0.S[0]
  67. };
  68. }
  69. #endregion
  70. private const int RndCnt = 2;
  71. private const int RndCntIndex = 2;
  72. [Test, Pairwise]
  73. public void Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H([ValueSource(nameof(_Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H_))] uint opcodes,
  74. [Values(0u)] uint rd,
  75. [Values(1u, 0u)] uint rn,
  76. [Values(2u, 0u)] uint rm,
  77. [ValueSource(nameof(_4H_))] [Random(RndCnt)] ulong z,
  78. [ValueSource(nameof(_4H_))] [Random(RndCnt)] ulong a,
  79. [ValueSource(nameof(_4H_))] [Random(RndCnt)] ulong b,
  80. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index,
  81. [Values(0b0u, 0b1u)] uint q) // <4H, 8H>
  82. {
  83. uint h = (index >> 2) & 1;
  84. uint l = (index >> 1) & 1;
  85. uint m = index & 1;
  86. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  87. opcodes |= (l << 21) | (m << 20) | (h << 11);
  88. opcodes |= ((q & 1) << 30);
  89. V128 v0 = MakeVectorE0E1(z, z);
  90. V128 v1 = MakeVectorE0E1(a, a * q);
  91. V128 v2 = MakeVectorE0E1(b, b * h);
  92. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  93. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  94. }
  95. [Test, Pairwise]
  96. public void Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_2S_4S([ValueSource(nameof(_Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_2S_4S_))] uint opcodes,
  97. [Values(0u)] uint rd,
  98. [Values(1u, 0u)] uint rn,
  99. [Values(2u, 0u)] uint rm,
  100. [ValueSource(nameof(_2S_))] [Random(RndCnt)] ulong z,
  101. [ValueSource(nameof(_2S_))] [Random(RndCnt)] ulong a,
  102. [ValueSource(nameof(_2S_))] [Random(RndCnt)] ulong b,
  103. [Values(0u, 1u, 2u, 3u)] uint index,
  104. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  105. {
  106. uint h = (index >> 1) & 1;
  107. uint l = index & 1;
  108. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  109. opcodes |= (l << 21) | (h << 11);
  110. opcodes |= ((q & 1) << 30);
  111. V128 v0 = MakeVectorE0E1(z, z);
  112. V128 v1 = MakeVectorE0E1(a, a * q);
  113. V128 v2 = MakeVectorE0E1(b, b * h);
  114. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  115. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  116. }
  117. [Test, Pairwise]
  118. public void SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S([ValueSource("_SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S_")] uint opcodes,
  119. [Values(0u)] uint rd,
  120. [Values(1u, 0u)] uint rn,
  121. [Values(2u, 0u)] uint rm,
  122. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  123. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  124. [ValueSource("_4H_")] [Random(RndCnt)] ulong b,
  125. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index,
  126. [Values(0b0u, 0b1u)] uint q) // <4H4S, 8H4S>
  127. {
  128. uint h = (index >> 2) & 1;
  129. uint l = (index >> 1) & 1;
  130. uint m = index & 1;
  131. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  132. opcodes |= (l << 21) | (m << 20) | (h << 11);
  133. opcodes |= ((q & 1) << 30);
  134. V128 v0 = MakeVectorE0E1(z, z);
  135. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  136. V128 v2 = MakeVectorE0E1(b, b * h);
  137. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  138. CompareAgainstUnicorn();
  139. }
  140. [Test, Pairwise]
  141. public void SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D([ValueSource("_SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D_")] uint opcodes,
  142. [Values(0u)] uint rd,
  143. [Values(1u, 0u)] uint rn,
  144. [Values(2u, 0u)] uint rm,
  145. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  146. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  147. [ValueSource("_2S_")] [Random(RndCnt)] ulong b,
  148. [Values(0u, 1u, 2u, 3u)] uint index,
  149. [Values(0b0u, 0b1u)] uint q) // <2S2D, 4S2D>
  150. {
  151. uint h = (index >> 1) & 1;
  152. uint l = index & 1;
  153. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  154. opcodes |= (l << 21) | (h << 11);
  155. opcodes |= ((q & 1) << 30);
  156. V128 v0 = MakeVectorE0E1(z, z);
  157. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  158. V128 v2 = MakeVectorE0E1(b, b * h);
  159. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  160. CompareAgainstUnicorn();
  161. }
  162. #endif
  163. }
  164. }