CpuTestSimdReg.cs 39 KB

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