ExecutionContext.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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
  21. {
  22. get => _nativeContext.GetTpidrEl0();
  23. set => _nativeContext.SetTpidrEl0(value);
  24. }
  25. public long TpidrroEl0
  26. {
  27. get => _nativeContext.GetTpidrroEl0();
  28. set => _nativeContext.SetTpidrroEl0(value);
  29. }
  30. public uint Pstate
  31. {
  32. get => _nativeContext.GetPstate();
  33. set => _nativeContext.SetPstate(value);
  34. }
  35. public FPSR Fpsr
  36. {
  37. get => (FPSR)_nativeContext.GetFPState((uint)FPSR.Mask);
  38. set => _nativeContext.SetFPState((uint)value, (uint)FPSR.Mask);
  39. }
  40. public FPCR Fpcr
  41. {
  42. get => (FPCR)_nativeContext.GetFPState((uint)FPCR.Mask);
  43. set => _nativeContext.SetFPState((uint)value, (uint)FPCR.Mask);
  44. }
  45. public FPCR StandardFpcrValue => (Fpcr & (FPCR.Ahp)) | FPCR.Dn | FPCR.Fz;
  46. public FPSCR Fpscr
  47. {
  48. get => (FPSCR)_nativeContext.GetFPState((uint)FPSCR.Mask);
  49. set => _nativeContext.SetFPState((uint)value, (uint)FPSCR.Mask);
  50. }
  51. public bool IsAarch32 { get; set; }
  52. internal ExecutionMode ExecutionMode
  53. {
  54. get
  55. {
  56. if (IsAarch32)
  57. {
  58. return GetPstateFlag(PState.TFlag)
  59. ? ExecutionMode.Aarch32Thumb
  60. : ExecutionMode.Aarch32Arm;
  61. }
  62. else
  63. {
  64. return ExecutionMode.Aarch64;
  65. }
  66. }
  67. }
  68. public bool Running
  69. {
  70. get => _nativeContext.GetRunning();
  71. private set => _nativeContext.SetRunning(value);
  72. }
  73. private readonly ExceptionCallbackNoArgs _interruptCallback;
  74. private readonly ExceptionCallback _breakCallback;
  75. private readonly ExceptionCallback _supervisorCallback;
  76. private readonly ExceptionCallback _undefinedCallback;
  77. public ExecutionContext(
  78. IJitMemoryAllocator allocator,
  79. ICounter counter,
  80. ExceptionCallbackNoArgs interruptCallback = null,
  81. ExceptionCallback breakCallback = null,
  82. ExceptionCallback supervisorCallback = null,
  83. ExceptionCallback undefinedCallback = null)
  84. {
  85. _nativeContext = new NativeContext(allocator);
  86. _counter = counter;
  87. _interruptCallback = interruptCallback;
  88. _breakCallback = breakCallback;
  89. _supervisorCallback = supervisorCallback;
  90. _undefinedCallback = undefinedCallback;
  91. Running = true;
  92. _nativeContext.SetCounter(MinCountForCheck);
  93. }
  94. public ulong GetX(int index) => _nativeContext.GetX(index);
  95. public void SetX(int index, ulong value) => _nativeContext.SetX(index, value);
  96. public V128 GetV(int index) => _nativeContext.GetV(index);
  97. public void SetV(int index, V128 value) => _nativeContext.SetV(index, value);
  98. public bool GetPstateFlag(PState flag) => _nativeContext.GetPstateFlag(flag);
  99. public void SetPstateFlag(PState flag, bool value) => _nativeContext.SetPstateFlag(flag, value);
  100. public bool GetFPstateFlag(FPState flag) => _nativeContext.GetFPStateFlag(flag);
  101. public void SetFPstateFlag(FPState flag, bool value) => _nativeContext.SetFPStateFlag(flag, value);
  102. internal void CheckInterrupt()
  103. {
  104. if (_interrupted)
  105. {
  106. _interrupted = false;
  107. _interruptCallback?.Invoke(this);
  108. }
  109. _nativeContext.SetCounter(MinCountForCheck);
  110. }
  111. public void RequestInterrupt()
  112. {
  113. _interrupted = true;
  114. }
  115. internal void OnBreak(ulong address, int imm)
  116. {
  117. _breakCallback?.Invoke(this, address, imm);
  118. }
  119. internal void OnSupervisorCall(ulong address, int imm)
  120. {
  121. _supervisorCallback?.Invoke(this, address, imm);
  122. }
  123. internal void OnUndefined(ulong address, int opCode)
  124. {
  125. _undefinedCallback?.Invoke(this, address, opCode);
  126. }
  127. public void StopRunning()
  128. {
  129. Running = false;
  130. _nativeContext.SetCounter(0);
  131. }
  132. public void Dispose()
  133. {
  134. _nativeContext.Dispose();
  135. }
  136. }
  137. }