CpuTestAluImm.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. #define AluImm
  2. using NUnit.Framework;
  3. namespace Ryujinx.Tests.Cpu
  4. {
  5. [Category("AluImm")]
  6. public sealed class CpuTestAluImm : CpuTest
  7. {
  8. #if AluImm
  9. [Test, Pairwise, Description("ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
  10. public void Add_64bit([Values(0u, 31u)] uint rd,
  11. [Values(1u, 31u)] uint rn,
  12. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  13. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xnSp,
  14. [Values(0u, 4095u)] uint imm,
  15. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  16. {
  17. uint opcode = 0x91000000; // ADD X0, X0, #0, LSL #0
  18. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  19. opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  20. if (rn != 31)
  21. {
  22. SingleOpcode(opcode, x1: xnSp);
  23. }
  24. else
  25. {
  26. SingleOpcode(opcode, x31: xnSp);
  27. }
  28. CompareAgainstUnicorn();
  29. }
  30. [Test, Pairwise, Description("ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
  31. public void Add_32bit([Values(0u, 31u)] uint rd,
  32. [Values(1u, 31u)] uint rn,
  33. [Values(0x00000000u, 0x7FFFFFFFu,
  34. 0x80000000u, 0xFFFFFFFFu)] uint wnWsp,
  35. [Values(0u, 4095u)] uint imm,
  36. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  37. {
  38. uint opcode = 0x11000000; // ADD W0, W0, #0, LSL #0
  39. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  40. opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  41. if (rn != 31)
  42. {
  43. SingleOpcode(opcode, x1: wnWsp);
  44. }
  45. else
  46. {
  47. SingleOpcode(opcode, x31: wnWsp);
  48. }
  49. CompareAgainstUnicorn();
  50. }
  51. [Test, Pairwise, Description("ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
  52. public void Adds_64bit([Values(0u, 31u)] uint rd,
  53. [Values(1u, 31u)] uint rn,
  54. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  55. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xnSp,
  56. [Values(0u, 4095u)] uint imm,
  57. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  58. {
  59. uint opcode = 0xB1000000; // ADDS X0, X0, #0, LSL #0
  60. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  61. opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  62. if (rn != 31)
  63. {
  64. SingleOpcode(opcode, x1: xnSp);
  65. }
  66. else
  67. {
  68. SingleOpcode(opcode, x31: xnSp);
  69. }
  70. CompareAgainstUnicorn();
  71. }
  72. [Test, Pairwise, Description("ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
  73. public void Adds_32bit([Values(0u, 31u)] uint rd,
  74. [Values(1u, 31u)] uint rn,
  75. [Values(0x00000000u, 0x7FFFFFFFu,
  76. 0x80000000u, 0xFFFFFFFFu)] uint wnWsp,
  77. [Values(0u, 4095u)] uint imm,
  78. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  79. {
  80. uint opcode = 0x31000000; // ADDS W0, W0, #0, LSL #0
  81. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  82. opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  83. if (rn != 31)
  84. {
  85. SingleOpcode(opcode, x1: wnWsp);
  86. }
  87. else
  88. {
  89. SingleOpcode(opcode, x31: wnWsp);
  90. }
  91. CompareAgainstUnicorn();
  92. }
  93. [Test, Pairwise, Description("AND <Xd|SP>, <Xn>, #<imm>")]
  94. public void And_N1_64bit([Values(0u, 31u)] uint rd,
  95. [Values(1u, 31u)] uint rn,
  96. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  97. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
  98. [Values(0u, 31u, 32u, 62u)] uint imms, // <imm>
  99. [Values(0u, 31u, 32u, 63u)] uint immr) // <imm>
  100. {
  101. uint opcode = 0x92400000; // AND X0, X0, #0x1
  102. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  103. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  104. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  105. SingleOpcode(opcode, x1: xn, x31: x31);
  106. CompareAgainstUnicorn();
  107. }
  108. [Test, Pairwise, Description("AND <Xd|SP>, <Xn>, #<imm>")]
  109. public void And_N0_64bit([Values(0u, 31u)] uint rd,
  110. [Values(1u, 31u)] uint rn,
  111. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  112. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
  113. [Values(0u, 15u, 16u, 30u)] uint imms, // <imm>
  114. [Values(0u, 15u, 16u, 31u)] uint immr) // <imm>
  115. {
  116. uint opcode = 0x92000000; // AND X0, X0, #0x100000001
  117. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  118. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  119. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  120. SingleOpcode(opcode, x1: xn, x31: x31);
  121. CompareAgainstUnicorn();
  122. }
  123. [Test, Pairwise, Description("AND <Wd|WSP>, <Wn>, #<imm>")]
  124. public void And_32bit([Values(0u, 31u)] uint rd,
  125. [Values(1u, 31u)] uint rn,
  126. [Values(0x00000000u, 0x7FFFFFFFu,
  127. 0x80000000u, 0xFFFFFFFFu)] uint wn,
  128. [Values(0u, 15u, 16u, 30u)] uint imms, // <imm>
  129. [Values(0u, 15u, 16u, 31u)] uint immr) // <imm>
  130. {
  131. uint opcode = 0x12000000; // AND W0, W0, #0x1
  132. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  133. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  134. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  135. SingleOpcode(opcode, x1: wn, x31: w31);
  136. CompareAgainstUnicorn();
  137. }
  138. [Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
  139. public void Ands_N1_64bit([Values(0u, 31u)] uint rd,
  140. [Values(1u, 31u)] uint rn,
  141. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  142. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
  143. [Values(0u, 31u, 32u, 62u)] uint imms, // <imm>
  144. [Values(0u, 31u, 32u, 63u)] uint immr) // <imm>
  145. {
  146. uint opcode = 0xF2400000; // ANDS X0, X0, #0x1
  147. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  148. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  149. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  150. SingleOpcode(opcode, x1: xn, x31: x31);
  151. CompareAgainstUnicorn();
  152. }
  153. [Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
  154. public void Ands_N0_64bit([Values(0u, 31u)] uint rd,
  155. [Values(1u, 31u)] uint rn,
  156. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  157. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
  158. [Values(0u, 15u, 16u, 30u)] uint imms, // <imm>
  159. [Values(0u, 15u, 16u, 31u)] uint immr) // <imm>
  160. {
  161. uint opcode = 0xF2000000; // ANDS X0, X0, #0x100000001
  162. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  163. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  164. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  165. SingleOpcode(opcode, x1: xn, x31: x31);
  166. CompareAgainstUnicorn();
  167. }
  168. [Test, Pairwise, Description("ANDS <Wd>, <Wn>, #<imm>")]
  169. public void Ands_32bit([Values(0u, 31u)] uint rd,
  170. [Values(1u, 31u)] uint rn,
  171. [Values(0x00000000u, 0x7FFFFFFFu,
  172. 0x80000000u, 0xFFFFFFFFu)] uint wn,
  173. [Values(0u, 15u, 16u, 30u)] uint imms, // <imm>
  174. [Values(0u, 15u, 16u, 31u)] uint immr) // <imm>
  175. {
  176. uint opcode = 0x72000000; // ANDS W0, W0, #0x1
  177. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  178. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  179. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  180. SingleOpcode(opcode, x1: wn, x31: w31);
  181. CompareAgainstUnicorn();
  182. }
  183. [Test, Pairwise, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
  184. public void Eor_N1_64bit([Values(0u, 31u)] uint rd,
  185. [Values(1u, 31u)] uint rn,
  186. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  187. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
  188. [Values(0u, 31u, 32u, 62u)] uint imms, // <imm>
  189. [Values(0u, 31u, 32u, 63u)] uint immr) // <imm>
  190. {
  191. uint opcode = 0xD2400000; // EOR X0, X0, #0x1
  192. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  193. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  194. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  195. SingleOpcode(opcode, x1: xn, x31: x31);
  196. CompareAgainstUnicorn();
  197. }
  198. [Test, Pairwise, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
  199. public void Eor_N0_64bit([Values(0u, 31u)] uint rd,
  200. [Values(1u, 31u)] uint rn,
  201. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  202. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
  203. [Values(0u, 15u, 16u, 30u)] uint imms, // <imm>
  204. [Values(0u, 15u, 16u, 31u)] uint immr) // <imm>
  205. {
  206. uint opcode = 0xD2000000; // EOR X0, X0, #0x100000001
  207. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  208. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  209. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  210. SingleOpcode(opcode, x1: xn, x31: x31);
  211. CompareAgainstUnicorn();
  212. }
  213. [Test, Pairwise, Description("EOR <Wd>, <Wn>, #<imm>")]
  214. public void Eor_32bit([Values(0u, 31u)] uint rd,
  215. [Values(1u, 31u)] uint rn,
  216. [Values(0x00000000u, 0x7FFFFFFFu,
  217. 0x80000000u, 0xFFFFFFFFu)] uint wn,
  218. [Values(0u, 15u, 16u, 30u)] uint imms, // <imm>
  219. [Values(0u, 15u, 16u, 31u)] uint immr) // <imm>
  220. {
  221. uint opcode = 0x52000000; // EOR W0, W0, #0x1
  222. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  223. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  224. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  225. SingleOpcode(opcode, x1: wn, x31: w31);
  226. CompareAgainstUnicorn();
  227. }
  228. [Test, Pairwise, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
  229. public void Orr_N1_64bit([Values(0u, 31u)] uint rd,
  230. [Values(1u, 31u)] uint rn,
  231. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  232. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
  233. [Values(0u, 31u, 32u, 62u)] uint imms, // <imm>
  234. [Values(0u, 31u, 32u, 63u)] uint immr) // <imm>
  235. {
  236. uint opcode = 0xB2400000; // ORR X0, X0, #0x1
  237. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  238. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  239. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  240. SingleOpcode(opcode, x1: xn, x31: x31);
  241. CompareAgainstUnicorn();
  242. }
  243. [Test, Pairwise, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
  244. public void Orr_N0_64bit([Values(0u, 31u)] uint rd,
  245. [Values(1u, 31u)] uint rn,
  246. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  247. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
  248. [Values(0u, 15u, 16u, 30u)] uint imms, // <imm>
  249. [Values(0u, 15u, 16u, 31u)] uint immr) // <imm>
  250. {
  251. uint opcode = 0xB2000000; // ORR X0, X0, #0x100000001
  252. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  253. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  254. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  255. SingleOpcode(opcode, x1: xn, x31: x31);
  256. CompareAgainstUnicorn();
  257. }
  258. [Test, Pairwise, Description("ORR <Wd|WSP>, <Wn>, #<imm>")]
  259. public void Orr_32bit([Values(0u, 31u)] uint rd,
  260. [Values(1u, 31u)] uint rn,
  261. [Values(0x00000000u, 0x7FFFFFFFu,
  262. 0x80000000u, 0xFFFFFFFFu)] uint wn,
  263. [Values(0u, 15u, 16u, 30u)] uint imms, // <imm>
  264. [Values(0u, 15u, 16u, 31u)] uint immr) // <imm>
  265. {
  266. uint opcode = 0x32000000; // ORR W0, W0, #0x1
  267. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  268. opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
  269. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  270. SingleOpcode(opcode, x1: wn, x31: w31);
  271. CompareAgainstUnicorn();
  272. }
  273. [Test, Pairwise, Description("SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
  274. public void Sub_64bit([Values(0u, 31u)] uint rd,
  275. [Values(1u, 31u)] uint rn,
  276. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  277. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xnSp,
  278. [Values(0u, 4095u)] uint imm,
  279. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  280. {
  281. uint opcode = 0xD1000000; // SUB X0, X0, #0, LSL #0
  282. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  283. opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  284. if (rn != 31)
  285. {
  286. SingleOpcode(opcode, x1: xnSp);
  287. }
  288. else
  289. {
  290. SingleOpcode(opcode, x31: xnSp);
  291. }
  292. CompareAgainstUnicorn();
  293. }
  294. [Test, Pairwise, Description("SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
  295. public void Sub_32bit([Values(0u, 31u)] uint rd,
  296. [Values(1u, 31u)] uint rn,
  297. [Values(0x00000000u, 0x7FFFFFFFu,
  298. 0x80000000u, 0xFFFFFFFFu)] uint wnWsp,
  299. [Values(0u, 4095u)] uint imm,
  300. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  301. {
  302. uint opcode = 0x51000000; // SUB W0, W0, #0, LSL #0
  303. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  304. opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  305. if (rn != 31)
  306. {
  307. SingleOpcode(opcode, x1: wnWsp);
  308. }
  309. else
  310. {
  311. SingleOpcode(opcode, x31: wnWsp);
  312. }
  313. CompareAgainstUnicorn();
  314. }
  315. [Test, Pairwise, Description("SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
  316. public void Subs_64bit([Values(0u, 31u)] uint rd,
  317. [Values(1u, 31u)] uint rn,
  318. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  319. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xnSp,
  320. [Values(0u, 4095u)] uint imm,
  321. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  322. {
  323. uint opcode = 0xF1000000; // SUBS X0, X0, #0, LSL #0
  324. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  325. opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  326. if (rn != 31)
  327. {
  328. SingleOpcode(opcode, x1: xnSp);
  329. }
  330. else
  331. {
  332. SingleOpcode(opcode, x31: xnSp);
  333. }
  334. CompareAgainstUnicorn();
  335. }
  336. [Test, Pairwise, Description("SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
  337. public void Subs_32bit([Values(0u, 31u)] uint rd,
  338. [Values(1u, 31u)] uint rn,
  339. [Values(0x00000000u, 0x7FFFFFFFu,
  340. 0x80000000u, 0xFFFFFFFFu)] uint wnWsp,
  341. [Values(0u, 4095u)] uint imm,
  342. [Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
  343. {
  344. uint opcode = 0x71000000; // SUBS W0, W0, #0, LSL #0
  345. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  346. opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
  347. if (rn != 31)
  348. {
  349. SingleOpcode(opcode, x1: wnWsp);
  350. }
  351. else
  352. {
  353. SingleOpcode(opcode, x31: wnWsp);
  354. }
  355. CompareAgainstUnicorn();
  356. }
  357. #endif
  358. }
  359. }