CpuTestAluRs.cs 88 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965
  1. //#define AluRs
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. using Tester;
  7. using Tester.Types;
  8. [Category("AluRs"), Ignore("Tested: second half of 2018.")]
  9. public sealed class CpuTestAluRs : CpuTest
  10. {
  11. #if AluRs
  12. [SetUp]
  13. public void SetupTester()
  14. {
  15. AArch64.TakeReset(false);
  16. }
  17. [Test, Description("ADC <Xd>, <Xn>, <Xm>")]
  18. public void Adc_64bit([Values(0u, 31u)] uint Rd,
  19. [Values(1u, 31u)] uint Rn,
  20. [Values(2u, 31u)] uint Rm,
  21. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  22. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xn,
  23. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  24. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xm,
  25. [Values] bool CarryIn)
  26. {
  27. uint Opcode = 0x9A000000; // ADC X0, X0, X0
  28. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  29. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  30. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31, Carry: CarryIn);
  31. if (Rd != 31)
  32. {
  33. Bits Op = new Bits(Opcode);
  34. AArch64.X((int)Rn, new Bits(Xn));
  35. AArch64.X((int)Rm, new Bits(Xm));
  36. Shared.PSTATE.C = CarryIn;
  37. Base.Adc(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  38. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  39. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  40. }
  41. else
  42. {
  43. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  44. }
  45. CompareAgainstUnicorn();
  46. }
  47. [Test, Description("ADC <Wd>, <Wn>, <Wm>")]
  48. public void Adc_32bit([Values(0u, 31u)] uint Rd,
  49. [Values(1u, 31u)] uint Rn,
  50. [Values(2u, 31u)] uint Rm,
  51. [Values(0x00000000u, 0x7FFFFFFFu,
  52. 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wn,
  53. [Values(0x00000000u, 0x7FFFFFFFu,
  54. 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wm,
  55. [Values] bool CarryIn)
  56. {
  57. uint Opcode = 0x1A000000; // ADC W0, W0, W0
  58. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  59. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  60. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31, Carry: CarryIn);
  61. if (Rd != 31)
  62. {
  63. Bits Op = new Bits(Opcode);
  64. AArch64.X((int)Rn, new Bits(Wn));
  65. AArch64.X((int)Rm, new Bits(Wm));
  66. Shared.PSTATE.C = CarryIn;
  67. Base.Adc(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  68. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  69. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  70. }
  71. else
  72. {
  73. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  74. }
  75. CompareAgainstUnicorn();
  76. }
  77. [Test, Description("ADCS <Xd>, <Xn>, <Xm>")]
  78. public void Adcs_64bit([Values(0u, 31u)] uint Rd,
  79. [Values(1u, 31u)] uint Rn,
  80. [Values(2u, 31u)] uint Rm,
  81. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  82. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xn,
  83. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  84. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xm,
  85. [Values] bool CarryIn)
  86. {
  87. uint Opcode = 0xBA000000; // ADCS X0, X0, X0
  88. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  89. Bits Op = new Bits(Opcode);
  90. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  91. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31, Carry: CarryIn);
  92. AArch64.X((int)Rn, new Bits(Xn));
  93. AArch64.X((int)Rm, new Bits(Xm));
  94. Shared.PSTATE.C = CarryIn;
  95. Base.Adcs(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  96. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  97. if (Rd != 31)
  98. {
  99. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  100. }
  101. else
  102. {
  103. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  104. }
  105. Assert.Multiple(() =>
  106. {
  107. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  108. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  109. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  110. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  111. });
  112. CompareAgainstUnicorn();
  113. }
  114. [Test, Description("ADCS <Wd>, <Wn>, <Wm>")]
  115. public void Adcs_32bit([Values(0u, 31u)] uint Rd,
  116. [Values(1u, 31u)] uint Rn,
  117. [Values(2u, 31u)] uint Rm,
  118. [Values(0x00000000u, 0x7FFFFFFFu,
  119. 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wn,
  120. [Values(0x00000000u, 0x7FFFFFFFu,
  121. 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wm,
  122. [Values] bool CarryIn)
  123. {
  124. uint Opcode = 0x3A000000; // ADCS W0, W0, W0
  125. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  126. Bits Op = new Bits(Opcode);
  127. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  128. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31, Carry: CarryIn);
  129. AArch64.X((int)Rn, new Bits(Wn));
  130. AArch64.X((int)Rm, new Bits(Wm));
  131. Shared.PSTATE.C = CarryIn;
  132. Base.Adcs(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  133. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  134. if (Rd != 31)
  135. {
  136. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  137. }
  138. else
  139. {
  140. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  141. }
  142. Assert.Multiple(() =>
  143. {
  144. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  145. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  146. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  147. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  148. });
  149. CompareAgainstUnicorn();
  150. }
  151. [Test, Description("ADD <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  152. public void Add_64bit([Values(0u, 31u)] uint Rd,
  153. [Values(1u, 31u)] uint Rn,
  154. [Values(2u, 31u)] uint Rm,
  155. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  156. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  157. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  158. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  159. [Values(0b00u, 0b01u, 0b10u)] uint shift, // <LSL, LSR, ASR>
  160. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  161. {
  162. uint Opcode = 0x8B000000; // ADD X0, X0, X0, LSL #0
  163. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  164. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  165. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  166. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  167. if (Rd != 31)
  168. {
  169. Bits Op = new Bits(Opcode);
  170. AArch64.X((int)Rn, new Bits(Xn));
  171. AArch64.X((int)Rm, new Bits(Xm));
  172. Base.Add_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  173. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  174. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  175. }
  176. else
  177. {
  178. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  179. }
  180. CompareAgainstUnicorn();
  181. }
  182. [Test, Description("ADD <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  183. public void Add_32bit([Values(0u, 31u)] uint Rd,
  184. [Values(1u, 31u)] uint Rn,
  185. [Values(2u, 31u)] uint Rm,
  186. [Values(0x00000000u, 0x7FFFFFFFu,
  187. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  188. [Values(0x00000000u, 0x7FFFFFFFu,
  189. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  190. [Values(0b00u, 0b01u, 0b10u)] uint shift, // <LSL, LSR, ASR>
  191. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  192. {
  193. uint Opcode = 0x0B000000; // ADD W0, W0, W0, LSL #0
  194. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  195. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  196. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  197. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  198. if (Rd != 31)
  199. {
  200. Bits Op = new Bits(Opcode);
  201. AArch64.X((int)Rn, new Bits(Wn));
  202. AArch64.X((int)Rm, new Bits(Wm));
  203. Base.Add_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  204. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  205. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  206. }
  207. else
  208. {
  209. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  210. CompareAgainstUnicorn();
  211. }
  212. }
  213. [Test, Description("ADDS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  214. public void Adds_64bit([Values(0u, 31u)] uint Rd,
  215. [Values(1u, 31u)] uint Rn,
  216. [Values(2u, 31u)] uint Rm,
  217. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  218. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  219. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  220. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  221. [Values(0b00u, 0b01u, 0b10u)] uint shift, // <LSL, LSR, ASR>
  222. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  223. {
  224. uint Opcode = 0xAB000000; // ADDS X0, X0, X0, LSL #0
  225. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  226. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  227. Bits Op = new Bits(Opcode);
  228. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  229. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  230. AArch64.X((int)Rn, new Bits(Xn));
  231. AArch64.X((int)Rm, new Bits(Xm));
  232. Base.Adds_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  233. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  234. if (Rd != 31)
  235. {
  236. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  237. }
  238. else
  239. {
  240. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  241. }
  242. Assert.Multiple(() =>
  243. {
  244. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  245. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  246. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  247. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  248. });
  249. CompareAgainstUnicorn();
  250. }
  251. [Test, Description("ADDS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  252. public void Adds_32bit([Values(0u, 31u)] uint Rd,
  253. [Values(1u, 31u)] uint Rn,
  254. [Values(2u, 31u)] uint Rm,
  255. [Values(0x00000000u, 0x7FFFFFFFu,
  256. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  257. [Values(0x00000000u, 0x7FFFFFFFu,
  258. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  259. [Values(0b00u, 0b01u, 0b10u)] uint shift, // <LSL, LSR, ASR>
  260. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  261. {
  262. uint Opcode = 0x2B000000; // ADDS W0, W0, W0, LSL #0
  263. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  264. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  265. Bits Op = new Bits(Opcode);
  266. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  267. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  268. AArch64.X((int)Rn, new Bits(Wn));
  269. AArch64.X((int)Rm, new Bits(Wm));
  270. Base.Adds_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  271. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  272. if (Rd != 31)
  273. {
  274. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  275. }
  276. else
  277. {
  278. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  279. }
  280. Assert.Multiple(() =>
  281. {
  282. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  283. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  284. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  285. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  286. });
  287. CompareAgainstUnicorn();
  288. }
  289. [Test, Description("AND <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  290. public void And_64bit([Values(0u, 31u)] uint Rd,
  291. [Values(1u, 31u)] uint Rn,
  292. [Values(2u, 31u)] uint Rm,
  293. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  294. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  295. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  296. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  297. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  298. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  299. {
  300. uint Opcode = 0x8A000000; // AND X0, X0, X0, LSL #0
  301. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  302. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  303. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  304. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  305. if (Rd != 31)
  306. {
  307. Bits Op = new Bits(Opcode);
  308. AArch64.X((int)Rn, new Bits(Xn));
  309. AArch64.X((int)Rm, new Bits(Xm));
  310. Base.And_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  311. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  312. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  313. }
  314. else
  315. {
  316. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  317. }
  318. CompareAgainstUnicorn();
  319. }
  320. [Test, Description("AND <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  321. public void And_32bit([Values(0u, 31u)] uint Rd,
  322. [Values(1u, 31u)] uint Rn,
  323. [Values(2u, 31u)] uint Rm,
  324. [Values(0x00000000u, 0x7FFFFFFFu,
  325. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  326. [Values(0x00000000u, 0x7FFFFFFFu,
  327. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  328. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  329. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  330. {
  331. uint Opcode = 0x0A000000; // AND W0, W0, W0, LSL #0
  332. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  333. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  334. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  335. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  336. if (Rd != 31)
  337. {
  338. Bits Op = new Bits(Opcode);
  339. AArch64.X((int)Rn, new Bits(Wn));
  340. AArch64.X((int)Rm, new Bits(Wm));
  341. Base.And_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  342. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  343. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  344. }
  345. else
  346. {
  347. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  348. }
  349. CompareAgainstUnicorn();
  350. }
  351. [Test, Description("ANDS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  352. public void Ands_64bit([Values(0u, 31u)] uint Rd,
  353. [Values(1u, 31u)] uint Rn,
  354. [Values(2u, 31u)] uint Rm,
  355. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  356. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  357. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  358. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  359. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  360. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  361. {
  362. uint Opcode = 0xEA000000; // ANDS X0, X0, X0, LSL #0
  363. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  364. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  365. Bits Op = new Bits(Opcode);
  366. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  367. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  368. AArch64.X((int)Rn, new Bits(Xn));
  369. AArch64.X((int)Rm, new Bits(Xm));
  370. Base.Ands_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  371. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  372. if (Rd != 31)
  373. {
  374. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  375. }
  376. else
  377. {
  378. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  379. }
  380. Assert.Multiple(() =>
  381. {
  382. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  383. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  384. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  385. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  386. });
  387. CompareAgainstUnicorn();
  388. }
  389. [Test, Description("ANDS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  390. public void Ands_32bit([Values(0u, 31u)] uint Rd,
  391. [Values(1u, 31u)] uint Rn,
  392. [Values(2u, 31u)] uint Rm,
  393. [Values(0x00000000u, 0x7FFFFFFFu,
  394. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  395. [Values(0x00000000u, 0x7FFFFFFFu,
  396. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  397. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  398. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  399. {
  400. uint Opcode = 0x6A000000; // ANDS W0, W0, W0, LSL #0
  401. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  402. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  403. Bits Op = new Bits(Opcode);
  404. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  405. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  406. AArch64.X((int)Rn, new Bits(Wn));
  407. AArch64.X((int)Rm, new Bits(Wm));
  408. Base.Ands_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  409. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  410. if (Rd != 31)
  411. {
  412. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  413. }
  414. else
  415. {
  416. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  417. }
  418. Assert.Multiple(() =>
  419. {
  420. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  421. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  422. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  423. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  424. });
  425. CompareAgainstUnicorn();
  426. }
  427. [Test, Description("ASRV <Xd>, <Xn>, <Xm>")]
  428. public void Asrv_64bit([Values(0u, 31u)] uint Rd,
  429. [Values(1u, 31u)] uint Rn,
  430. [Values(2u, 31u)] uint Rm,
  431. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  432. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn,
  433. [Values(0ul, 31ul, 32ul, 63ul, 0x7FFFFFFFFFFFFFFFul,
  434. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(5)] ulong Xm)
  435. {
  436. uint Opcode = 0x9AC02800; // ASRV X0, X0, X0
  437. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  438. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  439. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  440. if (Rd != 31)
  441. {
  442. Bits Op = new Bits(Opcode);
  443. AArch64.X((int)Rn, new Bits(Xn));
  444. AArch64.X((int)Rm, new Bits(Xm));
  445. Base.Asrv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  446. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  447. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  448. }
  449. else
  450. {
  451. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  452. }
  453. CompareAgainstUnicorn();
  454. }
  455. [Test, Description("ASRV <Wd>, <Wn>, <Wm>")]
  456. public void Asrv_32bit([Values(0u, 31u)] uint Rd,
  457. [Values(1u, 31u)] uint Rn,
  458. [Values(2u, 31u)] uint Rm,
  459. [Values(0x00000000u, 0x7FFFFFFFu,
  460. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn,
  461. [Values(0u, 15u, 16u, 31u, 0x7FFFFFFFu,
  462. 0x80000000u, 0xFFFFFFFFu)] [Random(5)] uint Wm)
  463. {
  464. uint Opcode = 0x1AC02800; // ASRV W0, W0, W0
  465. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  466. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  467. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  468. if (Rd != 31)
  469. {
  470. Bits Op = new Bits(Opcode);
  471. AArch64.X((int)Rn, new Bits(Wn));
  472. AArch64.X((int)Rm, new Bits(Wm));
  473. Base.Asrv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  474. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  475. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  476. }
  477. else
  478. {
  479. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  480. }
  481. CompareAgainstUnicorn();
  482. }
  483. [Test, Description("BIC <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  484. public void Bic_64bit([Values(0u, 31u)] uint Rd,
  485. [Values(1u, 31u)] uint Rn,
  486. [Values(2u, 31u)] uint Rm,
  487. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  488. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  489. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  490. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  491. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  492. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  493. {
  494. uint Opcode = 0x8A200000; // BIC X0, X0, X0, LSL #0
  495. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  496. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  497. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  498. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  499. if (Rd != 31)
  500. {
  501. Bits Op = new Bits(Opcode);
  502. AArch64.X((int)Rn, new Bits(Xn));
  503. AArch64.X((int)Rm, new Bits(Xm));
  504. Base.Bic(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  505. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  506. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  507. }
  508. else
  509. {
  510. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  511. }
  512. CompareAgainstUnicorn();
  513. }
  514. [Test, Description("BIC <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  515. public void Bic_32bit([Values(0u, 31u)] uint Rd,
  516. [Values(1u, 31u)] uint Rn,
  517. [Values(2u, 31u)] uint Rm,
  518. [Values(0x00000000u, 0x7FFFFFFFu,
  519. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  520. [Values(0x00000000u, 0x7FFFFFFFu,
  521. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  522. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  523. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  524. {
  525. uint Opcode = 0x0A200000; // BIC W0, W0, W0, LSL #0
  526. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  527. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  528. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  529. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  530. if (Rd != 31)
  531. {
  532. Bits Op = new Bits(Opcode);
  533. AArch64.X((int)Rn, new Bits(Wn));
  534. AArch64.X((int)Rm, new Bits(Wm));
  535. Base.Bic(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  536. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  537. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  538. }
  539. else
  540. {
  541. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  542. }
  543. CompareAgainstUnicorn();
  544. }
  545. [Test, Description("BICS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  546. public void Bics_64bit([Values(0u, 31u)] uint Rd,
  547. [Values(1u, 31u)] uint Rn,
  548. [Values(2u, 31u)] uint Rm,
  549. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  550. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  551. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  552. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  553. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  554. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  555. {
  556. uint Opcode = 0xEA200000; // BICS X0, X0, X0, LSL #0
  557. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  558. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  559. Bits Op = new Bits(Opcode);
  560. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  561. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  562. AArch64.X((int)Rn, new Bits(Xn));
  563. AArch64.X((int)Rm, new Bits(Xm));
  564. Base.Bics(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  565. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  566. if (Rd != 31)
  567. {
  568. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  569. }
  570. else
  571. {
  572. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  573. }
  574. Assert.Multiple(() =>
  575. {
  576. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  577. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  578. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  579. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  580. });
  581. CompareAgainstUnicorn();
  582. }
  583. [Test, Description("BICS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  584. public void Bics_32bit([Values(0u, 31u)] uint Rd,
  585. [Values(1u, 31u)] uint Rn,
  586. [Values(2u, 31u)] uint Rm,
  587. [Values(0x00000000u, 0x7FFFFFFFu,
  588. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  589. [Values(0x00000000u, 0x7FFFFFFFu,
  590. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  591. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  592. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  593. {
  594. uint Opcode = 0x6A200000; // BICS W0, W0, W0, LSL #0
  595. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  596. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  597. Bits Op = new Bits(Opcode);
  598. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  599. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  600. AArch64.X((int)Rn, new Bits(Wn));
  601. AArch64.X((int)Rm, new Bits(Wm));
  602. Base.Bics(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  603. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  604. if (Rd != 31)
  605. {
  606. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  607. }
  608. else
  609. {
  610. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  611. }
  612. Assert.Multiple(() =>
  613. {
  614. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  615. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  616. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  617. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  618. });
  619. CompareAgainstUnicorn();
  620. }
  621. [Test, Description("CRC32X <Wd>, <Wn>, <Xm>")]
  622. public void Crc32x([Values(0u, 31u)] uint Rd,
  623. [Values(1u, 31u)] uint Rn,
  624. [Values(2u, 31u)] uint Rm,
  625. [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  626. [Values((ulong)0x00_00_00_00_00_00_00_00,
  627. (ulong)0x7F_FF_FF_FF_FF_FF_FF_FF,
  628. (ulong)0x80_00_00_00_00_00_00_00,
  629. (ulong)0xFF_FF_FF_FF_FF_FF_FF_FF)] [Random(64)] ulong Xm)
  630. {
  631. uint Opcode = 0x9AC04C00; // CRC32X W0, W0, X0
  632. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  633. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  634. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Xm, X31: _W31);
  635. if (Rd != 31)
  636. {
  637. Bits Op = new Bits(Opcode);
  638. AArch64.X((int)Rn, new Bits(Wn));
  639. AArch64.X((int)Rm, new Bits(Xm));
  640. Base.Crc32(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]);
  641. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  642. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  643. }
  644. else
  645. {
  646. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  647. }
  648. CompareAgainstUnicorn();
  649. }
  650. [Test, Description("CRC32W <Wd>, <Wn>, <Wm>")]
  651. public void Crc32w([Values(0u, 31u)] uint Rd,
  652. [Values(1u, 31u)] uint Rn,
  653. [Values(2u, 31u)] uint Rm,
  654. [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  655. [Values((uint)0x00_00_00_00, (uint)0x7F_FF_FF_FF,
  656. (uint)0x80_00_00_00, (uint)0xFF_FF_FF_FF)] [Random(64)] uint Wm)
  657. {
  658. uint Opcode = 0x1AC04800; // CRC32W W0, W0, W0
  659. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  660. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  661. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  662. if (Rd != 31)
  663. {
  664. Bits Op = new Bits(Opcode);
  665. AArch64.X((int)Rn, new Bits(Wn));
  666. AArch64.X((int)Rm, new Bits(Wm));
  667. Base.Crc32(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]);
  668. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  669. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  670. }
  671. else
  672. {
  673. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  674. }
  675. CompareAgainstUnicorn();
  676. }
  677. [Test, Description("CRC32H <Wd>, <Wn>, <Wm>")]
  678. public void Crc32h([Values(0u, 31u)] uint Rd,
  679. [Values(1u, 31u)] uint Rn,
  680. [Values(2u, 31u)] uint Rm,
  681. [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  682. [Values((ushort)0x00_00, (ushort)0x7F_FF,
  683. (ushort)0x80_00, (ushort)0xFF_FF)] [Random(64)] ushort Wm)
  684. {
  685. uint Opcode = 0x1AC04400; // CRC32H W0, W0, W0
  686. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  687. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  688. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  689. if (Rd != 31)
  690. {
  691. Bits Op = new Bits(Opcode);
  692. AArch64.X((int)Rn, new Bits(Wn));
  693. AArch64.X((int)Rm, new Bits(Wm));
  694. Base.Crc32(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]);
  695. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  696. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  697. }
  698. else
  699. {
  700. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  701. }
  702. CompareAgainstUnicorn();
  703. }
  704. [Test, Description("CRC32B <Wd>, <Wn>, <Wm>")]
  705. public void Crc32b([Values(0u, 31u)] uint Rd,
  706. [Values(1u, 31u)] uint Rn,
  707. [Values(2u, 31u)] uint Rm,
  708. [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  709. [Values((byte)0x00, (byte)0x7F,
  710. (byte)0x80, (byte)0xFF)] [Random(64)] byte Wm)
  711. {
  712. uint Opcode = 0x1AC04000; // CRC32B W0, W0, W0
  713. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  714. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  715. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  716. if (Rd != 31)
  717. {
  718. Bits Op = new Bits(Opcode);
  719. AArch64.X((int)Rn, new Bits(Wn));
  720. AArch64.X((int)Rm, new Bits(Wm));
  721. Base.Crc32(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]);
  722. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  723. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  724. }
  725. else
  726. {
  727. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  728. }
  729. CompareAgainstUnicorn();
  730. }
  731. [Test, Description("CRC32CX <Wd>, <Wn>, <Xm>")]
  732. public void Crc32cx([Values(0u, 31u)] uint Rd,
  733. [Values(1u, 31u)] uint Rn,
  734. [Values(2u, 31u)] uint Rm,
  735. [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  736. [Values((ulong)0x00_00_00_00_00_00_00_00,
  737. (ulong)0x7F_FF_FF_FF_FF_FF_FF_FF,
  738. (ulong)0x80_00_00_00_00_00_00_00,
  739. (ulong)0xFF_FF_FF_FF_FF_FF_FF_FF)] [Random(64)] ulong Xm)
  740. {
  741. uint Opcode = 0x9AC05C00; // CRC32CX W0, W0, X0
  742. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  743. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  744. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Xm, X31: _W31);
  745. if (Rd != 31)
  746. {
  747. Bits Op = new Bits(Opcode);
  748. AArch64.X((int)Rn, new Bits(Wn));
  749. AArch64.X((int)Rm, new Bits(Xm));
  750. Base.Crc32c(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]);
  751. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  752. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  753. }
  754. else
  755. {
  756. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  757. }
  758. CompareAgainstUnicorn();
  759. }
  760. [Test, Description("CRC32CW <Wd>, <Wn>, <Wm>")]
  761. public void Crc32cw([Values(0u, 31u)] uint Rd,
  762. [Values(1u, 31u)] uint Rn,
  763. [Values(2u, 31u)] uint Rm,
  764. [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  765. [Values((uint)0x00_00_00_00, (uint)0x7F_FF_FF_FF,
  766. (uint)0x80_00_00_00, (uint)0xFF_FF_FF_FF)] [Random(64)] uint Wm)
  767. {
  768. uint Opcode = 0x1AC05800; // CRC32CW W0, W0, W0
  769. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  770. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  771. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  772. if (Rd != 31)
  773. {
  774. Bits Op = new Bits(Opcode);
  775. AArch64.X((int)Rn, new Bits(Wn));
  776. AArch64.X((int)Rm, new Bits(Wm));
  777. Base.Crc32c(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]);
  778. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  779. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  780. }
  781. else
  782. {
  783. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  784. }
  785. CompareAgainstUnicorn();
  786. }
  787. [Test, Description("CRC32CH <Wd>, <Wn>, <Wm>")]
  788. public void Crc32ch([Values(0u, 31u)] uint Rd,
  789. [Values(1u, 31u)] uint Rn,
  790. [Values(2u, 31u)] uint Rm,
  791. [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  792. [Values((ushort)0x00_00, (ushort)0x7F_FF,
  793. (ushort)0x80_00, (ushort)0xFF_FF)] [Random(64)] ushort Wm)
  794. {
  795. uint Opcode = 0x1AC05400; // CRC32CH W0, W0, W0
  796. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  797. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  798. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  799. if (Rd != 31)
  800. {
  801. Bits Op = new Bits(Opcode);
  802. AArch64.X((int)Rn, new Bits(Wn));
  803. AArch64.X((int)Rm, new Bits(Wm));
  804. Base.Crc32c(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]);
  805. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  806. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  807. }
  808. else
  809. {
  810. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  811. }
  812. CompareAgainstUnicorn();
  813. }
  814. [Test, Description("CRC32CB <Wd>, <Wn>, <Wm>")]
  815. public void Crc32cb([Values(0u, 31u)] uint Rd,
  816. [Values(1u, 31u)] uint Rn,
  817. [Values(2u, 31u)] uint Rm,
  818. [Values(0x00000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  819. [Values((byte)0x00, (byte)0x7F,
  820. (byte)0x80, (byte)0xFF)] [Random(64)] byte Wm)
  821. {
  822. uint Opcode = 0x1AC05000; // CRC32CB W0, W0, W0
  823. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  824. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  825. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  826. if (Rd != 31)
  827. {
  828. Bits Op = new Bits(Opcode);
  829. AArch64.X((int)Rn, new Bits(Wn));
  830. AArch64.X((int)Rm, new Bits(Wm));
  831. Base.Crc32c(Op[31], Op[20, 16], Op[11, 10], Op[9, 5], Op[4, 0]);
  832. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  833. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  834. }
  835. else
  836. {
  837. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  838. }
  839. CompareAgainstUnicorn();
  840. }
  841. [Test, Description("EON <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  842. public void Eon_64bit([Values(0u, 31u)] uint Rd,
  843. [Values(1u, 31u)] uint Rn,
  844. [Values(2u, 31u)] uint Rm,
  845. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  846. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  847. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  848. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  849. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  850. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  851. {
  852. uint Opcode = 0xCA200000; // EON X0, X0, X0, LSL #0
  853. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  854. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  855. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  856. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  857. if (Rd != 31)
  858. {
  859. Bits Op = new Bits(Opcode);
  860. AArch64.X((int)Rn, new Bits(Xn));
  861. AArch64.X((int)Rm, new Bits(Xm));
  862. Base.Eon(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  863. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  864. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  865. }
  866. else
  867. {
  868. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  869. }
  870. CompareAgainstUnicorn();
  871. }
  872. [Test, Description("EON <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  873. public void Eon_32bit([Values(0u, 31u)] uint Rd,
  874. [Values(1u, 31u)] uint Rn,
  875. [Values(2u, 31u)] uint Rm,
  876. [Values(0x00000000u, 0x7FFFFFFFu,
  877. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  878. [Values(0x00000000u, 0x7FFFFFFFu,
  879. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  880. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  881. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  882. {
  883. uint Opcode = 0x4A200000; // EON W0, W0, W0, LSL #0
  884. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  885. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  886. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  887. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  888. if (Rd != 31)
  889. {
  890. Bits Op = new Bits(Opcode);
  891. AArch64.X((int)Rn, new Bits(Wn));
  892. AArch64.X((int)Rm, new Bits(Wm));
  893. Base.Eon(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  894. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  895. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  896. }
  897. else
  898. {
  899. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  900. }
  901. CompareAgainstUnicorn();
  902. }
  903. [Test, Description("EOR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  904. public void Eor_64bit([Values(0u, 31u)] uint Rd,
  905. [Values(1u, 31u)] uint Rn,
  906. [Values(2u, 31u)] uint Rm,
  907. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  908. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  909. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  910. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  911. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  912. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  913. {
  914. uint Opcode = 0xCA000000; // EOR X0, X0, X0, LSL #0
  915. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  916. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  917. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  918. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  919. if (Rd != 31)
  920. {
  921. Bits Op = new Bits(Opcode);
  922. AArch64.X((int)Rn, new Bits(Xn));
  923. AArch64.X((int)Rm, new Bits(Xm));
  924. Base.Eor_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  925. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  926. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  927. }
  928. else
  929. {
  930. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  931. }
  932. CompareAgainstUnicorn();
  933. }
  934. [Test, Description("EOR <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  935. public void Eor_32bit([Values(0u, 31u)] uint Rd,
  936. [Values(1u, 31u)] uint Rn,
  937. [Values(2u, 31u)] uint Rm,
  938. [Values(0x00000000u, 0x7FFFFFFFu,
  939. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  940. [Values(0x00000000u, 0x7FFFFFFFu,
  941. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  942. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  943. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  944. {
  945. uint Opcode = 0x4A000000; // EOR W0, W0, W0, LSL #0
  946. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  947. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  948. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  949. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  950. if (Rd != 31)
  951. {
  952. Bits Op = new Bits(Opcode);
  953. AArch64.X((int)Rn, new Bits(Wn));
  954. AArch64.X((int)Rm, new Bits(Wm));
  955. Base.Eor_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  956. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  957. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  958. }
  959. else
  960. {
  961. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  962. }
  963. CompareAgainstUnicorn();
  964. }
  965. [Test, Description("EXTR <Xd>, <Xn>, <Xm>, #<lsb>")]
  966. public void Extr_64bit([Values(0u, 31u)] uint Rd,
  967. [Values(1u, 31u)] uint Rn,
  968. [Values(2u, 31u)] uint Rm,
  969. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  970. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  971. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  972. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm,
  973. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint lsb)
  974. {
  975. uint Opcode = 0x93C00000; // EXTR X0, X0, X0, #0
  976. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  977. Opcode |= ((lsb & 63) << 10);
  978. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  979. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  980. if (Rd != 31)
  981. {
  982. Bits Op = new Bits(Opcode);
  983. AArch64.X((int)Rn, new Bits(Xn));
  984. AArch64.X((int)Rm, new Bits(Xm));
  985. Base.Extr(Op[31], Op[22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  986. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  987. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  988. }
  989. else
  990. {
  991. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  992. }
  993. CompareAgainstUnicorn();
  994. }
  995. [Test, Description("EXTR <Wd>, <Wn>, <Wm>, #<lsb>")]
  996. public void Extr_32bit([Values(0u, 31u)] uint Rd,
  997. [Values(1u, 31u)] uint Rn,
  998. [Values(2u, 31u)] uint Rm,
  999. [Values(0x00000000u, 0x7FFFFFFFu,
  1000. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  1001. [Values(0x00000000u, 0x7FFFFFFFu,
  1002. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
  1003. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint lsb)
  1004. {
  1005. uint Opcode = 0x13800000; // EXTR W0, W0, W0, #0
  1006. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1007. Opcode |= ((lsb & 63) << 10);
  1008. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1009. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1010. if (Rd != 31)
  1011. {
  1012. Bits Op = new Bits(Opcode);
  1013. AArch64.X((int)Rn, new Bits(Wn));
  1014. AArch64.X((int)Rm, new Bits(Wm));
  1015. Base.Extr(Op[31], Op[22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1016. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1017. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1018. }
  1019. else
  1020. {
  1021. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1022. }
  1023. CompareAgainstUnicorn();
  1024. }
  1025. [Test, Description("LSLV <Xd>, <Xn>, <Xm>")]
  1026. public void Lslv_64bit([Values(0u, 31u)] uint Rd,
  1027. [Values(1u, 31u)] uint Rn,
  1028. [Values(2u, 31u)] uint Rm,
  1029. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1030. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn,
  1031. [Values(0ul, 31ul, 32ul, 63ul, 0x7FFFFFFFFFFFFFFFul,
  1032. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(5)] ulong Xm)
  1033. {
  1034. uint Opcode = 0x9AC02000; // LSLV X0, X0, X0
  1035. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1036. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1037. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1038. if (Rd != 31)
  1039. {
  1040. Bits Op = new Bits(Opcode);
  1041. AArch64.X((int)Rn, new Bits(Xn));
  1042. AArch64.X((int)Rm, new Bits(Xm));
  1043. Base.Lslv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1044. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1045. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1046. }
  1047. else
  1048. {
  1049. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1050. }
  1051. CompareAgainstUnicorn();
  1052. }
  1053. [Test, Description("LSLV <Wd>, <Wn>, <Wm>")]
  1054. public void Lslv_32bit([Values(0u, 31u)] uint Rd,
  1055. [Values(1u, 31u)] uint Rn,
  1056. [Values(2u, 31u)] uint Rm,
  1057. [Values(0x00000000u, 0x7FFFFFFFu,
  1058. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn,
  1059. [Values(0u, 15u, 16u, 31u, 0x7FFFFFFFu,
  1060. 0x80000000u, 0xFFFFFFFFu)] [Random(5)] uint Wm)
  1061. {
  1062. uint Opcode = 0x1AC02000; // LSLV W0, W0, W0
  1063. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1064. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1065. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1066. if (Rd != 31)
  1067. {
  1068. Bits Op = new Bits(Opcode);
  1069. AArch64.X((int)Rn, new Bits(Wn));
  1070. AArch64.X((int)Rm, new Bits(Wm));
  1071. Base.Lslv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1072. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1073. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1074. }
  1075. else
  1076. {
  1077. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1078. }
  1079. CompareAgainstUnicorn();
  1080. }
  1081. [Test, Description("LSRV <Xd>, <Xn>, <Xm>")]
  1082. public void Lsrv_64bit([Values(0u, 31u)] uint Rd,
  1083. [Values(1u, 31u)] uint Rn,
  1084. [Values(2u, 31u)] uint Rm,
  1085. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1086. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn,
  1087. [Values(0ul, 31ul, 32ul, 63ul, 0x7FFFFFFFFFFFFFFFul,
  1088. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(5)] ulong Xm)
  1089. {
  1090. uint Opcode = 0x9AC02400; // LSRV X0, X0, X0
  1091. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1092. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1093. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1094. if (Rd != 31)
  1095. {
  1096. Bits Op = new Bits(Opcode);
  1097. AArch64.X((int)Rn, new Bits(Xn));
  1098. AArch64.X((int)Rm, new Bits(Xm));
  1099. Base.Lsrv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1100. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1101. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1102. }
  1103. else
  1104. {
  1105. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1106. }
  1107. CompareAgainstUnicorn();
  1108. }
  1109. [Test, Description("LSRV <Wd>, <Wn>, <Wm>")]
  1110. public void Lsrv_32bit([Values(0u, 31u)] uint Rd,
  1111. [Values(1u, 31u)] uint Rn,
  1112. [Values(2u, 31u)] uint Rm,
  1113. [Values(0x00000000u, 0x7FFFFFFFu,
  1114. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn,
  1115. [Values(0u, 15u, 16u, 31u, 0x7FFFFFFFu,
  1116. 0x80000000u, 0xFFFFFFFFu)] [Random(5)] uint Wm)
  1117. {
  1118. uint Opcode = 0x1AC02400; // LSRV W0, W0, W0
  1119. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1120. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1121. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1122. if (Rd != 31)
  1123. {
  1124. Bits Op = new Bits(Opcode);
  1125. AArch64.X((int)Rn, new Bits(Wn));
  1126. AArch64.X((int)Rm, new Bits(Wm));
  1127. Base.Lsrv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1128. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1129. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1130. }
  1131. else
  1132. {
  1133. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1134. }
  1135. CompareAgainstUnicorn();
  1136. }
  1137. [Test, Description("ORN <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  1138. public void Orn_64bit([Values(0u, 31u)] uint Rd,
  1139. [Values(1u, 31u)] uint Rn,
  1140. [Values(2u, 31u)] uint Rm,
  1141. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1142. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  1143. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1144. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  1145. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  1146. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  1147. {
  1148. uint Opcode = 0xAA200000; // ORN X0, X0, X0, LSL #0
  1149. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1150. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  1151. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1152. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1153. if (Rd != 31)
  1154. {
  1155. Bits Op = new Bits(Opcode);
  1156. AArch64.X((int)Rn, new Bits(Xn));
  1157. AArch64.X((int)Rm, new Bits(Xm));
  1158. Base.Orn(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1159. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1160. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1161. }
  1162. else
  1163. {
  1164. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1165. }
  1166. CompareAgainstUnicorn();
  1167. }
  1168. [Test, Description("ORN <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  1169. public void Orn_32bit([Values(0u, 31u)] uint Rd,
  1170. [Values(1u, 31u)] uint Rn,
  1171. [Values(2u, 31u)] uint Rm,
  1172. [Values(0x00000000u, 0x7FFFFFFFu,
  1173. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  1174. [Values(0x00000000u, 0x7FFFFFFFu,
  1175. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  1176. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  1177. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  1178. {
  1179. uint Opcode = 0x2A200000; // ORN W0, W0, W0, LSL #0
  1180. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1181. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  1182. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1183. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1184. if (Rd != 31)
  1185. {
  1186. Bits Op = new Bits(Opcode);
  1187. AArch64.X((int)Rn, new Bits(Wn));
  1188. AArch64.X((int)Rm, new Bits(Wm));
  1189. Base.Orn(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1190. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1191. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1192. }
  1193. else
  1194. {
  1195. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1196. }
  1197. CompareAgainstUnicorn();
  1198. }
  1199. [Test, Description("ORR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  1200. public void Orr_64bit([Values(0u, 31u)] uint Rd,
  1201. [Values(1u, 31u)] uint Rn,
  1202. [Values(2u, 31u)] uint Rm,
  1203. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1204. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  1205. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1206. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  1207. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  1208. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  1209. {
  1210. uint Opcode = 0xAA000000; // ORR X0, X0, X0, LSL #0
  1211. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1212. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  1213. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1214. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1215. if (Rd != 31)
  1216. {
  1217. Bits Op = new Bits(Opcode);
  1218. AArch64.X((int)Rn, new Bits(Xn));
  1219. AArch64.X((int)Rm, new Bits(Xm));
  1220. Base.Orr_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1221. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1222. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1223. }
  1224. else
  1225. {
  1226. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1227. }
  1228. CompareAgainstUnicorn();
  1229. }
  1230. [Test, Description("ORR <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  1231. public void Orr_32bit([Values(0u, 31u)] uint Rd,
  1232. [Values(1u, 31u)] uint Rn,
  1233. [Values(2u, 31u)] uint Rm,
  1234. [Values(0x00000000u, 0x7FFFFFFFu,
  1235. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  1236. [Values(0x00000000u, 0x7FFFFFFFu,
  1237. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  1238. [Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
  1239. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  1240. {
  1241. uint Opcode = 0x2A000000; // ORR W0, W0, W0, LSL #0
  1242. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1243. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  1244. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1245. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1246. if (Rd != 31)
  1247. {
  1248. Bits Op = new Bits(Opcode);
  1249. AArch64.X((int)Rn, new Bits(Wn));
  1250. AArch64.X((int)Rm, new Bits(Wm));
  1251. Base.Orr_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1252. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1253. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1254. }
  1255. else
  1256. {
  1257. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1258. }
  1259. CompareAgainstUnicorn();
  1260. }
  1261. [Test, Description("RORV <Xd>, <Xn>, <Xm>")]
  1262. public void Rorv_64bit([Values(0u, 31u)] uint Rd,
  1263. [Values(1u, 31u)] uint Rn,
  1264. [Values(2u, 31u)] uint Rm,
  1265. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1266. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn,
  1267. [Values(0ul, 31ul, 32ul, 63ul, 0x7FFFFFFFFFFFFFFFul,
  1268. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(5)] ulong Xm)
  1269. {
  1270. uint Opcode = 0x9AC02C00; // RORV X0, X0, X0
  1271. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1272. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1273. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1274. if (Rd != 31)
  1275. {
  1276. Bits Op = new Bits(Opcode);
  1277. AArch64.X((int)Rn, new Bits(Xn));
  1278. AArch64.X((int)Rm, new Bits(Xm));
  1279. Base.Rorv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1280. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1281. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1282. }
  1283. else
  1284. {
  1285. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1286. }
  1287. CompareAgainstUnicorn();
  1288. }
  1289. [Test, Description("RORV <Wd>, <Wn>, <Wm>")]
  1290. public void Rorv_32bit([Values(0u, 31u)] uint Rd,
  1291. [Values(1u, 31u)] uint Rn,
  1292. [Values(2u, 31u)] uint Rm,
  1293. [Values(0x00000000u, 0x7FFFFFFFu,
  1294. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn,
  1295. [Values(0u, 15u, 16u, 31u, 0x7FFFFFFFu,
  1296. 0x80000000u, 0xFFFFFFFFu)] [Random(5)] uint Wm)
  1297. {
  1298. uint Opcode = 0x1AC02C00; // RORV W0, W0, W0
  1299. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1300. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1301. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1302. if (Rd != 31)
  1303. {
  1304. Bits Op = new Bits(Opcode);
  1305. AArch64.X((int)Rn, new Bits(Wn));
  1306. AArch64.X((int)Rm, new Bits(Wm));
  1307. Base.Rorv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1308. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1309. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1310. }
  1311. else
  1312. {
  1313. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1314. }
  1315. CompareAgainstUnicorn();
  1316. }
  1317. [Test, Description("SBC <Xd>, <Xn>, <Xm>")]
  1318. public void Sbc_64bit([Values(0u, 31u)] uint Rd,
  1319. [Values(1u, 31u)] uint Rn,
  1320. [Values(2u, 31u)] uint Rm,
  1321. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1322. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xn,
  1323. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1324. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xm,
  1325. [Values] bool CarryIn)
  1326. {
  1327. uint Opcode = 0xDA000000; // SBC X0, X0, X0
  1328. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1329. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1330. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31, Carry: CarryIn);
  1331. if (Rd != 31)
  1332. {
  1333. Bits Op = new Bits(Opcode);
  1334. AArch64.X((int)Rn, new Bits(Xn));
  1335. AArch64.X((int)Rm, new Bits(Xm));
  1336. Shared.PSTATE.C = CarryIn;
  1337. Base.Sbc(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1338. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1339. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1340. }
  1341. else
  1342. {
  1343. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1344. }
  1345. CompareAgainstUnicorn();
  1346. }
  1347. [Test, Description("SBC <Wd>, <Wn>, <Wm>")]
  1348. public void Sbc_32bit([Values(0u, 31u)] uint Rd,
  1349. [Values(1u, 31u)] uint Rn,
  1350. [Values(2u, 31u)] uint Rm,
  1351. [Values(0x00000000u, 0x7FFFFFFFu,
  1352. 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wn,
  1353. [Values(0x00000000u, 0x7FFFFFFFu,
  1354. 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wm,
  1355. [Values] bool CarryIn)
  1356. {
  1357. uint Opcode = 0x5A000000; // SBC W0, W0, W0
  1358. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1359. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1360. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31, Carry: CarryIn);
  1361. if (Rd != 31)
  1362. {
  1363. Bits Op = new Bits(Opcode);
  1364. AArch64.X((int)Rn, new Bits(Wn));
  1365. AArch64.X((int)Rm, new Bits(Wm));
  1366. Shared.PSTATE.C = CarryIn;
  1367. Base.Sbc(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1368. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1369. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1370. }
  1371. else
  1372. {
  1373. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1374. }
  1375. CompareAgainstUnicorn();
  1376. }
  1377. [Test, Description("SBCS <Xd>, <Xn>, <Xm>")]
  1378. public void Sbcs_64bit([Values(0u, 31u)] uint Rd,
  1379. [Values(1u, 31u)] uint Rn,
  1380. [Values(2u, 31u)] uint Rm,
  1381. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1382. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xn,
  1383. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1384. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(4)] ulong Xm,
  1385. [Values] bool CarryIn)
  1386. {
  1387. uint Opcode = 0xFA000000; // SBCS X0, X0, X0
  1388. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1389. Bits Op = new Bits(Opcode);
  1390. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1391. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31, Carry: CarryIn);
  1392. AArch64.X((int)Rn, new Bits(Xn));
  1393. AArch64.X((int)Rm, new Bits(Xm));
  1394. Shared.PSTATE.C = CarryIn;
  1395. Base.Sbcs(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1396. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1397. if (Rd != 31)
  1398. {
  1399. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1400. }
  1401. else
  1402. {
  1403. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1404. }
  1405. Assert.Multiple(() =>
  1406. {
  1407. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  1408. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  1409. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  1410. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  1411. });
  1412. CompareAgainstUnicorn();
  1413. }
  1414. [Test, Description("SBCS <Wd>, <Wn>, <Wm>")]
  1415. public void Sbcs_32bit([Values(0u, 31u)] uint Rd,
  1416. [Values(1u, 31u)] uint Rn,
  1417. [Values(2u, 31u)] uint Rm,
  1418. [Values(0x00000000u, 0x7FFFFFFFu,
  1419. 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wn,
  1420. [Values(0x00000000u, 0x7FFFFFFFu,
  1421. 0x80000000u, 0xFFFFFFFFu)] [Random(4)] uint Wm,
  1422. [Values] bool CarryIn)
  1423. {
  1424. uint Opcode = 0x7A000000; // SBCS W0, W0, W0
  1425. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1426. Bits Op = new Bits(Opcode);
  1427. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1428. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31, Carry: CarryIn);
  1429. AArch64.X((int)Rn, new Bits(Wn));
  1430. AArch64.X((int)Rm, new Bits(Wm));
  1431. Shared.PSTATE.C = CarryIn;
  1432. Base.Sbcs(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1433. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1434. if (Rd != 31)
  1435. {
  1436. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1437. }
  1438. else
  1439. {
  1440. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1441. }
  1442. Assert.Multiple(() =>
  1443. {
  1444. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  1445. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  1446. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  1447. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  1448. });
  1449. CompareAgainstUnicorn();
  1450. }
  1451. [Test, Description("SDIV <Xd>, <Xn>, <Xm>")]
  1452. public void Sdiv_64bit([Values(0u, 31u)] uint Rd,
  1453. [Values(1u, 31u)] uint Rn,
  1454. [Values(2u, 31u)] uint Rm,
  1455. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1456. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn,
  1457. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1458. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xm)
  1459. {
  1460. uint Opcode = 0x9AC00C00; // SDIV X0, X0, X0
  1461. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1462. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1463. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1464. if (Rd != 31)
  1465. {
  1466. Bits Op = new Bits(Opcode);
  1467. AArch64.X((int)Rn, new Bits(Xn));
  1468. AArch64.X((int)Rm, new Bits(Xm));
  1469. Base.Sdiv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1470. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1471. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1472. }
  1473. else
  1474. {
  1475. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1476. }
  1477. CompareAgainstUnicorn();
  1478. }
  1479. [Test, Description("SDIV <Wd>, <Wn>, <Wm>")]
  1480. public void Sdiv_32bit([Values(0u, 31u)] uint Rd,
  1481. [Values(1u, 31u)] uint Rn,
  1482. [Values(2u, 31u)] uint Rm,
  1483. [Values(0x00000000u, 0x7FFFFFFFu,
  1484. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn,
  1485. [Values(0x00000000u, 0x7FFFFFFFu,
  1486. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wm)
  1487. {
  1488. uint Opcode = 0x1AC00C00; // SDIV W0, W0, W0
  1489. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1490. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1491. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1492. if (Rd != 31)
  1493. {
  1494. Bits Op = new Bits(Opcode);
  1495. AArch64.X((int)Rn, new Bits(Wn));
  1496. AArch64.X((int)Rm, new Bits(Wm));
  1497. Base.Sdiv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1498. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1499. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1500. }
  1501. else
  1502. {
  1503. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1504. }
  1505. CompareAgainstUnicorn();
  1506. }
  1507. [Test, Description("SUB <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  1508. public void Sub_64bit([Values(0u, 31u)] uint Rd,
  1509. [Values(1u, 31u)] uint Rn,
  1510. [Values(2u, 31u)] uint Rm,
  1511. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1512. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  1513. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1514. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  1515. [Values(0b00u, 0b01u, 0b10u)] uint shift, // <LSL, LSR, ASR>
  1516. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  1517. {
  1518. uint Opcode = 0xCB000000; // SUB X0, X0, X0, LSL #0
  1519. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1520. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  1521. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1522. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1523. if (Rd != 31)
  1524. {
  1525. Bits Op = new Bits(Opcode);
  1526. AArch64.X((int)Rn, new Bits(Xn));
  1527. AArch64.X((int)Rm, new Bits(Xm));
  1528. Base.Sub_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1529. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1530. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1531. }
  1532. else
  1533. {
  1534. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1535. }
  1536. CompareAgainstUnicorn();
  1537. }
  1538. [Test, Description("SUB <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  1539. public void Sub_32bit([Values(0u, 31u)] uint Rd,
  1540. [Values(1u, 31u)] uint Rn,
  1541. [Values(2u, 31u)] uint Rm,
  1542. [Values(0x00000000u, 0x7FFFFFFFu,
  1543. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  1544. [Values(0x00000000u, 0x7FFFFFFFu,
  1545. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  1546. [Values(0b00u, 0b01u, 0b10u)] uint shift, // <LSL, LSR, ASR>
  1547. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  1548. {
  1549. uint Opcode = 0x4B000000; // SUB W0, W0, W0, LSL #0
  1550. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1551. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  1552. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1553. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1554. if (Rd != 31)
  1555. {
  1556. Bits Op = new Bits(Opcode);
  1557. AArch64.X((int)Rn, new Bits(Wn));
  1558. AArch64.X((int)Rm, new Bits(Wm));
  1559. Base.Sub_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1560. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1561. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1562. }
  1563. else
  1564. {
  1565. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1566. }
  1567. CompareAgainstUnicorn();
  1568. }
  1569. [Test, Description("SUBS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}")]
  1570. public void Subs_64bit([Values(0u, 31u)] uint Rd,
  1571. [Values(1u, 31u)] uint Rn,
  1572. [Values(2u, 31u)] uint Rm,
  1573. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1574. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  1575. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1576. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  1577. [Values(0b00u, 0b01u, 0b10u)] uint shift, // <LSL, LSR, ASR>
  1578. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 1)] uint amount)
  1579. {
  1580. uint Opcode = 0xEB000000; // SUBS X0, X0, X0, LSL #0
  1581. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1582. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  1583. Bits Op = new Bits(Opcode);
  1584. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1585. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1586. AArch64.X((int)Rn, new Bits(Xn));
  1587. AArch64.X((int)Rm, new Bits(Xm));
  1588. Base.Subs_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1589. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1590. if (Rd != 31)
  1591. {
  1592. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1593. }
  1594. else
  1595. {
  1596. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1597. }
  1598. Assert.Multiple(() =>
  1599. {
  1600. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  1601. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  1602. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  1603. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  1604. });
  1605. CompareAgainstUnicorn();
  1606. }
  1607. [Test, Description("SUBS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}")]
  1608. public void Subs_32bit([Values(0u, 31u)] uint Rd,
  1609. [Values(1u, 31u)] uint Rn,
  1610. [Values(2u, 31u)] uint Rm,
  1611. [Values(0x00000000u, 0x7FFFFFFFu,
  1612. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  1613. [Values(0x00000000u, 0x7FFFFFFFu,
  1614. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  1615. [Values(0b00u, 0b01u, 0b10u)] uint shift, // <LSL, LSR, ASR>
  1616. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 1)] uint amount)
  1617. {
  1618. uint Opcode = 0x6B000000; // SUBS W0, W0, W0, LSL #0
  1619. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1620. Opcode |= ((shift & 3) << 22) | ((amount & 63) << 10);
  1621. Bits Op = new Bits(Opcode);
  1622. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1623. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1624. AArch64.X((int)Rn, new Bits(Wn));
  1625. AArch64.X((int)Rm, new Bits(Wm));
  1626. Base.Subs_Rs(Op[31], Op[23, 22], Op[20, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  1627. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1628. if (Rd != 31)
  1629. {
  1630. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1631. }
  1632. else
  1633. {
  1634. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1635. }
  1636. Assert.Multiple(() =>
  1637. {
  1638. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  1639. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  1640. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  1641. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  1642. });
  1643. CompareAgainstUnicorn();
  1644. }
  1645. [Test, Description("UDIV <Xd>, <Xn>, <Xm>")]
  1646. public void Udiv_64bit([Values(0u, 31u)] uint Rd,
  1647. [Values(1u, 31u)] uint Rn,
  1648. [Values(2u, 31u)] uint Rm,
  1649. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1650. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn,
  1651. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  1652. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xm)
  1653. {
  1654. uint Opcode = 0x9AC00800; // UDIV X0, X0, X0
  1655. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1656. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  1657. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  1658. if (Rd != 31)
  1659. {
  1660. Bits Op = new Bits(Opcode);
  1661. AArch64.X((int)Rn, new Bits(Xn));
  1662. AArch64.X((int)Rm, new Bits(Xm));
  1663. Base.Udiv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1664. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  1665. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  1666. }
  1667. else
  1668. {
  1669. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  1670. }
  1671. CompareAgainstUnicorn();
  1672. }
  1673. [Test, Description("UDIV <Wd>, <Wn>, <Wm>")]
  1674. public void Udiv_32bit([Values(0u, 31u)] uint Rd,
  1675. [Values(1u, 31u)] uint Rn,
  1676. [Values(2u, 31u)] uint Rm,
  1677. [Values(0x00000000u, 0x7FFFFFFFu,
  1678. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn,
  1679. [Values(0x00000000u, 0x7FFFFFFFu,
  1680. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wm)
  1681. {
  1682. uint Opcode = 0x1AC00800; // UDIV W0, W0, W0
  1683. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  1684. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  1685. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  1686. if (Rd != 31)
  1687. {
  1688. Bits Op = new Bits(Opcode);
  1689. AArch64.X((int)Rn, new Bits(Wn));
  1690. AArch64.X((int)Rm, new Bits(Wm));
  1691. Base.Udiv(Op[31], Op[20, 16], Op[9, 5], Op[4, 0]);
  1692. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  1693. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  1694. }
  1695. else
  1696. {
  1697. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  1698. }
  1699. CompareAgainstUnicorn();
  1700. }
  1701. #endif
  1702. }
  1703. }