AInstEmitException.cs 2.3 KB

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