ExecutionContext.cs 4.9 KB

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