NativeInterface.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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 GetFpcr()
  59. {
  60. return (ulong)GetContext().Fpcr;
  61. }
  62. public static bool GetFpcrFz()
  63. {
  64. return (GetContext().Fpcr & FPCR.Fz) != 0;
  65. }
  66. public static ulong GetFpsr()
  67. {
  68. return (ulong)GetContext().Fpsr;
  69. }
  70. public static uint GetFpscr()
  71. {
  72. ExecutionContext context = GetContext();
  73. return (uint)(context.Fpsr & FPSR.A32Mask & ~FPSR.Nzcv) |
  74. (uint)(context.Fpcr & FPCR.A32Mask);
  75. }
  76. public static ulong GetTpidrEl0()
  77. {
  78. return (ulong)GetContext().TpidrEl0;
  79. }
  80. public static uint GetTpidrEl032()
  81. {
  82. return (uint)GetContext().TpidrEl0;
  83. }
  84. public static ulong GetTpidrroEl0()
  85. {
  86. return (ulong)GetContext().TpidrroEl0;
  87. }
  88. public static uint GetTpidr32()
  89. {
  90. return (uint)GetContext().TpidrroEl0;
  91. }
  92. public static ulong GetCntfrqEl0()
  93. {
  94. return GetContext().CntfrqEl0;
  95. }
  96. public static ulong GetCntpctEl0()
  97. {
  98. return GetContext().CntpctEl0;
  99. }
  100. public static ulong GetCntvctEl0()
  101. {
  102. return GetContext().CntvctEl0;
  103. }
  104. public static void SetFpcr(ulong value)
  105. {
  106. GetContext().Fpcr = (FPCR)value;
  107. }
  108. public static void SetFpsr(ulong value)
  109. {
  110. GetContext().Fpsr = (FPSR)value;
  111. }
  112. public static void SetFpsrQc()
  113. {
  114. GetContext().Fpsr |= FPSR.Qc;
  115. }
  116. public static void SetFpscr(uint fpscr)
  117. {
  118. ExecutionContext context = GetContext();
  119. context.Fpsr = FPSR.A32Mask & (FPSR)fpscr;
  120. context.Fpcr = FPCR.A32Mask & (FPCR)fpscr;
  121. }
  122. public static void SetTpidrEl0(ulong value)
  123. {
  124. GetContext().TpidrEl0 = (long)value;
  125. }
  126. public static void SetTpidrEl032(uint value)
  127. {
  128. GetContext().TpidrEl0 = (long)value;
  129. }
  130. #endregion
  131. #region "Read"
  132. public static byte ReadByte(ulong address)
  133. {
  134. return GetMemoryManager().ReadTracked<byte>(address);
  135. }
  136. public static ushort ReadUInt16(ulong address)
  137. {
  138. return GetMemoryManager().ReadTracked<ushort>(address);
  139. }
  140. public static uint ReadUInt32(ulong address)
  141. {
  142. return GetMemoryManager().ReadTracked<uint>(address);
  143. }
  144. public static ulong ReadUInt64(ulong address)
  145. {
  146. return GetMemoryManager().ReadTracked<ulong>(address);
  147. }
  148. public static V128 ReadVector128(ulong address)
  149. {
  150. return GetMemoryManager().ReadTracked<V128>(address);
  151. }
  152. #endregion
  153. #region "Write"
  154. public static void WriteByte(ulong address, byte value)
  155. {
  156. GetMemoryManager().Write(address, value);
  157. }
  158. public static void WriteUInt16(ulong address, ushort value)
  159. {
  160. GetMemoryManager().Write(address, value);
  161. }
  162. public static void WriteUInt32(ulong address, uint value)
  163. {
  164. GetMemoryManager().Write(address, value);
  165. }
  166. public static void WriteUInt64(ulong address, ulong value)
  167. {
  168. GetMemoryManager().Write(address, value);
  169. }
  170. public static void WriteVector128(ulong address, V128 value)
  171. {
  172. GetMemoryManager().Write(address, value);
  173. }
  174. #endregion
  175. public static void EnqueueForRejit(ulong address)
  176. {
  177. Context.Translator.EnqueueForRejit(address, GetContext().ExecutionMode);
  178. }
  179. public static void SignalMemoryTracking(ulong address, ulong size, bool write)
  180. {
  181. GetMemoryManager().SignalMemoryTracking(address, size, write);
  182. }
  183. public static void ThrowInvalidMemoryAccess(ulong address)
  184. {
  185. throw new InvalidAccessException(address);
  186. }
  187. public static ulong GetFunctionAddress(ulong address)
  188. {
  189. TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
  190. return (ulong)function.FuncPtr.ToInt64();
  191. }
  192. public static void InvalidateCacheLine(ulong address)
  193. {
  194. Context.Translator.InvalidateJitCacheRegion(address, InstEmit.DczSizeInBytes);
  195. }
  196. public static bool CheckSynchronization()
  197. {
  198. Statistics.PauseTimer();
  199. ExecutionContext context = GetContext();
  200. context.CheckInterrupt();
  201. Statistics.ResumeTimer();
  202. return context.Running;
  203. }
  204. public static ExecutionContext GetContext()
  205. {
  206. return Context.Context;
  207. }
  208. public static IMemoryManager GetMemoryManager()
  209. {
  210. return Context.Memory;
  211. }
  212. }
  213. }