CpuTestAluImm.cs 19 KB

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