CpuTestSimdIns.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. #define SimdIns
  2. using ARMeilleure.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. [Category("SimdIns")]
  7. public sealed class CpuTestSimdIns : CpuTest
  8. {
  9. #if SimdIns
  10. #region "ValueSource"
  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. private static ulong[] _8B4H_()
  32. {
  33. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  34. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  35. 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
  36. }
  37. private static ulong[] _8B4H2S_()
  38. {
  39. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  40. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  41. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  42. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  43. }
  44. private static uint[] _W_()
  45. {
  46. return new uint[] { 0x00000000u, 0x0000007Fu,
  47. 0x00000080u, 0x000000FFu,
  48. 0x00007FFFu, 0x00008000u,
  49. 0x0000FFFFu, 0x7FFFFFFFu,
  50. 0x80000000u, 0xFFFFFFFFu };
  51. }
  52. private static ulong[] _X_()
  53. {
  54. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  55. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  56. }
  57. #endregion
  58. private const int RndCnt = 2;
  59. private const int RndCntIndex = 2;
  60. [Test, Pairwise, Description("DUP <Vd>.<T>, W<n>")]
  61. public void Dup_Gp_W([Values(0u)] uint rd,
  62. [Values(1u, 31u)] uint rn,
  63. [ValueSource("_W_")] [Random(RndCnt)] uint wn,
  64. [Values(0, 1, 2)] int size, // Q0: <8B, 4H, 2S>
  65. [Values(0b0u, 0b1u)] uint q) // Q1: <16B, 8H, 4S>
  66. {
  67. uint imm5 = (1u << size) & 0x1Fu;
  68. uint opcode = 0x0E000C00; // RESERVED
  69. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  70. opcode |= (imm5 << 16);
  71. opcode |= ((q & 1) << 30);
  72. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  73. ulong z = TestContext.CurrentContext.Random.NextULong();
  74. V128 v0 = MakeVectorE0E1(z, z);
  75. SingleOpcode(opcode, x1: wn, x31: w31, v0: v0);
  76. CompareAgainstUnicorn();
  77. }
  78. [Test, Pairwise, Description("DUP <Vd>.<T>, X<n>")]
  79. public void Dup_Gp_X([Values(0u)] uint rd,
  80. [Values(1u, 31u)] uint rn,
  81. [ValueSource("_X_")] [Random(RndCnt)] ulong xn)
  82. {
  83. uint opcode = 0x4E080C00; // DUP V0.2D, X0
  84. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  85. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  86. ulong z = TestContext.CurrentContext.Random.NextULong();
  87. V128 v0 = MakeVectorE0E1(z, z);
  88. SingleOpcode(opcode, x1: xn, x31: x31, v0: v0);
  89. CompareAgainstUnicorn();
  90. }
  91. [Test, Pairwise, Description("DUP B0, V1.B[<index>]")]
  92. public void Dup_S_B([ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  93. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index)
  94. {
  95. const int size = 0;
  96. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  97. uint opcode = 0x5E000420; // RESERVED
  98. opcode |= (imm5 << 16);
  99. ulong z = TestContext.CurrentContext.Random.NextULong();
  100. V128 v0 = MakeVectorE0E1(z, z);
  101. V128 v1 = MakeVectorE0E1(a, a);
  102. SingleOpcode(opcode, v0: v0, v1: v1);
  103. CompareAgainstUnicorn();
  104. }
  105. [Test, Pairwise, Description("DUP H0, V1.H[<index>]")]
  106. public void Dup_S_H([ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  107. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  108. {
  109. const int size = 1;
  110. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  111. uint opcode = 0x5E000420; // RESERVED
  112. opcode |= (imm5 << 16);
  113. ulong z = TestContext.CurrentContext.Random.NextULong();
  114. V128 v0 = MakeVectorE0E1(z, z);
  115. V128 v1 = MakeVectorE0E1(a, a);
  116. SingleOpcode(opcode, v0: v0, v1: v1);
  117. CompareAgainstUnicorn();
  118. }
  119. [Test, Pairwise, Description("DUP S0, V1.S[<index>]")]
  120. public void Dup_S_S([ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  121. [Values(0u, 1u, 2u, 3u)] uint index)
  122. {
  123. const int size = 2;
  124. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  125. uint opcode = 0x5E000420; // RESERVED
  126. opcode |= (imm5 << 16);
  127. ulong z = TestContext.CurrentContext.Random.NextULong();
  128. V128 v0 = MakeVectorE0E1(z, z);
  129. V128 v1 = MakeVectorE0E1(a, a);
  130. SingleOpcode(opcode, v0: v0, v1: v1);
  131. CompareAgainstUnicorn();
  132. }
  133. [Test, Pairwise, Description("DUP D0, V1.D[<index>]")]
  134. public void Dup_S_D([ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  135. [Values(0u, 1u)] uint index)
  136. {
  137. const int size = 3;
  138. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  139. uint opcode = 0x5E000420; // RESERVED
  140. opcode |= (imm5 << 16);
  141. ulong z = TestContext.CurrentContext.Random.NextULong();
  142. V128 v0 = MakeVectorE0E1(z, z);
  143. V128 v1 = MakeVectorE0E1(a, a);
  144. SingleOpcode(opcode, v0: v0, v1: v1);
  145. CompareAgainstUnicorn();
  146. }
  147. [Test, Pairwise, Description("DUP <Vd>.<T>, <Vn>.B[<index>]")]
  148. public void Dup_V_8B_16B([Values(0u)] uint rd,
  149. [Values(1u, 0u)] uint rn,
  150. [ValueSource("_8B_")] [Random(RndCnt)] ulong z,
  151. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  152. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index,
  153. [Values(0b0u, 0b1u)] uint q) // <8B, 16B>
  154. {
  155. const int size = 0;
  156. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  157. uint opcode = 0x0E000400; // RESERVED
  158. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  159. opcode |= (imm5 << 16);
  160. opcode |= ((q & 1) << 30);
  161. V128 v0 = MakeVectorE0E1(z, z);
  162. V128 v1 = MakeVectorE0E1(a, a);
  163. SingleOpcode(opcode, v0: v0, v1: v1);
  164. CompareAgainstUnicorn();
  165. }
  166. [Test, Pairwise, Description("DUP <Vd>.<T>, <Vn>.H[<index>]")]
  167. public void Dup_V_4H_8H([Values(0u)] uint rd,
  168. [Values(1u, 0u)] uint rn,
  169. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  170. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  171. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index,
  172. [Values(0b0u, 0b1u)] uint q) // <4H, 8H>
  173. {
  174. const int size = 1;
  175. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  176. uint opcode = 0x0E000400; // RESERVED
  177. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  178. opcode |= (imm5 << 16);
  179. opcode |= ((q & 1) << 30);
  180. V128 v0 = MakeVectorE0E1(z, z);
  181. V128 v1 = MakeVectorE0E1(a, a);
  182. SingleOpcode(opcode, v0: v0, v1: v1);
  183. CompareAgainstUnicorn();
  184. }
  185. [Test, Pairwise, Description("DUP <Vd>.<T>, <Vn>.S[<index>]")]
  186. public void Dup_V_2S_4S([Values(0u)] uint rd,
  187. [Values(1u, 0u)] uint rn,
  188. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  189. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  190. [Values(0u, 1u, 2u, 3u)] uint index,
  191. [Values(0b0u, 0b1u)] uint q) // <2S, 4S>
  192. {
  193. const int size = 2;
  194. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  195. uint opcode = 0x0E000400; // RESERVED
  196. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  197. opcode |= (imm5 << 16);
  198. opcode |= ((q & 1) << 30);
  199. V128 v0 = MakeVectorE0E1(z, z);
  200. V128 v1 = MakeVectorE0E1(a, a);
  201. SingleOpcode(opcode, v0: v0, v1: v1);
  202. CompareAgainstUnicorn();
  203. }
  204. [Test, Pairwise, Description("DUP <Vd>.<T>, <Vn>.D[<index>]")]
  205. public void Dup_V_2D([Values(0u)] uint rd,
  206. [Values(1u, 0u)] uint rn,
  207. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  208. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  209. [Values(0u, 1u)] uint index,
  210. [Values(0b1u)] uint q) // <2D>
  211. {
  212. const int size = 3;
  213. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  214. uint opcode = 0x0E000400; // RESERVED
  215. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  216. opcode |= (imm5 << 16);
  217. opcode |= ((q & 1) << 30);
  218. V128 v0 = MakeVectorE0E1(z, z);
  219. V128 v1 = MakeVectorE0E1(a, a);
  220. SingleOpcode(opcode, v0: v0, v1: v1);
  221. CompareAgainstUnicorn();
  222. }
  223. [Test, Pairwise, Description("INS <Vd>.B[<index>], W<n>")]
  224. public void Ins_Gp_WB([Values(0u)] uint rd,
  225. [Values(1u, 31u)] uint rn,
  226. [ValueSource("_8B_")] [Random(RndCnt)] ulong z,
  227. [ValueSource("_W_")] [Random(RndCnt)] uint wn,
  228. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index)
  229. {
  230. const int size = 0;
  231. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  232. uint opcode = 0x4E001C00; // RESERVED
  233. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  234. opcode |= (imm5 << 16);
  235. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  236. V128 v0 = MakeVectorE0E1(z, z);
  237. SingleOpcode(opcode, x1: wn, x31: w31, v0: v0);
  238. CompareAgainstUnicorn();
  239. }
  240. [Test, Pairwise, Description("INS <Vd>.H[<index>], W<n>")]
  241. public void Ins_Gp_WH([Values(0u)] uint rd,
  242. [Values(1u, 31u)] uint rn,
  243. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  244. [ValueSource("_W_")] [Random(RndCnt)] uint wn,
  245. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  246. {
  247. const int size = 1;
  248. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  249. uint opcode = 0x4E001C00; // RESERVED
  250. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  251. opcode |= (imm5 << 16);
  252. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  253. V128 v0 = MakeVectorE0E1(z, z);
  254. SingleOpcode(opcode, x1: wn, x31: w31, v0: v0);
  255. CompareAgainstUnicorn();
  256. }
  257. [Test, Pairwise, Description("INS <Vd>.S[<index>], W<n>")]
  258. public void Ins_Gp_WS([Values(0u)] uint rd,
  259. [Values(1u, 31u)] uint rn,
  260. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  261. [ValueSource("_W_")] [Random(RndCnt)] uint wn,
  262. [Values(0u, 1u, 2u, 3u)] uint index)
  263. {
  264. const int size = 2;
  265. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  266. uint opcode = 0x4E001C00; // RESERVED
  267. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  268. opcode |= (imm5 << 16);
  269. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  270. V128 v0 = MakeVectorE0E1(z, z);
  271. SingleOpcode(opcode, x1: wn, x31: w31, v0: v0);
  272. CompareAgainstUnicorn();
  273. }
  274. [Test, Pairwise, Description("INS <Vd>.D[<index>], X<n>")]
  275. public void Ins_Gp_XD([Values(0u)] uint rd,
  276. [Values(1u, 31u)] uint rn,
  277. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  278. [ValueSource("_X_")] [Random(RndCnt)] ulong xn,
  279. [Values(0u, 1u)] uint index)
  280. {
  281. const int size = 3;
  282. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  283. uint opcode = 0x4E001C00; // RESERVED
  284. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  285. opcode |= (imm5 << 16);
  286. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  287. V128 v0 = MakeVectorE0E1(z, z);
  288. SingleOpcode(opcode, x1: xn, x31: x31, v0: v0);
  289. CompareAgainstUnicorn();
  290. }
  291. [Test, Pairwise, Description("INS <Vd>.B[<index1>], <Vn>.B[<index2>]")]
  292. public void Ins_V_BB([Values(0u)] uint rd,
  293. [Values(1u, 0u)] uint rn,
  294. [ValueSource("_8B_")] [Random(RndCnt)] ulong z,
  295. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  296. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint dstIndex,
  297. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint srcIndex)
  298. {
  299. const int size = 0;
  300. uint imm5 = (dstIndex << (size + 1) | 1u << size) & 0x1Fu;
  301. uint imm4 = (srcIndex << size) & 0xFu;
  302. uint opcode = 0x6E000400; // RESERVED
  303. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  304. opcode |= (imm5 << 16);
  305. opcode |= (imm4 << 11);
  306. V128 v0 = MakeVectorE0E1(z, z);
  307. V128 v1 = MakeVectorE0E1(a, a);
  308. SingleOpcode(opcode, v0: v0, v1: v1);
  309. CompareAgainstUnicorn();
  310. }
  311. [Test, Pairwise, Description("INS <Vd>.H[<index1>], <Vn>.H[<index2>]")]
  312. public void Ins_V_HH([Values(0u)] uint rd,
  313. [Values(1u, 0u)] uint rn,
  314. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  315. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  316. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint dstIndex,
  317. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint srcIndex)
  318. {
  319. const int size = 1;
  320. uint imm5 = (dstIndex << (size + 1) | 1u << size) & 0x1Fu;
  321. uint imm4 = (srcIndex << size) & 0xFu;
  322. uint opcode = 0x6E000400; // RESERVED
  323. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  324. opcode |= (imm5 << 16);
  325. opcode |= (imm4 << 11);
  326. V128 v0 = MakeVectorE0E1(z, z);
  327. V128 v1 = MakeVectorE0E1(a, a);
  328. SingleOpcode(opcode, v0: v0, v1: v1);
  329. CompareAgainstUnicorn();
  330. }
  331. [Test, Pairwise, Description("INS <Vd>.S[<index1>], <Vn>.S[<index2>]")]
  332. public void Ins_V_SS([Values(0u)] uint rd,
  333. [Values(1u, 0u)] uint rn,
  334. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  335. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  336. [Values(0u, 1u, 2u, 3u)] uint dstIndex,
  337. [Values(0u, 1u, 2u, 3u)] uint srcIndex)
  338. {
  339. const int size = 2;
  340. uint imm5 = (dstIndex << (size + 1) | 1u << size) & 0x1Fu;
  341. uint imm4 = (srcIndex << size) & 0xFu;
  342. uint opcode = 0x6E000400; // RESERVED
  343. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  344. opcode |= (imm5 << 16);
  345. opcode |= (imm4 << 11);
  346. V128 v0 = MakeVectorE0E1(z, z);
  347. V128 v1 = MakeVectorE0E1(a, a);
  348. SingleOpcode(opcode, v0: v0, v1: v1);
  349. CompareAgainstUnicorn();
  350. }
  351. [Test, Pairwise, Description("INS <Vd>.D[<index1>], <Vn>.D[<index2>]")]
  352. public void Ins_V_DD([Values(0u)] uint rd,
  353. [Values(1u, 0u)] uint rn,
  354. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  355. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  356. [Values(0u, 1u)] uint dstIndex,
  357. [Values(0u, 1u)] uint srcIndex)
  358. {
  359. const int size = 3;
  360. uint imm5 = (dstIndex << (size + 1) | 1u << size) & 0x1Fu;
  361. uint imm4 = (srcIndex << size) & 0xFu;
  362. uint opcode = 0x6E000400; // RESERVED
  363. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  364. opcode |= (imm5 << 16);
  365. opcode |= (imm4 << 11);
  366. V128 v0 = MakeVectorE0E1(z, z);
  367. V128 v1 = MakeVectorE0E1(a, a);
  368. SingleOpcode(opcode, v0: v0, v1: v1);
  369. CompareAgainstUnicorn();
  370. }
  371. [Test, Pairwise, Description("SMOV <Wd>, <Vn>.B[<index>]")]
  372. public void Smov_S_BW([Values(0u, 31u)] uint rd,
  373. [Values(1u)] uint rn,
  374. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  375. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index)
  376. {
  377. const int size = 0;
  378. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  379. uint opcode = 0x0E002C00; // RESERVED
  380. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  381. opcode |= (imm5 << 16);
  382. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  383. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  384. V128 v1 = MakeVectorE0E1(a, a);
  385. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  386. CompareAgainstUnicorn();
  387. }
  388. [Test, Pairwise, Description("SMOV <Wd>, <Vn>.H[<index>]")]
  389. public void Smov_S_HW([Values(0u, 31u)] uint rd,
  390. [Values(1u)] uint rn,
  391. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  392. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  393. {
  394. const int size = 1;
  395. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  396. uint opcode = 0x0E002C00; // RESERVED
  397. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  398. opcode |= (imm5 << 16);
  399. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  400. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  401. V128 v1 = MakeVectorE0E1(a, a);
  402. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  403. CompareAgainstUnicorn();
  404. }
  405. [Test, Pairwise, Description("SMOV <Xd>, <Vn>.B[<index>]")]
  406. public void Smov_S_BX([Values(0u, 31u)] uint rd,
  407. [Values(1u)] uint rn,
  408. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  409. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index)
  410. {
  411. const int size = 0;
  412. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  413. uint opcode = 0x4E002C00; // RESERVED
  414. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  415. opcode |= (imm5 << 16);
  416. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  417. V128 v1 = MakeVectorE0E1(a, a);
  418. SingleOpcode(opcode, x31: x31, v1: v1);
  419. CompareAgainstUnicorn();
  420. }
  421. [Test, Pairwise, Description("SMOV <Xd>, <Vn>.H[<index>]")]
  422. public void Smov_S_HX([Values(0u, 31u)] uint rd,
  423. [Values(1u)] uint rn,
  424. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  425. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  426. {
  427. const int size = 1;
  428. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  429. uint opcode = 0x4E002C00; // RESERVED
  430. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  431. opcode |= (imm5 << 16);
  432. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  433. V128 v1 = MakeVectorE0E1(a, a);
  434. SingleOpcode(opcode, x31: x31, v1: v1);
  435. CompareAgainstUnicorn();
  436. }
  437. [Test, Pairwise, Description("SMOV <Xd>, <Vn>.S[<index>]")]
  438. public void Smov_S_SX([Values(0u, 31u)] uint rd,
  439. [Values(1u)] uint rn,
  440. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  441. [Values(0u, 1u, 2u, 3u)] uint index)
  442. {
  443. const int size = 2;
  444. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  445. uint opcode = 0x4E002C00; // RESERVED
  446. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  447. opcode |= (imm5 << 16);
  448. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  449. V128 v1 = MakeVectorE0E1(a, a);
  450. SingleOpcode(opcode, x31: x31, v1: v1);
  451. CompareAgainstUnicorn();
  452. }
  453. [Test, Pairwise, Description("UMOV <Wd>, <Vn>.B[<index>]")]
  454. public void Umov_S_BW([Values(0u, 31u)] uint rd,
  455. [Values(1u)] uint rn,
  456. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  457. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index)
  458. {
  459. const int size = 0;
  460. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  461. uint opcode = 0x0E003C00; // RESERVED
  462. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  463. opcode |= (imm5 << 16);
  464. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  465. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  466. V128 v1 = MakeVectorE0E1(a, a);
  467. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  468. CompareAgainstUnicorn();
  469. }
  470. [Test, Pairwise, Description("UMOV <Wd>, <Vn>.H[<index>]")]
  471. public void Umov_S_HW([Values(0u, 31u)] uint rd,
  472. [Values(1u)] uint rn,
  473. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  474. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  475. {
  476. const int size = 1;
  477. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  478. uint opcode = 0x0E003C00; // RESERVED
  479. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  480. opcode |= (imm5 << 16);
  481. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  482. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  483. V128 v1 = MakeVectorE0E1(a, a);
  484. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  485. CompareAgainstUnicorn();
  486. }
  487. [Test, Pairwise, Description("UMOV <Wd>, <Vn>.S[<index>]")]
  488. public void Umov_S_SW([Values(0u, 31u)] uint rd,
  489. [Values(1u)] uint rn,
  490. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  491. [Values(0u, 1u, 2u, 3u)] uint index)
  492. {
  493. const int size = 2;
  494. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  495. uint opcode = 0x0E003C00; // RESERVED
  496. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  497. opcode |= (imm5 << 16);
  498. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  499. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  500. V128 v1 = MakeVectorE0E1(a, a);
  501. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  502. CompareAgainstUnicorn();
  503. }
  504. [Test, Pairwise, Description("UMOV <Xd>, <Vn>.D[<index>]")]
  505. public void Umov_S_DX([Values(0u, 31u)] uint rd,
  506. [Values(1u)] uint rn,
  507. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  508. [Values(0u, 1u)] uint index)
  509. {
  510. const int size = 3;
  511. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  512. uint opcode = 0x4E003C00; // RESERVED
  513. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  514. opcode |= (imm5 << 16);
  515. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  516. V128 v1 = MakeVectorE0E1(a, a);
  517. SingleOpcode(opcode, x31: x31, v1: v1);
  518. CompareAgainstUnicorn();
  519. }
  520. #endif
  521. }
  522. }