CpuTestSimdIns.cs 24 KB

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