AInstEmitException.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using ChocolArm64.Decoder;
  2. using ChocolArm64.State;
  3. using ChocolArm64.Translation;
  4. using System.Reflection;
  5. using System.Reflection.Emit;
  6. namespace ChocolArm64.Instruction
  7. {
  8. static partial class AInstEmit
  9. {
  10. private const BindingFlags Binding = BindingFlags.NonPublic | BindingFlags.Instance;
  11. public static void Brk(AILEmitterCtx Context)
  12. {
  13. EmitExceptionCall(Context, nameof(AThreadState.OnBreak));
  14. }
  15. public static void Svc(AILEmitterCtx Context)
  16. {
  17. EmitExceptionCall(Context, nameof(AThreadState.OnSvcCall));
  18. }
  19. private static void EmitExceptionCall(AILEmitterCtx Context, string MthdName)
  20. {
  21. AOpCodeException Op = (AOpCodeException)Context.CurrOp;
  22. Context.EmitStoreState();
  23. Context.EmitLdarg(ATranslatedSub.StateArgIdx);
  24. Context.EmitLdc_I4(Op.Id);
  25. MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
  26. Context.EmitCall(MthdInfo);
  27. //Check if the thread should still be running, if it isn't then we return 0
  28. //to force a return to the dispatcher and then exit the thread.
  29. Context.EmitLdarg(ATranslatedSub.StateArgIdx);
  30. Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Running));
  31. AILLabel LblEnd = new AILLabel();
  32. Context.Emit(OpCodes.Brtrue_S, LblEnd);
  33. Context.EmitLdc_I8(0);
  34. Context.Emit(OpCodes.Ret);
  35. Context.MarkLabel(LblEnd);
  36. if (Context.CurrBlock.Next != null)
  37. {
  38. Context.EmitLoadState(Context.CurrBlock.Next);
  39. }
  40. else
  41. {
  42. Context.EmitLdc_I8(Op.Position + 4);
  43. Context.Emit(OpCodes.Ret);
  44. }
  45. }
  46. public static void Und(AILEmitterCtx Context)
  47. {
  48. AOpCode Op = Context.CurrOp;
  49. Context.EmitStoreState();
  50. Context.EmitLdarg(ATranslatedSub.StateArgIdx);
  51. Context.EmitLdc_I8(Op.Position);
  52. Context.EmitLdc_I4(Op.RawOpCode);
  53. string MthdName = nameof(AThreadState.OnUndefined);
  54. MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
  55. Context.EmitCall(MthdInfo);
  56. if (Context.CurrBlock.Next != null)
  57. {
  58. Context.EmitLoadState(Context.CurrBlock.Next);
  59. }
  60. else
  61. {
  62. Context.EmitLdc_I8(Op.Position + 4);
  63. Context.Emit(OpCodes.Ret);
  64. }
  65. }
  66. }
  67. }