ExecutionContext.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. using ARMeilleure.Memory;
  2. using System;
  3. using System.Diagnostics;
  4. namespace ARMeilleure.State
  5. {
  6. public class ExecutionContext
  7. {
  8. private const int MinCountForCheck = 4000;
  9. private NativeContext _nativeContext;
  10. internal IntPtr NativeContextPtr => _nativeContext.BasePtr;
  11. private bool _interrupted;
  12. private static Stopwatch _tickCounter;
  13. private static double _hostTickFreq;
  14. public uint CtrEl0 => 0x8444c004;
  15. public uint DczidEl0 => 0x00000004;
  16. public ulong CntfrqEl0 { get; set; }
  17. public ulong CntpctEl0
  18. {
  19. get
  20. {
  21. double ticks = _tickCounter.ElapsedTicks * _hostTickFreq;
  22. return (ulong)(ticks * CntfrqEl0);
  23. }
  24. }
  25. // CNTVCT_EL0 = CNTPCT_EL0 - CNTVOFF_EL2
  26. // Since EL2 isn't implemented, CNTVOFF_EL2 = 0
  27. public ulong CntvctEl0 => CntpctEl0;
  28. public static TimeSpan ElapsedTime => _tickCounter.Elapsed;
  29. public static long ElapsedTicks => _tickCounter.ElapsedTicks;
  30. public static double TickFrequency => _hostTickFreq;
  31. public long TpidrEl0 { get; set; }
  32. public long Tpidr { get; set; }
  33. public uint Pstate
  34. {
  35. get => _nativeContext.GetPstate();
  36. set => _nativeContext.SetPstate(value);
  37. }
  38. public FPCR Fpcr { get; set; }
  39. public FPSR Fpsr { get; set; }
  40. public FPCR StandardFpcrValue => (Fpcr & (FPCR.Ahp)) | FPCR.Dn | FPCR.Fz;
  41. public bool IsAarch32 { get; set; }
  42. internal ExecutionMode ExecutionMode
  43. {
  44. get
  45. {
  46. if (IsAarch32)
  47. {
  48. return GetPstateFlag(PState.TFlag)
  49. ? ExecutionMode.Aarch32Thumb
  50. : ExecutionMode.Aarch32Arm;
  51. }
  52. else
  53. {
  54. return ExecutionMode.Aarch64;
  55. }
  56. }
  57. }
  58. public bool Running
  59. {
  60. get => _nativeContext.GetRunning();
  61. private set => _nativeContext.SetRunning(value);
  62. }
  63. public event EventHandler<EventArgs> Interrupt;
  64. public event EventHandler<InstExceptionEventArgs> Break;
  65. public event EventHandler<InstExceptionEventArgs> SupervisorCall;
  66. public event EventHandler<InstUndefinedEventArgs> Undefined;
  67. static ExecutionContext()
  68. {
  69. _hostTickFreq = 1.0 / Stopwatch.Frequency;
  70. _tickCounter = new Stopwatch();
  71. _tickCounter.Start();
  72. }
  73. public ExecutionContext(IJitMemoryAllocator allocator)
  74. {
  75. _nativeContext = new NativeContext(allocator);
  76. Running = true;
  77. _nativeContext.SetCounter(MinCountForCheck);
  78. }
  79. public ulong GetX(int index) => _nativeContext.GetX(index);
  80. public void SetX(int index, ulong value) => _nativeContext.SetX(index, value);
  81. public V128 GetV(int index) => _nativeContext.GetV(index);
  82. public void SetV(int index, V128 value) => _nativeContext.SetV(index, value);
  83. public bool GetPstateFlag(PState flag) => _nativeContext.GetPstateFlag(flag);
  84. public void SetPstateFlag(PState flag, bool value) => _nativeContext.SetPstateFlag(flag, value);
  85. public bool GetFPstateFlag(FPState flag) => _nativeContext.GetFPStateFlag(flag);
  86. public void SetFPstateFlag(FPState flag, bool value) => _nativeContext.SetFPStateFlag(flag, value);
  87. internal void CheckInterrupt()
  88. {
  89. if (_interrupted)
  90. {
  91. _interrupted = false;
  92. Interrupt?.Invoke(this, EventArgs.Empty);
  93. }
  94. _nativeContext.SetCounter(MinCountForCheck);
  95. }
  96. public void RequestInterrupt()
  97. {
  98. _interrupted = true;
  99. }
  100. internal void OnBreak(ulong address, int imm)
  101. {
  102. Break?.Invoke(this, new InstExceptionEventArgs(address, imm));
  103. }
  104. internal void OnSupervisorCall(ulong address, int imm)
  105. {
  106. SupervisorCall?.Invoke(this, new InstExceptionEventArgs(address, imm));
  107. }
  108. internal void OnUndefined(ulong address, int opCode)
  109. {
  110. Undefined?.Invoke(this, new InstUndefinedEventArgs(address, opCode));
  111. }
  112. public void StopRunning()
  113. {
  114. Running = false;
  115. _nativeContext.SetCounter(0);
  116. }
  117. public static void SuspendCounter()
  118. {
  119. _tickCounter.Stop();
  120. }
  121. public static void ResumeCounter()
  122. {
  123. _tickCounter.Start();
  124. }
  125. public void Dispose()
  126. {
  127. _nativeContext.Dispose();
  128. }
  129. }
  130. }