NativeInterface.cs 5.7 KB

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