CpuTestMov.cs 6.6 KB

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