CpuTestSimdArithmetic.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. using ChocolArm64.State;
  2. using NUnit.Framework;
  3. using System.Runtime.Intrinsics;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. public class CpuTestSimdArithmetic : CpuTest
  7. {
  8. [TestCase(0x00000000u, 0x7F800000u)]
  9. [TestCase(0x80000000u, 0xFF800000u)]
  10. [TestCase(0x00FFF000u, 0x7E000000u)]
  11. [TestCase(0x41200000u, 0x3DCC8000u)]
  12. [TestCase(0xC1200000u, 0xBDCC8000u)]
  13. [TestCase(0x001FFFFFu, 0x7F800000u)]
  14. [TestCase(0x007FF000u, 0x7E800000u)]
  15. public void Frecpe_S(uint a, uint result)
  16. {
  17. uint opcode = 0x5EA1D820; // FRECPE S0, S1
  18. Vector128<float> v1 = MakeVectorE0(a);
  19. CpuThreadState threadState = SingleOpcode(opcode, v1: v1);
  20. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  21. CompareAgainstUnicorn();
  22. }
  23. [TestCase(0x3FE66666u, false, 0x40000000u)]
  24. [TestCase(0x3F99999Au, false, 0x3F800000u)]
  25. [TestCase(0x404CCCCDu, false, 0x40400000u)]
  26. [TestCase(0x40733333u, false, 0x40800000u)]
  27. [TestCase(0x3FC00000u, false, 0x40000000u)]
  28. [TestCase(0x40200000u, false, 0x40400000u)]
  29. [TestCase(0x00000000u, false, 0x00000000u)]
  30. [TestCase(0x80000000u, false, 0x80000000u)]
  31. [TestCase(0x7F800000u, false, 0x7F800000u)]
  32. [TestCase(0xFF800000u, false, 0xFF800000u)]
  33. [TestCase(0xFF800001u, false, 0xFFC00001u, Ignore = "NaN test.")]
  34. [TestCase(0xFF800001u, true, 0x7FC00000u, Ignore = "NaN test.")]
  35. [TestCase(0x7FC00002u, false, 0x7FC00002u, Ignore = "NaN test.")]
  36. [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
  37. public void Frinta_S(uint a, bool defaultNaN, uint result)
  38. {
  39. uint opcode = 0x1E264020; // FRINTA S0, S1
  40. Vector128<float> v1 = MakeVectorE0(a);
  41. int fpcrTemp = 0x0;
  42. if (defaultNaN)
  43. {
  44. fpcrTemp = 0x2000000;
  45. }
  46. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  47. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  48. CompareAgainstUnicorn();
  49. }
  50. [TestCase(0x6E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTA V0.2D, V1.2D
  51. [TestCase(0x6E618820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
  52. [TestCase(0x6E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
  53. [TestCase(0x6E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTA V0.4S, V1.4S
  54. [TestCase(0x6E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
  55. [TestCase(0x2E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTA V0.2S, V1.2S
  56. [TestCase(0x2E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
  57. [TestCase(0x2E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
  58. [TestCase(0x2E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  59. [TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  60. [TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  61. public void Frinta_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
  62. {
  63. Vector128<float> v1 = MakeVectorE0E1(a, b);
  64. int fpcrTemp = 0x0;
  65. if (defaultNaN)
  66. {
  67. fpcrTemp = 0x2000000;
  68. }
  69. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  70. Assert.Multiple(() =>
  71. {
  72. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
  73. Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
  74. });
  75. CompareAgainstUnicorn();
  76. }
  77. [TestCase(0x3FE66666u, 'N', false, 0x40000000u)]
  78. [TestCase(0x3F99999Au, 'N', false, 0x3F800000u)]
  79. [TestCase(0x404CCCCDu, 'P', false, 0x40800000u)]
  80. [TestCase(0x40733333u, 'P', false, 0x40800000u)]
  81. [TestCase(0x404CCCCDu, 'M', false, 0x40400000u)]
  82. [TestCase(0x40733333u, 'M', false, 0x40400000u)]
  83. [TestCase(0x3F99999Au, 'Z', false, 0x3F800000u)]
  84. [TestCase(0x3FE66666u, 'Z', false, 0x3F800000u)]
  85. [TestCase(0x00000000u, 'N', false, 0x00000000u)]
  86. [TestCase(0x00000000u, 'P', false, 0x00000000u)]
  87. [TestCase(0x00000000u, 'M', false, 0x00000000u)]
  88. [TestCase(0x00000000u, 'Z', false, 0x00000000u)]
  89. [TestCase(0x80000000u, 'N', false, 0x80000000u)]
  90. [TestCase(0x80000000u, 'P', false, 0x80000000u)]
  91. [TestCase(0x80000000u, 'M', false, 0x80000000u)]
  92. [TestCase(0x80000000u, 'Z', false, 0x80000000u)]
  93. [TestCase(0x7F800000u, 'N', false, 0x7F800000u)]
  94. [TestCase(0x7F800000u, 'P', false, 0x7F800000u)]
  95. [TestCase(0x7F800000u, 'M', false, 0x7F800000u)]
  96. [TestCase(0x7F800000u, 'Z', false, 0x7F800000u)]
  97. [TestCase(0xFF800000u, 'N', false, 0xFF800000u)]
  98. [TestCase(0xFF800000u, 'P', false, 0xFF800000u)]
  99. [TestCase(0xFF800000u, 'M', false, 0xFF800000u)]
  100. [TestCase(0xFF800000u, 'Z', false, 0xFF800000u)]
  101. [TestCase(0xFF800001u, 'N', false, 0xFFC00001u, Ignore = "NaN test.")]
  102. [TestCase(0xFF800001u, 'P', false, 0xFFC00001u, Ignore = "NaN test.")]
  103. [TestCase(0xFF800001u, 'M', false, 0xFFC00001u, Ignore = "NaN test.")]
  104. [TestCase(0xFF800001u, 'Z', false, 0xFFC00001u, Ignore = "NaN test.")]
  105. [TestCase(0xFF800001u, 'N', true, 0x7FC00000u, Ignore = "NaN test.")]
  106. [TestCase(0xFF800001u, 'P', true, 0x7FC00000u, Ignore = "NaN test.")]
  107. [TestCase(0xFF800001u, 'M', true, 0x7FC00000u, Ignore = "NaN test.")]
  108. [TestCase(0xFF800001u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
  109. [TestCase(0x7FC00002u, 'N', false, 0x7FC00002u, Ignore = "NaN test.")]
  110. [TestCase(0x7FC00002u, 'P', false, 0x7FC00002u, Ignore = "NaN test.")]
  111. [TestCase(0x7FC00002u, 'M', false, 0x7FC00002u, Ignore = "NaN test.")]
  112. [TestCase(0x7FC00002u, 'Z', false, 0x7FC00002u, Ignore = "NaN test.")]
  113. [TestCase(0x7FC00002u, 'N', true, 0x7FC00000u, Ignore = "NaN test.")]
  114. [TestCase(0x7FC00002u, 'P', true, 0x7FC00000u, Ignore = "NaN test.")]
  115. [TestCase(0x7FC00002u, 'M', true, 0x7FC00000u, Ignore = "NaN test.")]
  116. [TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
  117. public void Frinti_S(uint a, char roundMode, bool defaultNaN, uint result)
  118. {
  119. uint opcode = 0x1E27C020; // FRINTI S0, S1
  120. Vector128<float> v1 = MakeVectorE0(a);
  121. int fpcrTemp = 0x0;
  122. switch (roundMode)
  123. {
  124. case 'N': fpcrTemp = 0x0; break;
  125. case 'P': fpcrTemp = 0x400000; break;
  126. case 'M': fpcrTemp = 0x800000; break;
  127. case 'Z': fpcrTemp = 0xC00000; break;
  128. }
  129. if (defaultNaN)
  130. {
  131. fpcrTemp |= 1 << 25;
  132. }
  133. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  134. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  135. CompareAgainstUnicorn();
  136. }
  137. [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTI V0.2D, V1.2D
  138. [TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'N', false, 0x4000000000000000ul, 0x4000000000000000ul)]
  139. [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
  140. [TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
  141. [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  142. [TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  143. [TestCase(0x6EE19820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  144. [TestCase(0x6EE19820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  145. [TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTI V0.4S, V1.4S
  146. [TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)]
  147. [TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
  148. [TestCase(0x6EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
  149. [TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTI V0.2S, V1.2S
  150. [TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)]
  151. [TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
  152. [TestCase(0x2EA19820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
  153. [TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)]
  154. [TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)]
  155. [TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'M', false, 0x0000000080000000ul, 0x0000000000000000ul)]
  156. [TestCase(0x2EA19820u, 0x0000000080000000ul, 0x0000000000000000ul, 'Z', false, 0x0000000080000000ul, 0x0000000000000000ul)]
  157. [TestCase(0x2EA19820u, 0x7F800000FF800000ul, 0x0000000000000000ul, 'N', false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  158. [TestCase(0x2EA19820u, 0x7F800000FF800000ul, 0x0000000000000000ul, 'P', false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  159. [TestCase(0x2EA19820u, 0x7F800000FF800000ul, 0x0000000000000000ul, 'M', false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  160. [TestCase(0x2EA19820u, 0x7F800000FF800000ul, 0x0000000000000000ul, 'Z', false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  161. [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'N', false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  162. [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'P', false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  163. [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'M', false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  164. [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  165. [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'N', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  166. [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'P', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  167. [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'M', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  168. [TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  169. public void Frinti_V(uint opcode, ulong a, ulong b, char roundMode, bool defaultNaN, ulong result0, ulong result1)
  170. {
  171. Vector128<float> v1 = MakeVectorE0E1(a, b);
  172. int fpcrTemp = 0x0;
  173. switch (roundMode)
  174. {
  175. case 'N': fpcrTemp = 0x0; break;
  176. case 'P': fpcrTemp = 0x400000; break;
  177. case 'M': fpcrTemp = 0x800000; break;
  178. case 'Z': fpcrTemp = 0xC00000; break;
  179. }
  180. if (defaultNaN)
  181. {
  182. fpcrTemp |= 1 << 25;
  183. }
  184. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  185. Assert.Multiple(() =>
  186. {
  187. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
  188. Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
  189. });
  190. CompareAgainstUnicorn();
  191. }
  192. [TestCase(0x3FE66666u, false, 0x3F800000u)]
  193. [TestCase(0x3F99999Au, false, 0x3F800000u)]
  194. [TestCase(0x404CCCCDu, false, 0x40400000u)]
  195. [TestCase(0x40733333u, false, 0x40400000u)]
  196. [TestCase(0x3FC00000u, false, 0x3F800000u)]
  197. [TestCase(0x40200000u, false, 0x40000000u)]
  198. [TestCase(0x00000000u, false, 0x00000000u)]
  199. [TestCase(0x80000000u, false, 0x80000000u)]
  200. [TestCase(0x7F800000u, false, 0x7F800000u)]
  201. [TestCase(0xFF800000u, false, 0xFF800000u)]
  202. [TestCase(0xFF800001u, false, 0xFFC00001u, Ignore = "NaN test.")]
  203. [TestCase(0xFF800001u, true, 0x7FC00000u, Ignore = "NaN test.")]
  204. [TestCase(0x7FC00002u, false, 0x7FC00002u, Ignore = "NaN test.")]
  205. [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
  206. public void Frintm_S(uint a, bool defaultNaN, uint result)
  207. {
  208. uint opcode = 0x1E254020; // FRINTM S0, S1
  209. Vector128<float> v1 = MakeVectorE0(a);
  210. int fpcrTemp = 0x0;
  211. if (defaultNaN)
  212. {
  213. fpcrTemp = 0x2000000;
  214. }
  215. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  216. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  217. CompareAgainstUnicorn();
  218. }
  219. [TestCase(0x4E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTM V0.2D, V1.2D
  220. [TestCase(0x4E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  221. [TestCase(0x4E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)] // FRINTM V0.4S, V1.4S
  222. [TestCase(0x0E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F8000003F800000ul, 0x0000000000000000ul)] // FRINTM V0.2S, V1.2S
  223. [TestCase(0x0E219820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
  224. [TestCase(0x0E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  225. [TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  226. [TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  227. public void Frintm_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
  228. {
  229. Vector128<float> v1 = MakeVectorE0E1(a, b);
  230. int fpcrTemp = 0x0;
  231. if (defaultNaN)
  232. {
  233. fpcrTemp = 0x2000000;
  234. }
  235. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  236. Assert.Multiple(() =>
  237. {
  238. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
  239. Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
  240. });
  241. CompareAgainstUnicorn();
  242. }
  243. [TestCase(0x3FE66666u, false, 0x40000000u)]
  244. [TestCase(0x3F99999Au, false, 0x3F800000u)]
  245. [TestCase(0x404CCCCDu, false, 0x40400000u)]
  246. [TestCase(0x40733333u, false, 0x40800000u)]
  247. [TestCase(0x3FC00000u, false, 0x40000000u)]
  248. [TestCase(0x40200000u, false, 0x40000000u)]
  249. [TestCase(0x00000000u, false, 0x00000000u)]
  250. [TestCase(0x80000000u, false, 0x80000000u)]
  251. [TestCase(0x7F800000u, false, 0x7F800000u)]
  252. [TestCase(0xFF800000u, false, 0xFF800000u)]
  253. [TestCase(0xFF800001u, false, 0xFFC00001u, Ignore = "NaN test.")]
  254. [TestCase(0xFF800001u, true, 0x7FC00000u, Ignore = "NaN test.")]
  255. [TestCase(0x7FC00002u, false, 0x7FC00002u, Ignore = "NaN test.")]
  256. [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
  257. public void Frintn_S(uint a, bool defaultNaN, uint result)
  258. {
  259. uint opcode = 0x1E244020; // FRINTN S0, S1
  260. Vector128<float> v1 = MakeVectorE0(a);
  261. int fpcrTemp = 0x0;
  262. if (defaultNaN)
  263. {
  264. fpcrTemp = 0x2000000;
  265. }
  266. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  267. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  268. CompareAgainstUnicorn();
  269. }
  270. [TestCase(0x4E618820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTN V0.2D, V1.2D
  271. [TestCase(0x4E618820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
  272. [TestCase(0x4E618820u, 0x3FF8000000000000ul, 0x3FF8000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
  273. [TestCase(0x4E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTN V0.4S, V1.4S
  274. [TestCase(0x4E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x4000000040000000ul)]
  275. [TestCase(0x0E218820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTN V0.2S, V1.2S
  276. [TestCase(0x0E218820u, 0x3FC000003FC00000ul, 0x3FC000003FC00000ul, false, 0x4000000040000000ul, 0x0000000000000000ul)]
  277. [TestCase(0x0E218820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
  278. [TestCase(0x0E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  279. [TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  280. [TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  281. public void Frintn_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
  282. {
  283. Vector128<float> v1 = MakeVectorE0E1(a, b);
  284. int fpcrTemp = 0x0;
  285. if (defaultNaN)
  286. {
  287. fpcrTemp = 0x2000000;
  288. }
  289. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  290. Assert.Multiple(() =>
  291. {
  292. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
  293. Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
  294. });
  295. CompareAgainstUnicorn();
  296. }
  297. [TestCase(0x3FE66666u, false, 0x40000000u)]
  298. [TestCase(0x3F99999Au, false, 0x40000000u)]
  299. [TestCase(0x404CCCCDu, false, 0x40800000u)]
  300. [TestCase(0x40733333u, false, 0x40800000u)]
  301. [TestCase(0x3FC00000u, false, 0x40000000u)]
  302. [TestCase(0x40200000u, false, 0x40400000u)]
  303. [TestCase(0x00000000u, false, 0x00000000u)]
  304. [TestCase(0x80000000u, false, 0x80000000u)]
  305. [TestCase(0x7F800000u, false, 0x7F800000u)]
  306. [TestCase(0xFF800000u, false, 0xFF800000u)]
  307. [TestCase(0xFF800001u, false, 0xFFC00001u, Ignore = "NaN test.")]
  308. [TestCase(0xFF800001u, true, 0x7FC00000u, Ignore = "NaN test.")]
  309. [TestCase(0x7FC00002u, false, 0x7FC00002u, Ignore = "NaN test.")]
  310. [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
  311. public void Frintp_S(uint a, bool defaultNaN, uint result)
  312. {
  313. uint opcode = 0x1E24C020; // FRINTP S0, S1
  314. Vector128<float> v1 = MakeVectorE0(a);
  315. int fpcrTemp = 0x0;
  316. if (defaultNaN)
  317. {
  318. fpcrTemp = 0x2000000;
  319. }
  320. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  321. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  322. CompareAgainstUnicorn();
  323. }
  324. [TestCase(0x4EE18820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, false, 0x4000000000000000ul, 0x4000000000000000ul)] // FRINTP V0.2D, v1.2D
  325. [TestCase(0x4EE18820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
  326. [TestCase(0x4EA18820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x4000000040000000ul, 0x4000000040000000ul)] // FRINTP V0.4S, v1.4S
  327. [TestCase(0x0EA18820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, false, 0x4000000040000000ul, 0x0000000000000000ul)] // FRINTP V0.2S, v1.2S
  328. [TestCase(0x0EA18820u, 0x0000000080000000ul, 0x0000000000000000ul, false, 0x0000000080000000ul, 0x0000000000000000ul)]
  329. [TestCase(0x0EA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  330. [TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  331. [TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  332. public void Frintp_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
  333. {
  334. Vector128<float> v1 = MakeVectorE0E1(a, b);
  335. int fpcrTemp = 0x0;
  336. if (defaultNaN)
  337. {
  338. fpcrTemp = 0x2000000;
  339. }
  340. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  341. Assert.Multiple(() =>
  342. {
  343. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
  344. Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
  345. });
  346. CompareAgainstUnicorn();
  347. }
  348. [TestCase(0x3FE66666u, 'N', false, 0x40000000u)]
  349. [TestCase(0x3F99999Au, 'N', false, 0x3F800000u)]
  350. [TestCase(0x404CCCCDu, 'P', false, 0x40800000u)]
  351. [TestCase(0x40733333u, 'P', false, 0x40800000u)]
  352. [TestCase(0x404CCCCDu, 'M', false, 0x40400000u)]
  353. [TestCase(0x40733333u, 'M', false, 0x40400000u)]
  354. [TestCase(0x3F99999Au, 'Z', false, 0x3F800000u)]
  355. [TestCase(0x3FE66666u, 'Z', false, 0x3F800000u)]
  356. [TestCase(0x00000000u, 'N', false, 0x00000000u)]
  357. [TestCase(0x00000000u, 'P', false, 0x00000000u)]
  358. [TestCase(0x00000000u, 'M', false, 0x00000000u)]
  359. [TestCase(0x00000000u, 'Z', false, 0x00000000u)]
  360. [TestCase(0x80000000u, 'N', false, 0x80000000u)]
  361. [TestCase(0x80000000u, 'P', false, 0x80000000u)]
  362. [TestCase(0x80000000u, 'M', false, 0x80000000u)]
  363. [TestCase(0x80000000u, 'Z', false, 0x80000000u)]
  364. [TestCase(0x7F800000u, 'N', false, 0x7F800000u)]
  365. [TestCase(0x7F800000u, 'P', false, 0x7F800000u)]
  366. [TestCase(0x7F800000u, 'M', false, 0x7F800000u)]
  367. [TestCase(0x7F800000u, 'Z', false, 0x7F800000u)]
  368. [TestCase(0xFF800000u, 'N', false, 0xFF800000u)]
  369. [TestCase(0xFF800000u, 'P', false, 0xFF800000u)]
  370. [TestCase(0xFF800000u, 'M', false, 0xFF800000u)]
  371. [TestCase(0xFF800000u, 'Z', false, 0xFF800000u)]
  372. [TestCase(0xFF800001u, 'N', false, 0xFFC00001u, Ignore = "NaN test.")]
  373. [TestCase(0xFF800001u, 'P', false, 0xFFC00001u, Ignore = "NaN test.")]
  374. [TestCase(0xFF800001u, 'M', false, 0xFFC00001u, Ignore = "NaN test.")]
  375. [TestCase(0xFF800001u, 'Z', false, 0xFFC00001u, Ignore = "NaN test.")]
  376. [TestCase(0xFF800001u, 'N', true, 0x7FC00000u, Ignore = "NaN test.")]
  377. [TestCase(0xFF800001u, 'P', true, 0x7FC00000u, Ignore = "NaN test.")]
  378. [TestCase(0xFF800001u, 'M', true, 0x7FC00000u, Ignore = "NaN test.")]
  379. [TestCase(0xFF800001u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
  380. [TestCase(0x7FC00002u, 'N', false, 0x7FC00002u, Ignore = "NaN test.")]
  381. [TestCase(0x7FC00002u, 'P', false, 0x7FC00002u, Ignore = "NaN test.")]
  382. [TestCase(0x7FC00002u, 'M', false, 0x7FC00002u, Ignore = "NaN test.")]
  383. [TestCase(0x7FC00002u, 'Z', false, 0x7FC00002u, Ignore = "NaN test.")]
  384. [TestCase(0x7FC00002u, 'N', true, 0x7FC00000u, Ignore = "NaN test.")]
  385. [TestCase(0x7FC00002u, 'P', true, 0x7FC00000u, Ignore = "NaN test.")]
  386. [TestCase(0x7FC00002u, 'M', true, 0x7FC00000u, Ignore = "NaN test.")]
  387. [TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
  388. public void Frintx_S(uint a, char roundMode, bool defaultNaN, uint result)
  389. {
  390. uint opcode = 0x1E274020; // FRINTX S0, S1
  391. Vector128<float> v1 = MakeVectorE0(a);
  392. int fpcrTemp = 0x0;
  393. switch (roundMode)
  394. {
  395. case 'N': fpcrTemp = 0x0; break;
  396. case 'P': fpcrTemp = 0x400000; break;
  397. case 'M': fpcrTemp = 0x800000; break;
  398. case 'Z': fpcrTemp = 0xC00000; break;
  399. }
  400. if (defaultNaN)
  401. {
  402. fpcrTemp |= 1 << 25;
  403. }
  404. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  405. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  406. CompareAgainstUnicorn();
  407. }
  408. [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'N', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)] // FRINTX V0.2D, V1.2D
  409. [TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'N', false, 0x4000000000000000ul, 0x4000000000000000ul)]
  410. [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
  411. [TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'P', false, 0x4000000000000000ul, 0x4000000000000000ul)]
  412. [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  413. [TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'M', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  414. [TestCase(0x6E619820u, 0x3FF3333333333333ul, 0x3FF3333333333333ul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  415. [TestCase(0x6E619820u, 0x3FFCCCCCCCCCCCCDul, 0x3FFCCCCCCCCCCCCDul, 'Z', false, 0x3FF0000000000000ul, 0x3FF0000000000000ul)]
  416. [TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x3F80000040000000ul)] // FRINTX V0.4S, V1.4S
  417. [TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'P', false, 0x4000000040000000ul, 0x4000000040000000ul)]
  418. [TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
  419. [TestCase(0x6E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x3F8000003F800000ul)]
  420. [TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'N', false, 0x3F80000040000000ul, 0x0000000000000000ul)] // FRINTX V0.2S, V1.2S
  421. [TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'P', false, 0x4000000040000000ul, 0x0000000000000000ul)]
  422. [TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'M', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
  423. [TestCase(0x2E219820u, 0x3F99999A3FE66666ul, 0x3F99999A3FE66666ul, 'Z', false, 0x3F8000003F800000ul, 0x0000000000000000ul)]
  424. [TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'N', false, 0x0000000080000000ul, 0x0000000000000000ul)]
  425. [TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'P', false, 0x0000000080000000ul, 0x0000000000000000ul)]
  426. [TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'M', false, 0x0000000080000000ul, 0x0000000000000000ul)]
  427. [TestCase(0x2E219820u, 0x0000000080000000ul, 0x0000000000000000ul, 'Z', false, 0x0000000080000000ul, 0x0000000000000000ul)]
  428. [TestCase(0x2E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, 'N', false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  429. [TestCase(0x2E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, 'P', false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  430. [TestCase(0x2E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, 'M', false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  431. [TestCase(0x2E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, 'Z', false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
  432. [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'N', false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  433. [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'P', false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  434. [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'M', false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  435. [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  436. [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'N', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  437. [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'P', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  438. [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'M', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  439. [TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  440. public void Frintx_V(uint opcode, ulong a, ulong b, char roundMode, bool defaultNaN, ulong result0, ulong result1)
  441. {
  442. Vector128<float> v1 = MakeVectorE0E1(a, b);
  443. int fpcrTemp = 0x0;
  444. switch (roundMode)
  445. {
  446. case 'N': fpcrTemp = 0x0; break;
  447. case 'P': fpcrTemp = 0x400000; break;
  448. case 'M': fpcrTemp = 0x800000; break;
  449. case 'Z': fpcrTemp = 0xC00000; break;
  450. }
  451. if (defaultNaN)
  452. {
  453. fpcrTemp |= 1 << 25;
  454. }
  455. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  456. Assert.Multiple(() =>
  457. {
  458. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
  459. Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
  460. });
  461. CompareAgainstUnicorn();
  462. }
  463. [TestCase(0xBFF33333u, false, 0xBF800000u)]
  464. [TestCase(0x40200000u, false, 0x40000000u)]
  465. [TestCase(0xFF800001u, false, 0xFFC00001u, Ignore = "NaN test.")]
  466. [TestCase(0xFF800001u, true, 0x7FC00000u, Ignore = "NaN test.")]
  467. [TestCase(0x7FC00002u, false, 0x7FC00002u, Ignore = "NaN test.")]
  468. [TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
  469. public void Frintz_S(uint a, bool defaultNaN, uint result)
  470. {
  471. uint opcode = 0x1E25C020; // FRINTZ S0, S1
  472. Vector128<float> v1 = MakeVectorE0(a);
  473. int fpcrTemp = 0x0;
  474. if (defaultNaN)
  475. {
  476. fpcrTemp = 0x2000000;
  477. }
  478. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  479. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  480. CompareAgainstUnicorn();
  481. }
  482. [TestCase(0x4EE19820u, 0xBFF999999999999Aul, 0xBFF999999999999Aul, false, 0xBFF0000000000000ul, 0xBFF0000000000000ul)] // FRINTZ V0.2D, V1.2D
  483. [TestCase(0x4EE19820u, 0x4004000000000000ul, 0x4004000000000000ul, false, 0x4000000000000000ul, 0x4000000000000000ul)]
  484. [TestCase(0x0EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  485. [TestCase(0x0EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
  486. public void Frintz_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
  487. {
  488. Vector128<float> v1 = MakeVectorE0E1(a, b);
  489. int fpcrTemp = 0x0;
  490. if (defaultNaN)
  491. {
  492. fpcrTemp = 0x2000000;
  493. }
  494. CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
  495. Assert.Multiple(() =>
  496. {
  497. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
  498. Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
  499. });
  500. CompareAgainstUnicorn();
  501. }
  502. [TestCase(0x41200000u, 0x3EA18000u)]
  503. public void Frsqrte_S(uint a, uint result)
  504. {
  505. uint opcode = 0x7EA1D820; // FRSQRTE S0, S1
  506. Vector128<float> v1 = MakeVectorE0(a);
  507. CpuThreadState threadState = SingleOpcode(opcode, v1: v1);
  508. Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
  509. CompareAgainstUnicorn();
  510. }
  511. }
  512. }