CpuTestAlu32.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #define Alu32
  2. using NUnit.Framework;
  3. namespace Ryujinx.Tests.Cpu
  4. {
  5. [Category("Alu32")]
  6. public sealed class CpuTestAlu32 : CpuTest32
  7. {
  8. #if Alu32
  9. #region "ValueSource (Opcodes)"
  10. private static uint[] _SU_H_AddSub_8_()
  11. {
  12. return new uint[]
  13. {
  14. 0xe6100f90u, // SADD8 R0, R0, R0
  15. 0xe6100ff0u, // SSUB8 R0, R0, R0
  16. 0xe6300f90u, // SHADD8 R0, R0, R0
  17. 0xe6300ff0u, // SHSUB8 R0, R0, R0
  18. 0xe6500f90u, // UADD8 R0, R0, R0
  19. 0xe6500ff0u, // USUB8 R0, R0, R0
  20. 0xe6700f90u, // UHADD8 R0, R0, R0
  21. 0xe6700ff0u // UHSUB8 R0, R0, R0
  22. };
  23. }
  24. private static uint[] _Ssat_Usat_()
  25. {
  26. return new uint[]
  27. {
  28. 0xe6a00010u, // SSAT R0, #1, R0, LSL #0
  29. 0xe6a00050u, // SSAT R0, #1, R0, ASR #32
  30. 0xe6e00010u, // USAT R0, #0, R0, LSL #0
  31. 0xe6e00050u // USAT R0, #0, R0, ASR #32
  32. };
  33. }
  34. private static uint[] _Ssat16_Usat16_()
  35. {
  36. return new uint[]
  37. {
  38. 0xe6a00f30u, // SSAT16 R0, #1, R0
  39. 0xe6e00f30u, // USAT16 R0, #0, R0
  40. };
  41. }
  42. private static uint[] _Lsr_Lsl_Asr_Ror_()
  43. {
  44. return new uint[]
  45. {
  46. 0xe1b00030u, // LSRS R0, R0, R0
  47. 0xe1b00010u, // LSLS R0, R0, R0
  48. 0xe1b00050u, // ASRS R0, R0, R0
  49. 0xe1b00070u // RORS R0, R0, R0
  50. };
  51. }
  52. #endregion
  53. private const int RndCnt = 2;
  54. [Test, Pairwise, Description("RBIT <Rd>, <Rn>")]
  55. public void Rbit_32bit([Values(0u, 0xdu)] uint rd,
  56. [Values(1u, 0xdu)] uint rm,
  57. [Values(0x00000000u, 0x7FFFFFFFu,
  58. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
  59. {
  60. uint opcode = 0xe6ff0f30u; // RBIT R0, R0
  61. opcode |= ((rm & 15) << 0) | ((rd & 15) << 12);
  62. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  63. SingleOpcode(opcode, r1: wn, sp: w31);
  64. CompareAgainstUnicorn();
  65. }
  66. [Test, Pairwise]
  67. public void Lsr_Lsl_Asr_Ror([ValueSource("_Lsr_Lsl_Asr_Ror_")] uint opcode,
  68. [Values(0x00000000u, 0x7FFFFFFFu,
  69. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint shiftValue,
  70. [Range(0, 31)] [Values(32, 256, 768, -1, -23)] int shiftAmount)
  71. {
  72. uint rd = 0;
  73. uint rm = 1;
  74. uint rs = 2;
  75. opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rs & 15) << 8);
  76. SingleOpcode(opcode, r1: shiftValue, r2: (uint)shiftAmount);
  77. CompareAgainstUnicorn();
  78. }
  79. [Test, Pairwise]
  80. public void Shadd8([Values(0u, 0xdu)] uint rd,
  81. [Values(1u)] uint rm,
  82. [Values(2u)] uint rn,
  83. [Random(RndCnt)] uint w0,
  84. [Random(RndCnt)] uint w1,
  85. [Random(RndCnt)] uint w2)
  86. {
  87. uint opcode = 0xE6300F90u; // SHADD8 R0, R0, R0
  88. opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
  89. uint sp = TestContext.CurrentContext.Random.NextUInt();
  90. SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp);
  91. CompareAgainstUnicorn();
  92. }
  93. [Test, Pairwise]
  94. public void Shsub8([Values(0u, 0xdu)] uint rd,
  95. [Values(1u)] uint rm,
  96. [Values(2u)] uint rn,
  97. [Random(RndCnt)] uint w0,
  98. [Random(RndCnt)] uint w1,
  99. [Random(RndCnt)] uint w2)
  100. {
  101. uint opcode = 0xE6300FF0u; // SHSUB8 R0, R0, R0
  102. opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
  103. uint sp = TestContext.CurrentContext.Random.NextUInt();
  104. SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp);
  105. CompareAgainstUnicorn();
  106. }
  107. [Test, Pairwise]
  108. public void Ssat_Usat([ValueSource("_Ssat_Usat_")] uint opcode,
  109. [Values(0u, 0xdu)] uint rd,
  110. [Values(1u, 0xdu)] uint rn,
  111. [Values(0u, 7u, 8u, 0xfu, 0x10u, 0x1fu)] uint sat,
  112. [Values(0u, 7u, 8u, 0xfu, 0x10u, 0x1fu)] uint shift,
  113. [Values(0x00000000u, 0x7FFFFFFFu,
  114. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
  115. {
  116. opcode |= ((rn & 15) << 0) | ((shift & 31) << 7) | ((rd & 15) << 12) | ((sat & 31) << 16);
  117. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  118. SingleOpcode(opcode, r1: wn, sp: w31);
  119. CompareAgainstUnicorn();
  120. }
  121. [Test, Pairwise]
  122. public void Ssat16_Usat16([ValueSource("_Ssat16_Usat16_")] uint opcode,
  123. [Values(0u, 0xdu)] uint rd,
  124. [Values(1u, 0xdu)] uint rn,
  125. [Values(0u, 7u, 8u, 0xfu)] uint sat,
  126. [Values(0x00000000u, 0x7FFFFFFFu,
  127. 0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
  128. {
  129. opcode |= ((rn & 15) << 0) | ((rd & 15) << 12) | ((sat & 15) << 16);
  130. uint w31 = TestContext.CurrentContext.Random.NextUInt();
  131. SingleOpcode(opcode, r1: wn, sp: w31);
  132. CompareAgainstUnicorn();
  133. }
  134. [Test, Pairwise]
  135. public void SU_H_AddSub_8([ValueSource("_SU_H_AddSub_8_")] uint opcode,
  136. [Values(0u, 0xdu)] uint rd,
  137. [Values(1u)] uint rm,
  138. [Values(2u)] uint rn,
  139. [Random(RndCnt)] uint w0,
  140. [Random(RndCnt)] uint w1,
  141. [Random(RndCnt)] uint w2)
  142. {
  143. opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
  144. uint sp = TestContext.CurrentContext.Random.NextUInt();
  145. SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp);
  146. CompareAgainstUnicorn();
  147. }
  148. [Test, Pairwise]
  149. public void Uadd8_Sel([Values(0u)] uint rd,
  150. [Values(1u)] uint rm,
  151. [Values(2u)] uint rn,
  152. [Random(RndCnt)] uint w0,
  153. [Random(RndCnt)] uint w1,
  154. [Random(RndCnt)] uint w2)
  155. {
  156. uint opUadd8 = 0xE6500F90; // UADD8 R0, R0, R0
  157. uint opSel = 0xE6800FB0; // SEL R0, R0, R0
  158. opUadd8 |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
  159. opSel |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
  160. SetContext(r0: w0, r1: w1, r2: w2);
  161. Opcode(opUadd8);
  162. Opcode(opSel);
  163. Opcode(0xE12FFF1E); // BX LR
  164. ExecuteOpcodes();
  165. CompareAgainstUnicorn();
  166. }
  167. #endif
  168. }
  169. }