CpuTestSimdIns.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. #define SimdIns
  2. using NUnit.Framework;
  3. using System.Runtime.Intrinsics;
  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. ulong z = TestContext.CurrentContext.Random.NextULong();
  73. Vector128<float> v0 = MakeVectorE0E1(z, z);
  74. SingleOpcode(opcode, x1: wn, v0: v0);
  75. CompareAgainstUnicorn();
  76. }
  77. [Test, Pairwise, Description("DUP <Vd>.<T>, X<n>")]
  78. public void Dup_Gp_X([Values(0u)] uint rd,
  79. [Values(1u, 31u)] uint rn,
  80. [ValueSource("_X_")] [Random(RndCnt)] ulong xn)
  81. {
  82. uint opcode = 0x4E080C00; // DUP V0.2D, X0
  83. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  84. ulong z = TestContext.CurrentContext.Random.NextULong();
  85. Vector128<float> v0 = MakeVectorE0E1(z, z);
  86. SingleOpcode(opcode, x1: xn, v0: v0);
  87. CompareAgainstUnicorn();
  88. }
  89. [Test, Pairwise, Description("DUP B0, V1.B[<index>]")]
  90. public void Dup_S_B([ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  91. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  99. Vector128<float> 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("_4H_")] [Random(RndCnt)] ulong a,
  105. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  113. Vector128<float> 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("_2S_")] [Random(RndCnt)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  127. Vector128<float> 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("_1D_")] [Random(RndCnt)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  141. Vector128<float> 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("_8B_")] [Random(RndCnt)] ulong z,
  149. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  150. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  160. Vector128<float> 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("_4H_")] [Random(RndCnt)] ulong z,
  168. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  169. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  179. Vector128<float> 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("_2S_")] [Random(RndCnt)] ulong z,
  187. [ValueSource("_2S_")] [Random(RndCnt)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  198. Vector128<float> 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("_1D_")] [Random(RndCnt)] ulong z,
  206. [ValueSource("_1D_")] [Random(RndCnt)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  217. Vector128<float> 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("_8B_")] [Random(RndCnt)] ulong z,
  225. [ValueSource("_W_")] [Random(RndCnt)] uint wn,
  226. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] 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. Vector128<float> v0 = MakeVectorE0E1(z, z);
  234. SingleOpcode(opcode, x1: wn, v0: v0);
  235. CompareAgainstUnicorn();
  236. }
  237. [Test, Pairwise, Description("INS <Vd>.H[<index>], W<n>")]
  238. public void Ins_Gp_WH([Values(0u)] uint rd,
  239. [Values(1u, 31u)] uint rn,
  240. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  241. [ValueSource("_W_")] [Random(RndCnt)] uint wn,
  242. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  243. {
  244. const int size = 1;
  245. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  246. uint opcode = 0x4E001C00; // RESERVED
  247. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  248. opcode |= (imm5 << 16);
  249. Vector128<float> v0 = MakeVectorE0E1(z, z);
  250. SingleOpcode(opcode, x1: wn, v0: v0);
  251. CompareAgainstUnicorn();
  252. }
  253. [Test, Pairwise, Description("INS <Vd>.S[<index>], W<n>")]
  254. public void Ins_Gp_WS([Values(0u)] uint rd,
  255. [Values(1u, 31u)] uint rn,
  256. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  257. [ValueSource("_W_")] [Random(RndCnt)] uint wn,
  258. [Values(0u, 1u, 2u, 3u)] uint index)
  259. {
  260. const int size = 2;
  261. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  262. uint opcode = 0x4E001C00; // RESERVED
  263. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  264. opcode |= (imm5 << 16);
  265. Vector128<float> v0 = MakeVectorE0E1(z, z);
  266. SingleOpcode(opcode, x1: wn, v0: v0);
  267. CompareAgainstUnicorn();
  268. }
  269. [Test, Pairwise, Description("INS <Vd>.D[<index>], X<n>")]
  270. public void Ins_Gp_XD([Values(0u)] uint rd,
  271. [Values(1u, 31u)] uint rn,
  272. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  273. [ValueSource("_X_")] [Random(RndCnt)] ulong xn,
  274. [Values(0u, 1u)] uint index)
  275. {
  276. const int size = 3;
  277. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  278. uint opcode = 0x4E001C00; // RESERVED
  279. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  280. opcode |= (imm5 << 16);
  281. Vector128<float> v0 = MakeVectorE0E1(z, z);
  282. SingleOpcode(opcode, x1: xn, v0: v0);
  283. CompareAgainstUnicorn();
  284. }
  285. [Test, Pairwise, Description("INS <Vd>.B[<index1>], <Vn>.B[<index2>]")]
  286. public void Ins_V_BB([Values(0u)] uint rd,
  287. [Values(1u, 0u)] uint rn,
  288. [ValueSource("_8B_")] [Random(RndCnt)] ulong z,
  289. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  290. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint dstIndex,
  291. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint srcIndex)
  292. {
  293. const int size = 0;
  294. uint imm5 = (dstIndex << (size + 1) | 1u << size) & 0x1Fu;
  295. uint imm4 = (srcIndex << size) & 0xFu;
  296. uint opcode = 0x6E000400; // RESERVED
  297. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  298. opcode |= (imm5 << 16);
  299. opcode |= (imm4 << 11);
  300. Vector128<float> v0 = MakeVectorE0E1(z, z);
  301. Vector128<float> v1 = MakeVectorE0E1(a, a);
  302. SingleOpcode(opcode, v0: v0, v1: v1);
  303. CompareAgainstUnicorn();
  304. }
  305. [Test, Pairwise, Description("INS <Vd>.H[<index1>], <Vn>.H[<index2>]")]
  306. public void Ins_V_HH([Values(0u)] uint rd,
  307. [Values(1u, 0u)] uint rn,
  308. [ValueSource("_4H_")] [Random(RndCnt)] ulong z,
  309. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  310. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint dstIndex,
  311. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint srcIndex)
  312. {
  313. const int size = 1;
  314. uint imm5 = (dstIndex << (size + 1) | 1u << size) & 0x1Fu;
  315. uint imm4 = (srcIndex << size) & 0xFu;
  316. uint opcode = 0x6E000400; // RESERVED
  317. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  318. opcode |= (imm5 << 16);
  319. opcode |= (imm4 << 11);
  320. Vector128<float> v0 = MakeVectorE0E1(z, z);
  321. Vector128<float> v1 = MakeVectorE0E1(a, a);
  322. SingleOpcode(opcode, v0: v0, v1: v1);
  323. CompareAgainstUnicorn();
  324. }
  325. [Test, Pairwise, Description("INS <Vd>.S[<index1>], <Vn>.S[<index2>]")]
  326. public void Ins_V_SS([Values(0u)] uint rd,
  327. [Values(1u, 0u)] uint rn,
  328. [ValueSource("_2S_")] [Random(RndCnt)] ulong z,
  329. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  330. [Values(0u, 1u, 2u, 3u)] uint dstIndex,
  331. [Values(0u, 1u, 2u, 3u)] uint srcIndex)
  332. {
  333. const int size = 2;
  334. uint imm5 = (dstIndex << (size + 1) | 1u << size) & 0x1Fu;
  335. uint imm4 = (srcIndex << size) & 0xFu;
  336. uint opcode = 0x6E000400; // RESERVED
  337. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  338. opcode |= (imm5 << 16);
  339. opcode |= (imm4 << 11);
  340. Vector128<float> v0 = MakeVectorE0E1(z, z);
  341. Vector128<float> v1 = MakeVectorE0E1(a, a);
  342. SingleOpcode(opcode, v0: v0, v1: v1);
  343. CompareAgainstUnicorn();
  344. }
  345. [Test, Pairwise, Description("INS <Vd>.D[<index1>], <Vn>.D[<index2>]")]
  346. public void Ins_V_DD([Values(0u)] uint rd,
  347. [Values(1u, 0u)] uint rn,
  348. [ValueSource("_1D_")] [Random(RndCnt)] ulong z,
  349. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  350. [Values(0u, 1u)] uint dstIndex,
  351. [Values(0u, 1u)] uint srcIndex)
  352. {
  353. const int size = 3;
  354. uint imm5 = (dstIndex << (size + 1) | 1u << size) & 0x1Fu;
  355. uint imm4 = (srcIndex << size) & 0xFu;
  356. uint opcode = 0x6E000400; // RESERVED
  357. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  358. opcode |= (imm5 << 16);
  359. opcode |= (imm4 << 11);
  360. Vector128<float> v0 = MakeVectorE0E1(z, z);
  361. Vector128<float> v1 = MakeVectorE0E1(a, a);
  362. SingleOpcode(opcode, v0: v0, v1: v1);
  363. CompareAgainstUnicorn();
  364. }
  365. [Test, Pairwise, Description("SMOV <Wd>, <Vn>.B[<index>]")]
  366. public void Smov_S_BW([Values(0u, 31u)] uint rd,
  367. [Values(1u)] uint rn,
  368. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  369. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index)
  370. {
  371. const int size = 0;
  372. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  373. uint opcode = 0x0E002C00; // RESERVED
  374. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  375. opcode |= (imm5 << 16);
  376. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  377. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  378. Vector128<float> v1 = MakeVectorE0E1(a, a);
  379. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  380. CompareAgainstUnicorn();
  381. }
  382. [Test, Pairwise, Description("SMOV <Wd>, <Vn>.H[<index>]")]
  383. public void Smov_S_HW([Values(0u, 31u)] uint rd,
  384. [Values(1u)] uint rn,
  385. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  386. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  387. {
  388. const int size = 1;
  389. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  390. uint opcode = 0x0E002C00; // RESERVED
  391. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  392. opcode |= (imm5 << 16);
  393. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  394. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  395. Vector128<float> v1 = MakeVectorE0E1(a, a);
  396. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  397. CompareAgainstUnicorn();
  398. }
  399. [Test, Pairwise, Description("SMOV <Xd>, <Vn>.B[<index>]")]
  400. public void Smov_S_BX([Values(0u, 31u)] uint rd,
  401. [Values(1u)] uint rn,
  402. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  403. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index)
  404. {
  405. const int size = 0;
  406. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  407. uint opcode = 0x4E002C00; // RESERVED
  408. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  409. opcode |= (imm5 << 16);
  410. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  411. Vector128<float> v1 = MakeVectorE0E1(a, a);
  412. SingleOpcode(opcode, x31: x31, v1: v1);
  413. CompareAgainstUnicorn();
  414. }
  415. [Test, Pairwise, Description("SMOV <Xd>, <Vn>.H[<index>]")]
  416. public void Smov_S_HX([Values(0u, 31u)] uint rd,
  417. [Values(1u)] uint rn,
  418. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  419. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  420. {
  421. const int size = 1;
  422. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  423. uint opcode = 0x4E002C00; // RESERVED
  424. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  425. opcode |= (imm5 << 16);
  426. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  427. Vector128<float> v1 = MakeVectorE0E1(a, a);
  428. SingleOpcode(opcode, x31: x31, v1: v1);
  429. CompareAgainstUnicorn();
  430. }
  431. [Test, Pairwise, Description("SMOV <Xd>, <Vn>.S[<index>]")]
  432. public void Smov_S_SX([Values(0u, 31u)] uint rd,
  433. [Values(1u)] uint rn,
  434. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  435. [Values(0u, 1u, 2u, 3u)] uint index)
  436. {
  437. const int size = 2;
  438. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  439. uint opcode = 0x4E002C00; // RESERVED
  440. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  441. opcode |= (imm5 << 16);
  442. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  443. Vector128<float> v1 = MakeVectorE0E1(a, a);
  444. SingleOpcode(opcode, x31: x31, v1: v1);
  445. CompareAgainstUnicorn();
  446. }
  447. [Test, Pairwise, Description("UMOV <Wd>, <Vn>.B[<index>]")]
  448. public void Umov_S_BW([Values(0u, 31u)] uint rd,
  449. [Values(1u)] uint rn,
  450. [ValueSource("_8B_")] [Random(RndCnt)] ulong a,
  451. [Values(0u, 15u)] [Random(1u, 14u, RndCntIndex)] uint index)
  452. {
  453. const int size = 0;
  454. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  455. uint opcode = 0x0E003C00; // RESERVED
  456. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  457. opcode |= (imm5 << 16);
  458. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  459. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  460. Vector128<float> v1 = MakeVectorE0E1(a, a);
  461. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  462. CompareAgainstUnicorn();
  463. }
  464. [Test, Pairwise, Description("UMOV <Wd>, <Vn>.H[<index>]")]
  465. public void Umov_S_HW([Values(0u, 31u)] uint rd,
  466. [Values(1u)] uint rn,
  467. [ValueSource("_4H_")] [Random(RndCnt)] ulong a,
  468. [Values(0u, 7u)] [Random(1u, 6u, RndCntIndex)] uint index)
  469. {
  470. const int size = 1;
  471. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  472. uint opcode = 0x0E003C00; // RESERVED
  473. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  474. opcode |= (imm5 << 16);
  475. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  476. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  477. Vector128<float> v1 = MakeVectorE0E1(a, a);
  478. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  479. CompareAgainstUnicorn();
  480. }
  481. [Test, Pairwise, Description("UMOV <Wd>, <Vn>.S[<index>]")]
  482. public void Umov_S_SW([Values(0u, 31u)] uint rd,
  483. [Values(1u)] uint rn,
  484. [ValueSource("_2S_")] [Random(RndCnt)] ulong a,
  485. [Values(0u, 1u, 2u, 3u)] uint index)
  486. {
  487. const int size = 2;
  488. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  489. uint opcode = 0x0E003C00; // RESERVED
  490. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  491. opcode |= (imm5 << 16);
  492. ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
  493. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  494. Vector128<float> v1 = MakeVectorE0E1(a, a);
  495. SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
  496. CompareAgainstUnicorn();
  497. }
  498. [Test, Pairwise, Description("UMOV <Xd>, <Vn>.D[<index>]")]
  499. public void Umov_S_DX([Values(0u, 31u)] uint rd,
  500. [Values(1u)] uint rn,
  501. [ValueSource("_1D_")] [Random(RndCnt)] ulong a,
  502. [Values(0u, 1u)] uint index)
  503. {
  504. const int size = 3;
  505. uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
  506. uint opcode = 0x4E003C00; // RESERVED
  507. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  508. opcode |= (imm5 << 16);
  509. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  510. Vector128<float> v1 = MakeVectorE0E1(a, a);
  511. SingleOpcode(opcode, x31: x31, v1: v1);
  512. CompareAgainstUnicorn();
  513. }
  514. #endif
  515. }
  516. }