CpuTestMul.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. //#define Mul
  2. using NUnit.Framework;
  3. namespace Ryujinx.Tests.Cpu
  4. {
  5. [Category("Mul"), Ignore("Tested: first half of 2018.")]
  6. public sealed class CpuTestMul : CpuTest
  7. {
  8. #if Mul
  9. [SetUp]
  10. public void SetupTester()
  11. {
  12. AArch64.TakeReset(false);
  13. }
  14. [Test, Description("MADD <Xd>, <Xn>, <Xm>, <Xa>")]
  15. public void Madd_64bit([Values(0u, 31u)] uint Rd,
  16. [Values(1u, 31u)] uint Rn,
  17. [Values(2u, 31u)] uint Rm,
  18. [Values(3u, 31u)] uint Ra,
  19. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  20. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  21. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  22. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm,
  23. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  24. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
  25. {
  26. uint Opcode = 0x9B000000; // MADD X0, X0, X0, X0
  27. Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  28. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  29. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31);
  30. if (Rd != 31)
  31. {
  32. Bits Op = new Bits(Opcode);
  33. AArch64.X((int)Rn, new Bits(Xn));
  34. AArch64.X((int)Rm, new Bits(Xm));
  35. AArch64.X((int)Ra, new Bits(Xa));
  36. Base.Madd(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
  37. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  38. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  39. }
  40. else
  41. {
  42. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  43. }
  44. }
  45. [Test, Description("MADD <Wd>, <Wn>, <Wm>, <Wa>")]
  46. public void Madd_32bit([Values(0u, 31u)] uint Rd,
  47. [Values(1u, 31u)] uint Rn,
  48. [Values(2u, 31u)] uint Rm,
  49. [Values(3u, 31u)] uint Ra,
  50. [Values(0x00000000u, 0x7FFFFFFFu,
  51. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  52. [Values(0x00000000u, 0x7FFFFFFFu,
  53. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
  54. [Values(0x00000000u, 0x7FFFFFFFu,
  55. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wa)
  56. {
  57. uint Opcode = 0x1B000000; // MADD W0, W0, W0, W0
  58. Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  59. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  60. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31);
  61. if (Rd != 31)
  62. {
  63. Bits Op = new Bits(Opcode);
  64. AArch64.X((int)Rn, new Bits(Wn));
  65. AArch64.X((int)Rm, new Bits(Wm));
  66. AArch64.X((int)Ra, new Bits(Wa));
  67. Base.Madd(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
  68. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  69. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  70. }
  71. else
  72. {
  73. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  74. }
  75. }
  76. [Test, Description("MSUB <Xd>, <Xn>, <Xm>, <Xa>")]
  77. public void Msub_64bit([Values(0u, 31u)] uint Rd,
  78. [Values(1u, 31u)] uint Rn,
  79. [Values(2u, 31u)] uint Rm,
  80. [Values(3u, 31u)] uint Ra,
  81. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  82. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xn,
  83. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  84. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xm,
  85. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  86. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
  87. {
  88. uint Opcode = 0x9B008000; // MSUB X0, X0, X0, X0
  89. Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  90. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  91. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31);
  92. if (Rd != 31)
  93. {
  94. Bits Op = new Bits(Opcode);
  95. AArch64.X((int)Rn, new Bits(Xn));
  96. AArch64.X((int)Rm, new Bits(Xm));
  97. AArch64.X((int)Ra, new Bits(Xa));
  98. Base.Msub(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
  99. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  100. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  101. }
  102. else
  103. {
  104. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  105. }
  106. }
  107. [Test, Description("MSUB <Wd>, <Wn>, <Wm>, <Wa>")]
  108. public void Msub_32bit([Values(0u, 31u)] uint Rd,
  109. [Values(1u, 31u)] uint Rn,
  110. [Values(2u, 31u)] uint Rm,
  111. [Values(3u, 31u)] uint Ra,
  112. [Values(0x00000000u, 0x7FFFFFFFu,
  113. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  114. [Values(0x00000000u, 0x7FFFFFFFu,
  115. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
  116. [Values(0x00000000u, 0x7FFFFFFFu,
  117. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wa)
  118. {
  119. uint Opcode = 0x1B008000; // MSUB W0, W0, W0, W0
  120. Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  121. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  122. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31);
  123. if (Rd != 31)
  124. {
  125. Bits Op = new Bits(Opcode);
  126. AArch64.X((int)Rn, new Bits(Wn));
  127. AArch64.X((int)Rm, new Bits(Wm));
  128. AArch64.X((int)Ra, new Bits(Wa));
  129. Base.Msub(Op[31], Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
  130. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  131. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  132. }
  133. else
  134. {
  135. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  136. }
  137. }
  138. [Test, Description("SMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
  139. public void Smaddl_64bit([Values(0u, 31u)] uint Rd,
  140. [Values(1u, 31u)] uint Rn,
  141. [Values(2u, 31u)] uint Rm,
  142. [Values(3u, 31u)] uint Ra,
  143. [Values(0x00000000u, 0x7FFFFFFFu,
  144. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  145. [Values(0x00000000u, 0x7FFFFFFFu,
  146. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
  147. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  148. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
  149. {
  150. uint Opcode = 0x9B200000; // SMADDL X0, W0, W0, X0
  151. Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  152. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  153. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
  154. if (Rd != 31)
  155. {
  156. Bits Op = new Bits(Opcode);
  157. AArch64.X((int)Rn, new Bits(Wn));
  158. AArch64.X((int)Rm, new Bits(Wm));
  159. AArch64.X((int)Ra, new Bits(Xa));
  160. Base.Smaddl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
  161. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  162. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  163. }
  164. else
  165. {
  166. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  167. }
  168. }
  169. [Test, Description("UMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
  170. public void Umaddl_64bit([Values(0u, 31u)] uint Rd,
  171. [Values(1u, 31u)] uint Rn,
  172. [Values(2u, 31u)] uint Rm,
  173. [Values(3u, 31u)] uint Ra,
  174. [Values(0x00000000u, 0x7FFFFFFFu,
  175. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  176. [Values(0x00000000u, 0x7FFFFFFFu,
  177. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
  178. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  179. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
  180. {
  181. uint Opcode = 0x9BA00000; // UMADDL X0, W0, W0, X0
  182. Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  183. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  184. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
  185. if (Rd != 31)
  186. {
  187. Bits Op = new Bits(Opcode);
  188. AArch64.X((int)Rn, new Bits(Wn));
  189. AArch64.X((int)Rm, new Bits(Wm));
  190. AArch64.X((int)Ra, new Bits(Xa));
  191. Base.Umaddl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
  192. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  193. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  194. }
  195. else
  196. {
  197. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  198. }
  199. }
  200. [Test, Description("SMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
  201. public void Smsubl_64bit([Values(0u, 31u)] uint Rd,
  202. [Values(1u, 31u)] uint Rn,
  203. [Values(2u, 31u)] uint Rm,
  204. [Values(3u, 31u)] uint Ra,
  205. [Values(0x00000000u, 0x7FFFFFFFu,
  206. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  207. [Values(0x00000000u, 0x7FFFFFFFu,
  208. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
  209. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  210. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
  211. {
  212. uint Opcode = 0x9B208000; // SMSUBL X0, W0, W0, X0
  213. Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  214. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  215. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
  216. if (Rd != 31)
  217. {
  218. Bits Op = new Bits(Opcode);
  219. AArch64.X((int)Rn, new Bits(Wn));
  220. AArch64.X((int)Rm, new Bits(Wm));
  221. AArch64.X((int)Ra, new Bits(Xa));
  222. Base.Smsubl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
  223. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  224. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  225. }
  226. else
  227. {
  228. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  229. }
  230. }
  231. [Test, Description("UMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
  232. public void Umsubl_64bit([Values(0u, 31u)] uint Rd,
  233. [Values(1u, 31u)] uint Rn,
  234. [Values(2u, 31u)] uint Rm,
  235. [Values(3u, 31u)] uint Ra,
  236. [Values(0x00000000u, 0x7FFFFFFFu,
  237. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wn,
  238. [Values(0x00000000u, 0x7FFFFFFFu,
  239. 0x80000000u, 0xFFFFFFFFu)] [Random(2)] uint Wm,
  240. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  241. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(2)] ulong Xa)
  242. {
  243. uint Opcode = 0x9BA08000; // UMSUBL X0, W0, W0, X0
  244. Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  245. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  246. AThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
  247. if (Rd != 31)
  248. {
  249. Bits Op = new Bits(Opcode);
  250. AArch64.X((int)Rn, new Bits(Wn));
  251. AArch64.X((int)Rm, new Bits(Wm));
  252. AArch64.X((int)Ra, new Bits(Xa));
  253. Base.Umsubl(Op[20, 16], Op[14, 10], Op[9, 5], Op[4, 0]);
  254. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  255. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  256. }
  257. else
  258. {
  259. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  260. }
  261. }
  262. [Test, Description("SMULH <Xd>, <Xn>, <Xm>")]
  263. public void Smulh_64bit([Values(0u, 31u)] uint Rd,
  264. [Values(1u, 31u)] uint Rn,
  265. [Values(2u, 31u)] uint Rm,
  266. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  267. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xn,
  268. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  269. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xm)
  270. {
  271. uint Opcode = 0x9B407C00; // SMULH X0, X0, X0
  272. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  273. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  274. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  275. if (Rd != 31)
  276. {
  277. Bits Op = new Bits(Opcode);
  278. AArch64.X((int)Rn, new Bits(Xn));
  279. AArch64.X((int)Rm, new Bits(Xm));
  280. Base.Smulh(Op[20, 16], Op[9, 5], Op[4, 0]);
  281. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  282. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  283. }
  284. else
  285. {
  286. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  287. }
  288. }
  289. [Test, Description("UMULH <Xd>, <Xn>, <Xm>")]
  290. public void Umulh_64bit([Values(0u, 31u)] uint Rd,
  291. [Values(1u, 31u)] uint Rn,
  292. [Values(2u, 31u)] uint Rm,
  293. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  294. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xn,
  295. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  296. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(16)] ulong Xm)
  297. {
  298. uint Opcode = 0x9BC07C00; // UMULH X0, X0, X0
  299. Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
  300. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  301. AThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
  302. if (Rd != 31)
  303. {
  304. Bits Op = new Bits(Opcode);
  305. AArch64.X((int)Rn, new Bits(Xn));
  306. AArch64.X((int)Rm, new Bits(Xm));
  307. Base.Umulh(Op[20, 16], Op[9, 5], Op[4, 0]);
  308. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  309. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  310. }
  311. else
  312. {
  313. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  314. }
  315. }
  316. #endif
  317. }
  318. }