CpuTestMov.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //#define Mov
  2. using ChocolArm64.State;
  3. using NUnit.Framework;
  4. namespace Ryujinx.Tests.Cpu
  5. {
  6. using Tester;
  7. using Tester.Types;
  8. [Category("Mov"), Ignore("Tested: second half of 2018.")]
  9. public sealed class CpuTestMov : CpuTest
  10. {
  11. #if Mov
  12. [SetUp]
  13. public void SetupTester()
  14. {
  15. AArch64.TakeReset(false);
  16. }
  17. [Test, Description("MOVK <Xd>, #<imm>{, LSL #<shift>}")]
  18. public void Movk_64bit([Values(0u, 31u)] uint Rd,
  19. [Random(12)] ulong _Xd,
  20. [Values(0u, 65535u)] [Random(0u, 65535u, 10)] uint imm,
  21. [Values(0u, 16u, 32u, 48u)] uint shift)
  22. {
  23. uint Opcode = 0xF2800000; // MOVK X0, #0, LSL #0
  24. Opcode |= ((Rd & 31) << 0);
  25. Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
  26. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  27. AThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X31: _X31);
  28. if (Rd != 31)
  29. {
  30. Bits Op = new Bits(Opcode);
  31. AArch64.X((int)Rd, new Bits(_Xd));
  32. Base.Movk(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
  33. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  34. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  35. }
  36. else
  37. {
  38. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  39. }
  40. CompareAgainstUnicorn();
  41. }
  42. [Test, Description("MOVK <Wd>, #<imm>{, LSL #<shift>}")]
  43. public void Movk_32bit([Values(0u, 31u)] uint Rd,
  44. [Random(12)] uint _Wd,
  45. [Values(0u, 65535u)] [Random(0u, 65535u, 10)] uint imm,
  46. [Values(0u, 16u)] uint shift)
  47. {
  48. uint Opcode = 0x72800000; // MOVK W0, #0, LSL #0
  49. Opcode |= ((Rd & 31) << 0);
  50. Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
  51. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  52. AThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X31: _W31);
  53. if (Rd != 31)
  54. {
  55. Bits Op = new Bits(Opcode);
  56. AArch64.X((int)Rd, new Bits(_Wd));
  57. Base.Movk(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
  58. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  59. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  60. }
  61. else
  62. {
  63. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  64. }
  65. CompareAgainstUnicorn();
  66. }
  67. [Test, Description("MOVN <Xd>, #<imm>{, LSL #<shift>}")]
  68. public void Movn_64bit([Values(0u, 31u)] uint Rd,
  69. [Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm,
  70. [Values(0u, 16u, 32u, 48u)] uint shift)
  71. {
  72. uint Opcode = 0x92800000; // MOVN X0, #0, LSL #0
  73. Opcode |= ((Rd & 31) << 0);
  74. Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
  75. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  76. AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);
  77. if (Rd != 31)
  78. {
  79. Bits Op = new Bits(Opcode);
  80. Base.Movn(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
  81. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  82. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  83. }
  84. else
  85. {
  86. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  87. }
  88. CompareAgainstUnicorn();
  89. }
  90. [Test, Description("MOVN <Wd>, #<imm>{, LSL #<shift>}")]
  91. public void Movn_32bit([Values(0u, 31u)] uint Rd,
  92. [Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm,
  93. [Values(0u, 16u)] uint shift)
  94. {
  95. uint Opcode = 0x12800000; // MOVN W0, #0, LSL #0
  96. Opcode |= ((Rd & 31) << 0);
  97. Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
  98. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  99. AThreadState ThreadState = SingleOpcode(Opcode, X31: _W31);
  100. if (Rd != 31)
  101. {
  102. Bits Op = new Bits(Opcode);
  103. Base.Movn(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
  104. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  105. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  106. }
  107. else
  108. {
  109. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  110. }
  111. CompareAgainstUnicorn();
  112. }
  113. [Test, Description("MOVZ <Xd>, #<imm>{, LSL #<shift>}")]
  114. public void Movz_64bit([Values(0u, 31u)] uint Rd,
  115. [Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm,
  116. [Values(0u, 16u, 32u, 48u)] uint shift)
  117. {
  118. uint Opcode = 0xD2800000; // MOVZ X0, #0, LSL #0
  119. Opcode |= ((Rd & 31) << 0);
  120. Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
  121. ulong _X31 = TestContext.CurrentContext.Random.NextULong();
  122. AThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);
  123. if (Rd != 31)
  124. {
  125. Bits Op = new Bits(Opcode);
  126. Base.Movz(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
  127. ulong Xd = AArch64.X(64, (int)Rd).ToUInt64();
  128. Assert.That((ulong)ThreadState.X0, Is.EqualTo(Xd));
  129. }
  130. else
  131. {
  132. Assert.That((ulong)ThreadState.X31, Is.EqualTo(_X31));
  133. }
  134. CompareAgainstUnicorn();
  135. }
  136. [Test, Description("MOVZ <Wd>, #<imm>{, LSL #<shift>}")]
  137. public void Movz_32bit([Values(0u, 31u)] uint Rd,
  138. [Values(0u, 65535u)] [Random(0u, 65535u, 128)] uint imm,
  139. [Values(0u, 16u)] uint shift)
  140. {
  141. uint Opcode = 0x52800000; // MOVZ W0, #0, LSL #0
  142. Opcode |= ((Rd & 31) << 0);
  143. Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
  144. uint _W31 = TestContext.CurrentContext.Random.NextUInt();
  145. AThreadState ThreadState = SingleOpcode(Opcode, X31: _W31);
  146. if (Rd != 31)
  147. {
  148. Bits Op = new Bits(Opcode);
  149. Base.Movz(Op[31], Op[22, 21], Op[20, 5], Op[4, 0]);
  150. uint Wd = AArch64.X(32, (int)Rd).ToUInt32();
  151. Assert.That((uint)ThreadState.X0, Is.EqualTo(Wd));
  152. }
  153. else
  154. {
  155. Assert.That((uint)ThreadState.X31, Is.EqualTo(_W31));
  156. }
  157. CompareAgainstUnicorn();
  158. }
  159. #endif
  160. }
  161. }