CpuTestSimdReg.cs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. #define SimdReg
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. using Tester;
  7. using Tester.Types;
  8. [Category("SimdReg")]
  9. public sealed class CpuTestSimdReg : CpuTest
  10. {
  11. #if SimdReg
  12. [SetUp]
  13. public void SetupTester()
  14. {
  15. AArch64.TakeReset(false);
  16. }
  17. #region "ValueSource"
  18. private static ulong[] _1D_()
  19. {
  20. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  21. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  22. }
  23. private static ulong[] _4H2S1D_()
  24. {
  25. return new ulong[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
  26. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  27. 0x8000000080000000ul, 0x7FFFFFFFFFFFFFFFul,
  28. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  29. }
  30. private static ulong[] _8B_()
  31. {
  32. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  33. 0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
  34. }
  35. private static ulong[] _8B4H2S_()
  36. {
  37. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  38. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  39. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  40. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  41. }
  42. private static ulong[] _8B4H2S1D_()
  43. {
  44. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  45. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  46. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  47. 0x8000000080000000ul, 0x7FFFFFFFFFFFFFFFul,
  48. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  49. }
  50. #endregion
  51. [Test, Description("ADD <V><d>, <V><n>, <V><m>")]
  52. public void Add_S_D([ValueSource("_1D_")] [Random(1)] ulong A,
  53. [ValueSource("_1D_")] [Random(1)] ulong B)
  54. {
  55. uint Opcode = 0x5EE28420; // ADD D0, D1, D2
  56. Bits Op = new Bits(Opcode);
  57. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  58. AVec V1 = new AVec { X0 = A };
  59. AVec V2 = new AVec { X0 = B };
  60. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  61. AArch64.V(1, new Bits(A));
  62. AArch64.V(2, new Bits(B));
  63. SimdFp.Add_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  64. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  65. Assert.That(ThreadState.V0.X1, Is.Zero);
  66. }
  67. [Test, Description("ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  68. public void Add_V_8B_4H_2S([ValueSource("_8B4H2S_")] [Random(1)] ulong A,
  69. [ValueSource("_8B4H2S_")] [Random(1)] ulong B,
  70. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  71. {
  72. uint Opcode = 0x0E228420; // ADD V0.8B, V1.8B, V2.8B
  73. Opcode |= ((size & 3) << 22);
  74. Bits Op = new Bits(Opcode);
  75. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  76. AVec V1 = new AVec { X0 = A };
  77. AVec V2 = new AVec { X0 = B };
  78. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  79. AArch64.V(1, new Bits(A));
  80. AArch64.V(2, new Bits(B));
  81. SimdFp.Add_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  82. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  83. Assert.That(ThreadState.V0.X1, Is.Zero);
  84. }
  85. [Test, Pairwise, Description("ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  86. public void Add_V_16B_8H_4S_2D([ValueSource("_8B4H2S1D_")] [Random(1)] ulong A0,
  87. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong A1,
  88. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong B0,
  89. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong B1,
  90. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  91. {
  92. uint Opcode = 0x4E228420; // ADD V0.16B, V1.16B, V2.16B
  93. Opcode |= ((size & 3) << 22);
  94. Bits Op = new Bits(Opcode);
  95. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  96. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  97. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  98. AArch64.Vpart(1, 0, new Bits(A0));
  99. AArch64.Vpart(1, 1, new Bits(A1));
  100. AArch64.Vpart(2, 0, new Bits(B0));
  101. AArch64.Vpart(2, 1, new Bits(B1));
  102. SimdFp.Add_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  103. Assert.Multiple(() =>
  104. {
  105. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  106. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  107. });
  108. }
  109. [Test, Pairwise, Description("ADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  110. public void Addhn_V_8H8B_4S4H_2D2S([ValueSource("_4H2S1D_")] [Random(1)] ulong A0,
  111. [ValueSource("_4H2S1D_")] [Random(1)] ulong A1,
  112. [ValueSource("_4H2S1D_")] [Random(1)] ulong B0,
  113. [ValueSource("_4H2S1D_")] [Random(1)] ulong B1,
  114. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  115. {
  116. uint Opcode = 0x0E224020; // ADDHN V0.8B, V1.8H, V2.8H
  117. Opcode |= ((size & 3) << 22);
  118. Bits Op = new Bits(Opcode);
  119. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  120. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  121. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  122. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  123. AArch64.Vpart(1, 0, new Bits(A0));
  124. AArch64.Vpart(1, 1, new Bits(A1));
  125. AArch64.Vpart(2, 0, new Bits(B0));
  126. AArch64.Vpart(2, 1, new Bits(B1));
  127. SimdFp.Addhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  128. Assert.Multiple(() =>
  129. {
  130. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  131. Assert.That(ThreadState.V0.X1, Is.Zero);
  132. });
  133. }
  134. [Test, Pairwise, Description("ADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  135. public void Addhn_V_8H16B_4S8H_2D4S([ValueSource("_4H2S1D_")] [Random(1)] ulong A0,
  136. [ValueSource("_4H2S1D_")] [Random(1)] ulong A1,
  137. [ValueSource("_4H2S1D_")] [Random(1)] ulong B0,
  138. [ValueSource("_4H2S1D_")] [Random(1)] ulong B1,
  139. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  140. {
  141. uint Opcode = 0x4E224020; // ADDHN2 V0.16B, V1.8H, V2.8H
  142. Opcode |= ((size & 3) << 22);
  143. Bits Op = new Bits(Opcode);
  144. ulong _X0 = TestContext.CurrentContext.Random.NextULong();
  145. AVec V0 = new AVec { X0 = _X0 };
  146. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  147. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  148. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  149. AArch64.Vpart(1, 0, new Bits(A0));
  150. AArch64.Vpart(1, 1, new Bits(A1));
  151. AArch64.Vpart(2, 0, new Bits(B0));
  152. AArch64.Vpart(2, 1, new Bits(B1));
  153. SimdFp.Addhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  154. Assert.Multiple(() =>
  155. {
  156. Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0));
  157. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  158. });
  159. }
  160. [Test, Description("ADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  161. public void Addp_V_8B_4H_2S([ValueSource("_8B4H2S_")] [Random(1)] ulong A,
  162. [ValueSource("_8B4H2S_")] [Random(1)] ulong B,
  163. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  164. {
  165. uint Opcode = 0x0E22BC20; // ADDP V0.8B, V1.8B, V2.8B
  166. Opcode |= ((size & 3) << 22);
  167. Bits Op = new Bits(Opcode);
  168. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  169. AVec V1 = new AVec { X0 = A };
  170. AVec V2 = new AVec { X0 = B };
  171. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  172. AArch64.V(1, new Bits(A));
  173. AArch64.V(2, new Bits(B));
  174. SimdFp.Addp_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  175. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  176. Assert.That(ThreadState.V0.X1, Is.Zero);
  177. }
  178. [Test, Pairwise, Description("ADDP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  179. public void Addp_V_16B_8H_4S_2D([ValueSource("_8B4H2S1D_")] [Random(1)] ulong A0,
  180. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong A1,
  181. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong B0,
  182. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong B1,
  183. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  184. {
  185. uint Opcode = 0x4E22BC20; // ADDP V0.16B, V1.16B, V2.16B
  186. Opcode |= ((size & 3) << 22);
  187. Bits Op = new Bits(Opcode);
  188. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  189. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  190. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  191. AArch64.Vpart(1, 0, new Bits(A0));
  192. AArch64.Vpart(1, 1, new Bits(A1));
  193. AArch64.Vpart(2, 0, new Bits(B0));
  194. AArch64.Vpart(2, 1, new Bits(B1));
  195. SimdFp.Addp_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  196. Assert.Multiple(() =>
  197. {
  198. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  199. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  200. });
  201. }
  202. [Test, Description("AND <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  203. public void And_V_8B([ValueSource("_8B_")] [Random(1)] ulong A,
  204. [ValueSource("_8B_")] [Random(1)] ulong B)
  205. {
  206. uint Opcode = 0x0E221C20; // AND V0.8B, V1.8B, V2.8B
  207. Bits Op = new Bits(Opcode);
  208. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  209. AVec V1 = new AVec { X0 = A };
  210. AVec V2 = new AVec { X0 = B };
  211. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  212. AArch64.V(1, new Bits(A));
  213. AArch64.V(2, new Bits(B));
  214. SimdFp.And_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  215. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  216. Assert.That(ThreadState.V0.X1, Is.Zero);
  217. }
  218. [Test, Pairwise, Description("AND <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  219. public void And_V_16B([ValueSource("_8B_")] [Random(1)] ulong A0,
  220. [ValueSource("_8B_")] [Random(1)] ulong A1,
  221. [ValueSource("_8B_")] [Random(1)] ulong B0,
  222. [ValueSource("_8B_")] [Random(1)] ulong B1)
  223. {
  224. uint Opcode = 0x4E221C20; // AND V0.16B, V1.16B, V2.16B
  225. Bits Op = new Bits(Opcode);
  226. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  227. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  228. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  229. AArch64.Vpart(1, 0, new Bits(A0));
  230. AArch64.Vpart(1, 1, new Bits(A1));
  231. AArch64.Vpart(2, 0, new Bits(B0));
  232. AArch64.Vpart(2, 1, new Bits(B1));
  233. SimdFp.And_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  234. Assert.Multiple(() =>
  235. {
  236. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  237. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  238. });
  239. }
  240. [Test, Description("BIC <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  241. public void Bic_V_8B([ValueSource("_8B_")] [Random(1)] ulong A,
  242. [ValueSource("_8B_")] [Random(1)] ulong B)
  243. {
  244. uint Opcode = 0x0E621C20; // BIC V0.8B, V1.8B, V2.8B
  245. Bits Op = new Bits(Opcode);
  246. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  247. AVec V1 = new AVec { X0 = A };
  248. AVec V2 = new AVec { X0 = B };
  249. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  250. AArch64.V(1, new Bits(A));
  251. AArch64.V(2, new Bits(B));
  252. SimdFp.Bic_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  253. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  254. Assert.That(ThreadState.V0.X1, Is.Zero);
  255. }
  256. [Test, Pairwise, Description("BIC <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  257. public void Bic_V_16B([ValueSource("_8B_")] [Random(1)] ulong A0,
  258. [ValueSource("_8B_")] [Random(1)] ulong A1,
  259. [ValueSource("_8B_")] [Random(1)] ulong B0,
  260. [ValueSource("_8B_")] [Random(1)] ulong B1)
  261. {
  262. uint Opcode = 0x4E621C20; // BIC V0.16B, V1.16B, V2.16B
  263. Bits Op = new Bits(Opcode);
  264. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  265. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  266. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  267. AArch64.Vpart(1, 0, new Bits(A0));
  268. AArch64.Vpart(1, 1, new Bits(A1));
  269. AArch64.Vpart(2, 0, new Bits(B0));
  270. AArch64.Vpart(2, 1, new Bits(B1));
  271. SimdFp.Bic_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  272. Assert.Multiple(() =>
  273. {
  274. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  275. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  276. });
  277. }
  278. [Test, Description("BIF <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  279. public void Bif_V_8B([ValueSource("_8B_")] [Random(1)] ulong _Z,
  280. [ValueSource("_8B_")] [Random(1)] ulong A,
  281. [ValueSource("_8B_")] [Random(1)] ulong B)
  282. {
  283. uint Opcode = 0x2EE21C20; // BIF V0.8B, V1.8B, V2.8B
  284. Bits Op = new Bits(Opcode);
  285. AVec V0 = new AVec { X0 = _Z, X1 = TestContext.CurrentContext.Random.NextULong() };
  286. AVec V1 = new AVec { X0 = A };
  287. AVec V2 = new AVec { X0 = B };
  288. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  289. AArch64.Vpart(0, 0, new Bits(_Z));
  290. AArch64.V(1, new Bits(A));
  291. AArch64.V(2, new Bits(B));
  292. SimdFp.Bif_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  293. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  294. Assert.That(ThreadState.V0.X1, Is.Zero);
  295. }
  296. [Test, Pairwise, Description("BIF <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  297. public void Bif_V_16B([ValueSource("_8B_")] [Random(1)] ulong _Z0,
  298. [ValueSource("_8B_")] [Random(1)] ulong _Z1,
  299. [ValueSource("_8B_")] [Random(1)] ulong A0,
  300. [ValueSource("_8B_")] [Random(1)] ulong A1,
  301. [ValueSource("_8B_")] [Random(1)] ulong B0,
  302. [ValueSource("_8B_")] [Random(1)] ulong B1)
  303. {
  304. uint Opcode = 0x6EE21C20; // BIF V0.16B, V1.16B, V2.16B
  305. Bits Op = new Bits(Opcode);
  306. AVec V0 = new AVec { X0 = _Z0, X1 = _Z1 };
  307. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  308. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  309. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  310. AArch64.Vpart(0, 0, new Bits(_Z0));
  311. AArch64.Vpart(0, 1, new Bits(_Z1));
  312. AArch64.Vpart(1, 0, new Bits(A0));
  313. AArch64.Vpart(1, 1, new Bits(A1));
  314. AArch64.Vpart(2, 0, new Bits(B0));
  315. AArch64.Vpart(2, 1, new Bits(B1));
  316. SimdFp.Bif_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  317. Assert.Multiple(() =>
  318. {
  319. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  320. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  321. });
  322. }
  323. [Test, Description("BIT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  324. public void Bit_V_8B([ValueSource("_8B_")] [Random(1)] ulong _Z,
  325. [ValueSource("_8B_")] [Random(1)] ulong A,
  326. [ValueSource("_8B_")] [Random(1)] ulong B)
  327. {
  328. uint Opcode = 0x2EA21C20; // BIT V0.8B, V1.8B, V2.8B
  329. Bits Op = new Bits(Opcode);
  330. AVec V0 = new AVec { X0 = _Z, X1 = TestContext.CurrentContext.Random.NextULong() };
  331. AVec V1 = new AVec { X0 = A };
  332. AVec V2 = new AVec { X0 = B };
  333. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  334. AArch64.Vpart(0, 0, new Bits(_Z));
  335. AArch64.V(1, new Bits(A));
  336. AArch64.V(2, new Bits(B));
  337. SimdFp.Bit_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  338. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  339. Assert.That(ThreadState.V0.X1, Is.Zero);
  340. }
  341. [Test, Pairwise, Description("BIT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  342. public void Bit_V_16B([ValueSource("_8B_")] [Random(1)] ulong _Z0,
  343. [ValueSource("_8B_")] [Random(1)] ulong _Z1,
  344. [ValueSource("_8B_")] [Random(1)] ulong A0,
  345. [ValueSource("_8B_")] [Random(1)] ulong A1,
  346. [ValueSource("_8B_")] [Random(1)] ulong B0,
  347. [ValueSource("_8B_")] [Random(1)] ulong B1)
  348. {
  349. uint Opcode = 0x6EA21C20; // BIT V0.16B, V1.16B, V2.16B
  350. Bits Op = new Bits(Opcode);
  351. AVec V0 = new AVec { X0 = _Z0, X1 = _Z1 };
  352. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  353. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  354. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  355. AArch64.Vpart(0, 0, new Bits(_Z0));
  356. AArch64.Vpart(0, 1, new Bits(_Z1));
  357. AArch64.Vpart(1, 0, new Bits(A0));
  358. AArch64.Vpart(1, 1, new Bits(A1));
  359. AArch64.Vpart(2, 0, new Bits(B0));
  360. AArch64.Vpart(2, 1, new Bits(B1));
  361. SimdFp.Bit_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  362. Assert.Multiple(() =>
  363. {
  364. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  365. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  366. });
  367. }
  368. [Test, Description("BSL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  369. public void Bsl_V_8B([ValueSource("_8B_")] [Random(1)] ulong _Z,
  370. [ValueSource("_8B_")] [Random(1)] ulong A,
  371. [ValueSource("_8B_")] [Random(1)] ulong B)
  372. {
  373. uint Opcode = 0x2E621C20; // BSL V0.8B, V1.8B, V2.8B
  374. Bits Op = new Bits(Opcode);
  375. AVec V0 = new AVec { X0 = _Z, X1 = TestContext.CurrentContext.Random.NextULong() };
  376. AVec V1 = new AVec { X0 = A };
  377. AVec V2 = new AVec { X0 = B };
  378. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  379. AArch64.Vpart(0, 0, new Bits(_Z));
  380. AArch64.V(1, new Bits(A));
  381. AArch64.V(2, new Bits(B));
  382. SimdFp.Bsl_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  383. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  384. Assert.That(ThreadState.V0.X1, Is.Zero);
  385. }
  386. [Test, Pairwise, Description("BSL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  387. public void Bsl_V_16B([ValueSource("_8B_")] [Random(1)] ulong _Z0,
  388. [ValueSource("_8B_")] [Random(1)] ulong _Z1,
  389. [ValueSource("_8B_")] [Random(1)] ulong A0,
  390. [ValueSource("_8B_")] [Random(1)] ulong A1,
  391. [ValueSource("_8B_")] [Random(1)] ulong B0,
  392. [ValueSource("_8B_")] [Random(1)] ulong B1)
  393. {
  394. uint Opcode = 0x6E621C20; // BSL V0.16B, V1.16B, V2.16B
  395. Bits Op = new Bits(Opcode);
  396. AVec V0 = new AVec { X0 = _Z0, X1 = _Z1 };
  397. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  398. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  399. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  400. AArch64.Vpart(0, 0, new Bits(_Z0));
  401. AArch64.Vpart(0, 1, new Bits(_Z1));
  402. AArch64.Vpart(1, 0, new Bits(A0));
  403. AArch64.Vpart(1, 1, new Bits(A1));
  404. AArch64.Vpart(2, 0, new Bits(B0));
  405. AArch64.Vpart(2, 1, new Bits(B1));
  406. SimdFp.Bsl_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  407. Assert.Multiple(() =>
  408. {
  409. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  410. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  411. });
  412. }
  413. [Test, Description("ORN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  414. public void Orn_V_8B([ValueSource("_8B_")] [Random(1)] ulong A,
  415. [ValueSource("_8B_")] [Random(1)] ulong B)
  416. {
  417. uint Opcode = 0x0EE21C20; // ORN V0.8B, V1.8B, V2.8B
  418. Bits Op = new Bits(Opcode);
  419. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  420. AVec V1 = new AVec { X0 = A };
  421. AVec V2 = new AVec { X0 = B };
  422. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  423. AArch64.V(1, new Bits(A));
  424. AArch64.V(2, new Bits(B));
  425. SimdFp.Orn_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  426. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  427. Assert.That(ThreadState.V0.X1, Is.Zero);
  428. }
  429. [Test, Pairwise, Description("ORN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  430. public void Orn_V_16B([ValueSource("_8B_")] [Random(1)] ulong A0,
  431. [ValueSource("_8B_")] [Random(1)] ulong A1,
  432. [ValueSource("_8B_")] [Random(1)] ulong B0,
  433. [ValueSource("_8B_")] [Random(1)] ulong B1)
  434. {
  435. uint Opcode = 0x4EE21C20; // ORN V0.16B, V1.16B, V2.16B
  436. Bits Op = new Bits(Opcode);
  437. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  438. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  439. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  440. AArch64.Vpart(1, 0, new Bits(A0));
  441. AArch64.Vpart(1, 1, new Bits(A1));
  442. AArch64.Vpart(2, 0, new Bits(B0));
  443. AArch64.Vpart(2, 1, new Bits(B1));
  444. SimdFp.Orn_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  445. Assert.Multiple(() =>
  446. {
  447. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  448. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  449. });
  450. }
  451. [Test, Description("ORR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  452. public void Orr_V_8B([ValueSource("_8B_")] [Random(1)] ulong A,
  453. [ValueSource("_8B_")] [Random(1)] ulong B)
  454. {
  455. uint Opcode = 0x0EA21C20; // ORR V0.8B, V1.8B, V2.8B
  456. Bits Op = new Bits(Opcode);
  457. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  458. AVec V1 = new AVec { X0 = A };
  459. AVec V2 = new AVec { X0 = B };
  460. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  461. AArch64.V(1, new Bits(A));
  462. AArch64.V(2, new Bits(B));
  463. SimdFp.Orr_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  464. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  465. Assert.That(ThreadState.V0.X1, Is.Zero);
  466. }
  467. [Test, Pairwise, Description("ORR <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  468. public void Orr_V_16B([ValueSource("_8B_")] [Random(1)] ulong A0,
  469. [ValueSource("_8B_")] [Random(1)] ulong A1,
  470. [ValueSource("_8B_")] [Random(1)] ulong B0,
  471. [ValueSource("_8B_")] [Random(1)] ulong B1)
  472. {
  473. uint Opcode = 0x4EA21C20; // ORR V0.16B, V1.16B, V2.16B
  474. Bits Op = new Bits(Opcode);
  475. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  476. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  477. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  478. AArch64.Vpart(1, 0, new Bits(A0));
  479. AArch64.Vpart(1, 1, new Bits(A1));
  480. AArch64.Vpart(2, 0, new Bits(B0));
  481. AArch64.Vpart(2, 1, new Bits(B1));
  482. SimdFp.Orr_V(Op[30], Op[20, 16], Op[9, 5], Op[4, 0]);
  483. Assert.Multiple(() =>
  484. {
  485. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  486. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  487. });
  488. }
  489. [Test, Pairwise, Description("RADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  490. public void Raddhn_V_8H8B_4S4H_2D2S([ValueSource("_4H2S1D_")] [Random(1)] ulong A0,
  491. [ValueSource("_4H2S1D_")] [Random(1)] ulong A1,
  492. [ValueSource("_4H2S1D_")] [Random(1)] ulong B0,
  493. [ValueSource("_4H2S1D_")] [Random(1)] ulong B1,
  494. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  495. {
  496. uint Opcode = 0x2E224020; // RADDHN V0.8B, V1.8H, V2.8H
  497. Opcode |= ((size & 3) << 22);
  498. Bits Op = new Bits(Opcode);
  499. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  500. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  501. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  502. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  503. AArch64.Vpart(1, 0, new Bits(A0));
  504. AArch64.Vpart(1, 1, new Bits(A1));
  505. AArch64.Vpart(2, 0, new Bits(B0));
  506. AArch64.Vpart(2, 1, new Bits(B1));
  507. SimdFp.Raddhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  508. Assert.Multiple(() =>
  509. {
  510. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  511. Assert.That(ThreadState.V0.X1, Is.Zero);
  512. });
  513. }
  514. [Test, Pairwise, Description("RADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  515. public void Raddhn_V_8H16B_4S8H_2D4S([ValueSource("_4H2S1D_")] [Random(1)] ulong A0,
  516. [ValueSource("_4H2S1D_")] [Random(1)] ulong A1,
  517. [ValueSource("_4H2S1D_")] [Random(1)] ulong B0,
  518. [ValueSource("_4H2S1D_")] [Random(1)] ulong B1,
  519. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  520. {
  521. uint Opcode = 0x6E224020; // RADDHN2 V0.16B, V1.8H, V2.8H
  522. Opcode |= ((size & 3) << 22);
  523. Bits Op = new Bits(Opcode);
  524. ulong _X0 = TestContext.CurrentContext.Random.NextULong();
  525. AVec V0 = new AVec { X0 = _X0 };
  526. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  527. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  528. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  529. AArch64.Vpart(1, 0, new Bits(A0));
  530. AArch64.Vpart(1, 1, new Bits(A1));
  531. AArch64.Vpart(2, 0, new Bits(B0));
  532. AArch64.Vpart(2, 1, new Bits(B1));
  533. SimdFp.Raddhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  534. Assert.Multiple(() =>
  535. {
  536. Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0));
  537. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  538. });
  539. }
  540. [Test, Pairwise, Description("RSUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  541. public void Rsubhn_V_8H8B_4S4H_2D2S([ValueSource("_4H2S1D_")] [Random(1)] ulong A0,
  542. [ValueSource("_4H2S1D_")] [Random(1)] ulong A1,
  543. [ValueSource("_4H2S1D_")] [Random(1)] ulong B0,
  544. [ValueSource("_4H2S1D_")] [Random(1)] ulong B1,
  545. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  546. {
  547. uint Opcode = 0x2E226020; // RSUBHN V0.8B, V1.8H, V2.8H
  548. Opcode |= ((size & 3) << 22);
  549. Bits Op = new Bits(Opcode);
  550. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  551. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  552. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  553. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  554. AArch64.Vpart(1, 0, new Bits(A0));
  555. AArch64.Vpart(1, 1, new Bits(A1));
  556. AArch64.Vpart(2, 0, new Bits(B0));
  557. AArch64.Vpart(2, 1, new Bits(B1));
  558. SimdFp.Rsubhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  559. Assert.Multiple(() =>
  560. {
  561. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  562. Assert.That(ThreadState.V0.X1, Is.Zero);
  563. });
  564. }
  565. [Test, Pairwise, Description("RSUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  566. public void Rsubhn_V_8H16B_4S8H_2D4S([ValueSource("_4H2S1D_")] [Random(1)] ulong A0,
  567. [ValueSource("_4H2S1D_")] [Random(1)] ulong A1,
  568. [ValueSource("_4H2S1D_")] [Random(1)] ulong B0,
  569. [ValueSource("_4H2S1D_")] [Random(1)] ulong B1,
  570. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  571. {
  572. uint Opcode = 0x6E226020; // RSUBHN2 V0.16B, V1.8H, V2.8H
  573. Opcode |= ((size & 3) << 22);
  574. Bits Op = new Bits(Opcode);
  575. ulong _X0 = TestContext.CurrentContext.Random.NextULong();
  576. AVec V0 = new AVec { X0 = _X0 };
  577. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  578. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  579. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  580. AArch64.Vpart(1, 0, new Bits(A0));
  581. AArch64.Vpart(1, 1, new Bits(A1));
  582. AArch64.Vpart(2, 0, new Bits(B0));
  583. AArch64.Vpart(2, 1, new Bits(B1));
  584. SimdFp.Rsubhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  585. Assert.Multiple(() =>
  586. {
  587. Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0));
  588. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  589. });
  590. }
  591. [Test, Description("SUB <V><d>, <V><n>, <V><m>")]
  592. public void Sub_S_D([ValueSource("_1D_")] [Random(1)] ulong A,
  593. [ValueSource("_1D_")] [Random(1)] ulong B)
  594. {
  595. uint Opcode = 0x7EE28420; // SUB D0, D1, D2
  596. Bits Op = new Bits(Opcode);
  597. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  598. AVec V1 = new AVec { X0 = A };
  599. AVec V2 = new AVec { X0 = B };
  600. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  601. AArch64.V(1, new Bits(A));
  602. AArch64.V(2, new Bits(B));
  603. SimdFp.Sub_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  604. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  605. Assert.That(ThreadState.V0.X1, Is.Zero);
  606. }
  607. [Test, Description("SUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  608. public void Sub_V_8B_4H_2S([ValueSource("_8B4H2S_")] [Random(1)] ulong A,
  609. [ValueSource("_8B4H2S_")] [Random(1)] ulong B,
  610. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  611. {
  612. uint Opcode = 0x2E228420; // SUB V0.8B, V1.8B, V2.8B
  613. Opcode |= ((size & 3) << 22);
  614. Bits Op = new Bits(Opcode);
  615. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  616. AVec V1 = new AVec { X0 = A };
  617. AVec V2 = new AVec { X0 = B };
  618. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  619. AArch64.V(1, new Bits(A));
  620. AArch64.V(2, new Bits(B));
  621. SimdFp.Sub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  622. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  623. Assert.That(ThreadState.V0.X1, Is.Zero);
  624. }
  625. [Test, Pairwise, Description("SUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  626. public void Sub_V_16B_8H_4S_2D([ValueSource("_8B4H2S1D_")] [Random(1)] ulong A0,
  627. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong A1,
  628. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong B0,
  629. [ValueSource("_8B4H2S1D_")] [Random(1)] ulong B1,
  630. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  631. {
  632. uint Opcode = 0x6E228420; // SUB V0.16B, V1.16B, V2.16B
  633. Opcode |= ((size & 3) << 22);
  634. Bits Op = new Bits(Opcode);
  635. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  636. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  637. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  638. AArch64.Vpart(1, 0, new Bits(A0));
  639. AArch64.Vpart(1, 1, new Bits(A1));
  640. AArch64.Vpart(2, 0, new Bits(B0));
  641. AArch64.Vpart(2, 1, new Bits(B1));
  642. SimdFp.Sub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  643. Assert.Multiple(() =>
  644. {
  645. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  646. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  647. });
  648. }
  649. [Test, Pairwise, Description("SUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  650. public void Subhn_V_8H8B_4S4H_2D2S([ValueSource("_4H2S1D_")] [Random(1)] ulong A0,
  651. [ValueSource("_4H2S1D_")] [Random(1)] ulong A1,
  652. [ValueSource("_4H2S1D_")] [Random(1)] ulong B0,
  653. [ValueSource("_4H2S1D_")] [Random(1)] ulong B1,
  654. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  655. {
  656. uint Opcode = 0x0E226020; // SUBHN V0.8B, V1.8H, V2.8H
  657. Opcode |= ((size & 3) << 22);
  658. Bits Op = new Bits(Opcode);
  659. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  660. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  661. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  662. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  663. AArch64.Vpart(1, 0, new Bits(A0));
  664. AArch64.Vpart(1, 1, new Bits(A1));
  665. AArch64.Vpart(2, 0, new Bits(B0));
  666. AArch64.Vpart(2, 1, new Bits(B1));
  667. SimdFp.Subhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  668. Assert.Multiple(() =>
  669. {
  670. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  671. Assert.That(ThreadState.V0.X1, Is.Zero);
  672. });
  673. }
  674. [Test, Pairwise, Description("SUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  675. public void Subhn_V_8H16B_4S8H_2D4S([ValueSource("_4H2S1D_")] [Random(1)] ulong A0,
  676. [ValueSource("_4H2S1D_")] [Random(1)] ulong A1,
  677. [ValueSource("_4H2S1D_")] [Random(1)] ulong B0,
  678. [ValueSource("_4H2S1D_")] [Random(1)] ulong B1,
  679. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  680. {
  681. uint Opcode = 0x4E226020; // SUBHN2 V0.16B, V1.8H, V2.8H
  682. Opcode |= ((size & 3) << 22);
  683. Bits Op = new Bits(Opcode);
  684. ulong _X0 = TestContext.CurrentContext.Random.NextULong();
  685. AVec V0 = new AVec { X0 = _X0 };
  686. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  687. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  688. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  689. AArch64.Vpart(1, 0, new Bits(A0));
  690. AArch64.Vpart(1, 1, new Bits(A1));
  691. AArch64.Vpart(2, 0, new Bits(B0));
  692. AArch64.Vpart(2, 1, new Bits(B1));
  693. SimdFp.Subhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  694. Assert.Multiple(() =>
  695. {
  696. Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0));
  697. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  698. });
  699. }
  700. #endif
  701. }
  702. }