CpuTestSimdReg.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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[] _D_()
  19. {
  20. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  21. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  22. }
  23. private static ulong[] _8B4H2S_()
  24. {
  25. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  26. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  27. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  28. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  29. }
  30. private static ulong[] _16B8H4S2D_()
  31. {
  32. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  33. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  34. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  35. 0x8000000080000000ul, 0x7FFFFFFFFFFFFFFFul,
  36. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  37. }
  38. private static ulong[] _8H4S2D_()
  39. {
  40. return new ulong[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
  41. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  42. 0x8000000080000000ul, 0x7FFFFFFFFFFFFFFFul,
  43. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  44. }
  45. #endregion
  46. [Test, Description("ADD <V><d>, <V><n>, <V><m>")]
  47. public void Add_S_D([ValueSource("_D_")] [Random(1)] ulong A,
  48. [ValueSource("_D_")] [Random(1)] ulong B)
  49. {
  50. uint Opcode = 0x5EE28420; // ADD D0, D1, D2
  51. Bits Op = new Bits(Opcode);
  52. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  53. AVec V1 = new AVec { X0 = A };
  54. AVec V2 = new AVec { X0 = B };
  55. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  56. AArch64.V(1, new Bits(A));
  57. AArch64.V(2, new Bits(B));
  58. SimdFp.Add_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  59. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  60. Assert.That(ThreadState.V0.X1, Is.Zero);
  61. }
  62. [Test, Description("ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  63. public void Add_V_8B_4H_2S([ValueSource("_8B4H2S_")] [Random(1)] ulong A,
  64. [ValueSource("_8B4H2S_")] [Random(1)] ulong B,
  65. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  66. {
  67. uint Opcode = 0x0E228420; // ADD V0.8B, V1.8B, V2.8B
  68. Opcode |= ((size & 3) << 22);
  69. Bits Op = new Bits(Opcode);
  70. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  71. AVec V1 = new AVec { X0 = A };
  72. AVec V2 = new AVec { X0 = B };
  73. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  74. AArch64.V(1, new Bits(A));
  75. AArch64.V(2, new Bits(B));
  76. SimdFp.Add_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  77. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  78. Assert.That(ThreadState.V0.X1, Is.Zero);
  79. }
  80. [Test, Pairwise, Description("ADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  81. public void Add_V_16B_8H_4S_2D([ValueSource("_16B8H4S2D_")] [Random(1)] ulong A0,
  82. [ValueSource("_16B8H4S2D_")] [Random(1)] ulong A1,
  83. [ValueSource("_16B8H4S2D_")] [Random(1)] ulong B0,
  84. [ValueSource("_16B8H4S2D_")] [Random(1)] ulong B1,
  85. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  86. {
  87. uint Opcode = 0x4E228420; // ADD V0.16B, V1.16B, V2.16B
  88. Opcode |= ((size & 3) << 22);
  89. Bits Op = new Bits(Opcode);
  90. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  91. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  92. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  93. AArch64.Vpart(1, 0, new Bits(A0));
  94. AArch64.Vpart(1, 1, new Bits(A1));
  95. AArch64.Vpart(2, 0, new Bits(B0));
  96. AArch64.Vpart(2, 1, new Bits(B1));
  97. SimdFp.Add_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  98. Assert.Multiple(() =>
  99. {
  100. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  101. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  102. });
  103. }
  104. [Test, Pairwise, Description("ADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  105. public void Addhn_V_8H8B_4S4H_2D2S([ValueSource("_8H4S2D_")] [Random(1)] ulong A0,
  106. [ValueSource("_8H4S2D_")] [Random(1)] ulong A1,
  107. [ValueSource("_8H4S2D_")] [Random(1)] ulong B0,
  108. [ValueSource("_8H4S2D_")] [Random(1)] ulong B1,
  109. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  110. {
  111. uint Opcode = 0x0E224020; // ADDHN V0.8B, V1.8H, V2.8H
  112. Opcode |= ((size & 3) << 22);
  113. Bits Op = new Bits(Opcode);
  114. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  115. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  116. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  117. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  118. AArch64.Vpart(1, 0, new Bits(A0));
  119. AArch64.Vpart(1, 1, new Bits(A1));
  120. AArch64.Vpart(2, 0, new Bits(B0));
  121. AArch64.Vpart(2, 1, new Bits(B1));
  122. SimdFp.Addhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  123. Assert.Multiple(() =>
  124. {
  125. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  126. Assert.That(ThreadState.V0.X1, Is.Zero);
  127. });
  128. }
  129. [Test, Pairwise, Description("ADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  130. public void Addhn_V_8H16B_4S8H_2D4S([ValueSource("_8H4S2D_")] [Random(1)] ulong A0,
  131. [ValueSource("_8H4S2D_")] [Random(1)] ulong A1,
  132. [ValueSource("_8H4S2D_")] [Random(1)] ulong B0,
  133. [ValueSource("_8H4S2D_")] [Random(1)] ulong B1,
  134. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  135. {
  136. uint Opcode = 0x4E224020; // ADDHN2 V0.16B, V1.8H, V2.8H
  137. Opcode |= ((size & 3) << 22);
  138. Bits Op = new Bits(Opcode);
  139. ulong _X0 = TestContext.CurrentContext.Random.NextULong();
  140. AVec V0 = new AVec { X0 = _X0 };
  141. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  142. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  143. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  144. AArch64.Vpart(1, 0, new Bits(A0));
  145. AArch64.Vpart(1, 1, new Bits(A1));
  146. AArch64.Vpart(2, 0, new Bits(B0));
  147. AArch64.Vpart(2, 1, new Bits(B1));
  148. SimdFp.Addhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  149. Assert.Multiple(() =>
  150. {
  151. Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0));
  152. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  153. });
  154. }
  155. [Test, Pairwise, Description("RADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  156. public void Raddhn_V_8H8B_4S4H_2D2S([ValueSource("_8H4S2D_")] [Random(1)] ulong A0,
  157. [ValueSource("_8H4S2D_")] [Random(1)] ulong A1,
  158. [ValueSource("_8H4S2D_")] [Random(1)] ulong B0,
  159. [ValueSource("_8H4S2D_")] [Random(1)] ulong B1,
  160. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  161. {
  162. uint Opcode = 0x2E224020; // RADDHN V0.8B, V1.8H, V2.8H
  163. Opcode |= ((size & 3) << 22);
  164. Bits Op = new Bits(Opcode);
  165. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  166. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  167. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  168. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  169. AArch64.Vpart(1, 0, new Bits(A0));
  170. AArch64.Vpart(1, 1, new Bits(A1));
  171. AArch64.Vpart(2, 0, new Bits(B0));
  172. AArch64.Vpart(2, 1, new Bits(B1));
  173. SimdFp.Raddhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  174. Assert.Multiple(() =>
  175. {
  176. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  177. Assert.That(ThreadState.V0.X1, Is.Zero);
  178. });
  179. }
  180. [Test, Pairwise, Description("RADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  181. public void Raddhn_V_8H16B_4S8H_2D4S([ValueSource("_8H4S2D_")] [Random(1)] ulong A0,
  182. [ValueSource("_8H4S2D_")] [Random(1)] ulong A1,
  183. [ValueSource("_8H4S2D_")] [Random(1)] ulong B0,
  184. [ValueSource("_8H4S2D_")] [Random(1)] ulong B1,
  185. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  186. {
  187. uint Opcode = 0x6E224020; // RADDHN2 V0.16B, V1.8H, V2.8H
  188. Opcode |= ((size & 3) << 22);
  189. Bits Op = new Bits(Opcode);
  190. ulong _X0 = TestContext.CurrentContext.Random.NextULong();
  191. AVec V0 = new AVec { X0 = _X0 };
  192. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  193. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  194. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  195. AArch64.Vpart(1, 0, new Bits(A0));
  196. AArch64.Vpart(1, 1, new Bits(A1));
  197. AArch64.Vpart(2, 0, new Bits(B0));
  198. AArch64.Vpart(2, 1, new Bits(B1));
  199. SimdFp.Raddhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  200. Assert.Multiple(() =>
  201. {
  202. Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0));
  203. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  204. });
  205. }
  206. [Test, Pairwise, Description("RSUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  207. public void Rsubhn_V_8H8B_4S4H_2D2S([ValueSource("_8H4S2D_")] [Random(1)] ulong A0,
  208. [ValueSource("_8H4S2D_")] [Random(1)] ulong A1,
  209. [ValueSource("_8H4S2D_")] [Random(1)] ulong B0,
  210. [ValueSource("_8H4S2D_")] [Random(1)] ulong B1,
  211. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  212. {
  213. uint Opcode = 0x2E226020; // RSUBHN V0.8B, V1.8H, V2.8H
  214. Opcode |= ((size & 3) << 22);
  215. Bits Op = new Bits(Opcode);
  216. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  217. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  218. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  219. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  220. AArch64.Vpart(1, 0, new Bits(A0));
  221. AArch64.Vpart(1, 1, new Bits(A1));
  222. AArch64.Vpart(2, 0, new Bits(B0));
  223. AArch64.Vpart(2, 1, new Bits(B1));
  224. SimdFp.Rsubhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  225. Assert.Multiple(() =>
  226. {
  227. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  228. Assert.That(ThreadState.V0.X1, Is.Zero);
  229. });
  230. }
  231. [Test, Pairwise, Description("RSUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  232. public void Rsubhn_V_8H16B_4S8H_2D4S([ValueSource("_8H4S2D_")] [Random(1)] ulong A0,
  233. [ValueSource("_8H4S2D_")] [Random(1)] ulong A1,
  234. [ValueSource("_8H4S2D_")] [Random(1)] ulong B0,
  235. [ValueSource("_8H4S2D_")] [Random(1)] ulong B1,
  236. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  237. {
  238. uint Opcode = 0x6E226020; // RSUBHN2 V0.16B, V1.8H, V2.8H
  239. Opcode |= ((size & 3) << 22);
  240. Bits Op = new Bits(Opcode);
  241. ulong _X0 = TestContext.CurrentContext.Random.NextULong();
  242. AVec V0 = new AVec { X0 = _X0 };
  243. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  244. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  245. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  246. AArch64.Vpart(1, 0, new Bits(A0));
  247. AArch64.Vpart(1, 1, new Bits(A1));
  248. AArch64.Vpart(2, 0, new Bits(B0));
  249. AArch64.Vpart(2, 1, new Bits(B1));
  250. SimdFp.Rsubhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  251. Assert.Multiple(() =>
  252. {
  253. Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0));
  254. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  255. });
  256. }
  257. [Test, Description("SUB <V><d>, <V><n>, <V><m>")]
  258. public void Sub_S_D([ValueSource("_D_")] [Random(1)] ulong A,
  259. [ValueSource("_D_")] [Random(1)] ulong B)
  260. {
  261. uint Opcode = 0x7EE28420; // SUB D0, D1, D2
  262. Bits Op = new Bits(Opcode);
  263. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  264. AVec V1 = new AVec { X0 = A };
  265. AVec V2 = new AVec { X0 = B };
  266. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  267. AArch64.V(1, new Bits(A));
  268. AArch64.V(2, new Bits(B));
  269. SimdFp.Sub_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  270. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  271. Assert.That(ThreadState.V0.X1, Is.Zero);
  272. }
  273. [Test, Description("SUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  274. public void Sub_V_8B_4H_2S([ValueSource("_8B4H2S_")] [Random(1)] ulong A,
  275. [ValueSource("_8B4H2S_")] [Random(1)] ulong B,
  276. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  277. {
  278. uint Opcode = 0x2E228420; // SUB V0.8B, V1.8B, V2.8B
  279. Opcode |= ((size & 3) << 22);
  280. Bits Op = new Bits(Opcode);
  281. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  282. AVec V1 = new AVec { X0 = A };
  283. AVec V2 = new AVec { X0 = B };
  284. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  285. AArch64.V(1, new Bits(A));
  286. AArch64.V(2, new Bits(B));
  287. SimdFp.Sub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  288. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  289. Assert.That(ThreadState.V0.X1, Is.Zero);
  290. }
  291. [Test, Pairwise, Description("SUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>")]
  292. public void Sub_V_16B_8H_4S_2D([ValueSource("_16B8H4S2D_")] [Random(1)] ulong A0,
  293. [ValueSource("_16B8H4S2D_")] [Random(1)] ulong A1,
  294. [ValueSource("_16B8H4S2D_")] [Random(1)] ulong B0,
  295. [ValueSource("_16B8H4S2D_")] [Random(1)] ulong B1,
  296. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  297. {
  298. uint Opcode = 0x6E228420; // SUB V0.16B, V1.16B, V2.16B
  299. Opcode |= ((size & 3) << 22);
  300. Bits Op = new Bits(Opcode);
  301. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  302. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  303. AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);
  304. AArch64.Vpart(1, 0, new Bits(A0));
  305. AArch64.Vpart(1, 1, new Bits(A1));
  306. AArch64.Vpart(2, 0, new Bits(B0));
  307. AArch64.Vpart(2, 1, new Bits(B1));
  308. SimdFp.Sub_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  309. Assert.Multiple(() =>
  310. {
  311. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  312. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  313. });
  314. }
  315. [Test, Pairwise, Description("SUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  316. public void Subhn_V_8H8B_4S4H_2D2S([ValueSource("_8H4S2D_")] [Random(1)] ulong A0,
  317. [ValueSource("_8H4S2D_")] [Random(1)] ulong A1,
  318. [ValueSource("_8H4S2D_")] [Random(1)] ulong B0,
  319. [ValueSource("_8H4S2D_")] [Random(1)] ulong B1,
  320. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  321. {
  322. uint Opcode = 0x0E226020; // SUBHN V0.8B, V1.8H, V2.8H
  323. Opcode |= ((size & 3) << 22);
  324. Bits Op = new Bits(Opcode);
  325. AVec V0 = new AVec { X1 = TestContext.CurrentContext.Random.NextULong() };
  326. AVec V1 = new AVec { X0 = A0, X1 = A1 };
  327. AVec V2 = new AVec { X0 = B0, X1 = B1 };
  328. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);
  329. AArch64.Vpart(1, 0, new Bits(A0));
  330. AArch64.Vpart(1, 1, new Bits(A1));
  331. AArch64.Vpart(2, 0, new Bits(B0));
  332. AArch64.Vpart(2, 1, new Bits(B1));
  333. SimdFp.Subhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  334. Assert.Multiple(() =>
  335. {
  336. Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
  337. Assert.That(ThreadState.V0.X1, Is.Zero);
  338. });
  339. }
  340. [Test, Pairwise, Description("SUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>")]
  341. public void Subhn_V_8H16B_4S8H_2D4S([ValueSource("_8H4S2D_")] [Random(1)] ulong A0,
  342. [ValueSource("_8H4S2D_")] [Random(1)] ulong A1,
  343. [ValueSource("_8H4S2D_")] [Random(1)] ulong B0,
  344. [ValueSource("_8H4S2D_")] [Random(1)] ulong B1,
  345. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  346. {
  347. uint Opcode = 0x4E226020; // SUBHN2 V0.16B, V1.8H, V2.8H
  348. Opcode |= ((size & 3) << 22);
  349. Bits Op = new Bits(Opcode);
  350. ulong _X0 = TestContext.CurrentContext.Random.NextULong();
  351. AVec V0 = new AVec { X0 = _X0 };
  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(1, 0, new Bits(A0));
  356. AArch64.Vpart(1, 1, new Bits(A1));
  357. AArch64.Vpart(2, 0, new Bits(B0));
  358. AArch64.Vpart(2, 1, new Bits(B1));
  359. SimdFp.Subhn_V(Op[30], Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);
  360. Assert.Multiple(() =>
  361. {
  362. Assert.That(ThreadState.V0.X0, Is.EqualTo(_X0));
  363. Assert.That(ThreadState.V0.X1, Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  364. });
  365. }
  366. #endif
  367. }
  368. }