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