CpuTestAluImm.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. //#define AluImm
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. using Tester;
  7. using Tester.Types;
  8. [Category("AluImm"), Ignore("Tested: second half of 2018.")]
  9. public sealed class CpuTestAluImm : CpuTest
  10. {
  11. #if AluImm
  12. [SetUp]
  13. public void SetupTester()
  14. {
  15. AArch64.TakeReset(false);
  16. }
  17. [Test, Description("ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
  18. public void Add_64bit([Values(0u, 31u)] uint Rd,
  19. [Values(1u, 31u)] uint Rn,
  20. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  21. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
  22. [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
  23. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  24. {
  25. uint Opcode = 0x91000000; // ADD X0, X0, #0, LSL #0
  26. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  27. Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  28. Bits Op = new Bits(Opcode);
  29. AThreadState ThreadState;
  30. if (Rn != 31)
  31. {
  32. ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
  33. AArch64.X((int)Rn, new Bits(Xn_SP));
  34. }
  35. else
  36. {
  37. ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
  38. AArch64.SP(new Bits(Xn_SP));
  39. }
  40. Base.Add_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
  41. if (Rd != 31)
  42. {
  43. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  44. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  45. }
  46. else
  47. {
  48. ulong SP = AArch64.SP(64).ToUInt64();
  49. Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
  50. }
  51. CompareAgainstUnicorn();
  52. }
  53. [Test, Description("ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
  54. public void Add_32bit([Values(0u, 31u)] uint Rd,
  55. [Values(1u, 31u)] uint Rn,
  56. [Values(0x00000000u, 0x7FFFFFFFu,
  57. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
  58. [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
  59. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  60. {
  61. uint Opcode = 0x11000000; // ADD W0, W0, #0, LSL #0
  62. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  63. Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  64. Bits Op = new Bits(Opcode);
  65. AThreadState ThreadState;
  66. if (Rn != 31)
  67. {
  68. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
  69. AArch64.X((int)Rn, new Bits(Wn_WSP));
  70. }
  71. else
  72. {
  73. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
  74. AArch64.SP(new Bits(Wn_WSP));
  75. }
  76. Base.Add_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
  77. if (Rd != 31)
  78. {
  79. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  80. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  81. }
  82. else
  83. {
  84. uint WSP = AArch64.SP(32).ToUInt32();
  85. Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
  86. }
  87. CompareAgainstUnicorn();
  88. }
  89. [Test, Description("ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
  90. public void Adds_64bit([Values(0u, 31u)] uint Rd,
  91. [Values(1u, 31u)] uint Rn,
  92. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  93. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
  94. [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
  95. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  96. {
  97. uint Opcode = 0xB1000000; // ADDS X0, X0, #0, LSL #0
  98. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  99. Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  100. Bits Op = new Bits(Opcode);
  101. AThreadState ThreadState;
  102. if (Rn != 31)
  103. {
  104. ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
  105. AArch64.X((int)Rn, new Bits(Xn_SP));
  106. }
  107. else
  108. {
  109. ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
  110. AArch64.SP(new Bits(Xn_SP));
  111. }
  112. Base.Adds_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
  113. if (Rd != 31)
  114. {
  115. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  116. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  117. }
  118. else
  119. {
  120. ulong _X31 = AArch64.SP(64).ToUInt64();
  121. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  122. }
  123. Assert.Multiple(() =>
  124. {
  125. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  126. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  127. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  128. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  129. });
  130. CompareAgainstUnicorn();
  131. }
  132. [Test, Description("ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
  133. public void Adds_32bit([Values(0u, 31u)] uint Rd,
  134. [Values(1u, 31u)] uint Rn,
  135. [Values(0x00000000u, 0x7FFFFFFFu,
  136. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
  137. [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
  138. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  139. {
  140. uint Opcode = 0x31000000; // ADDS W0, W0, #0, LSL #0
  141. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  142. Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  143. Bits Op = new Bits(Opcode);
  144. AThreadState ThreadState;
  145. if (Rn != 31)
  146. {
  147. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
  148. AArch64.X((int)Rn, new Bits(Wn_WSP));
  149. }
  150. else
  151. {
  152. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
  153. AArch64.SP(new Bits(Wn_WSP));
  154. }
  155. Base.Adds_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
  156. if (Rd != 31)
  157. {
  158. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  159. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  160. }
  161. else
  162. {
  163. uint _W31 = AArch64.SP(32).ToUInt32();
  164. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  165. }
  166. Assert.Multiple(() =>
  167. {
  168. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  169. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  170. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  171. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  172. });
  173. CompareAgainstUnicorn();
  174. }
  175. [Test, Description("AND <Xd|SP>, <Xn>, #<imm>")]
  176. public void And_N1_64bit([Values(0u, 31u)] uint Rd,
  177. [Values(1u, 31u)] uint Rn,
  178. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  179. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  180. [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
  181. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
  182. {
  183. uint Opcode = 0x92400000; // AND X0, X0, #0x1
  184. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  185. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  186. Bits Op = new Bits(Opcode);
  187. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  188. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
  189. AArch64.X((int)Rn, new Bits(Xn));
  190. Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  191. if (Rd != 31)
  192. {
  193. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  194. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  195. }
  196. else
  197. {
  198. ulong SP = AArch64.SP(64).ToUInt64();
  199. Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
  200. }
  201. CompareAgainstUnicorn();
  202. }
  203. [Test, Description("AND <Xd|SP>, <Xn>, #<imm>")]
  204. public void And_N0_64bit([Values(0u, 31u)] uint Rd,
  205. [Values(1u, 31u)] uint Rn,
  206. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  207. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  208. [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
  209. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
  210. {
  211. uint Opcode = 0x92000000; // AND X0, X0, #0x100000001
  212. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  213. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  214. Bits Op = new Bits(Opcode);
  215. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  216. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
  217. AArch64.X((int)Rn, new Bits(Xn));
  218. Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  219. if (Rd != 31)
  220. {
  221. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  222. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  223. }
  224. else
  225. {
  226. ulong SP = AArch64.SP(64).ToUInt64();
  227. Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
  228. }
  229. CompareAgainstUnicorn();
  230. }
  231. [Test, Description("AND <Wd|WSP>, <Wn>, #<imm>")]
  232. public void And_32bit([Values(0u, 31u)] uint Rd,
  233. [Values(1u, 31u)] uint Rn,
  234. [Values(0x00000000u, 0x7FFFFFFFu,
  235. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  236. [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
  237. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
  238. {
  239. uint Opcode = 0x12000000; // AND W0, W0, #0x1
  240. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  241. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  242. Bits Op = new Bits(Opcode);
  243. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  244. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
  245. AArch64.X((int)Rn, new Bits(Wn));
  246. Base.And_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  247. if (Rd != 31)
  248. {
  249. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  250. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  251. }
  252. else
  253. {
  254. uint WSP = AArch64.SP(32).ToUInt32();
  255. Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
  256. }
  257. CompareAgainstUnicorn();
  258. }
  259. [Test, Description("ANDS <Xd>, <Xn>, #<imm>")]
  260. public void Ands_N1_64bit([Values(0u, 31u)] uint Rd,
  261. [Values(1u, 31u)] uint Rn,
  262. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  263. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  264. [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
  265. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
  266. {
  267. uint Opcode = 0xF2400000; // ANDS X0, X0, #0x1
  268. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  269. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  270. Bits Op = new Bits(Opcode);
  271. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  272. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
  273. AArch64.X((int)Rn, new Bits(Xn));
  274. Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  275. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  276. if (Rd != 31)
  277. {
  278. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  279. }
  280. else
  281. {
  282. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  283. }
  284. Assert.Multiple(() =>
  285. {
  286. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  287. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  288. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  289. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  290. });
  291. CompareAgainstUnicorn();
  292. }
  293. [Test, Description("ANDS <Xd>, <Xn>, #<imm>")]
  294. public void Ands_N0_64bit([Values(0u, 31u)] uint Rd,
  295. [Values(1u, 31u)] uint Rn,
  296. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  297. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  298. [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
  299. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
  300. {
  301. uint Opcode = 0xF2000000; // ANDS X0, X0, #0x100000001
  302. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  303. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  304. Bits Op = new Bits(Opcode);
  305. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  306. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
  307. AArch64.X((int)Rn, new Bits(Xn));
  308. Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  309. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  310. if (Rd != 31)
  311. {
  312. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  313. }
  314. else
  315. {
  316. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  317. }
  318. Assert.Multiple(() =>
  319. {
  320. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  321. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  322. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  323. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  324. });
  325. CompareAgainstUnicorn();
  326. }
  327. [Test, Description("ANDS <Wd>, <Wn>, #<imm>")]
  328. public void Ands_32bit([Values(0u, 31u)] uint Rd,
  329. [Values(1u, 31u)] uint Rn,
  330. [Values(0x00000000u, 0x7FFFFFFFu,
  331. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  332. [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
  333. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
  334. {
  335. uint Opcode = 0x72000000; // ANDS W0, W0, #0x1
  336. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  337. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  338. Bits Op = new Bits(Opcode);
  339. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  340. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
  341. AArch64.X((int)Rn, new Bits(Wn));
  342. Base.Ands_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  343. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  344. if (Rd != 31)
  345. {
  346. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  347. }
  348. else
  349. {
  350. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  351. }
  352. Assert.Multiple(() =>
  353. {
  354. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  355. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  356. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  357. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  358. });
  359. CompareAgainstUnicorn();
  360. }
  361. [Test, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
  362. public void Eor_N1_64bit([Values(0u, 31u)] uint Rd,
  363. [Values(1u, 31u)] uint Rn,
  364. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  365. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  366. [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
  367. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
  368. {
  369. uint Opcode = 0xD2400000; // EOR X0, X0, #0x1
  370. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  371. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  372. Bits Op = new Bits(Opcode);
  373. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  374. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
  375. AArch64.X((int)Rn, new Bits(Xn));
  376. Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  377. if (Rd != 31)
  378. {
  379. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  380. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  381. }
  382. else
  383. {
  384. ulong SP = AArch64.SP(64).ToUInt64();
  385. Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
  386. }
  387. CompareAgainstUnicorn();
  388. }
  389. [Test, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
  390. public void Eor_N0_64bit([Values(0u, 31u)] uint Rd,
  391. [Values(1u, 31u)] uint Rn,
  392. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  393. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  394. [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
  395. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
  396. {
  397. uint Opcode = 0xD2000000; // EOR X0, X0, #0x100000001
  398. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  399. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  400. Bits Op = new Bits(Opcode);
  401. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  402. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
  403. AArch64.X((int)Rn, new Bits(Xn));
  404. Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  405. if (Rd != 31)
  406. {
  407. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  408. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  409. }
  410. else
  411. {
  412. ulong SP = AArch64.SP(64).ToUInt64();
  413. Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
  414. }
  415. CompareAgainstUnicorn();
  416. }
  417. [Test, Description("EOR <Wd>, <Wn>, #<imm>")]
  418. public void Eor_32bit([Values(0u, 31u)] uint Rd,
  419. [Values(1u, 31u)] uint Rn,
  420. [Values(0x00000000u, 0x7FFFFFFFu,
  421. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  422. [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
  423. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
  424. {
  425. uint Opcode = 0x52000000; // EOR W0, W0, #0x1
  426. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  427. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  428. Bits Op = new Bits(Opcode);
  429. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  430. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
  431. AArch64.X((int)Rn, new Bits(Wn));
  432. Base.Eor_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  433. if (Rd != 31)
  434. {
  435. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  436. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  437. }
  438. else
  439. {
  440. uint WSP = AArch64.SP(32).ToUInt32();
  441. Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
  442. }
  443. CompareAgainstUnicorn();
  444. }
  445. [Test, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
  446. public void Orr_N1_64bit([Values(0u, 31u)] uint Rd,
  447. [Values(1u, 31u)] uint Rn,
  448. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  449. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  450. [Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, 2)] uint imms, // <imm>
  451. [Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, 2)] uint immr) // <imm>
  452. {
  453. uint Opcode = 0xB2400000; // ORR X0, X0, #0x1
  454. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  455. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  456. Bits Op = new Bits(Opcode);
  457. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  458. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
  459. AArch64.X((int)Rn, new Bits(Xn));
  460. Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  461. if (Rd != 31)
  462. {
  463. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  464. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  465. }
  466. else
  467. {
  468. ulong SP = AArch64.SP(64).ToUInt64();
  469. Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
  470. }
  471. CompareAgainstUnicorn();
  472. }
  473. [Test, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
  474. public void Orr_N0_64bit([Values(0u, 31u)] uint Rd,
  475. [Values(1u, 31u)] uint Rn,
  476. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  477. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  478. [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
  479. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
  480. {
  481. uint Opcode = 0xB2000000; // ORR X0, X0, #0x100000001
  482. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  483. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  484. Bits Op = new Bits(Opcode);
  485. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  486. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
  487. AArch64.X((int)Rn, new Bits(Xn));
  488. Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  489. if (Rd != 31)
  490. {
  491. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  492. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  493. }
  494. else
  495. {
  496. ulong SP = AArch64.SP(64).ToUInt64();
  497. Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
  498. }
  499. CompareAgainstUnicorn();
  500. }
  501. [Test, Description("ORR <Wd|WSP>, <Wn>, #<imm>")]
  502. public void Orr_32bit([Values(0u, 31u)] uint Rd,
  503. [Values(1u, 31u)] uint Rn,
  504. [Values(0x00000000u, 0x7FFFFFFFu,
  505. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  506. [Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, 2)] uint imms, // <imm>
  507. [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, 2)] uint immr) // <imm>
  508. {
  509. uint Opcode = 0x32000000; // ORR W0, W0, #0x1
  510. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  511. Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  512. Bits Op = new Bits(Opcode);
  513. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  514. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
  515. AArch64.X((int)Rn, new Bits(Wn));
  516. Base.Orr_Imm(Op[31], Op[22], Op[21, 16], Op[15, 10], Op[9, 5], Op[4, 0]);
  517. if (Rd != 31)
  518. {
  519. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  520. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  521. }
  522. else
  523. {
  524. uint WSP = AArch64.SP(32).ToUInt32();
  525. Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
  526. }
  527. CompareAgainstUnicorn();
  528. }
  529. [Test, Description("SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
  530. public void Sub_64bit([Values(0u, 31u)] uint Rd,
  531. [Values(1u, 31u)] uint Rn,
  532. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  533. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
  534. [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
  535. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  536. {
  537. uint Opcode = 0xD1000000; // SUB X0, X0, #0, LSL #0
  538. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  539. Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  540. Bits Op = new Bits(Opcode);
  541. AThreadState ThreadState;
  542. if (Rn != 31)
  543. {
  544. ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
  545. AArch64.X((int)Rn, new Bits(Xn_SP));
  546. }
  547. else
  548. {
  549. ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
  550. AArch64.SP(new Bits(Xn_SP));
  551. }
  552. Base.Sub_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
  553. if (Rd != 31)
  554. {
  555. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  556. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  557. }
  558. else
  559. {
  560. ulong SP = AArch64.SP(64).ToUInt64();
  561. Assert.That((ulong)ThreadState.X31, Is.EqualTo(SP));
  562. }
  563. CompareAgainstUnicorn();
  564. }
  565. [Test, Description("SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
  566. public void Sub_32bit([Values(0u, 31u)] uint Rd,
  567. [Values(1u, 31u)] uint Rn,
  568. [Values(0x00000000u, 0x7FFFFFFFu,
  569. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
  570. [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
  571. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  572. {
  573. uint Opcode = 0x51000000; // SUB W0, W0, #0, LSL #0
  574. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  575. Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  576. Bits Op = new Bits(Opcode);
  577. AThreadState ThreadState;
  578. if (Rn != 31)
  579. {
  580. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
  581. AArch64.X((int)Rn, new Bits(Wn_WSP));
  582. }
  583. else
  584. {
  585. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
  586. AArch64.SP(new Bits(Wn_WSP));
  587. }
  588. Base.Sub_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
  589. if (Rd != 31)
  590. {
  591. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  592. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  593. }
  594. else
  595. {
  596. uint WSP = AArch64.SP(32).ToUInt32();
  597. Assert.That((uint)ThreadState.X31, Is.EqualTo(WSP));
  598. }
  599. CompareAgainstUnicorn();
  600. }
  601. [Test, Description("SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
  602. public void Subs_64bit([Values(0u, 31u)] uint Rd,
  603. [Values(1u, 31u)] uint Rn,
  604. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  605. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(8)] ulong Xn_SP,
  606. [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
  607. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  608. {
  609. uint Opcode = 0xF1000000; // SUBS X0, X0, #0, LSL #0
  610. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  611. Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  612. Bits Op = new Bits(Opcode);
  613. AThreadState ThreadState;
  614. if (Rn != 31)
  615. {
  616. ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
  617. AArch64.X((int)Rn, new Bits(Xn_SP));
  618. }
  619. else
  620. {
  621. ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
  622. AArch64.SP(new Bits(Xn_SP));
  623. }
  624. Base.Subs_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
  625. if (Rd != 31)
  626. {
  627. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  628. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  629. }
  630. else
  631. {
  632. ulong _X31 = AArch64.SP(64).ToUInt64();
  633. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  634. }
  635. Assert.Multiple(() =>
  636. {
  637. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  638. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  639. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  640. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  641. });
  642. CompareAgainstUnicorn();
  643. }
  644. [Test, Description("SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
  645. public void Subs_32bit([Values(0u, 31u)] uint Rd,
  646. [Values(1u, 31u)] uint Rn,
  647. [Values(0x00000000u, 0x7FFFFFFFu,
  648. 0x80000000u, 0xFFFFFFFFu)] [Random(8)] uint Wn_WSP,
  649. [Values(0u, 4095u)] [Random(0u, 4095u, 10)] uint imm,
  650. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  651. {
  652. uint Opcode = 0x71000000; // SUBS W0, W0, #0, LSL #0
  653. Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
  654. Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  655. Bits Op = new Bits(Opcode);
  656. AThreadState ThreadState;
  657. if (Rn != 31)
  658. {
  659. ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
  660. AArch64.X((int)Rn, new Bits(Wn_WSP));
  661. }
  662. else
  663. {
  664. ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
  665. AArch64.SP(new Bits(Wn_WSP));
  666. }
  667. Base.Subs_Imm(Op[31], Op[23, 22], Op[21, 10], Op[9, 5], Op[4, 0]);
  668. if (Rd != 31)
  669. {
  670. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  671. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  672. }
  673. else
  674. {
  675. uint _W31 = AArch64.SP(32).ToUInt32();
  676. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  677. }
  678. Assert.Multiple(() =>
  679. {
  680. Assert.That(ThreadState.Negative, Is.EqualTo(Shared.PSTATE.N));
  681. Assert.That(ThreadState.Zero, Is.EqualTo(Shared.PSTATE.Z));
  682. Assert.That(ThreadState.Carry, Is.EqualTo(Shared.PSTATE.C));
  683. Assert.That(ThreadState.Overflow, Is.EqualTo(Shared.PSTATE.V));
  684. });
  685. CompareAgainstUnicorn();
  686. }
  687. #endif
  688. }
  689. }