CpuTestAluImm.cs 32 KB

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