CpuTestSimdRegElem.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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_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. };
  31. }
  32. private static uint[] _Mla_Mls_Mul_Ve_2S_4S_()
  33. {
  34. return new uint[]
  35. {
  36. 0x2F800000u, // MLA V0.2S, V0.2S, V0.S[0]
  37. 0x2F804000u, // MLS V0.2S, V0.2S, V0.S[0]
  38. 0x0F808000u // MUL V0.2S, V0.2S, V0.S[0]
  39. };
  40. }
  41. private static uint[] _SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S_()
  42. {
  43. return new uint[]
  44. {
  45. 0x0F402000u, // SMLAL V0.4S, V0.4H, V0.H[0]
  46. 0x0F406000u, // SMLSL V0.4S, V0.4H, V0.H[0]
  47. 0x0F40A000u, // SMULL V0.4S, V0.4H, V0.H[0]
  48. 0x2F402000u, // UMLAL V0.4S, V0.4H, V0.H[0]
  49. 0x2F406000u, // UMLSL V0.4S, V0.4H, V0.H[0]
  50. 0x2F40A000u // UMULL V0.4S, V0.4H, V0.H[0]
  51. };
  52. }
  53. private static uint[] _SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D_()
  54. {
  55. return new uint[]
  56. {
  57. 0x0F802000u, // SMLAL V0.2D, V0.2S, V0.S[0]
  58. 0x0F806000u, // SMLSL V0.2D, V0.2S, V0.S[0]
  59. 0x0F80A000u, // SMULL V0.2D, V0.2S, V0.S[0]
  60. 0x2F802000u, // UMLAL V0.2D, V0.2S, V0.S[0]
  61. 0x2F806000u, // UMLSL V0.2D, V0.2S, V0.S[0]
  62. 0x2F80A000u // UMULL V0.2D, V0.2S, V0.S[0]
  63. };
  64. }
  65. #endregion
  66. private const int RndCnt = 2;
  67. private const int RndCntIndex = 2;
  68. [Test, Pairwise]
  69. public void Mla_Mls_Mul_Ve_4H_8H([ValueSource("_Mla_Mls_Mul_Ve_4H_8H_")] uint opcodes,
  70. [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, 7u)] [Random(1u, 6u, RndCntIndex)] uint index,
  77. [Values(0b0u, 0b1u)] uint q) // <4H, 8H>
  78. {
  79. uint h = (index >> 2) & 1;
  80. uint l = (index >> 1) & 1;
  81. uint m = index & 1;
  82. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  83. opcodes |= (l << 21) | (m << 20) | (h << 11);
  84. opcodes |= ((q & 1) << 30);
  85. V128 v0 = MakeVectorE0E1(z, z);
  86. V128 v1 = MakeVectorE0E1(a, a * q);
  87. V128 v2 = MakeVectorE0E1(b, b * h);
  88. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  89. CompareAgainstUnicorn();
  90. }
  91. [Test, Pairwise]
  92. public void Mla_Mls_Mul_Ve_2S_4S([ValueSource("_Mla_Mls_Mul_Ve_2S_4S_")] uint opcodes,
  93. [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 >> 1) & 1;
  103. uint l = index & 1;
  104. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  105. opcodes |= (l << 21) | (h << 11);
  106. opcodes |= ((q & 1) << 30);
  107. V128 v0 = MakeVectorE0E1(z, z);
  108. V128 v1 = MakeVectorE0E1(a, a * q);
  109. V128 v2 = MakeVectorE0E1(b, b * h);
  110. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  111. CompareAgainstUnicorn();
  112. }
  113. [Test, Pairwise]
  114. public void SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S([ValueSource("_SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S_")] uint opcodes,
  115. [Values(0u)] uint rd,
  116. [Values(1u, 0u)] uint rn,
  117. [Values(2u, 0u)] uint rm,
  118. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  119. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  120. [ValueSource("_4H_")] [Random(RndCnt)] ulong b,
  121. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index,
  122. [Values(0b0u, 0b1u)] uint q) // <4H4S, 8H4S>
  123. {
  124. uint h = (index >> 2) & 1;
  125. uint l = (index >> 1) & 1;
  126. uint m = index & 1;
  127. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  128. opcodes |= (l << 21) | (m << 20) | (h << 11);
  129. opcodes |= ((q & 1) << 30);
  130. V128 v0 = MakeVectorE0E1(z, z);
  131. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  132. V128 v2 = MakeVectorE0E1(b, b * h);
  133. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  134. CompareAgainstUnicorn();
  135. }
  136. [Test, Pairwise]
  137. public void SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D([ValueSource("_SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D_")] uint opcodes,
  138. [Values(0u)] uint rd,
  139. [Values(1u, 0u)] uint rn,
  140. [Values(2u, 0u)] uint rm,
  141. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  142. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  143. [ValueSource("_2S_")] [Random(RndCnt)] ulong b,
  144. [Values(0u, 1u, 2u, 3u)] uint index,
  145. [Values(0b0u, 0b1u)] uint q) // <2S2D, 4S2D>
  146. {
  147. uint h = (index >> 1) & 1;
  148. uint l = index & 1;
  149. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  150. opcodes |= (l << 21) | (h << 11);
  151. opcodes |= ((q & 1) << 30);
  152. V128 v0 = MakeVectorE0E1(z, z);
  153. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  154. V128 v2 = MakeVectorE0E1(b, b * h);
  155. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  156. CompareAgainstUnicorn();
  157. }
  158. #endif
  159. }
  160. }