CpuTestSimd.cs 118 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448
  1. #define Simd
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. using System.Runtime.Intrinsics;
  5. namespace Ryujinx.Tests.Cpu
  6. {
  7. using Tester;
  8. using Tester.Types;
  9. [Category("Simd")/*, Ignore("Tested: second half of 2018.")*/]
  10. public sealed class CpuTestSimd : CpuTest
  11. {
  12. #if Simd
  13. [SetUp]
  14. public void SetupTester()
  15. {
  16. AArch64.TakeReset(false);
  17. }
  18. #region "ValueSource"
  19. private static ulong[] _1B1H1S1D_()
  20. {
  21. return new ulong[] { 0x0000000000000000ul, 0x000000000000007Ful,
  22. 0x0000000000000080ul, 0x00000000000000FFul,
  23. 0x0000000000007FFFul, 0x0000000000008000ul,
  24. 0x000000000000FFFFul, 0x000000007FFFFFFFul,
  25. 0x0000000080000000ul, 0x00000000FFFFFFFFul,
  26. 0x7FFFFFFFFFFFFFFFul, 0x8000000000000000ul,
  27. 0xFFFFFFFFFFFFFFFFul };
  28. }
  29. private static ulong[] _1D_()
  30. {
  31. return new ulong[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  32. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  33. }
  34. private static ulong[] _1H1S1D_()
  35. {
  36. return new ulong[] { 0x0000000000000000ul, 0x0000000000007FFFul,
  37. 0x0000000000008000ul, 0x000000000000FFFFul,
  38. 0x000000007FFFFFFFul, 0x0000000080000000ul,
  39. 0x00000000FFFFFFFFul, 0x7FFFFFFFFFFFFFFFul,
  40. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  41. }
  42. private static ulong[] _4H2S1D_()
  43. {
  44. return new ulong[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
  45. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  46. 0x8000000080000000ul, 0x7FFFFFFFFFFFFFFFul,
  47. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  48. }
  49. private static ulong[] _8B_()
  50. {
  51. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  52. 0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
  53. }
  54. private static ulong[] _8B4H_()
  55. {
  56. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  57. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  58. 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
  59. }
  60. private static ulong[] _8B4H2S_()
  61. {
  62. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  63. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  64. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  65. 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
  66. }
  67. private static ulong[] _8B4H2S1D_()
  68. {
  69. return new ulong[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
  70. 0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
  71. 0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
  72. 0x8000000080000000ul, 0x7FFFFFFFFFFFFFFFul,
  73. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
  74. }
  75. private static ulong[] _1S_F_()
  76. {
  77. return new ulong[]
  78. {
  79. 0x00000000FFFFFFFFul, // -QNaN (all ones payload)
  80. 0x00000000FFBFFFFFul, // -SNaN (all ones payload)
  81. 0x00000000FF800000ul, // -INF
  82. 0x00000000FF7FFFFFul, // -Max Normal, float.MinValue
  83. 0x0000000080800000ul, // -Min Normal
  84. 0x00000000807FFFFFul, // -Max SubNormal
  85. 0x0000000080000001ul, // -Min SubNormal
  86. 0x0000000080000000ul, // -0
  87. 0x0000000000000000ul, // +0
  88. 0x0000000000000001ul, // +Min SubNormal
  89. 0x00000000007FFFFFul, // +Max SubNormal
  90. 0x0000000000800000ul, // +Min Normal
  91. 0x000000007F7FFFFFul, // +Max Normal, float.MaxValue
  92. 0x000000007F800000ul, // +INF
  93. 0x000000007FBFFFFFul, // +SNaN (all ones payload)
  94. 0x000000007FFFFFFFul // +QNaN (all ones payload)
  95. };
  96. }
  97. private static ulong[] _2S_F_()
  98. {
  99. return new ulong[]
  100. {
  101. 0xFFFFFFFFFFFFFFFFul, // -QNaN (all ones payload)
  102. 0xFFBFFFFFFFBFFFFFul, // -SNaN (all ones payload)
  103. 0xFF800000FF800000ul, // -INF
  104. 0xFF7FFFFFFF7FFFFFul, // -Max Normal, float.MinValue
  105. 0x8080000080800000ul, // -Min Normal
  106. 0x807FFFFF807FFFFFul, // -Max SubNormal
  107. 0x8000000180000001ul, // -Min SubNormal
  108. 0x8000000080000000ul, // -0
  109. 0x0000000000000000ul, // +0
  110. 0x0000000100000001ul, // +Min SubNormal
  111. 0x007FFFFF007FFFFFul, // +Max SubNormal
  112. 0x0080000000800000ul, // +Min Normal
  113. 0x7F7FFFFF7F7FFFFFul, // +Max Normal, float.MaxValue
  114. 0x7F8000007F800000ul, // +INF
  115. 0x7FBFFFFF7FBFFFFFul, // +SNaN (all ones payload)
  116. 0x7FFFFFFF7FFFFFFFul // +QNaN (all ones payload)
  117. };
  118. }
  119. private static ulong[] _1D_F_()
  120. {
  121. return new ulong[]
  122. {
  123. 0xFFFFFFFFFFFFFFFFul, // -QNaN (all ones payload)
  124. 0xFFF7FFFFFFFFFFFFul, // -SNaN (all ones payload)
  125. 0xFFF0000000000000ul, // -INF
  126. 0xFFEFFFFFFFFFFFFFul, // -Max Normal, double.MinValue
  127. 0x8010000000000000ul, // -Min Normal
  128. 0x800FFFFFFFFFFFFFul, // -Max SubNormal
  129. 0x8000000000000001ul, // -Min SubNormal
  130. 0x8000000000000000ul, // -0
  131. 0x0000000000000000ul, // +0
  132. 0x0000000000000001ul, // +Min SubNormal
  133. 0x000FFFFFFFFFFFFFul, // +Max SubNormal
  134. 0x0010000000000000ul, // +Min Normal
  135. 0x7FEFFFFFFFFFFFFFul, // +Max Normal, double.MaxValue
  136. 0x7FF0000000000000ul, // +INF
  137. 0x7FF7FFFFFFFFFFFFul, // +SNaN (all ones payload)
  138. 0x7FFFFFFFFFFFFFFFul // +QNaN (all ones payload)
  139. };
  140. }
  141. #endregion
  142. private const int RndCnt = 4;
  143. [Test, Pairwise, Description("ABS <V><d>, <V><n>")]
  144. public void Abs_S_D([Values(0u)] uint Rd,
  145. [Values(1u, 0u)] uint Rn,
  146. [ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
  147. [ValueSource("_1D_")] [Random(RndCnt)] ulong A)
  148. {
  149. uint Opcode = 0x5EE0B800; // ABS D0, D0
  150. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  151. Bits Op = new Bits(Opcode);
  152. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  153. Vector128<float> V1 = MakeVectorE0(A);
  154. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  155. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  156. AArch64.V(1, new Bits(A));
  157. SimdFp.Abs_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  158. Assert.Multiple(() =>
  159. {
  160. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  161. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  162. });
  163. CompareAgainstUnicorn();
  164. }
  165. [Test, Pairwise, Description("ABS <Vd>.<T>, <Vn>.<T>")]
  166. public void Abs_V_8B_4H_2S([Values(0u)] uint Rd,
  167. [Values(1u, 0u)] uint Rn,
  168. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  169. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  170. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  171. {
  172. uint Opcode = 0x0E20B800; // ABS V0.8B, V0.8B
  173. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  174. Opcode |= ((size & 3) << 22);
  175. Bits Op = new Bits(Opcode);
  176. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  177. Vector128<float> V1 = MakeVectorE0(A);
  178. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  179. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  180. AArch64.V(1, new Bits(A));
  181. SimdFp.Abs_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  182. Assert.Multiple(() =>
  183. {
  184. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  185. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  186. });
  187. CompareAgainstUnicorn();
  188. }
  189. [Test, Pairwise, Description("ABS <Vd>.<T>, <Vn>.<T>")]
  190. public void Abs_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  191. [Values(1u, 0u)] uint Rn,
  192. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  193. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  194. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  195. {
  196. uint Opcode = 0x4E20B800; // ABS V0.16B, V0.16B
  197. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  198. Opcode |= ((size & 3) << 22);
  199. Bits Op = new Bits(Opcode);
  200. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  201. Vector128<float> V1 = MakeVectorE0E1(A, A);
  202. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  203. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  204. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  205. SimdFp.Abs_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  206. Assert.Multiple(() =>
  207. {
  208. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  209. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  210. });
  211. CompareAgainstUnicorn();
  212. }
  213. [Test, Pairwise, Description("ADDP <V><d>, <Vn>.<T>")]
  214. public void Addp_S_2DD([Values(0u)] uint Rd,
  215. [Values(1u, 0u)] uint Rn,
  216. [ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
  217. [ValueSource("_1D_")] [Random(RndCnt)] ulong A)
  218. {
  219. uint Opcode = 0x5EF1B800; // ADDP D0, V0.2D
  220. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  221. Bits Op = new Bits(Opcode);
  222. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  223. Vector128<float> V1 = MakeVectorE0E1(A, A);
  224. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  225. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  226. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  227. SimdFp.Addp_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  228. Assert.Multiple(() =>
  229. {
  230. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  231. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  232. });
  233. CompareAgainstUnicorn();
  234. }
  235. [Test, Pairwise, Description("ADDV <V><d>, <Vn>.<T>")]
  236. public void Addv_V_8BB_4HH([Values(0u)] uint Rd,
  237. [Values(1u, 0u)] uint Rn,
  238. [ValueSource("_8B4H_")] [Random(RndCnt)] ulong Z,
  239. [ValueSource("_8B4H_")] [Random(RndCnt)] ulong A,
  240. [Values(0b00u, 0b01u)] uint size) // <8BB, 4HH>
  241. {
  242. uint Opcode = 0x0E31B800; // ADDV B0, V0.8B
  243. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  244. Opcode |= ((size & 3) << 22);
  245. Bits Op = new Bits(Opcode);
  246. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  247. Vector128<float> V1 = MakeVectorE0(A);
  248. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  249. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  250. AArch64.V(1, new Bits(A));
  251. SimdFp.Addv_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  252. Assert.Multiple(() =>
  253. {
  254. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  255. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  256. });
  257. CompareAgainstUnicorn();
  258. }
  259. [Test, Pairwise, Description("ADDV <V><d>, <Vn>.<T>")]
  260. public void Addv_V_16BB_8HH_4SS([Values(0u)] uint Rd,
  261. [Values(1u, 0u)] uint Rn,
  262. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  263. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  264. [Values(0b00u, 0b01u, 0b10u)] uint size) // <16BB, 8HH, 4SS>
  265. {
  266. uint Opcode = 0x4E31B800; // ADDV B0, V0.16B
  267. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  268. Opcode |= ((size & 3) << 22);
  269. Bits Op = new Bits(Opcode);
  270. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  271. Vector128<float> V1 = MakeVectorE0E1(A, A);
  272. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  273. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  274. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  275. SimdFp.Addv_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  276. Assert.Multiple(() =>
  277. {
  278. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  279. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  280. });
  281. CompareAgainstUnicorn();
  282. }
  283. [Test, Pairwise, Description("CLS <Vd>.<T>, <Vn>.<T>")]
  284. public void Cls_V_8B_4H_2S([Values(0u)] uint Rd,
  285. [Values(1u, 0u)] uint Rn,
  286. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  287. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  288. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  289. {
  290. uint Opcode = 0x0E204800; // CLS V0.8B, V0.8B
  291. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  292. Opcode |= ((size & 3) << 22);
  293. Bits Op = new Bits(Opcode);
  294. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  295. Vector128<float> V1 = MakeVectorE0(A);
  296. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  297. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  298. AArch64.V(1, new Bits(A));
  299. SimdFp.Cls_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  300. Assert.Multiple(() =>
  301. {
  302. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  303. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  304. });
  305. CompareAgainstUnicorn();
  306. }
  307. [Test, Pairwise, Description("CLS <Vd>.<T>, <Vn>.<T>")]
  308. public void Cls_V_16B_8H_4S([Values(0u)] uint Rd,
  309. [Values(1u, 0u)] uint Rn,
  310. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  311. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  312. [Values(0b00u, 0b01u, 0b10u)] uint size) // <16B, 8H, 4S>
  313. {
  314. uint Opcode = 0x4E204800; // CLS V0.16B, V0.16B
  315. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  316. Opcode |= ((size & 3) << 22);
  317. Bits Op = new Bits(Opcode);
  318. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  319. Vector128<float> V1 = MakeVectorE0E1(A, A);
  320. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  321. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  322. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  323. SimdFp.Cls_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  324. Assert.Multiple(() =>
  325. {
  326. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  327. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  328. });
  329. CompareAgainstUnicorn();
  330. }
  331. [Test, Pairwise, Description("CLZ <Vd>.<T>, <Vn>.<T>")]
  332. public void Clz_V_8B_4H_2S([Values(0u)] uint Rd,
  333. [Values(1u, 0u)] uint Rn,
  334. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  335. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  336. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  337. {
  338. uint Opcode = 0x2E204800; // CLZ V0.8B, V0.8B
  339. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  340. Opcode |= ((size & 3) << 22);
  341. Bits Op = new Bits(Opcode);
  342. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  343. Vector128<float> V1 = MakeVectorE0(A);
  344. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  345. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  346. AArch64.V(1, new Bits(A));
  347. SimdFp.Clz_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  348. Assert.Multiple(() =>
  349. {
  350. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  351. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  352. });
  353. CompareAgainstUnicorn();
  354. }
  355. [Test, Pairwise, Description("CLZ <Vd>.<T>, <Vn>.<T>")]
  356. public void Clz_V_16B_8H_4S([Values(0u)] uint Rd,
  357. [Values(1u, 0u)] uint Rn,
  358. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  359. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  360. [Values(0b00u, 0b01u, 0b10u)] uint size) // <16B, 8H, 4S>
  361. {
  362. uint Opcode = 0x6E204800; // CLZ V0.16B, V0.16B
  363. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  364. Opcode |= ((size & 3) << 22);
  365. Bits Op = new Bits(Opcode);
  366. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  367. Vector128<float> V1 = MakeVectorE0E1(A, A);
  368. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  369. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  370. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  371. SimdFp.Clz_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  372. Assert.Multiple(() =>
  373. {
  374. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  375. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  376. });
  377. CompareAgainstUnicorn();
  378. }
  379. [Test, Pairwise, Description("CMEQ <V><d>, <V><n>, #0")]
  380. public void Cmeq_S_D([Values(0u)] uint Rd,
  381. [Values(1u, 0u)] uint Rn,
  382. [ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
  383. [ValueSource("_1D_")] [Random(RndCnt)] ulong A)
  384. {
  385. uint Opcode = 0x5EE09800; // CMEQ D0, D0, #0
  386. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  387. Bits Op = new Bits(Opcode);
  388. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  389. Vector128<float> V1 = MakeVectorE0(A);
  390. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  391. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  392. AArch64.V(1, new Bits(A));
  393. SimdFp.Cmeq_Zero_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  394. Assert.Multiple(() =>
  395. {
  396. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  397. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  398. });
  399. CompareAgainstUnicorn();
  400. }
  401. [Test, Pairwise, Description("CMEQ <Vd>.<T>, <Vn>.<T>, #0")]
  402. public void Cmeq_V_8B_4H_2S([Values(0u)] uint Rd,
  403. [Values(1u, 0u)] uint Rn,
  404. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  405. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  406. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  407. {
  408. uint Opcode = 0x0E209800; // CMEQ V0.8B, V0.8B, #0
  409. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  410. Opcode |= ((size & 3) << 22);
  411. Bits Op = new Bits(Opcode);
  412. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  413. Vector128<float> V1 = MakeVectorE0(A);
  414. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  415. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  416. AArch64.V(1, new Bits(A));
  417. SimdFp.Cmeq_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  418. Assert.Multiple(() =>
  419. {
  420. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  421. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  422. });
  423. CompareAgainstUnicorn();
  424. }
  425. [Test, Pairwise, Description("CMEQ <Vd>.<T>, <Vn>.<T>, #0")]
  426. public void Cmeq_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  427. [Values(1u, 0u)] uint Rn,
  428. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  429. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  430. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  431. {
  432. uint Opcode = 0x4E209800; // CMEQ V0.16B, V0.16B, #0
  433. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  434. Opcode |= ((size & 3) << 22);
  435. Bits Op = new Bits(Opcode);
  436. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  437. Vector128<float> V1 = MakeVectorE0E1(A, A);
  438. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  439. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  440. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  441. SimdFp.Cmeq_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  442. Assert.Multiple(() =>
  443. {
  444. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  445. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  446. });
  447. CompareAgainstUnicorn();
  448. }
  449. [Test, Pairwise, Description("CMGE <V><d>, <V><n>, #0")]
  450. public void Cmge_S_D([Values(0u)] uint Rd,
  451. [Values(1u, 0u)] uint Rn,
  452. [ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
  453. [ValueSource("_1D_")] [Random(RndCnt)] ulong A)
  454. {
  455. uint Opcode = 0x7EE08800; // CMGE D0, D0, #0
  456. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  457. Bits Op = new Bits(Opcode);
  458. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  459. Vector128<float> V1 = MakeVectorE0(A);
  460. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  461. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  462. AArch64.V(1, new Bits(A));
  463. SimdFp.Cmge_Zero_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  464. Assert.Multiple(() =>
  465. {
  466. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  467. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  468. });
  469. CompareAgainstUnicorn();
  470. }
  471. [Test, Pairwise, Description("CMGE <Vd>.<T>, <Vn>.<T>, #0")]
  472. public void Cmge_V_8B_4H_2S([Values(0u)] uint Rd,
  473. [Values(1u, 0u)] uint Rn,
  474. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  475. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  476. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  477. {
  478. uint Opcode = 0x2E208800; // CMGE V0.8B, V0.8B, #0
  479. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  480. Opcode |= ((size & 3) << 22);
  481. Bits Op = new Bits(Opcode);
  482. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  483. Vector128<float> V1 = MakeVectorE0(A);
  484. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  485. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  486. AArch64.V(1, new Bits(A));
  487. SimdFp.Cmge_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  488. Assert.Multiple(() =>
  489. {
  490. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  491. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  492. });
  493. CompareAgainstUnicorn();
  494. }
  495. [Test, Pairwise, Description("CMGE <Vd>.<T>, <Vn>.<T>, #0")]
  496. public void Cmge_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  497. [Values(1u, 0u)] uint Rn,
  498. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  499. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  500. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  501. {
  502. uint Opcode = 0x6E208800; // CMGE V0.16B, V0.16B, #0
  503. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  504. Opcode |= ((size & 3) << 22);
  505. Bits Op = new Bits(Opcode);
  506. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  507. Vector128<float> V1 = MakeVectorE0E1(A, A);
  508. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  509. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  510. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  511. SimdFp.Cmge_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  512. Assert.Multiple(() =>
  513. {
  514. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  515. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  516. });
  517. CompareAgainstUnicorn();
  518. }
  519. [Test, Pairwise, Description("CMGT <V><d>, <V><n>, #0")]
  520. public void Cmgt_S_D([Values(0u)] uint Rd,
  521. [Values(1u, 0u)] uint Rn,
  522. [ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
  523. [ValueSource("_1D_")] [Random(RndCnt)] ulong A)
  524. {
  525. uint Opcode = 0x5EE08800; // CMGT D0, D0, #0
  526. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  527. Bits Op = new Bits(Opcode);
  528. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  529. Vector128<float> V1 = MakeVectorE0(A);
  530. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  531. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  532. AArch64.V(1, new Bits(A));
  533. SimdFp.Cmgt_Zero_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  534. Assert.Multiple(() =>
  535. {
  536. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  537. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  538. });
  539. CompareAgainstUnicorn();
  540. }
  541. [Test, Pairwise, Description("CMGT <Vd>.<T>, <Vn>.<T>, #0")]
  542. public void Cmgt_V_8B_4H_2S([Values(0u)] uint Rd,
  543. [Values(1u, 0u)] uint Rn,
  544. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  545. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  546. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  547. {
  548. uint Opcode = 0x0E208800; // CMGT V0.8B, V0.8B, #0
  549. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  550. Opcode |= ((size & 3) << 22);
  551. Bits Op = new Bits(Opcode);
  552. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  553. Vector128<float> V1 = MakeVectorE0(A);
  554. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  555. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  556. AArch64.V(1, new Bits(A));
  557. SimdFp.Cmgt_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  558. Assert.Multiple(() =>
  559. {
  560. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  561. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  562. });
  563. CompareAgainstUnicorn();
  564. }
  565. [Test, Pairwise, Description("CMGT <Vd>.<T>, <Vn>.<T>, #0")]
  566. public void Cmgt_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  567. [Values(1u, 0u)] uint Rn,
  568. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  569. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  570. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  571. {
  572. uint Opcode = 0x4E208800; // CMGT V0.16B, V0.16B, #0
  573. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  574. Opcode |= ((size & 3) << 22);
  575. Bits Op = new Bits(Opcode);
  576. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  577. Vector128<float> V1 = MakeVectorE0E1(A, A);
  578. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  579. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  580. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  581. SimdFp.Cmgt_Zero_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  582. Assert.Multiple(() =>
  583. {
  584. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  585. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  586. });
  587. CompareAgainstUnicorn();
  588. }
  589. [Test, Pairwise, Description("CMLE <V><d>, <V><n>, #0")]
  590. public void Cmle_S_D([Values(0u)] uint Rd,
  591. [Values(1u, 0u)] uint Rn,
  592. [ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
  593. [ValueSource("_1D_")] [Random(RndCnt)] ulong A)
  594. {
  595. uint Opcode = 0x7EE09800; // CMLE D0, D0, #0
  596. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  597. Bits Op = new Bits(Opcode);
  598. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  599. Vector128<float> V1 = MakeVectorE0(A);
  600. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  601. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  602. AArch64.V(1, new Bits(A));
  603. SimdFp.Cmle_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  604. Assert.Multiple(() =>
  605. {
  606. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  607. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  608. });
  609. CompareAgainstUnicorn();
  610. }
  611. [Test, Pairwise, Description("CMLE <Vd>.<T>, <Vn>.<T>, #0")]
  612. public void Cmle_V_8B_4H_2S([Values(0u)] uint Rd,
  613. [Values(1u, 0u)] uint Rn,
  614. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  615. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  616. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  617. {
  618. uint Opcode = 0x2E209800; // CMLE V0.8B, V0.8B, #0
  619. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  620. Opcode |= ((size & 3) << 22);
  621. Bits Op = new Bits(Opcode);
  622. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  623. Vector128<float> V1 = MakeVectorE0(A);
  624. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  625. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  626. AArch64.V(1, new Bits(A));
  627. SimdFp.Cmle_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  628. Assert.Multiple(() =>
  629. {
  630. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  631. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  632. });
  633. CompareAgainstUnicorn();
  634. }
  635. [Test, Pairwise, Description("CMLE <Vd>.<T>, <Vn>.<T>, #0")]
  636. public void Cmle_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  637. [Values(1u, 0u)] uint Rn,
  638. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  639. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  640. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  641. {
  642. uint Opcode = 0x6E209800; // CMLE V0.16B, V0.16B, #0
  643. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  644. Opcode |= ((size & 3) << 22);
  645. Bits Op = new Bits(Opcode);
  646. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  647. Vector128<float> V1 = MakeVectorE0E1(A, A);
  648. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  649. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  650. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  651. SimdFp.Cmle_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  652. Assert.Multiple(() =>
  653. {
  654. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  655. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  656. });
  657. CompareAgainstUnicorn();
  658. }
  659. [Test, Pairwise, Description("CMLT <V><d>, <V><n>, #0")]
  660. public void Cmlt_S_D([Values(0u)] uint Rd,
  661. [Values(1u, 0u)] uint Rn,
  662. [ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
  663. [ValueSource("_1D_")] [Random(RndCnt)] ulong A)
  664. {
  665. uint Opcode = 0x5EE0A800; // CMLT D0, D0, #0
  666. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  667. Bits Op = new Bits(Opcode);
  668. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  669. Vector128<float> V1 = MakeVectorE0(A);
  670. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  671. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  672. AArch64.V(1, new Bits(A));
  673. SimdFp.Cmlt_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  674. Assert.Multiple(() =>
  675. {
  676. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  677. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  678. });
  679. CompareAgainstUnicorn();
  680. }
  681. [Test, Pairwise, Description("CMLT <Vd>.<T>, <Vn>.<T>, #0")]
  682. public void Cmlt_V_8B_4H_2S([Values(0u)] uint Rd,
  683. [Values(1u, 0u)] uint Rn,
  684. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  685. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  686. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  687. {
  688. uint Opcode = 0x0E20A800; // CMLT V0.8B, V0.8B, #0
  689. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  690. Opcode |= ((size & 3) << 22);
  691. Bits Op = new Bits(Opcode);
  692. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  693. Vector128<float> V1 = MakeVectorE0(A);
  694. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  695. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  696. AArch64.V(1, new Bits(A));
  697. SimdFp.Cmlt_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  698. Assert.Multiple(() =>
  699. {
  700. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  701. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  702. });
  703. CompareAgainstUnicorn();
  704. }
  705. [Test, Pairwise, Description("CMLT <Vd>.<T>, <Vn>.<T>, #0")]
  706. public void Cmlt_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  707. [Values(1u, 0u)] uint Rn,
  708. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  709. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  710. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  711. {
  712. uint Opcode = 0x4E20A800; // CMLT V0.16B, V0.16B, #0
  713. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  714. Opcode |= ((size & 3) << 22);
  715. Bits Op = new Bits(Opcode);
  716. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  717. Vector128<float> V1 = MakeVectorE0E1(A, A);
  718. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  719. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  720. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  721. SimdFp.Cmlt_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  722. Assert.Multiple(() =>
  723. {
  724. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  725. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  726. });
  727. CompareAgainstUnicorn();
  728. }
  729. [Test, Pairwise, Description("CNT <Vd>.<T>, <Vn>.<T>")]
  730. public void Cnt_V_8B([Values(0u)] uint Rd,
  731. [Values(1u, 0u)] uint Rn,
  732. [ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
  733. [ValueSource("_8B_")] [Random(RndCnt)] ulong A)
  734. {
  735. uint Opcode = 0x0E205800; // CNT V0.8B, V0.8B
  736. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  737. Bits Op = new Bits(Opcode);
  738. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  739. Vector128<float> V1 = MakeVectorE0(A);
  740. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  741. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  742. AArch64.V(1, new Bits(A));
  743. SimdFp.Cnt_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  744. Assert.Multiple(() =>
  745. {
  746. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  747. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  748. });
  749. CompareAgainstUnicorn();
  750. }
  751. [Test, Pairwise, Description("CNT <Vd>.<T>, <Vn>.<T>")]
  752. public void Cnt_V_16B([Values(0u)] uint Rd,
  753. [Values(1u, 0u)] uint Rn,
  754. [ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
  755. [ValueSource("_8B_")] [Random(RndCnt)] ulong A)
  756. {
  757. uint Opcode = 0x4E205800; // CNT V0.16B, V0.16B
  758. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  759. Bits Op = new Bits(Opcode);
  760. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  761. Vector128<float> V1 = MakeVectorE0E1(A, A);
  762. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  763. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  764. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  765. SimdFp.Cnt_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  766. Assert.Multiple(() =>
  767. {
  768. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  769. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  770. });
  771. CompareAgainstUnicorn();
  772. }
  773. [Test, Pairwise, Description("FCVTNS <V><d>, <V><n>")]
  774. public void Fcvtns_S_S([Values(0u)] uint Rd,
  775. [Values(1u, 0u)] uint Rn,
  776. [ValueSource("_1S_F_")] [Random(RndCnt)] ulong Z,
  777. [ValueSource("_1S_F_")] [Random(RndCnt)] ulong A)
  778. {
  779. //const int FZFlagBit = 24; // Flush-to-zero mode control bit.
  780. //const int IDCFlagBit = 7; // Input Denormal cumulative floating-point exception bit.
  781. //const int IXCFlagBit = 4; // Inexact cumulative floating-point exception bit.
  782. //const int IOCFlagBit = 0; // Invalid Operation cumulative floating-point exception bit.
  783. uint Opcode = 0x5E21A800; // FCVTNS S0, S0
  784. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  785. Bits Op = new Bits(Opcode);
  786. //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled.
  787. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  788. Vector128<float> V1 = MakeVectorE0(A);
  789. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/);
  790. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  791. AArch64.V(1, new Bits(A));
  792. //Shared.FPCR = new Bits((uint)Fpcr);
  793. SimdFp.Fcvtns_S(Op[22], Op[9, 5], Op[4, 0]);
  794. Assert.Multiple(() =>
  795. {
  796. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  797. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  798. });
  799. /*Assert.Multiple(() =>
  800. {
  801. Assert.That(((ThreadState.Fpsr >> IDCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IDCFlagBit]));
  802. Assert.That(((ThreadState.Fpsr >> IXCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IXCFlagBit]));
  803. Assert.That(((ThreadState.Fpsr >> IOCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IOCFlagBit]));
  804. });*/
  805. }
  806. [Test, Pairwise, Description("FCVTNS <V><d>, <V><n>")]
  807. public void Fcvtns_S_D([Values(0u)] uint Rd,
  808. [Values(1u, 0u)] uint Rn,
  809. [ValueSource("_1D_F_")] [Random(RndCnt)] ulong Z,
  810. [ValueSource("_1D_F_")] [Random(RndCnt)] ulong A)
  811. {
  812. uint Opcode = 0x5E61A800; // FCVTNS D0, D0
  813. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  814. Bits Op = new Bits(Opcode);
  815. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  816. Vector128<float> V1 = MakeVectorE0(A);
  817. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  818. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  819. AArch64.V(1, new Bits(A));
  820. SimdFp.Fcvtns_S(Op[22], Op[9, 5], Op[4, 0]);
  821. Assert.Multiple(() =>
  822. {
  823. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  824. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  825. });
  826. }
  827. [Test, Pairwise, Description("FCVTNS <Vd>.<T>, <Vn>.<T>")]
  828. public void Fcvtns_V_2S_4S([Values(0u)] uint Rd,
  829. [Values(1u, 0u)] uint Rn,
  830. [ValueSource("_2S_F_")] [Random(RndCnt)] ulong Z,
  831. [ValueSource("_2S_F_")] [Random(RndCnt)] ulong A,
  832. [Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
  833. {
  834. uint Opcode = 0x0E21A800; // FCVTNS V0.2S, V0.2S
  835. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  836. Opcode |= ((Q & 1) << 30);
  837. Bits Op = new Bits(Opcode);
  838. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  839. Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
  840. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  841. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  842. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A * Q));
  843. SimdFp.Fcvtns_V(Op[30], Op[22], Op[9, 5], Op[4, 0]);
  844. Assert.Multiple(() =>
  845. {
  846. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  847. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  848. });
  849. }
  850. [Test, Pairwise, Description("FCVTNS <Vd>.<T>, <Vn>.<T>")]
  851. public void Fcvtns_V_2D([Values(0u)] uint Rd,
  852. [Values(1u, 0u)] uint Rn,
  853. [ValueSource("_1D_F_")] [Random(RndCnt)] ulong Z,
  854. [ValueSource("_1D_F_")] [Random(RndCnt)] ulong A)
  855. {
  856. uint Opcode = 0x4E61A800; // FCVTNS V0.2D, V0.2D
  857. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  858. Bits Op = new Bits(Opcode);
  859. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  860. Vector128<float> V1 = MakeVectorE0E1(A, A);
  861. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  862. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  863. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  864. SimdFp.Fcvtns_V(Op[30], Op[22], Op[9, 5], Op[4, 0]);
  865. Assert.Multiple(() =>
  866. {
  867. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  868. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  869. });
  870. }
  871. [Test, Pairwise, Description("FCVTNU <V><d>, <V><n>")]
  872. public void Fcvtnu_S_S([Values(0u)] uint Rd,
  873. [Values(1u, 0u)] uint Rn,
  874. [ValueSource("_1S_F_")] [Random(RndCnt)] ulong Z,
  875. [ValueSource("_1S_F_")] [Random(RndCnt)] ulong A)
  876. {
  877. //const int FZFlagBit = 24; // Flush-to-zero mode control bit.
  878. //const int IDCFlagBit = 7; // Input Denormal cumulative floating-point exception bit.
  879. //const int IXCFlagBit = 4; // Inexact cumulative floating-point exception bit.
  880. //const int IOCFlagBit = 0; // Invalid Operation cumulative floating-point exception bit.
  881. uint Opcode = 0x7E21A800; // FCVTNU S0, S0
  882. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  883. Bits Op = new Bits(Opcode);
  884. //int Fpcr = 1 << FZFlagBit; // Flush-to-zero mode enabled.
  885. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  886. Vector128<float> V1 = MakeVectorE0(A);
  887. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1/*, Fpcr: Fpcr*/);
  888. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  889. AArch64.V(1, new Bits(A));
  890. //Shared.FPCR = new Bits((uint)Fpcr);
  891. SimdFp.Fcvtnu_S(Op[22], Op[9, 5], Op[4, 0]);
  892. Assert.Multiple(() =>
  893. {
  894. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  895. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  896. });
  897. /*Assert.Multiple(() =>
  898. {
  899. Assert.That(((ThreadState.Fpsr >> IDCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IDCFlagBit]));
  900. Assert.That(((ThreadState.Fpsr >> IXCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IXCFlagBit]));
  901. Assert.That(((ThreadState.Fpsr >> IOCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[IOCFlagBit]));
  902. });*/
  903. }
  904. [Test, Pairwise, Description("FCVTNU <V><d>, <V><n>")]
  905. public void Fcvtnu_S_D([Values(0u)] uint Rd,
  906. [Values(1u, 0u)] uint Rn,
  907. [ValueSource("_1D_F_")] [Random(RndCnt)] ulong Z,
  908. [ValueSource("_1D_F_")] [Random(RndCnt)] ulong A)
  909. {
  910. uint Opcode = 0x7E61A800; // FCVTNU D0, D0
  911. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  912. Bits Op = new Bits(Opcode);
  913. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  914. Vector128<float> V1 = MakeVectorE0(A);
  915. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  916. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  917. AArch64.V(1, new Bits(A));
  918. SimdFp.Fcvtnu_S(Op[22], Op[9, 5], Op[4, 0]);
  919. Assert.Multiple(() =>
  920. {
  921. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  922. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  923. });
  924. }
  925. [Test, Pairwise, Description("FCVTNU <Vd>.<T>, <Vn>.<T>")]
  926. public void Fcvtnu_V_2S_4S([Values(0u)] uint Rd,
  927. [Values(1u, 0u)] uint Rn,
  928. [ValueSource("_2S_F_")] [Random(RndCnt)] ulong Z,
  929. [ValueSource("_2S_F_")] [Random(RndCnt)] ulong A,
  930. [Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
  931. {
  932. uint Opcode = 0x2E21A800; // FCVTNU V0.2S, V0.2S
  933. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  934. Opcode |= ((Q & 1) << 30);
  935. Bits Op = new Bits(Opcode);
  936. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  937. Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
  938. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  939. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  940. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A * Q));
  941. SimdFp.Fcvtnu_V(Op[30], Op[22], Op[9, 5], Op[4, 0]);
  942. Assert.Multiple(() =>
  943. {
  944. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  945. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  946. });
  947. }
  948. [Test, Pairwise, Description("FCVTNU <Vd>.<T>, <Vn>.<T>")]
  949. public void Fcvtnu_V_2D([Values(0u)] uint Rd,
  950. [Values(1u, 0u)] uint Rn,
  951. [ValueSource("_1D_F_")] [Random(RndCnt)] ulong Z,
  952. [ValueSource("_1D_F_")] [Random(RndCnt)] ulong A)
  953. {
  954. uint Opcode = 0x6E61A800; // FCVTNU V0.2D, V0.2D
  955. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  956. Bits Op = new Bits(Opcode);
  957. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  958. Vector128<float> V1 = MakeVectorE0E1(A, A);
  959. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  960. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  961. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  962. SimdFp.Fcvtnu_V(Op[30], Op[22], Op[9, 5], Op[4, 0]);
  963. Assert.Multiple(() =>
  964. {
  965. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  966. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  967. });
  968. }
  969. [Test, Pairwise, Description("NEG <V><d>, <V><n>")]
  970. public void Neg_S_D([Values(0u)] uint Rd,
  971. [Values(1u, 0u)] uint Rn,
  972. [ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
  973. [ValueSource("_1D_")] [Random(RndCnt)] ulong A)
  974. {
  975. uint Opcode = 0x7EE0B800; // NEG D0, D0
  976. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  977. Bits Op = new Bits(Opcode);
  978. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  979. Vector128<float> V1 = MakeVectorE0(A);
  980. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  981. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  982. AArch64.V(1, new Bits(A));
  983. SimdFp.Neg_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  984. Assert.Multiple(() =>
  985. {
  986. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  987. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  988. });
  989. CompareAgainstUnicorn();
  990. }
  991. [Test, Pairwise, Description("NEG <Vd>.<T>, <Vn>.<T>")]
  992. public void Neg_V_8B_4H_2S([Values(0u)] uint Rd,
  993. [Values(1u, 0u)] uint Rn,
  994. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  995. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  996. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  997. {
  998. uint Opcode = 0x2E20B800; // NEG V0.8B, V0.8B
  999. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1000. Opcode |= ((size & 3) << 22);
  1001. Bits Op = new Bits(Opcode);
  1002. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1003. Vector128<float> V1 = MakeVectorE0(A);
  1004. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1005. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1006. AArch64.V(1, new Bits(A));
  1007. SimdFp.Neg_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1008. Assert.Multiple(() =>
  1009. {
  1010. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1011. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1012. });
  1013. CompareAgainstUnicorn();
  1014. }
  1015. [Test, Pairwise, Description("NEG <Vd>.<T>, <Vn>.<T>")]
  1016. public void Neg_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  1017. [Values(1u, 0u)] uint Rn,
  1018. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  1019. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  1020. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  1021. {
  1022. uint Opcode = 0x6E20B800; // NEG V0.16B, V0.16B
  1023. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1024. Opcode |= ((size & 3) << 22);
  1025. Bits Op = new Bits(Opcode);
  1026. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1027. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1028. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1029. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1030. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1031. SimdFp.Neg_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1032. Assert.Multiple(() =>
  1033. {
  1034. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1035. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1036. });
  1037. CompareAgainstUnicorn();
  1038. }
  1039. [Test, Pairwise, Description("NOT <Vd>.<T>, <Vn>.<T>")]
  1040. public void Not_V_8B([Values(0u)] uint Rd,
  1041. [Values(1u, 0u)] uint Rn,
  1042. [ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
  1043. [ValueSource("_8B_")] [Random(RndCnt)] ulong A)
  1044. {
  1045. uint Opcode = 0x2E205800; // NOT V0.8B, V0.8B
  1046. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1047. Bits Op = new Bits(Opcode);
  1048. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1049. Vector128<float> V1 = MakeVectorE0(A);
  1050. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1051. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1052. AArch64.V(1, new Bits(A));
  1053. SimdFp.Not_V(Op[30], Op[9, 5], Op[4, 0]);
  1054. Assert.Multiple(() =>
  1055. {
  1056. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1057. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1058. });
  1059. CompareAgainstUnicorn();
  1060. }
  1061. [Test, Pairwise, Description("NOT <Vd>.<T>, <Vn>.<T>")]
  1062. public void Not_V_16B([Values(0u)] uint Rd,
  1063. [Values(1u, 0u)] uint Rn,
  1064. [ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
  1065. [ValueSource("_8B_")] [Random(RndCnt)] ulong A)
  1066. {
  1067. uint Opcode = 0x6E205800; // NOT V0.16B, V0.16B
  1068. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1069. Bits Op = new Bits(Opcode);
  1070. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1071. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1072. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1073. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1074. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1075. SimdFp.Not_V(Op[30], Op[9, 5], Op[4, 0]);
  1076. Assert.Multiple(() =>
  1077. {
  1078. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1079. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1080. });
  1081. CompareAgainstUnicorn();
  1082. }
  1083. [Test, Pairwise, Description("RBIT <Vd>.<T>, <Vn>.<T>")]
  1084. public void Rbit_V_8B([Values(0u)] uint Rd,
  1085. [Values(1u, 0u)] uint Rn,
  1086. [ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
  1087. [ValueSource("_8B_")] [Random(RndCnt)] ulong A)
  1088. {
  1089. uint Opcode = 0x2E605800; // RBIT V0.8B, V0.8B
  1090. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1091. Bits Op = new Bits(Opcode);
  1092. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1093. Vector128<float> V1 = MakeVectorE0(A);
  1094. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1095. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1096. AArch64.V(1, new Bits(A));
  1097. SimdFp.Rbit_V(Op[30], Op[9, 5], Op[4, 0]);
  1098. Assert.Multiple(() =>
  1099. {
  1100. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1101. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1102. });
  1103. CompareAgainstUnicorn();
  1104. }
  1105. [Test, Pairwise, Description("RBIT <Vd>.<T>, <Vn>.<T>")]
  1106. public void Rbit_V_16B([Values(0u)] uint Rd,
  1107. [Values(1u, 0u)] uint Rn,
  1108. [ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
  1109. [ValueSource("_8B_")] [Random(RndCnt)] ulong A)
  1110. {
  1111. uint Opcode = 0x6E605800; // RBIT V0.16B, V0.16B
  1112. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1113. Bits Op = new Bits(Opcode);
  1114. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1115. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1116. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1117. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1118. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1119. SimdFp.Rbit_V(Op[30], Op[9, 5], Op[4, 0]);
  1120. Assert.Multiple(() =>
  1121. {
  1122. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1123. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1124. });
  1125. CompareAgainstUnicorn();
  1126. }
  1127. [Test, Pairwise, Description("REV16 <Vd>.<T>, <Vn>.<T>")]
  1128. public void Rev16_V_8B([Values(0u)] uint Rd,
  1129. [Values(1u, 0u)] uint Rn,
  1130. [ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
  1131. [ValueSource("_8B_")] [Random(RndCnt)] ulong A)
  1132. {
  1133. uint Opcode = 0x0E201800; // REV16 V0.8B, V0.8B
  1134. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1135. Bits Op = new Bits(Opcode);
  1136. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1137. Vector128<float> V1 = MakeVectorE0(A);
  1138. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1139. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1140. AArch64.V(1, new Bits(A));
  1141. SimdFp.Rev16_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1142. Assert.Multiple(() =>
  1143. {
  1144. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1145. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1146. });
  1147. CompareAgainstUnicorn();
  1148. }
  1149. [Test, Pairwise, Description("REV16 <Vd>.<T>, <Vn>.<T>")]
  1150. public void Rev16_V_16B([Values(0u)] uint Rd,
  1151. [Values(1u, 0u)] uint Rn,
  1152. [ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
  1153. [ValueSource("_8B_")] [Random(RndCnt)] ulong A)
  1154. {
  1155. uint Opcode = 0x4E201800; // REV16 V0.16B, V0.16B
  1156. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1157. Bits Op = new Bits(Opcode);
  1158. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1159. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1160. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1161. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1162. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1163. SimdFp.Rev16_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1164. Assert.Multiple(() =>
  1165. {
  1166. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1167. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1168. });
  1169. CompareAgainstUnicorn();
  1170. }
  1171. [Test, Pairwise, Description("REV32 <Vd>.<T>, <Vn>.<T>")]
  1172. public void Rev32_V_8B_4H([Values(0u)] uint Rd,
  1173. [Values(1u, 0u)] uint Rn,
  1174. [ValueSource("_8B4H_")] [Random(RndCnt)] ulong Z,
  1175. [ValueSource("_8B4H_")] [Random(RndCnt)] ulong A,
  1176. [Values(0b00u, 0b01u)] uint size) // <8B, 4H>
  1177. {
  1178. uint Opcode = 0x2E200800; // REV32 V0.8B, V0.8B
  1179. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1180. Opcode |= ((size & 3) << 22);
  1181. Bits Op = new Bits(Opcode);
  1182. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1183. Vector128<float> V1 = MakeVectorE0(A);
  1184. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1185. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1186. AArch64.V(1, new Bits(A));
  1187. SimdFp.Rev32_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1188. Assert.Multiple(() =>
  1189. {
  1190. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1191. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1192. });
  1193. CompareAgainstUnicorn();
  1194. }
  1195. [Test, Pairwise, Description("REV32 <Vd>.<T>, <Vn>.<T>")]
  1196. public void Rev32_V_16B_8H([Values(0u)] uint Rd,
  1197. [Values(1u, 0u)] uint Rn,
  1198. [ValueSource("_8B4H_")] [Random(RndCnt)] ulong Z,
  1199. [ValueSource("_8B4H_")] [Random(RndCnt)] ulong A,
  1200. [Values(0b00u, 0b01u)] uint size) // <16B, 8H>
  1201. {
  1202. uint Opcode = 0x6E200800; // REV32 V0.16B, V0.16B
  1203. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1204. Opcode |= ((size & 3) << 22);
  1205. Bits Op = new Bits(Opcode);
  1206. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1207. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1208. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1209. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1210. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1211. SimdFp.Rev32_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1212. Assert.Multiple(() =>
  1213. {
  1214. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1215. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1216. });
  1217. CompareAgainstUnicorn();
  1218. }
  1219. [Test, Pairwise, Description("REV64 <Vd>.<T>, <Vn>.<T>")]
  1220. public void Rev64_V_8B_4H_2S([Values(0u)] uint Rd,
  1221. [Values(1u, 0u)] uint Rn,
  1222. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1223. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1224. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  1225. {
  1226. uint Opcode = 0x0E200800; // REV64 V0.8B, V0.8B
  1227. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1228. Opcode |= ((size & 3) << 22);
  1229. Bits Op = new Bits(Opcode);
  1230. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1231. Vector128<float> V1 = MakeVectorE0(A);
  1232. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1233. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1234. AArch64.V(1, new Bits(A));
  1235. SimdFp.Rev64_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1236. Assert.Multiple(() =>
  1237. {
  1238. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1239. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1240. });
  1241. CompareAgainstUnicorn();
  1242. }
  1243. [Test, Pairwise, Description("REV64 <Vd>.<T>, <Vn>.<T>")]
  1244. public void Rev64_V_16B_8H_4S([Values(0u)] uint Rd,
  1245. [Values(1u, 0u)] uint Rn,
  1246. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1247. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1248. [Values(0b00u, 0b01u, 0b10u)] uint size) // <16B, 8H, 4S>
  1249. {
  1250. uint Opcode = 0x4E200800; // REV64 V0.16B, V0.16B
  1251. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1252. Opcode |= ((size & 3) << 22);
  1253. Bits Op = new Bits(Opcode);
  1254. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1255. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1256. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1257. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1258. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1259. SimdFp.Rev64_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1260. Assert.Multiple(() =>
  1261. {
  1262. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1263. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1264. });
  1265. CompareAgainstUnicorn();
  1266. }
  1267. [Test, Pairwise, Description("SADALP <Vd>.<Ta>, <Vn>.<Tb>")]
  1268. public void Sadalp_V_8B4H_4H2S_2S1D([Values(0u)] uint Rd,
  1269. [Values(1u, 0u)] uint Rn,
  1270. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1271. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1272. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B4H, 4H2S, 2S1D>
  1273. {
  1274. uint Opcode = 0x0E206800; // SADALP V0.4H, V0.8B
  1275. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1276. Opcode |= ((size & 3) << 22);
  1277. Bits Op = new Bits(Opcode);
  1278. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1279. Vector128<float> V1 = MakeVectorE0(A);
  1280. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1281. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1282. AArch64.V(1, new Bits(A));
  1283. SimdFp.Sadalp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1284. Assert.Multiple(() =>
  1285. {
  1286. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1287. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1288. });
  1289. CompareAgainstUnicorn();
  1290. }
  1291. [Test, Pairwise, Description("SADALP <Vd>.<Ta>, <Vn>.<Tb>")]
  1292. public void Sadalp_V_16B8H_8H4S_4S2D([Values(0u)] uint Rd,
  1293. [Values(1u, 0u)] uint Rn,
  1294. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1295. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1296. [Values(0b00u, 0b01u, 0b10u)] uint size) // <16B8H, 8H4S, 4S2D>
  1297. {
  1298. uint Opcode = 0x4E206800; // SADALP V0.8H, V0.16B
  1299. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1300. Opcode |= ((size & 3) << 22);
  1301. Bits Op = new Bits(Opcode);
  1302. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1303. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1304. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1305. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1306. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1307. SimdFp.Sadalp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1308. Assert.Multiple(() =>
  1309. {
  1310. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1311. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1312. });
  1313. CompareAgainstUnicorn();
  1314. }
  1315. [Test, Pairwise, Description("SADDLP <Vd>.<Ta>, <Vn>.<Tb>")]
  1316. public void Saddlp_V_8B4H_4H2S_2S1D([Values(0u)] uint Rd,
  1317. [Values(1u, 0u)] uint Rn,
  1318. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1319. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1320. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B4H, 4H2S, 2S1D>
  1321. {
  1322. uint Opcode = 0x0E202800; // SADDLP V0.4H, V0.8B
  1323. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1324. Opcode |= ((size & 3) << 22);
  1325. Bits Op = new Bits(Opcode);
  1326. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1327. Vector128<float> V1 = MakeVectorE0(A);
  1328. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1329. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1330. AArch64.V(1, new Bits(A));
  1331. SimdFp.Saddlp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1332. Assert.Multiple(() =>
  1333. {
  1334. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1335. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1336. });
  1337. CompareAgainstUnicorn();
  1338. }
  1339. [Test, Pairwise, Description("SADDLP <Vd>.<Ta>, <Vn>.<Tb>")]
  1340. public void Saddlp_V_16B8H_8H4S_4S2D([Values(0u)] uint Rd,
  1341. [Values(1u, 0u)] uint Rn,
  1342. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1343. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1344. [Values(0b00u, 0b01u, 0b10u)] uint size) // <16B8H, 8H4S, 4S2D>
  1345. {
  1346. uint Opcode = 0x4E202800; // SADDLP V0.8H, V0.16B
  1347. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1348. Opcode |= ((size & 3) << 22);
  1349. Bits Op = new Bits(Opcode);
  1350. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1351. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1352. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1353. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1354. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1355. SimdFp.Saddlp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1356. Assert.Multiple(() =>
  1357. {
  1358. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1359. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1360. });
  1361. CompareAgainstUnicorn();
  1362. }
  1363. [Test, Pairwise, Description("SHA256SU0 <Vd>.4S, <Vn>.4S")]
  1364. public void Sha256su0_V([Values(0u)] uint Rd,
  1365. [Values(1u, 0u)] uint Rn,
  1366. [Random(RndCnt / 2)] ulong Z0, [Random(RndCnt / 2)] ulong Z1,
  1367. [Random(RndCnt / 2)] ulong A0, [Random(RndCnt / 2)] ulong A1)
  1368. {
  1369. uint Opcode = 0x5E282800; // SHA256SU0 V0.4S, V0.4S
  1370. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1371. Bits Op = new Bits(Opcode);
  1372. Vector128<float> V0 = MakeVectorE0E1(Z0, Z1);
  1373. Vector128<float> V1 = MakeVectorE0E1(A0, A1);
  1374. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1375. AArch64.Vpart(0, 0, new Bits(Z0)); AArch64.Vpart(0, 1, new Bits(Z1));
  1376. AArch64.Vpart(1, 0, new Bits(A0)); AArch64.Vpart(1, 1, new Bits(A1));
  1377. SimdFp.Sha256su0_V(Op[9, 5], Op[4, 0]);
  1378. Assert.Multiple(() =>
  1379. {
  1380. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1381. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1382. });
  1383. Assert.Multiple(() =>
  1384. {
  1385. Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 0).ToUInt64()));
  1386. Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(AArch64.Vpart(64, 1, 1).ToUInt64()));
  1387. });
  1388. CompareAgainstUnicorn();
  1389. }
  1390. [Test, Pairwise, Description("SQABS <V><d>, <V><n>")]
  1391. public void Sqabs_S_B_H_S_D([Values(0u)] uint Rd,
  1392. [Values(1u, 0u)] uint Rn,
  1393. [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong Z,
  1394. [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong A,
  1395. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <B, H, S, D>
  1396. {
  1397. const int QCFlagBit = 27; // Cumulative saturation bit.
  1398. uint Opcode = 0x5E207800; // SQABS B0, B0
  1399. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1400. Opcode |= ((size & 3) << 22);
  1401. Bits Op = new Bits(Opcode);
  1402. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1403. Vector128<float> V1 = MakeVectorE0(A);
  1404. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1405. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1406. AArch64.V(1, new Bits(A));
  1407. SimdFp.Sqabs_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  1408. Assert.Multiple(() =>
  1409. {
  1410. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1411. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1412. });
  1413. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1414. CompareAgainstUnicorn();
  1415. }
  1416. [Test, Pairwise, Description("SQABS <Vd>.<T>, <Vn>.<T>")]
  1417. public void Sqabs_V_8B_4H_2S([Values(0u)] uint Rd,
  1418. [Values(1u, 0u)] uint Rn,
  1419. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1420. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1421. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  1422. {
  1423. const int QCFlagBit = 27; // Cumulative saturation bit.
  1424. uint Opcode = 0x0E207800; // SQABS V0.8B, V0.8B
  1425. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1426. Opcode |= ((size & 3) << 22);
  1427. Bits Op = new Bits(Opcode);
  1428. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1429. Vector128<float> V1 = MakeVectorE0(A);
  1430. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1431. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1432. AArch64.V(1, new Bits(A));
  1433. SimdFp.Sqabs_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1434. Assert.Multiple(() =>
  1435. {
  1436. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1437. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1438. });
  1439. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1440. CompareAgainstUnicorn();
  1441. }
  1442. [Test, Pairwise, Description("SQABS <Vd>.<T>, <Vn>.<T>")]
  1443. public void Sqabs_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  1444. [Values(1u, 0u)] uint Rn,
  1445. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  1446. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  1447. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  1448. {
  1449. const int QCFlagBit = 27; // Cumulative saturation bit.
  1450. uint Opcode = 0x4E207800; // SQABS V0.16B, V0.16B
  1451. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1452. Opcode |= ((size & 3) << 22);
  1453. Bits Op = new Bits(Opcode);
  1454. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1455. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1456. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1457. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1458. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1459. SimdFp.Sqabs_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1460. Assert.Multiple(() =>
  1461. {
  1462. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1463. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1464. });
  1465. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1466. CompareAgainstUnicorn();
  1467. }
  1468. [Test, Pairwise, Description("SQNEG <V><d>, <V><n>")]
  1469. public void Sqneg_S_B_H_S_D([Values(0u)] uint Rd,
  1470. [Values(1u, 0u)] uint Rn,
  1471. [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong Z,
  1472. [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong A,
  1473. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <B, H, S, D>
  1474. {
  1475. const int QCFlagBit = 27; // Cumulative saturation bit.
  1476. uint Opcode = 0x7E207800; // SQNEG B0, B0
  1477. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1478. Opcode |= ((size & 3) << 22);
  1479. Bits Op = new Bits(Opcode);
  1480. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1481. Vector128<float> V1 = MakeVectorE0(A);
  1482. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1483. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1484. AArch64.V(1, new Bits(A));
  1485. SimdFp.Sqneg_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  1486. Assert.Multiple(() =>
  1487. {
  1488. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1489. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1490. });
  1491. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1492. CompareAgainstUnicorn();
  1493. }
  1494. [Test, Pairwise, Description("SQNEG <Vd>.<T>, <Vn>.<T>")]
  1495. public void Sqneg_V_8B_4H_2S([Values(0u)] uint Rd,
  1496. [Values(1u, 0u)] uint Rn,
  1497. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1498. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1499. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  1500. {
  1501. const int QCFlagBit = 27; // Cumulative saturation bit.
  1502. uint Opcode = 0x2E207800; // SQNEG V0.8B, V0.8B
  1503. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1504. Opcode |= ((size & 3) << 22);
  1505. Bits Op = new Bits(Opcode);
  1506. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1507. Vector128<float> V1 = MakeVectorE0(A);
  1508. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1509. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1510. AArch64.V(1, new Bits(A));
  1511. SimdFp.Sqneg_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1512. Assert.Multiple(() =>
  1513. {
  1514. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1515. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1516. });
  1517. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1518. CompareAgainstUnicorn();
  1519. }
  1520. [Test, Pairwise, Description("SQNEG <Vd>.<T>, <Vn>.<T>")]
  1521. public void Sqneg_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  1522. [Values(1u, 0u)] uint Rn,
  1523. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  1524. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  1525. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  1526. {
  1527. const int QCFlagBit = 27; // Cumulative saturation bit.
  1528. uint Opcode = 0x6E207800; // SQNEG V0.16B, V0.16B
  1529. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1530. Opcode |= ((size & 3) << 22);
  1531. Bits Op = new Bits(Opcode);
  1532. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1533. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1534. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1535. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1536. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1537. SimdFp.Sqneg_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1538. Assert.Multiple(() =>
  1539. {
  1540. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1541. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1542. });
  1543. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1544. CompareAgainstUnicorn();
  1545. }
  1546. [Test, Pairwise, Description("SQXTN <Vb><d>, <Va><n>")]
  1547. public void Sqxtn_S_HB_SH_DS([Values(0u)] uint Rd,
  1548. [Values(1u, 0u)] uint Rn,
  1549. [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong Z,
  1550. [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong A,
  1551. [Values(0b00u, 0b01u, 0b10u)] uint size) // <HB, SH, DS>
  1552. {
  1553. const int QCFlagBit = 27; // Cumulative saturation bit.
  1554. uint Opcode = 0x5E214800; // SQXTN B0, H0
  1555. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1556. Opcode |= ((size & 3) << 22);
  1557. Bits Op = new Bits(Opcode);
  1558. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1559. Vector128<float> V1 = MakeVectorE0(A);
  1560. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1561. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1562. AArch64.V(1, new Bits(A));
  1563. SimdFp.Sqxtn_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  1564. Assert.Multiple(() =>
  1565. {
  1566. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1567. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1568. });
  1569. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1570. CompareAgainstUnicorn();
  1571. }
  1572. [Test, Pairwise, Description("SQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
  1573. public void Sqxtn_V_8H8B_4S4H_2D2S([Values(0u)] uint Rd,
  1574. [Values(1u, 0u)] uint Rn,
  1575. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong Z,
  1576. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A,
  1577. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  1578. {
  1579. const int QCFlagBit = 27; // Cumulative saturation bit.
  1580. uint Opcode = 0x0E214800; // SQXTN V0.8B, V0.8H
  1581. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1582. Opcode |= ((size & 3) << 22);
  1583. Bits Op = new Bits(Opcode);
  1584. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1585. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1586. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1587. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1588. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1589. SimdFp.Sqxtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1590. Assert.Multiple(() =>
  1591. {
  1592. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1593. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1594. });
  1595. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1596. CompareAgainstUnicorn();
  1597. }
  1598. [Test, Pairwise, Description("SQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
  1599. public void Sqxtn_V_8H16B_4S8H_2D4S([Values(0u)] uint Rd,
  1600. [Values(1u, 0u)] uint Rn,
  1601. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong Z,
  1602. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A,
  1603. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  1604. {
  1605. const int QCFlagBit = 27; // Cumulative saturation bit.
  1606. uint Opcode = 0x4E214800; // SQXTN2 V0.16B, V0.8H
  1607. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1608. Opcode |= ((size & 3) << 22);
  1609. Bits Op = new Bits(Opcode);
  1610. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1611. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1612. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1613. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1614. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1615. SimdFp.Sqxtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1616. Assert.Multiple(() =>
  1617. {
  1618. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1619. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1620. });
  1621. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1622. CompareAgainstUnicorn();
  1623. }
  1624. [Test, Pairwise, Description("SQXTUN <Vb><d>, <Va><n>")]
  1625. public void Sqxtun_S_HB_SH_DS([Values(0u)] uint Rd,
  1626. [Values(1u, 0u)] uint Rn,
  1627. [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong Z,
  1628. [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong A,
  1629. [Values(0b00u, 0b01u, 0b10u)] uint size) // <HB, SH, DS>
  1630. {
  1631. const int QCFlagBit = 27; // Cumulative saturation bit.
  1632. uint Opcode = 0x7E212800; // SQXTUN B0, H0
  1633. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1634. Opcode |= ((size & 3) << 22);
  1635. Bits Op = new Bits(Opcode);
  1636. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1637. Vector128<float> V1 = MakeVectorE0(A);
  1638. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1639. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1640. AArch64.V(1, new Bits(A));
  1641. SimdFp.Sqxtun_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  1642. Assert.Multiple(() =>
  1643. {
  1644. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1645. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1646. });
  1647. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1648. CompareAgainstUnicorn();
  1649. }
  1650. [Test, Pairwise, Description("SQXTUN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
  1651. public void Sqxtun_V_8H8B_4S4H_2D2S([Values(0u)] uint Rd,
  1652. [Values(1u, 0u)] uint Rn,
  1653. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong Z,
  1654. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A,
  1655. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  1656. {
  1657. const int QCFlagBit = 27; // Cumulative saturation bit.
  1658. uint Opcode = 0x2E212800; // SQXTUN V0.8B, V0.8H
  1659. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1660. Opcode |= ((size & 3) << 22);
  1661. Bits Op = new Bits(Opcode);
  1662. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1663. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1664. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1665. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1666. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1667. SimdFp.Sqxtun_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1668. Assert.Multiple(() =>
  1669. {
  1670. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1671. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1672. });
  1673. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1674. CompareAgainstUnicorn();
  1675. }
  1676. [Test, Pairwise, Description("SQXTUN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
  1677. public void Sqxtun_V_8H16B_4S8H_2D4S([Values(0u)] uint Rd,
  1678. [Values(1u, 0u)] uint Rn,
  1679. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong Z,
  1680. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A,
  1681. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  1682. {
  1683. const int QCFlagBit = 27; // Cumulative saturation bit.
  1684. uint Opcode = 0x6E212800; // SQXTUN2 V0.16B, V0.8H
  1685. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1686. Opcode |= ((size & 3) << 22);
  1687. Bits Op = new Bits(Opcode);
  1688. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1689. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1690. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1691. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1692. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1693. SimdFp.Sqxtun_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1694. Assert.Multiple(() =>
  1695. {
  1696. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1697. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1698. });
  1699. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1700. CompareAgainstUnicorn();
  1701. }
  1702. [Test, Pairwise, Description("SUQADD <V><d>, <V><n>")]
  1703. public void Suqadd_S_B_H_S_D([Values(0u)] uint Rd,
  1704. [Values(1u, 0u)] uint Rn,
  1705. [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong Z,
  1706. [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong A,
  1707. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <B, H, S, D>
  1708. {
  1709. const int QCFlagBit = 27; // Cumulative saturation bit.
  1710. uint Opcode = 0x5E203800; // SUQADD B0, B0
  1711. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1712. Opcode |= ((size & 3) << 22);
  1713. Bits Op = new Bits(Opcode);
  1714. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1715. Vector128<float> V1 = MakeVectorE0(A);
  1716. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1717. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1718. AArch64.V(1, new Bits(A));
  1719. SimdFp.Suqadd_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  1720. Assert.Multiple(() =>
  1721. {
  1722. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1723. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1724. });
  1725. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1726. CompareAgainstUnicorn();
  1727. }
  1728. [Test, Pairwise, Description("SUQADD <Vd>.<T>, <Vn>.<T>")]
  1729. public void Suqadd_V_8B_4H_2S([Values(0u)] uint Rd,
  1730. [Values(1u, 0u)] uint Rn,
  1731. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1732. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1733. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  1734. {
  1735. const int QCFlagBit = 27; // Cumulative saturation bit.
  1736. uint Opcode = 0x0E203800; // SUQADD V0.8B, V0.8B
  1737. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1738. Opcode |= ((size & 3) << 22);
  1739. Bits Op = new Bits(Opcode);
  1740. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1741. Vector128<float> V1 = MakeVectorE0(A);
  1742. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1743. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1744. AArch64.V(1, new Bits(A));
  1745. SimdFp.Suqadd_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1746. Assert.Multiple(() =>
  1747. {
  1748. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1749. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1750. });
  1751. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1752. CompareAgainstUnicorn();
  1753. }
  1754. [Test, Pairwise, Description("SUQADD <Vd>.<T>, <Vn>.<T>")]
  1755. public void Suqadd_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  1756. [Values(1u, 0u)] uint Rn,
  1757. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  1758. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  1759. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  1760. {
  1761. const int QCFlagBit = 27; // Cumulative saturation bit.
  1762. uint Opcode = 0x4E203800; // SUQADD V0.16B, V0.16B
  1763. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1764. Opcode |= ((size & 3) << 22);
  1765. Bits Op = new Bits(Opcode);
  1766. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1767. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1768. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1769. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1770. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1771. SimdFp.Suqadd_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1772. Assert.Multiple(() =>
  1773. {
  1774. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1775. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1776. });
  1777. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1778. CompareAgainstUnicorn();
  1779. }
  1780. [Test, Pairwise, Description("UADALP <Vd>.<Ta>, <Vn>.<Tb>")]
  1781. public void Uadalp_V_8B4H_4H2S_2S1D([Values(0u)] uint Rd,
  1782. [Values(1u, 0u)] uint Rn,
  1783. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1784. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1785. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B4H, 4H2S, 2S1D>
  1786. {
  1787. uint Opcode = 0x2E206800; // UADALP V0.4H, V0.8B
  1788. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1789. Opcode |= ((size & 3) << 22);
  1790. Bits Op = new Bits(Opcode);
  1791. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1792. Vector128<float> V1 = MakeVectorE0(A);
  1793. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1794. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1795. AArch64.V(1, new Bits(A));
  1796. SimdFp.Uadalp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1797. Assert.Multiple(() =>
  1798. {
  1799. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1800. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1801. });
  1802. CompareAgainstUnicorn();
  1803. }
  1804. [Test, Pairwise, Description("UADALP <Vd>.<Ta>, <Vn>.<Tb>")]
  1805. public void Uadalp_V_16B8H_8H4S_4S2D([Values(0u)] uint Rd,
  1806. [Values(1u, 0u)] uint Rn,
  1807. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1808. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1809. [Values(0b00u, 0b01u, 0b10u)] uint size) // <16B8H, 8H4S, 4S2D>
  1810. {
  1811. uint Opcode = 0x6E206800; // UADALP V0.8H, V0.16B
  1812. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1813. Opcode |= ((size & 3) << 22);
  1814. Bits Op = new Bits(Opcode);
  1815. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1816. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1817. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1818. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1819. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1820. SimdFp.Uadalp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1821. Assert.Multiple(() =>
  1822. {
  1823. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1824. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1825. });
  1826. CompareAgainstUnicorn();
  1827. }
  1828. [Test, Pairwise, Description("UADDLP <Vd>.<Ta>, <Vn>.<Tb>")]
  1829. public void Uaddlp_V_8B4H_4H2S_2S1D([Values(0u)] uint Rd,
  1830. [Values(1u, 0u)] uint Rn,
  1831. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1832. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1833. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B4H, 4H2S, 2S1D>
  1834. {
  1835. uint Opcode = 0x2E202800; // UADDLP V0.4H, V0.8B
  1836. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1837. Opcode |= ((size & 3) << 22);
  1838. Bits Op = new Bits(Opcode);
  1839. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1840. Vector128<float> V1 = MakeVectorE0(A);
  1841. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1842. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1843. AArch64.V(1, new Bits(A));
  1844. SimdFp.Uaddlp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1845. Assert.Multiple(() =>
  1846. {
  1847. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1848. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1849. });
  1850. CompareAgainstUnicorn();
  1851. }
  1852. [Test, Pairwise, Description("UADDLP <Vd>.<Ta>, <Vn>.<Tb>")]
  1853. public void Uaddlp_V_16B8H_8H4S_4S2D([Values(0u)] uint Rd,
  1854. [Values(1u, 0u)] uint Rn,
  1855. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1856. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1857. [Values(0b00u, 0b01u, 0b10u)] uint size) // <16B8H, 8H4S, 4S2D>
  1858. {
  1859. uint Opcode = 0x6E202800; // UADDLP V0.8H, V0.16B
  1860. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1861. Opcode |= ((size & 3) << 22);
  1862. Bits Op = new Bits(Opcode);
  1863. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1864. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1865. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1866. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1867. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1868. SimdFp.Uaddlp_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1869. Assert.Multiple(() =>
  1870. {
  1871. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1872. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1873. });
  1874. CompareAgainstUnicorn();
  1875. }
  1876. [Test, Pairwise, Description("UQXTN <Vb><d>, <Va><n>")]
  1877. public void Uqxtn_S_HB_SH_DS([Values(0u)] uint Rd,
  1878. [Values(1u, 0u)] uint Rn,
  1879. [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong Z,
  1880. [ValueSource("_1H1S1D_")] [Random(RndCnt)] ulong A,
  1881. [Values(0b00u, 0b01u, 0b10u)] uint size) // <HB, SH, DS>
  1882. {
  1883. const int QCFlagBit = 27; // Cumulative saturation bit.
  1884. uint Opcode = 0x7E214800; // UQXTN B0, H0
  1885. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1886. Opcode |= ((size & 3) << 22);
  1887. Bits Op = new Bits(Opcode);
  1888. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1889. Vector128<float> V1 = MakeVectorE0(A);
  1890. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1891. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1892. AArch64.V(1, new Bits(A));
  1893. SimdFp.Uqxtn_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  1894. Assert.Multiple(() =>
  1895. {
  1896. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1897. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1898. });
  1899. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1900. CompareAgainstUnicorn();
  1901. }
  1902. [Test, Pairwise, Description("UQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
  1903. public void Uqxtn_V_8H8B_4S4H_2D2S([Values(0u)] uint Rd,
  1904. [Values(1u, 0u)] uint Rn,
  1905. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong Z,
  1906. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A,
  1907. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  1908. {
  1909. const int QCFlagBit = 27; // Cumulative saturation bit.
  1910. uint Opcode = 0x2E214800; // UQXTN V0.8B, V0.8H
  1911. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1912. Opcode |= ((size & 3) << 22);
  1913. Bits Op = new Bits(Opcode);
  1914. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1915. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1916. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1917. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1918. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1919. SimdFp.Uqxtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1920. Assert.Multiple(() =>
  1921. {
  1922. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1923. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1924. });
  1925. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1926. CompareAgainstUnicorn();
  1927. }
  1928. [Test, Pairwise, Description("UQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
  1929. public void Uqxtn_V_8H16B_4S8H_2D4S([Values(0u)] uint Rd,
  1930. [Values(1u, 0u)] uint Rn,
  1931. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong Z,
  1932. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A,
  1933. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  1934. {
  1935. const int QCFlagBit = 27; // Cumulative saturation bit.
  1936. uint Opcode = 0x6E214800; // UQXTN2 V0.16B, V0.8H
  1937. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1938. Opcode |= ((size & 3) << 22);
  1939. Bits Op = new Bits(Opcode);
  1940. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1941. Vector128<float> V1 = MakeVectorE0E1(A, A);
  1942. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1943. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1944. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  1945. SimdFp.Uqxtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1946. Assert.Multiple(() =>
  1947. {
  1948. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1949. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1950. });
  1951. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1952. CompareAgainstUnicorn();
  1953. }
  1954. [Test, Pairwise, Description("USQADD <V><d>, <V><n>")]
  1955. public void Usqadd_S_B_H_S_D([Values(0u)] uint Rd,
  1956. [Values(1u, 0u)] uint Rn,
  1957. [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong Z,
  1958. [ValueSource("_1B1H1S1D_")] [Random(RndCnt)] ulong A,
  1959. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <B, H, S, D>
  1960. {
  1961. const int QCFlagBit = 27; // Cumulative saturation bit.
  1962. uint Opcode = 0x7E203800; // USQADD B0, B0
  1963. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1964. Opcode |= ((size & 3) << 22);
  1965. Bits Op = new Bits(Opcode);
  1966. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1967. Vector128<float> V1 = MakeVectorE0(A);
  1968. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1969. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1970. AArch64.V(1, new Bits(A));
  1971. SimdFp.Usqadd_S(Op[23, 22], Op[9, 5], Op[4, 0]);
  1972. Assert.Multiple(() =>
  1973. {
  1974. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  1975. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  1976. });
  1977. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  1978. CompareAgainstUnicorn();
  1979. }
  1980. [Test, Pairwise, Description("USQADD <Vd>.<T>, <Vn>.<T>")]
  1981. public void Usqadd_V_8B_4H_2S([Values(0u)] uint Rd,
  1982. [Values(1u, 0u)] uint Rn,
  1983. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong Z,
  1984. [ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
  1985. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8B, 4H, 2S>
  1986. {
  1987. const int QCFlagBit = 27; // Cumulative saturation bit.
  1988. uint Opcode = 0x2E203800; // USQADD V0.8B, V0.8B
  1989. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1990. Opcode |= ((size & 3) << 22);
  1991. Bits Op = new Bits(Opcode);
  1992. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  1993. Vector128<float> V1 = MakeVectorE0(A);
  1994. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  1995. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  1996. AArch64.V(1, new Bits(A));
  1997. SimdFp.Usqadd_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  1998. Assert.Multiple(() =>
  1999. {
  2000. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  2001. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  2002. });
  2003. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  2004. CompareAgainstUnicorn();
  2005. }
  2006. [Test, Pairwise, Description("USQADD <Vd>.<T>, <Vn>.<T>")]
  2007. public void Usqadd_V_16B_8H_4S_2D([Values(0u)] uint Rd,
  2008. [Values(1u, 0u)] uint Rn,
  2009. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong Z,
  2010. [ValueSource("_8B4H2S1D_")] [Random(RndCnt)] ulong A,
  2011. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint size) // <16B, 8H, 4S, 2D>
  2012. {
  2013. const int QCFlagBit = 27; // Cumulative saturation bit.
  2014. uint Opcode = 0x6E203800; // USQADD V0.16B, V0.16B
  2015. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  2016. Opcode |= ((size & 3) << 22);
  2017. Bits Op = new Bits(Opcode);
  2018. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  2019. Vector128<float> V1 = MakeVectorE0E1(A, A);
  2020. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  2021. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  2022. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  2023. SimdFp.Usqadd_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  2024. Assert.Multiple(() =>
  2025. {
  2026. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  2027. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  2028. });
  2029. Assert.That(((ThreadState.Fpsr >> QCFlagBit) & 1) != 0, Is.EqualTo(Shared.FPSR[QCFlagBit]));
  2030. CompareAgainstUnicorn();
  2031. }
  2032. [Test, Pairwise, Description("XTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
  2033. public void Xtn_V_8H8B_4S4H_2D2S([Values(0u)] uint Rd,
  2034. [Values(1u, 0u)] uint Rn,
  2035. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong Z,
  2036. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A,
  2037. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H8B, 4S4H, 2D2S>
  2038. {
  2039. uint Opcode = 0x0E212800; // XTN V0.8B, V0.8H
  2040. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  2041. Opcode |= ((size & 3) << 22);
  2042. Bits Op = new Bits(Opcode);
  2043. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  2044. Vector128<float> V1 = MakeVectorE0E1(A, A);
  2045. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  2046. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  2047. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  2048. SimdFp.Xtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  2049. Assert.Multiple(() =>
  2050. {
  2051. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  2052. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  2053. });
  2054. CompareAgainstUnicorn();
  2055. }
  2056. [Test, Pairwise, Description("XTN{2} <Vd>.<Tb>, <Vn>.<Ta>")]
  2057. public void Xtn_V_8H16B_4S8H_2D4S([Values(0u)] uint Rd,
  2058. [Values(1u, 0u)] uint Rn,
  2059. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong Z,
  2060. [ValueSource("_4H2S1D_")] [Random(RndCnt)] ulong A,
  2061. [Values(0b00u, 0b01u, 0b10u)] uint size) // <8H16B, 4S8H, 2D4S>
  2062. {
  2063. uint Opcode = 0x4E212800; // XTN2 V0.16B, V0.8H
  2064. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  2065. Opcode |= ((size & 3) << 22);
  2066. Bits Op = new Bits(Opcode);
  2067. Vector128<float> V0 = MakeVectorE0E1(Z, Z);
  2068. Vector128<float> V1 = MakeVectorE0E1(A, A);
  2069. AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
  2070. AArch64.Vpart(0, 0, new Bits(Z)); AArch64.Vpart(0, 1, new Bits(Z));
  2071. AArch64.Vpart(1, 0, new Bits(A)); AArch64.Vpart(1, 1, new Bits(A));
  2072. SimdFp.Xtn_V(Op[30], Op[23, 22], Op[9, 5], Op[4, 0]);
  2073. Assert.Multiple(() =>
  2074. {
  2075. Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 0).ToUInt64()));
  2076. Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(AArch64.Vpart(64, 0, 1).ToUInt64()));
  2077. });
  2078. CompareAgainstUnicorn();
  2079. }
  2080. #endif
  2081. }
  2082. }