CpuTestCsel.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. //#define Csel
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. using Tester;
  7. using Tester.Types;
  8. [Category("Csel"), Ignore("Tested: second half of 2018.")]
  9. public sealed class CpuTestCsel : CpuTest
  10. {
  11. #if Csel
  12. [SetUp]
  13. public void SetupTester()
  14. {
  15. AArch64.TakeReset(false);
  16. }
  17. [Test, Description("CSEL <Xd>, <Xn>, <Xm>, <cond>")]
  18. public void Csel_64bit([Values(0u, 31u)] uint Rd,
  19. [Values(1u, 31u)] uint Rn,
  20. [Values(2u, 31u)] uint Rm,
  21. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  22. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  23. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  24. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  25. [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
  26. 0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
  27. 0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
  28. 0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
  29. {
  30. uint Opcode = 0x9A800000; // CSEL X0, X0, X0, EQ
  31. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  32. Opcode |= ((cond & 15) << 12);
  33. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  34. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  35. if (Rd != 31)
  36. {
  37. Bits Op = new Bits(Opcode);
  38. AArch64.X((int)Rn, new Bits(Xn));
  39. AArch64.X((int)Rm, new Bits(Xm));
  40. Base.Csel(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
  41. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  42. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  43. }
  44. else
  45. {
  46. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  47. }
  48. CompareAgainstUnicorn();
  49. }
  50. [Test, Description("CSEL <Wd>, <Wn>, <Wm>, <cond>")]
  51. public void Csel_32bit([Values(0u, 31u)] uint Rd,
  52. [Values(1u, 31u)] uint Rn,
  53. [Values(2u, 31u)] uint Rm,
  54. [Values(0x00000000u, 0x7FFFFFFFu,
  55. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  56. [Values(0x00000000u, 0x7FFFFFFFu,
  57. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  58. [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
  59. 0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
  60. 0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
  61. 0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
  62. {
  63. uint Opcode = 0x1A800000; // CSEL W0, W0, W0, EQ
  64. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  65. Opcode |= ((cond & 15) << 12);
  66. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  67. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  68. if (Rd != 31)
  69. {
  70. Bits Op = new Bits(Opcode);
  71. AArch64.X((int)Rn, new Bits(Wn));
  72. AArch64.X((int)Rm, new Bits(Wm));
  73. Base.Csel(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
  74. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  75. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  76. }
  77. else
  78. {
  79. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  80. }
  81. CompareAgainstUnicorn();
  82. }
  83. [Test, Description("CSINC <Xd>, <Xn>, <Xm>, <cond>")]
  84. public void Csinc_64bit([Values(0u, 31u)] uint Rd,
  85. [Values(1u, 31u)] uint Rn,
  86. [Values(2u, 31u)] uint Rm,
  87. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  88. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  89. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  90. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  91. [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
  92. 0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
  93. 0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
  94. 0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
  95. {
  96. uint Opcode = 0x9A800400; // CSINC X0, X0, X0, EQ
  97. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  98. Opcode |= ((cond & 15) << 12);
  99. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  100. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  101. if (Rd != 31)
  102. {
  103. Bits Op = new Bits(Opcode);
  104. AArch64.X((int)Rn, new Bits(Xn));
  105. AArch64.X((int)Rm, new Bits(Xm));
  106. Base.Csinc(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
  107. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  108. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  109. }
  110. else
  111. {
  112. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  113. }
  114. CompareAgainstUnicorn();
  115. }
  116. [Test, Description("CSINC <Wd>, <Wn>, <Wm>, <cond>")]
  117. public void Csinc_32bit([Values(0u, 31u)] uint Rd,
  118. [Values(1u, 31u)] uint Rn,
  119. [Values(2u, 31u)] uint Rm,
  120. [Values(0x00000000u, 0x7FFFFFFFu,
  121. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  122. [Values(0x00000000u, 0x7FFFFFFFu,
  123. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  124. [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
  125. 0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
  126. 0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
  127. 0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
  128. {
  129. uint Opcode = 0x1A800400; // CSINC W0, W0, W0, EQ
  130. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  131. Opcode |= ((cond & 15) << 12);
  132. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  133. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  134. if (Rd != 31)
  135. {
  136. Bits Op = new Bits(Opcode);
  137. AArch64.X((int)Rn, new Bits(Wn));
  138. AArch64.X((int)Rm, new Bits(Wm));
  139. Base.Csinc(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
  140. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  141. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  142. }
  143. else
  144. {
  145. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  146. }
  147. CompareAgainstUnicorn();
  148. }
  149. [Test, Description("CSINV <Xd>, <Xn>, <Xm>, <cond>")]
  150. public void Csinv_64bit([Values(0u, 31u)] uint Rd,
  151. [Values(1u, 31u)] uint Rn,
  152. [Values(2u, 31u)] uint Rm,
  153. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  154. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  155. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  156. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  157. [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
  158. 0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
  159. 0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
  160. 0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
  161. {
  162. uint Opcode = 0xDA800000; // CSINV X0, X0, X0, EQ
  163. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  164. Opcode |= ((cond & 15) << 12);
  165. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  166. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  167. if (Rd != 31)
  168. {
  169. Bits Op = new Bits(Opcode);
  170. AArch64.X((int)Rn, new Bits(Xn));
  171. AArch64.X((int)Rm, new Bits(Xm));
  172. Base.Csinv(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
  173. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  174. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  175. }
  176. else
  177. {
  178. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  179. }
  180. CompareAgainstUnicorn();
  181. }
  182. [Test, Description("CSINV <Wd>, <Wn>, <Wm>, <cond>")]
  183. public void Csinv_32bit([Values(0u, 31u)] uint Rd,
  184. [Values(1u, 31u)] uint Rn,
  185. [Values(2u, 31u)] uint Rm,
  186. [Values(0x00000000u, 0x7FFFFFFFu,
  187. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  188. [Values(0x00000000u, 0x7FFFFFFFu,
  189. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  190. [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
  191. 0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
  192. 0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
  193. 0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
  194. {
  195. uint Opcode = 0x5A800000; // CSINV W0, W0, W0, EQ
  196. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  197. Opcode |= ((cond & 15) << 12);
  198. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  199. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  200. if (Rd != 31)
  201. {
  202. Bits Op = new Bits(Opcode);
  203. AArch64.X((int)Rn, new Bits(Wn));
  204. AArch64.X((int)Rm, new Bits(Wm));
  205. Base.Csinv(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
  206. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  207. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  208. }
  209. else
  210. {
  211. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  212. }
  213. CompareAgainstUnicorn();
  214. }
  215. [Test, Description("CSNEG <Xd>, <Xn>, <Xm>, <cond>")]
  216. public void Csneg_64bit([Values(0u, 31u)] uint Rd,
  217. [Values(1u, 31u)] uint Rn,
  218. [Values(2u, 31u)] uint Rm,
  219. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  220. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xn,
  221. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  222. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(1)] ulong Xm,
  223. [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
  224. 0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
  225. 0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
  226. 0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
  227. {
  228. uint Opcode = 0xDA800400; // CSNEG X0, X0, X0, EQ
  229. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  230. Opcode |= ((cond & 15) << 12);
  231. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  232. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  233. if (Rd != 31)
  234. {
  235. Bits Op = new Bits(Opcode);
  236. AArch64.X((int)Rn, new Bits(Xn));
  237. AArch64.X((int)Rm, new Bits(Xm));
  238. Base.Csneg(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
  239. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  240. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  241. }
  242. else
  243. {
  244. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  245. }
  246. CompareAgainstUnicorn();
  247. }
  248. [Test, Description("CSNEG <Wd>, <Wn>, <Wm>, <cond>")]
  249. public void Csneg_32bit([Values(0u, 31u)] uint Rd,
  250. [Values(1u, 31u)] uint Rn,
  251. [Values(2u, 31u)] uint Rm,
  252. [Values(0x00000000u, 0x7FFFFFFFu,
  253. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wn,
  254. [Values(0x00000000u, 0x7FFFFFFFu,
  255. 0x80000000u, 0xFFFFFFFFu)] [Random(1)] uint Wm,
  256. [Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
  257. 0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
  258. 0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
  259. 0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
  260. {
  261. uint Opcode = 0x5A800400; // CSNEG W0, W0, W0, EQ
  262. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  263. Opcode |= ((cond & 15) << 12);
  264. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  265. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
  266. if (Rd != 31)
  267. {
  268. Bits Op = new Bits(Opcode);
  269. AArch64.X((int)Rn, new Bits(Wn));
  270. AArch64.X((int)Rm, new Bits(Wm));
  271. Base.Csneg(Op[31], Op[20, 16], Op[15, 12], Op[9, 5], Op[4, 0]);
  272. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  273. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  274. }
  275. else
  276. {
  277. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  278. }
  279. CompareAgainstUnicorn();
  280. }
  281. #endif
  282. }
  283. }