CpuTestSimdRegElem.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #define SimdRegElem
  2. using NUnit.Framework;
  3. using System.Runtime.Intrinsics;
  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. [Test, Pairwise]
  68. public void Mla_Mls_Mul_Ve_4H_8H([ValueSource("_Mla_Mls_Mul_Ve_4H_8H_")] uint opcodes,
  69. [Values(0u)] uint rd,
  70. [Values(1u, 0u)] uint rn,
  71. [Values(2u, 0u)] uint rm,
  72. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  73. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  74. [ValueSource("_4H_")] [Random(RndCnt)] ulong b,
  75. [Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint index,
  76. [Values(0b0u, 0b1u)] uint q) // <4H, 8H>
  77. {
  78. uint h = (index >> 2) & 1;
  79. uint l = (index >> 1) & 1;
  80. uint m = index & 1;
  81. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  82. opcodes |= (l << 21) | (m << 20) | (h << 11);
  83. opcodes |= ((q & 1) << 30);
  84. Vector128<float> v0 = MakeVectorE0E1(z, z);
  85. Vector128<float> v1 = MakeVectorE0E1(a, a * q);
  86. Vector128<float> v2 = MakeVectorE0E1(b, b * h);
  87. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  88. CompareAgainstUnicorn();
  89. }
  90. [Test, Pairwise]
  91. public void Mla_Mls_Mul_Ve_2S_4S([ValueSource("_Mla_Mls_Mul_Ve_2S_4S_")] uint opcodes,
  92. [Values(0u)] uint rd,
  93. [Values(1u, 0u)] uint rn,
  94. [Values(2u, 0u)] uint rm,
  95. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  96. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  97. [ValueSource("_2S_")] [Random(RndCnt)] ulong b,
  98. [Values(0u, 1u, 2u, 3u)] uint index,
  99. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  100. {
  101. uint h = (index >> 1) & 1;
  102. uint l = index & 1;
  103. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  104. opcodes |= (l << 21) | (h << 11);
  105. opcodes |= ((q & 1) << 30);
  106. Vector128<float> v0 = MakeVectorE0E1(z, z);
  107. Vector128<float> v1 = MakeVectorE0E1(a, a * q);
  108. Vector128<float> v2 = MakeVectorE0E1(b, b * h);
  109. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  110. CompareAgainstUnicorn();
  111. }
  112. [Test, Pairwise]
  113. public void SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S([ValueSource("_SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S_")] uint opcodes,
  114. [Values(0u)] uint rd,
  115. [Values(1u, 0u)] uint rn,
  116. [Values(2u, 0u)] uint rm,
  117. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  118. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  119. [ValueSource("_4H_")] [Random(RndCnt)] ulong b,
  120. [Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint index,
  121. [Values(0b0u, 0b1u)] uint q) // <4H4S, 8H4S>
  122. {
  123. uint h = (index >> 2) & 1;
  124. uint l = (index >> 1) & 1;
  125. uint m = index & 1;
  126. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  127. opcodes |= (l << 21) | (m << 20) | (h << 11);
  128. opcodes |= ((q & 1) << 30);
  129. Vector128<float> v0 = MakeVectorE0E1(z, z);
  130. Vector128<float> v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  131. Vector128<float> v2 = MakeVectorE0E1(b, b * h);
  132. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  133. CompareAgainstUnicorn();
  134. }
  135. [Test, Pairwise]
  136. public void SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D([ValueSource("_SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D_")] uint opcodes,
  137. [Values(0u)] uint rd,
  138. [Values(1u, 0u)] uint rn,
  139. [Values(2u, 0u)] uint rm,
  140. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  141. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  142. [ValueSource("_2S_")] [Random(RndCnt)] ulong b,
  143. [Values(0u, 1u, 2u, 3u)] uint index,
  144. [Values(0b0u, 0b1u)] uint q) // <2S2D, 4S2D>
  145. {
  146. uint h = (index >> 1) & 1;
  147. uint l = index & 1;
  148. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  149. opcodes |= (l << 21) | (h << 11);
  150. opcodes |= ((q & 1) << 30);
  151. Vector128<float> v0 = MakeVectorE0E1(z, z);
  152. Vector128<float> v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  153. Vector128<float> v2 = MakeVectorE0E1(b, b * h);
  154. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  155. CompareAgainstUnicorn();
  156. }
  157. #endif
  158. }
  159. }