CpuTestAluImm.cs 32 KB

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