/ src / ARMeilleure / Instructions / NativeInterface.cs
NativeInterface.cs
  1  using ARMeilleure.Memory;
  2  using ARMeilleure.State;
  3  using ARMeilleure.Translation;
  4  using System;
  5  
  6  namespace ARMeilleure.Instructions
  7  {
  8      static class NativeInterface
  9      {
 10          private class ThreadContext
 11          {
 12              public ExecutionContext Context { get; }
 13              public IMemoryManager Memory { get; }
 14              public Translator Translator { get; }
 15  
 16              public ThreadContext(ExecutionContext context, IMemoryManager memory, Translator translator)
 17              {
 18                  Context = context;
 19                  Memory = memory;
 20                  Translator = translator;
 21              }
 22          }
 23  
 24          [ThreadStatic]
 25          private static ThreadContext Context;
 26  
 27          public static void RegisterThread(ExecutionContext context, IMemoryManager memory, Translator translator)
 28          {
 29              Context = new ThreadContext(context, memory, translator);
 30          }
 31  
 32          public static void UnregisterThread()
 33          {
 34              Context = null;
 35          }
 36  
 37          public static void Break(ulong address, int imm)
 38          {
 39              Statistics.PauseTimer();
 40  
 41              GetContext().OnBreak(address, imm);
 42  
 43              Statistics.ResumeTimer();
 44          }
 45  
 46          public static void SupervisorCall(ulong address, int imm)
 47          {
 48              Statistics.PauseTimer();
 49  
 50              GetContext().OnSupervisorCall(address, imm);
 51  
 52              Statistics.ResumeTimer();
 53          }
 54  
 55          public static void Undefined(ulong address, int opCode)
 56          {
 57              Statistics.PauseTimer();
 58  
 59              GetContext().OnUndefined(address, opCode);
 60  
 61              Statistics.ResumeTimer();
 62          }
 63  
 64          #region "System registers"
 65          public static ulong GetCtrEl0()
 66          {
 67              return GetContext().CtrEl0;
 68          }
 69  
 70          public static ulong GetDczidEl0()
 71          {
 72              return GetContext().DczidEl0;
 73          }
 74  
 75          public static ulong GetCntfrqEl0()
 76          {
 77              return GetContext().CntfrqEl0;
 78          }
 79  
 80          public static ulong GetCntpctEl0()
 81          {
 82              return GetContext().CntpctEl0;
 83          }
 84  
 85          public static ulong GetCntvctEl0()
 86          {
 87              return GetContext().CntvctEl0;
 88          }
 89          #endregion
 90  
 91          #region "Read"
 92          public static byte ReadByte(ulong address)
 93          {
 94              return GetMemoryManager().ReadGuest<byte>(address);
 95          }
 96  
 97          public static ushort ReadUInt16(ulong address)
 98          {
 99              return GetMemoryManager().ReadGuest<ushort>(address);
100          }
101  
102          public static uint ReadUInt32(ulong address)
103          {
104              return GetMemoryManager().ReadGuest<uint>(address);
105          }
106  
107          public static ulong ReadUInt64(ulong address)
108          {
109              return GetMemoryManager().ReadGuest<ulong>(address);
110          }
111  
112          public static V128 ReadVector128(ulong address)
113          {
114              return GetMemoryManager().ReadGuest<V128>(address);
115          }
116          #endregion
117  
118          #region "Write"
119          public static void WriteByte(ulong address, byte value)
120          {
121              GetMemoryManager().WriteGuest(address, value);
122          }
123  
124          public static void WriteUInt16(ulong address, ushort value)
125          {
126              GetMemoryManager().WriteGuest(address, value);
127          }
128  
129          public static void WriteUInt32(ulong address, uint value)
130          {
131              GetMemoryManager().WriteGuest(address, value);
132          }
133  
134          public static void WriteUInt64(ulong address, ulong value)
135          {
136              GetMemoryManager().WriteGuest(address, value);
137          }
138  
139          public static void WriteVector128(ulong address, V128 value)
140          {
141              GetMemoryManager().WriteGuest(address, value);
142          }
143          #endregion
144  
145          public static void EnqueueForRejit(ulong address)
146          {
147              Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode);
148          }
149  
150          public static void SignalMemoryTracking(ulong address, ulong size, bool write)
151          {
152              GetMemoryManager().SignalMemoryTracking(address, size, write);
153          }
154  
155          public static void ThrowInvalidMemoryAccess(ulong address)
156          {
157              throw new InvalidAccessException(address);
158          }
159  
160          public static ulong GetFunctionAddress(ulong address)
161          {
162              TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
163  
164              return (ulong)function.FuncPointer.ToInt64();
165          }
166  
167          public static void InvalidateCacheLine(ulong address)
168          {
169              Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes);
170          }
171  
172          public static bool CheckSynchronization()
173          {
174              Statistics.PauseTimer();
175  
176              ExecutionContext context = GetContext();
177  
178              context.CheckInterrupt();
179  
180              Statistics.ResumeTimer();
181  
182              return context.Running;
183          }
184  
185          public static ExecutionContext GetContext()
186          {
187              return Context.Context;
188          }
189  
190          public static IMemoryManager GetMemoryManager()
191          {
192              return Context.Memory;
193          }
194      }
195  }