CpuTest.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using ChocolArm64;
  2. using ChocolArm64.Memory;
  3. using ChocolArm64.State;
  4. using NUnit.Framework;
  5. using System;
  6. using System.Runtime.Intrinsics;
  7. using System.Runtime.Intrinsics.X86;
  8. using System.Threading;
  9. namespace Ryujinx.Tests.Cpu
  10. {
  11. [TestFixture]
  12. public class CpuTest
  13. {
  14. protected long Position { get; private set; }
  15. private long Size;
  16. private long EntryPoint;
  17. private AMemory Memory;
  18. private AThread Thread;
  19. [SetUp]
  20. public void Setup()
  21. {
  22. Position = 0x0;
  23. Size = 0x1000;
  24. EntryPoint = Position;
  25. ATranslator Translator = new ATranslator();
  26. Memory = new AMemory();
  27. Memory.Manager.Map(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
  28. Thread = new AThread(Translator, Memory, EntryPoint);
  29. }
  30. [TearDown]
  31. public void Teardown()
  32. {
  33. Memory.Dispose();
  34. Memory = null;
  35. Thread = null;
  36. }
  37. protected void Reset()
  38. {
  39. Teardown();
  40. Setup();
  41. }
  42. protected void Opcode(uint Opcode)
  43. {
  44. Thread.Memory.WriteUInt32Unchecked(Position, Opcode);
  45. Position += 4;
  46. }
  47. protected void SetThreadState(ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0,
  48. Vector128<float> V0 = default(Vector128<float>),
  49. Vector128<float> V1 = default(Vector128<float>),
  50. Vector128<float> V2 = default(Vector128<float>),
  51. bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false,
  52. int Fpcr = 0x0, int Fpsr = 0x0)
  53. {
  54. Thread.ThreadState.X0 = X0;
  55. Thread.ThreadState.X1 = X1;
  56. Thread.ThreadState.X2 = X2;
  57. Thread.ThreadState.X3 = X3;
  58. Thread.ThreadState.X31 = X31;
  59. Thread.ThreadState.V0 = V0;
  60. Thread.ThreadState.V1 = V1;
  61. Thread.ThreadState.V2 = V2;
  62. Thread.ThreadState.Overflow = Overflow;
  63. Thread.ThreadState.Carry = Carry;
  64. Thread.ThreadState.Zero = Zero;
  65. Thread.ThreadState.Negative = Negative;
  66. Thread.ThreadState.Fpcr = Fpcr;
  67. Thread.ThreadState.Fpsr = Fpsr;
  68. }
  69. protected void ExecuteOpcodes()
  70. {
  71. using (ManualResetEvent Wait = new ManualResetEvent(false))
  72. {
  73. Thread.ThreadState.Break += (sender, e) => Thread.StopExecution();
  74. Thread.WorkFinished += (sender, e) => Wait.Set();
  75. Thread.Execute();
  76. Wait.WaitOne();
  77. }
  78. }
  79. protected AThreadState GetThreadState()
  80. {
  81. return Thread.ThreadState;
  82. }
  83. protected AThreadState SingleOpcode(uint Opcode,
  84. ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0,
  85. Vector128<float> V0 = default(Vector128<float>),
  86. Vector128<float> V1 = default(Vector128<float>),
  87. Vector128<float> V2 = default(Vector128<float>),
  88. bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false,
  89. int Fpcr = 0x0, int Fpsr = 0x0)
  90. {
  91. this.Opcode(Opcode);
  92. this.Opcode(0xD4200000); // BRK #0
  93. this.Opcode(0xD65F03C0); // RET
  94. SetThreadState(X0, X1, X2, X3, X31, V0, V1, V2, Overflow, Carry, Zero, Negative, Fpcr, Fpsr);
  95. ExecuteOpcodes();
  96. return GetThreadState();
  97. }
  98. protected static Vector128<float> MakeVectorE0(double E0)
  99. {
  100. return Sse.StaticCast<long, float>(Sse2.SetVector128(0, BitConverter.DoubleToInt64Bits(E0)));
  101. }
  102. protected static Vector128<float> MakeVectorE0E1(double E0, double E1)
  103. {
  104. return Sse.StaticCast<long, float>(Sse2.SetVector128(BitConverter.DoubleToInt64Bits(E1),
  105. BitConverter.DoubleToInt64Bits(E0)));
  106. }
  107. protected static Vector128<float> MakeVectorE1(double E1)
  108. {
  109. return Sse.StaticCast<long, float>(Sse2.SetVector128(BitConverter.DoubleToInt64Bits(E1), 0));
  110. }
  111. protected static double VectorExtractDouble(Vector128<float> Vector, byte Index)
  112. {
  113. long Value = Sse41.Extract(Sse.StaticCast<float, long>(Vector), Index);
  114. return BitConverter.Int64BitsToDouble(Value);
  115. }
  116. protected static Vector128<float> MakeVectorE0(ulong E0)
  117. {
  118. return Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, E0));
  119. }
  120. protected static Vector128<float> MakeVectorE0E1(ulong E0, ulong E1)
  121. {
  122. return Sse.StaticCast<ulong, float>(Sse2.SetVector128(E1, E0));
  123. }
  124. protected static Vector128<float> MakeVectorE1(ulong E1)
  125. {
  126. return Sse.StaticCast<ulong, float>(Sse2.SetVector128(E1, 0));
  127. }
  128. protected static ulong GetVectorE0(Vector128<float> Vector)
  129. {
  130. return Sse41.Extract(Sse.StaticCast<float, ulong>(Vector), (byte)0);
  131. }
  132. protected static ulong GetVectorE1(Vector128<float> Vector)
  133. {
  134. return Sse41.Extract(Sse.StaticCast<float, ulong>(Vector), (byte)1);
  135. }
  136. }
  137. }