CpuTestAlu.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. #define Alu
  2. using NUnit.Framework;
  3. using System.Collections.Generic;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. [Category("Alu")]
  7. public sealed class CpuTestAlu : CpuTest
  8. {
  9. #if Alu
  10. #region "Helper methods"
  11. private static uint GenLeadingSignsMinus32(int cnt) // 0 <= cnt <= 31
  12. {
  13. return ~GenLeadingZeros32(cnt + 1);
  14. }
  15. private static ulong GenLeadingSignsMinus64(int cnt) // 0 <= cnt <= 63
  16. {
  17. return ~GenLeadingZeros64(cnt + 1);
  18. }
  19. private static uint GenLeadingSignsPlus32(int cnt) // 0 <= cnt <= 31
  20. {
  21. return GenLeadingZeros32(cnt + 1);
  22. }
  23. private static ulong GenLeadingSignsPlus64(int cnt) // 0 <= cnt <= 63
  24. {
  25. return GenLeadingZeros64(cnt + 1);
  26. }
  27. private static uint GenLeadingZeros32(int cnt) // 0 <= cnt <= 32
  28. {
  29. if (cnt == 32) return 0u;
  30. if (cnt == 31) return 1u;
  31. uint rnd = TestContext.CurrentContext.Random.NextUInt();
  32. int mask = int.MinValue;
  33. return (rnd >> (cnt + 1)) | ((uint)mask >> cnt);
  34. }
  35. private static ulong GenLeadingZeros64(int cnt) // 0 <= cnt <= 64
  36. {
  37. if (cnt == 64) return 0ul;
  38. if (cnt == 63) return 1ul;
  39. ulong rnd = TestContext.CurrentContext.Random.NextULong();
  40. long mask = long.MinValue;
  41. return (rnd >> (cnt + 1)) | ((ulong)mask >> cnt);
  42. }
  43. #endregion
  44. #region "ValueSource (Types)"
  45. private static IEnumerable<ulong> _GenLeadingSignsX_()
  46. {
  47. for (int cnt = 0; cnt <= 63; cnt++)
  48. {
  49. yield return GenLeadingSignsMinus64(cnt);
  50. yield return GenLeadingSignsPlus64(cnt);
  51. }
  52. }
  53. private static IEnumerable<uint> _GenLeadingSignsW_()
  54. {
  55. for (int cnt = 0; cnt <= 31; cnt++)
  56. {
  57. yield return GenLeadingSignsMinus32(cnt);
  58. yield return GenLeadingSignsPlus32(cnt);
  59. }
  60. }
  61. private static IEnumerable<ulong> _GenLeadingZerosX_()
  62. {
  63. for (int cnt = 0; cnt <= 64; cnt++)
  64. {
  65. yield return GenLeadingZeros64(cnt);
  66. }
  67. }
  68. private static IEnumerable<uint> _GenLeadingZerosW_()
  69. {
  70. for (int cnt = 0; cnt <= 32; cnt++)
  71. {
  72. yield return GenLeadingZeros32(cnt);
  73. }
  74. }
  75. #endregion
  76. private const int RndCnt = 2;
  77. [Test, Pairwise, Description("CLS <Xd>, <Xn>")]
  78. public void Cls_64bit([Values(0u, 31u)] uint rd,
  79. [Values(1u, 31u)] uint rn,
  80. [ValueSource("_GenLeadingSignsX_")] [Random(RndCnt)] ulong xn)
  81. {
  82. uint opcode = 0xDAC01400; // CLS X0, X0
  83. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  84. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  85. SingleOpcode(opcode, x1: xn, x31: x31);
  86. CompareAgainstUnicorn();
  87. }
  88. [Test, Pairwise, Description("CLS <Wd>, <Wn>")]
  89. public void Cls_32bit([Values(0u, 31u)] uint rd,
  90. [Values(1u, 31u)] uint rn,
  91. [ValueSource("_GenLeadingSignsW_")] [Random(RndCnt)] uint wn)
  92. {
  93. uint opcode = 0x5AC01400; // CLS W0, W0
  94. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  95. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  96. SingleOpcode(opcode, x1: wn, x31: w31);
  97. CompareAgainstUnicorn();
  98. }
  99. [Test, Pairwise, Description("CLZ <Xd>, <Xn>")]
  100. public void Clz_64bit([Values(0u, 31u)] uint rd,
  101. [Values(1u, 31u)] uint rn,
  102. [ValueSource("_GenLeadingZerosX_")] [Random(RndCnt)] ulong xn)
  103. {
  104. uint opcode = 0xDAC01000; // CLZ X0, X0
  105. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  106. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  107. SingleOpcode(opcode, x1: xn, x31: x31);
  108. CompareAgainstUnicorn();
  109. }
  110. [Test, Pairwise, Description("CLZ <Wd>, <Wn>")]
  111. public void Clz_32bit([Values(0u, 31u)] uint rd,
  112. [Values(1u, 31u)] uint rn,
  113. [ValueSource("_GenLeadingZerosW_")] [Random(RndCnt)] uint wn)
  114. {
  115. uint opcode = 0x5AC01000; // CLZ W0, W0
  116. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  117. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  118. SingleOpcode(opcode, x1: wn, x31: w31);
  119. CompareAgainstUnicorn();
  120. }
  121. [Test, Pairwise, Description("RBIT <Xd>, <Xn>")]
  122. public void Rbit_64bit([Values(0u, 31u)] uint rd,
  123. [Values(1u, 31u)] uint rn,
  124. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  125. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
  126. {
  127. uint opcode = 0xDAC00000; // RBIT X0, X0
  128. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  129. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  130. SingleOpcode(opcode, x1: xn, x31: x31);
  131. CompareAgainstUnicorn();
  132. }
  133. [Test, Pairwise, Description("RBIT <Wd>, <Wn>")]
  134. public void Rbit_32bit([Values(0u, 31u)] uint rd,
  135. [Values(1u, 31u)] uint rn,
  136. [Values(0x00000000u, 0x7FFFFFFFu,
  137. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
  138. {
  139. uint opcode = 0x5AC00000; // RBIT W0, W0
  140. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  141. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  142. SingleOpcode(opcode, x1: wn, x31: w31);
  143. CompareAgainstUnicorn();
  144. }
  145. [Test, Pairwise, Description("REV16 <Xd>, <Xn>")]
  146. public void Rev16_64bit([Values(0u, 31u)] uint rd,
  147. [Values(1u, 31u)] uint rn,
  148. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  149. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
  150. {
  151. uint opcode = 0xDAC00400; // REV16 X0, X0
  152. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  153. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  154. SingleOpcode(opcode, x1: xn, x31: x31);
  155. CompareAgainstUnicorn();
  156. }
  157. [Test, Pairwise, Description("REV16 <Wd>, <Wn>")]
  158. public void Rev16_32bit([Values(0u, 31u)] uint rd,
  159. [Values(1u, 31u)] uint rn,
  160. [Values(0x00000000u, 0x7FFFFFFFu,
  161. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
  162. {
  163. uint opcode = 0x5AC00400; // REV16 W0, W0
  164. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  165. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  166. SingleOpcode(opcode, x1: wn, x31: w31);
  167. CompareAgainstUnicorn();
  168. }
  169. [Test, Pairwise, Description("REV32 <Xd>, <Xn>")]
  170. public void Rev32_64bit([Values(0u, 31u)] uint rd,
  171. [Values(1u, 31u)] uint rn,
  172. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  173. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
  174. {
  175. uint opcode = 0xDAC00800; // REV32 X0, X0
  176. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  177. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  178. SingleOpcode(opcode, x1: xn, x31: x31);
  179. CompareAgainstUnicorn();
  180. }
  181. [Test, Pairwise, Description("REV <Wd>, <Wn>")]
  182. public void Rev32_32bit([Values(0u, 31u)] uint rd,
  183. [Values(1u, 31u)] uint rn,
  184. [Values(0x00000000u, 0x7FFFFFFFu,
  185. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
  186. {
  187. uint opcode = 0x5AC00800; // REV W0, W0
  188. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  189. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  190. SingleOpcode(opcode, x1: wn, x31: w31);
  191. CompareAgainstUnicorn();
  192. }
  193. [Test, Pairwise, Description("REV64 <Xd>, <Xn>")]
  194. public void Rev64_64bit([Values(0u, 31u)] uint rd,
  195. [Values(1u, 31u)] uint rn,
  196. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  197. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
  198. {
  199. uint opcode = 0xDAC00C00; // REV64 X0, X0
  200. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  201. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  202. SingleOpcode(opcode, x1: xn, x31: x31);
  203. CompareAgainstUnicorn();
  204. }
  205. #endif
  206. }
  207. }