CpuTestAlu.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. [Test, Pairwise, Description("CLS <Xd>, <Xn>")]
  77. public void Cls_64bit([Values(0u, 31u)] uint rd,
  78. [Values(1u, 31u)] uint rn,
  79. [ValueSource(nameof(_GenLeadingSignsX_))] ulong xn)
  80. {
  81. uint opcode = 0xDAC01400; // CLS X0, X0
  82. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  83. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  84. SingleOpcode(opcode, x1: xn, x31: x31);
  85. CompareAgainstUnicorn();
  86. }
  87. [Test, Pairwise, Description("CLS <Wd>, <Wn>")]
  88. public void Cls_32bit([Values(0u, 31u)] uint rd,
  89. [Values(1u, 31u)] uint rn,
  90. [ValueSource(nameof(_GenLeadingSignsW_))] uint wn)
  91. {
  92. uint opcode = 0x5AC01400; // CLS W0, W0
  93. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  94. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  95. SingleOpcode(opcode, x1: wn, x31: w31);
  96. CompareAgainstUnicorn();
  97. }
  98. [Test, Pairwise, Description("CLZ <Xd>, <Xn>")]
  99. public void Clz_64bit([Values(0u, 31u)] uint rd,
  100. [Values(1u, 31u)] uint rn,
  101. [ValueSource(nameof(_GenLeadingZerosX_))] ulong xn)
  102. {
  103. uint opcode = 0xDAC01000; // CLZ X0, X0
  104. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  105. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  106. SingleOpcode(opcode, x1: xn, x31: x31);
  107. CompareAgainstUnicorn();
  108. }
  109. [Test, Pairwise, Description("CLZ <Wd>, <Wn>")]
  110. public void Clz_32bit([Values(0u, 31u)] uint rd,
  111. [Values(1u, 31u)] uint rn,
  112. [ValueSource(nameof(_GenLeadingZerosW_))] uint wn)
  113. {
  114. uint opcode = 0x5AC01000; // CLZ W0, W0
  115. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  116. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  117. SingleOpcode(opcode, x1: wn, x31: w31);
  118. CompareAgainstUnicorn();
  119. }
  120. [Test, Pairwise, Description("RBIT <Xd>, <Xn>")]
  121. public void Rbit_64bit([Values(0u, 31u)] uint rd,
  122. [Values(1u, 31u)] uint rn,
  123. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  124. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn)
  125. {
  126. uint opcode = 0xDAC00000; // RBIT X0, X0
  127. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  128. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  129. SingleOpcode(opcode, x1: xn, x31: x31);
  130. CompareAgainstUnicorn();
  131. }
  132. [Test, Pairwise, Description("RBIT <Wd>, <Wn>")]
  133. public void Rbit_32bit([Values(0u, 31u)] uint rd,
  134. [Values(1u, 31u)] uint rn,
  135. [Values(0x00000000u, 0x7FFFFFFFu,
  136. 0x80000000u, 0xFFFFFFFFu)] uint wn)
  137. {
  138. uint opcode = 0x5AC00000; // RBIT W0, W0
  139. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  140. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  141. SingleOpcode(opcode, x1: wn, x31: w31);
  142. CompareAgainstUnicorn();
  143. }
  144. [Test, Pairwise, Description("REV16 <Xd>, <Xn>")]
  145. public void Rev16_64bit([Values(0u, 31u)] uint rd,
  146. [Values(1u, 31u)] uint rn,
  147. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  148. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn)
  149. {
  150. uint opcode = 0xDAC00400; // REV16 X0, X0
  151. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  152. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  153. SingleOpcode(opcode, x1: xn, x31: x31);
  154. CompareAgainstUnicorn();
  155. }
  156. [Test, Pairwise, Description("REV16 <Wd>, <Wn>")]
  157. public void Rev16_32bit([Values(0u, 31u)] uint rd,
  158. [Values(1u, 31u)] uint rn,
  159. [Values(0x00000000u, 0x7FFFFFFFu,
  160. 0x80000000u, 0xFFFFFFFFu)] uint wn)
  161. {
  162. uint opcode = 0x5AC00400; // REV16 W0, W0
  163. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  164. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  165. SingleOpcode(opcode, x1: wn, x31: w31);
  166. CompareAgainstUnicorn();
  167. }
  168. [Test, Pairwise, Description("REV32 <Xd>, <Xn>")]
  169. public void Rev32_64bit([Values(0u, 31u)] uint rd,
  170. [Values(1u, 31u)] uint rn,
  171. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  172. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn)
  173. {
  174. uint opcode = 0xDAC00800; // REV32 X0, X0
  175. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  176. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  177. SingleOpcode(opcode, x1: xn, x31: x31);
  178. CompareAgainstUnicorn();
  179. }
  180. [Test, Pairwise, Description("REV <Wd>, <Wn>")]
  181. public void Rev32_32bit([Values(0u, 31u)] uint rd,
  182. [Values(1u, 31u)] uint rn,
  183. [Values(0x00000000u, 0x7FFFFFFFu,
  184. 0x80000000u, 0xFFFFFFFFu)] uint wn)
  185. {
  186. uint opcode = 0x5AC00800; // REV W0, W0
  187. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  188. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  189. SingleOpcode(opcode, x1: wn, x31: w31);
  190. CompareAgainstUnicorn();
  191. }
  192. [Test, Pairwise, Description("REV64 <Xd>, <Xn>")]
  193. public void Rev64_64bit([Values(0u, 31u)] uint rd,
  194. [Values(1u, 31u)] uint rn,
  195. [Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
  196. 0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn)
  197. {
  198. uint opcode = 0xDAC00C00; // REV64 X0, X0
  199. opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
  200. ulong x31 = TestContext.CurrentContext.Random.NextULong();
  201. SingleOpcode(opcode, x1: xn, x31: x31);
  202. CompareAgainstUnicorn();
  203. }
  204. #endif
  205. }
  206. }