CpuTestSimdRegElem.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
  14. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  15. }
  16. private static ulong[] _4H_()
  17. {
  18. return new[] { 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[]
  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[]
  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[]
  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[]
  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. [Test, Pairwise]
  71. public void Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H([ValueSource(nameof(_Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H_))] uint opcodes,
  72. [Values(0u)] uint rd,
  73. [Values(1u, 0u)] uint rn,
  74. [Values(2u, 0u)] uint rm,
  75. [ValueSource(nameof(_4H_))] ulong z,
  76. [ValueSource(nameof(_4H_))] ulong a,
  77. [ValueSource(nameof(_4H_))] ulong b,
  78. [Values(0u, 7u)] uint index,
  79. [Values(0b0u, 0b1u)] uint q) // <4H, 8H>
  80. {
  81. uint h = (index >> 2) & 1;
  82. uint l = (index >> 1) & 1;
  83. uint m = index & 1;
  84. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  85. opcodes |= (l << 21) | (m << 20) | (h << 11);
  86. opcodes |= ((q & 1) << 30);
  87. V128 v0 = MakeVectorE0E1(z, z);
  88. V128 v1 = MakeVectorE0E1(a, a * q);
  89. V128 v2 = MakeVectorE0E1(b, b * h);
  90. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  91. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  92. }
  93. [Test, Pairwise]
  94. public void Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_2S_4S([ValueSource(nameof(_Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_2S_4S_))] uint opcodes,
  95. [Values(0u)] uint rd,
  96. [Values(1u, 0u)] uint rn,
  97. [Values(2u, 0u)] uint rm,
  98. [ValueSource(nameof(_2S_))] ulong z,
  99. [ValueSource(nameof(_2S_))] ulong a,
  100. [ValueSource(nameof(_2S_))] ulong b,
  101. [Values(0u, 1u, 2u, 3u)] uint index,
  102. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  103. {
  104. uint h = (index >> 1) & 1;
  105. uint l = index & 1;
  106. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  107. opcodes |= (l << 21) | (h << 11);
  108. opcodes |= ((q & 1) << 30);
  109. V128 v0 = MakeVectorE0E1(z, z);
  110. V128 v1 = MakeVectorE0E1(a, a * q);
  111. V128 v2 = MakeVectorE0E1(b, b * h);
  112. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  113. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  114. }
  115. [Test, Pairwise]
  116. public void SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S([ValueSource(nameof(_SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S_))] uint opcodes,
  117. [Values(0u)] uint rd,
  118. [Values(1u, 0u)] uint rn,
  119. [Values(2u, 0u)] uint rm,
  120. [ValueSource(nameof(_4H_))] ulong z,
  121. [ValueSource(nameof(_4H_))] ulong a,
  122. [ValueSource(nameof(_4H_))] ulong b,
  123. [Values(0u, 7u)] uint index,
  124. [Values(0b0u, 0b1u)] uint q) // <4H4S, 8H4S>
  125. {
  126. uint h = (index >> 2) & 1;
  127. uint l = (index >> 1) & 1;
  128. uint m = index & 1;
  129. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  130. opcodes |= (l << 21) | (m << 20) | (h << 11);
  131. opcodes |= ((q & 1) << 30);
  132. V128 v0 = MakeVectorE0E1(z, z);
  133. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  134. V128 v2 = MakeVectorE0E1(b, b * h);
  135. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  136. CompareAgainstUnicorn();
  137. }
  138. [Test, Pairwise]
  139. public void SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D([ValueSource(nameof(_SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D_))] uint opcodes,
  140. [Values(0u)] uint rd,
  141. [Values(1u, 0u)] uint rn,
  142. [Values(2u, 0u)] uint rm,
  143. [ValueSource(nameof(_2S_))] ulong z,
  144. [ValueSource(nameof(_2S_))] ulong a,
  145. [ValueSource(nameof(_2S_))] ulong b,
  146. [Values(0u, 1u, 2u, 3u)] uint index,
  147. [Values(0b0u, 0b1u)] uint q) // <2S2D, 4S2D>
  148. {
  149. uint h = (index >> 1) & 1;
  150. uint l = index & 1;
  151. opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
  152. opcodes |= (l << 21) | (h << 11);
  153. opcodes |= ((q & 1) << 30);
  154. V128 v0 = MakeVectorE0E1(z, z);
  155. V128 v1 = MakeVectorE0E1(q == 0u ? a : 0ul, q == 1u ? a : 0ul);
  156. V128 v2 = MakeVectorE0E1(b, b * h);
  157. SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
  158. CompareAgainstUnicorn();
  159. }
  160. #endif
  161. }
  162. }