CpuTestMisc.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. using ChocolArm64.State;
  2. using NUnit.Framework;
  3. namespace Ryujinx.Tests.Cpu
  4. {
  5. [Category("Misc"), Explicit]
  6. public sealed class CpuTestMisc : CpuTest
  7. {
  8. [TestCase(0xFFFFFFFDu)] // Roots.
  9. [TestCase(0x00000005u)]
  10. public void Misc1(uint A)
  11. {
  12. // ((A + 3) * (A - 5)) / ((A + 5) * (A - 3)) = 0
  13. /*
  14. ADD W2, W0, 3
  15. SUB W1, W0, #5
  16. MUL W2, W2, W1
  17. ADD W1, W0, 5
  18. SUB W0, W0, #3
  19. MUL W0, W1, W0
  20. SDIV W0, W2, W0
  21. BRK #0
  22. RET
  23. */
  24. SetThreadState(X0: A);
  25. Opcode(0x11000C02);
  26. Opcode(0x51001401);
  27. Opcode(0x1B017C42);
  28. Opcode(0x11001401);
  29. Opcode(0x51000C00);
  30. Opcode(0x1B007C20);
  31. Opcode(0x1AC00C40);
  32. Opcode(0xD4200000);
  33. Opcode(0xD65F03C0);
  34. ExecuteOpcodes();
  35. Assert.That(GetThreadState().X0, Is.Zero);
  36. }
  37. [TestCase(-20f, -5f)] // 18 integer solutions.
  38. [TestCase(-12f, -6f)]
  39. [TestCase(-12f, 3f)]
  40. [TestCase( -8f, -8f)]
  41. [TestCase( -6f, -12f)]
  42. [TestCase( -5f, -20f)]
  43. [TestCase( -4f, 2f)]
  44. [TestCase( -3f, 12f)]
  45. [TestCase( -2f, 4f)]
  46. [TestCase( 2f, -4f)]
  47. [TestCase( 3f, -12f)]
  48. [TestCase( 4f, -2f)]
  49. [TestCase( 5f, 20f)]
  50. [TestCase( 6f, 12f)]
  51. [TestCase( 8f, 8f)]
  52. [TestCase( 12f, -3f)]
  53. [TestCase( 12f, 6f)]
  54. [TestCase( 20f, 5f)]
  55. public void Misc2(float A, float B)
  56. {
  57. // 1 / ((1 / A + 1 / B) ^ 2) = 16
  58. /*
  59. FMOV S2, 1.0e+0
  60. FDIV S0, S2, S0
  61. FDIV S1, S2, S1
  62. FADD S0, S0, S1
  63. FDIV S0, S2, S0
  64. FMUL S0, S0, S0
  65. BRK #0
  66. RET
  67. */
  68. SetThreadState(V0: new AVec { S0 = A }, V1: new AVec { S0 = B });
  69. Opcode(0x1E2E1002);
  70. Opcode(0x1E201840);
  71. Opcode(0x1E211841);
  72. Opcode(0x1E212800);
  73. Opcode(0x1E201840);
  74. Opcode(0x1E200800);
  75. Opcode(0xD4200000);
  76. Opcode(0xD65F03C0);
  77. ExecuteOpcodes();
  78. Assert.That(GetThreadState().V0.S0, Is.EqualTo(16f));
  79. }
  80. [TestCase(-20d, -5d)] // 18 integer solutions.
  81. [TestCase(-12d, -6d)]
  82. [TestCase(-12d, 3d)]
  83. [TestCase( -8d, -8d)]
  84. [TestCase( -6d, -12d)]
  85. [TestCase( -5d, -20d)]
  86. [TestCase( -4d, 2d)]
  87. [TestCase( -3d, 12d)]
  88. [TestCase( -2d, 4d)]
  89. [TestCase( 2d, -4d)]
  90. [TestCase( 3d, -12d)]
  91. [TestCase( 4d, -2d)]
  92. [TestCase( 5d, 20d)]
  93. [TestCase( 6d, 12d)]
  94. [TestCase( 8d, 8d)]
  95. [TestCase( 12d, -3d)]
  96. [TestCase( 12d, 6d)]
  97. [TestCase( 20d, 5d)]
  98. public void Misc3(double A, double B)
  99. {
  100. // 1 / ((1 / A + 1 / B) ^ 2) = 16
  101. /*
  102. FMOV D2, 1.0e+0
  103. FDIV D0, D2, D0
  104. FDIV D1, D2, D1
  105. FADD D0, D0, D1
  106. FDIV D0, D2, D0
  107. FMUL D0, D0, D0
  108. BRK #0
  109. RET
  110. */
  111. SetThreadState(V0: new AVec { D0 = A }, V1: new AVec { D0 = B });
  112. Opcode(0x1E6E1002);
  113. Opcode(0x1E601840);
  114. Opcode(0x1E611841);
  115. Opcode(0x1E612800);
  116. Opcode(0x1E601840);
  117. Opcode(0x1E600800);
  118. Opcode(0xD4200000);
  119. Opcode(0xD65F03C0);
  120. ExecuteOpcodes();
  121. Assert.That(GetThreadState().V0.D0, Is.EqualTo(16d));
  122. }
  123. [Test]
  124. public void MiscF([Range(0u, 92u, 1u)] uint A)
  125. {
  126. ulong F_n(uint n)
  127. {
  128. ulong a = 0, b = 1, c;
  129. if (n == 0)
  130. {
  131. return a;
  132. }
  133. for (uint i = 2; i <= n; i++)
  134. {
  135. c = a + b;
  136. a = b;
  137. b = c;
  138. }
  139. return b;
  140. }
  141. /*
  142. 0x0000000000000000: MOV W4, W0
  143. 0x0000000000000004: CBZ W0, #0x3C
  144. 0x0000000000000008: CMP W0, #1
  145. 0x000000000000000C: B.LS #0x48
  146. 0x0000000000000010: MOVZ W2, #0x2
  147. 0x0000000000000014: MOVZ X1, #0x1
  148. 0x0000000000000018: MOVZ X3, #0
  149. 0x000000000000001C: ADD X0, X3, X1
  150. 0x0000000000000020: ADD W2, W2, #1
  151. 0x0000000000000024: MOV X3, X1
  152. 0x0000000000000028: MOV X1, X0
  153. 0x000000000000002C: CMP W4, W2
  154. 0x0000000000000030: B.HS #0x1C
  155. 0x0000000000000034: BRK #0
  156. 0x0000000000000038: RET
  157. 0x000000000000003C: MOVZ X0, #0
  158. 0x0000000000000040: BRK #0
  159. 0x0000000000000044: RET
  160. 0x0000000000000048: MOVZ X0, #0x1
  161. 0x000000000000004C: BRK #0
  162. 0x0000000000000050: RET
  163. */
  164. SetThreadState(X0: A);
  165. Opcode(0x2A0003E4);
  166. Opcode(0x340001C0);
  167. Opcode(0x7100041F);
  168. Opcode(0x540001E9);
  169. Opcode(0x52800042);
  170. Opcode(0xD2800021);
  171. Opcode(0xD2800003);
  172. Opcode(0x8B010060);
  173. Opcode(0x11000442);
  174. Opcode(0xAA0103E3);
  175. Opcode(0xAA0003E1);
  176. Opcode(0x6B02009F);
  177. Opcode(0x54FFFF62);
  178. Opcode(0xD4200000);
  179. Opcode(0xD65F03C0);
  180. Opcode(0xD2800000);
  181. Opcode(0xD4200000);
  182. Opcode(0xD65F03C0);
  183. Opcode(0xD2800020);
  184. Opcode(0xD4200000);
  185. Opcode(0xD65F03C0);
  186. ExecuteOpcodes();
  187. Assert.That(GetThreadState().X0, Is.EqualTo(F_n(A)));
  188. }
  189. [Test]
  190. public void MiscR()
  191. {
  192. const ulong Result = 5;
  193. /*
  194. 0x0000000000000000: MOV X0, #2
  195. 0x0000000000000004: MOV X1, #3
  196. 0x0000000000000008: ADD X0, X0, X1
  197. 0x000000000000000C: BRK #0
  198. 0x0000000000000010: RET
  199. */
  200. Opcode(0xD2800040);
  201. Opcode(0xD2800061);
  202. Opcode(0x8B010000);
  203. Opcode(0xD4200000);
  204. Opcode(0xD65F03C0);
  205. ExecuteOpcodes();
  206. Assert.That(GetThreadState().X0, Is.EqualTo(Result));
  207. Reset();
  208. /*
  209. 0x0000000000000000: MOV X0, #3
  210. 0x0000000000000004: MOV X1, #2
  211. 0x0000000000000008: ADD X0, X0, X1
  212. 0x000000000000000C: BRK #0
  213. 0x0000000000000010: RET
  214. */
  215. Opcode(0xD2800060);
  216. Opcode(0xD2800041);
  217. Opcode(0x8B010000);
  218. Opcode(0xD4200000);
  219. Opcode(0xD65F03C0);
  220. ExecuteOpcodes();
  221. Assert.That(GetThreadState().X0, Is.EqualTo(Result));
  222. }
  223. [TestCase( 0ul)]
  224. [TestCase( 1ul)]
  225. [TestCase( 2ul)]
  226. [TestCase(42ul)]
  227. public void SanityCheck(ulong A)
  228. {
  229. uint Opcode = 0xD503201F; // NOP
  230. AThreadState ThreadState = SingleOpcode(Opcode, X0: A);
  231. Assert.That(ThreadState.X0, Is.EqualTo(A));
  232. }
  233. }
  234. }