CpuTestSimdShImm32.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. #define SimdShImm32
  2. using ARMeilleure.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. [Category("SimdShImm32")]
  7. public sealed class CpuTestSimdShImm32 : CpuTest32
  8. {
  9. #if SimdShImm32
  10. #region "ValueSource (Types)"
  11. private static ulong[] _1D_()
  12. {
  13. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  14. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  15. }
  16. private static ulong[] _2S_()
  17. {
  18. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
  19. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  20. }
  21. private static ulong[] _4H_()
  22. {
  23. return new ulong[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
  24. 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
  25. }
  26. private static ulong[] _8B_()
  27. {
  28. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  29. 0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
  30. }
  31. #endregion
  32. #region "ValueSource (Opcodes)"
  33. private static uint[] _Vshr_Imm_SU8_()
  34. {
  35. return new uint[]
  36. {
  37. 0xf2880010u, // VSHR.S8 D0, D0, #8
  38. 0xf2880110u, // VSRA.S8 D0, D0, #8
  39. 0xf2880210u, // VRSHR.S8 D0, D0, #8
  40. 0xf2880310u // VRSRA.S8 D0, D0, #8
  41. };
  42. }
  43. private static uint[] _Vshr_Imm_SU16_()
  44. {
  45. return new uint[]
  46. {
  47. 0xf2900010u, // VSHR.S16 D0, D0, #16
  48. 0xf2900110u, // VSRA.S16 D0, D0, #16
  49. 0xf2900210u, // VRSHR.S16 D0, D0, #16
  50. 0xf2900310u // VRSRA.S16 D0, D0, #16
  51. };
  52. }
  53. private static uint[] _Vshr_Imm_SU32_()
  54. {
  55. return new uint[]
  56. {
  57. 0xf2a00010u, // VSHR.S32 D0, D0, #32
  58. 0xf2a00110u, // VSRA.S32 D0, D0, #32
  59. 0xf2a00210u, // VRSHR.S32 D0, D0, #32
  60. 0xf2a00310u // VRSRA.S32 D0, D0, #32
  61. };
  62. }
  63. private static uint[] _Vshr_Imm_SU64_()
  64. {
  65. return new uint[]
  66. {
  67. 0xf2800190u, // VSRA.S64 D0, D0, #64
  68. 0xf2800290u, // VRSHR.S64 D0, D0, #64
  69. 0xf2800090u // VSHR.S64 D0, D0, #64
  70. };
  71. }
  72. private static uint[] _Vqshrn_Vqrshrn_Vrshrn_Imm_()
  73. {
  74. return new uint[]
  75. {
  76. 0xf2800910u, // VORR.I16 D0, #0 (immediate value changes it into QSHRN)
  77. 0xf2800950u, // VORR.I16 Q0, #0 (immediate value changes it into QRSHRN)
  78. 0xf2800850u // VMOV.I16 Q0, #0 (immediate value changes it into RSHRN)
  79. };
  80. }
  81. private static uint[] _Vqshrun_Vqrshrun_Imm_()
  82. {
  83. return new uint[]
  84. {
  85. 0xf3800810u, // VMOV.I16 D0, #0x80 (immediate value changes it into QSHRUN)
  86. 0xf3800850u // VMOV.I16 Q0, #0x80 (immediate value changes it into QRSHRUN)
  87. };
  88. }
  89. #endregion
  90. private const int RndCnt = 2;
  91. private const int RndCntShiftImm = 2;
  92. [Test, Pairwise]
  93. public void Vshr_Imm_SU8([ValueSource("_Vshr_Imm_SU8_")] uint opcode,
  94. [Range(0u, 3u)] uint rd,
  95. [Range(0u, 3u)] uint rm,
  96. [ValueSource("_8B_")] [Random(RndCnt)] ulong z,
  97. [ValueSource("_8B_")] [Random(RndCnt)] ulong b,
  98. [Values(1u, 8u)] [Random(2u, 7u, RndCntShiftImm)] uint shiftImm,
  99. [Values] bool u,
  100. [Values] bool q)
  101. {
  102. uint imm6 = 16 - shiftImm;
  103. Vshr_Imm_SU(opcode, rd, rm, z, b, imm6, u, q);
  104. }
  105. [Test, Pairwise]
  106. public void Vshr_Imm_SU16([ValueSource("_Vshr_Imm_SU16_")] uint opcode,
  107. [Range(0u, 3u)] uint rd,
  108. [Range(0u, 3u)] uint rm,
  109. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  110. [ValueSource("_4H_")] [Random(RndCnt)] ulong b,
  111. [Values(1u, 16u)] [Random(2u, 15u, RndCntShiftImm)] uint shiftImm,
  112. [Values] bool u,
  113. [Values] bool q)
  114. {
  115. uint imm6 = 32 - shiftImm;
  116. Vshr_Imm_SU(opcode, rd, rm, z, b, imm6, u, q);
  117. }
  118. [Test, Pairwise]
  119. public void Vshr_Imm_SU32([ValueSource("_Vshr_Imm_SU32_")] uint opcode,
  120. [Range(0u, 3u)] uint rd,
  121. [Range(0u, 3u)] uint rm,
  122. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  123. [ValueSource("_2S_")] [Random(RndCnt)] ulong b,
  124. [Values(1u, 32u)] [Random(2u, 31u, RndCntShiftImm)] uint shiftImm,
  125. [Values] bool u,
  126. [Values] bool q)
  127. {
  128. uint imm6 = 64 - shiftImm;
  129. Vshr_Imm_SU(opcode, rd, rm, z, b, imm6, u, q);
  130. }
  131. [Test, Pairwise]
  132. public void Vshr_Imm_SU64([ValueSource("_Vshr_Imm_SU64_")] uint opcode,
  133. [Range(0u, 3u)] uint rd,
  134. [Range(0u, 3u)] uint rm,
  135. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  136. [ValueSource("_1D_")] [Random(RndCnt)] ulong b,
  137. [Values(1u, 64u)] [Random(2u, 63u, RndCntShiftImm)] uint shiftImm,
  138. [Values] bool u,
  139. [Values] bool q)
  140. {
  141. uint imm6 = 64 - shiftImm;
  142. Vshr_Imm_SU(opcode, rd, rm, z, b, imm6, u, q);
  143. }
  144. private void Vshr_Imm_SU(uint opcode, uint rd, uint rm, ulong z, ulong b, uint imm6, bool u, bool q)
  145. {
  146. if (u)
  147. {
  148. opcode |= 1 << 24;
  149. }
  150. if (q)
  151. {
  152. opcode |= 1 << 6;
  153. rd >>= 1; rd <<= 1;
  154. rm >>= 1; rm <<= 1;
  155. }
  156. opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
  157. opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
  158. opcode |= (imm6 & 0x3f) << 16;
  159. V128 v0 = MakeVectorE0E1(z, ~z);
  160. V128 v1 = MakeVectorE0E1(b, ~b);
  161. SingleOpcode(opcode, v0: v0, v1: v1);
  162. CompareAgainstUnicorn();
  163. }
  164. [Test, Pairwise, Description("VSHL.<size> {<Vd>}, <Vm>, #<imm>")]
  165. public void Vshl_Imm([Values(0u)] uint rd,
  166. [Values(2u, 0u)] uint rm,
  167. [Values(0u, 1u, 2u, 3u)] uint size,
  168. [Random(RndCntShiftImm)] [Values(0u)] uint shiftImm,
  169. [Random(RndCnt)] ulong z,
  170. [Random(RndCnt)] ulong a,
  171. [Random(RndCnt)] ulong b,
  172. [Values] bool q)
  173. {
  174. uint opcode = 0xf2800510u; // VORR.I32 D0, #0 (immediate value changes it into SHL)
  175. if (q)
  176. {
  177. opcode |= 1 << 6;
  178. rm <<= 1;
  179. rd <<= 1;
  180. }
  181. uint imm = 1u << ((int)size + 3);
  182. imm |= shiftImm & (imm - 1);
  183. opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
  184. opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
  185. opcode |= ((imm & 0x3f) << 16) | ((imm & 0x40) << 1);
  186. V128 v0 = MakeVectorE0E1(z, z);
  187. V128 v1 = MakeVectorE0E1(a, z);
  188. V128 v2 = MakeVectorE0E1(b, z);
  189. SingleOpcode(opcode, v0: v0, v1: v1, v2: v2);
  190. CompareAgainstUnicorn();
  191. }
  192. [Test, Pairwise, Description("VSHRN.<size> <Vd>, <Vm>, #<imm>")]
  193. public void Vshrn_Imm([Values(0u, 1u)] uint rd,
  194. [Values(2u, 0u)] uint rm,
  195. [Values(0u, 1u, 2u)] uint size,
  196. [Random(RndCntShiftImm)] [Values(0u)] uint shiftImm,
  197. [Random(RndCnt)] ulong z,
  198. [Random(RndCnt)] ulong a,
  199. [Random(RndCnt)] ulong b)
  200. {
  201. uint opcode = 0xf2800810u; // VMOV.I16 D0, #0 (immediate value changes it into SHRN)
  202. uint imm = 1u << ((int)size + 3);
  203. imm |= shiftImm & (imm - 1);
  204. opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
  205. opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
  206. opcode |= ((imm & 0x3f) << 16);
  207. V128 v0 = MakeVectorE0E1(z, z);
  208. V128 v1 = MakeVectorE0E1(a, z);
  209. V128 v2 = MakeVectorE0E1(b, z);
  210. SingleOpcode(opcode, v0: v0, v1: v1, v2: v2);
  211. CompareAgainstUnicorn();
  212. }
  213. [Test, Pairwise]
  214. public void Vqshrn_Vqrshrn_Vrshrn_Imm([ValueSource("_Vqshrn_Vqrshrn_Vrshrn_Imm_")] uint opcode,
  215. [Values(0u, 1u)] uint rd,
  216. [Values(2u, 0u)] uint rm,
  217. [Values(0u, 1u, 2u)] uint size,
  218. [Random(RndCntShiftImm)] [Values(0u)] uint shiftImm,
  219. [Random(RndCnt)] ulong z,
  220. [Random(RndCnt)] ulong a,
  221. [Random(RndCnt)] ulong b,
  222. [Values] bool u)
  223. {
  224. uint imm = 1u << ((int)size + 3);
  225. imm |= shiftImm & (imm - 1);
  226. opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
  227. opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
  228. opcode |= ((imm & 0x3f) << 16);
  229. if (u)
  230. {
  231. opcode |= 1u << 24;
  232. }
  233. V128 v0 = MakeVectorE0E1(z, z);
  234. V128 v1 = MakeVectorE0E1(a, z);
  235. V128 v2 = MakeVectorE0E1(b, z);
  236. int fpscr = (int)TestContext.CurrentContext.Random.NextUInt() & (int)Fpsr.Qc;
  237. SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, fpscr: fpscr);
  238. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  239. }
  240. [Test, Pairwise]
  241. public void Vqshrun_Vqrshrun_Imm([ValueSource("_Vqshrun_Vqrshrun_Imm_")] uint opcode,
  242. [Values(0u, 1u)] uint rd,
  243. [Values(2u, 0u)] uint rm,
  244. [Values(0u, 1u, 2u)] uint size,
  245. [Random(RndCntShiftImm)] [Values(0u)] uint shiftImm,
  246. [Random(RndCnt)] ulong z,
  247. [Random(RndCnt)] ulong a,
  248. [Random(RndCnt)] ulong b)
  249. {
  250. uint imm = 1u << ((int)size + 3);
  251. imm |= shiftImm & (imm - 1);
  252. opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
  253. opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
  254. opcode |= ((imm & 0x3f) << 16);
  255. V128 v0 = MakeVectorE0E1(z, z);
  256. V128 v1 = MakeVectorE0E1(a, z);
  257. V128 v2 = MakeVectorE0E1(b, z);
  258. int fpscr = (int)TestContext.CurrentContext.Random.NextUInt() & (int)Fpsr.Qc;
  259. SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, fpscr: fpscr);
  260. CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
  261. }
  262. #endif
  263. }
  264. }