CpuTestCsel.cs 15 KB

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