InstEmitException.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using ChocolArm64.Decoders;
  2. using ChocolArm64.IntermediateRepresentation;
  3. using ChocolArm64.State;
  4. using ChocolArm64.Translation;
  5. using System.Reflection.Emit;
  6. namespace ChocolArm64.Instructions
  7. {
  8. static partial class InstEmit
  9. {
  10. public static void Brk(ILEmitterCtx context)
  11. {
  12. EmitExceptionCall(context, nameof(CpuThreadState.OnBreak));
  13. }
  14. public static void Svc(ILEmitterCtx context)
  15. {
  16. EmitExceptionCall(context, nameof(CpuThreadState.OnSvcCall));
  17. }
  18. private static void EmitExceptionCall(ILEmitterCtx context, string mthdName)
  19. {
  20. OpCodeException64 op = (OpCodeException64)context.CurrOp;
  21. context.EmitStoreContext();
  22. context.EmitLdarg(TranslatedSub.StateArgIdx);
  23. context.EmitLdc_I8(op.Position);
  24. context.EmitLdc_I4(op.Id);
  25. context.EmitPrivateCall(typeof(CpuThreadState), mthdName);
  26. // Check if the thread should still be running, if it isn't then we return 0
  27. // to force a return to the dispatcher and then exit the thread.
  28. context.EmitLdarg(TranslatedSub.StateArgIdx);
  29. context.EmitCallPropGet(typeof(CpuThreadState), nameof(CpuThreadState.Running));
  30. ILLabel lblEnd = new ILLabel();
  31. context.Emit(OpCodes.Brtrue_S, lblEnd);
  32. context.EmitLdc_I8(0);
  33. context.Emit(OpCodes.Ret);
  34. context.MarkLabel(lblEnd);
  35. if (context.CurrBlock.Next != null)
  36. {
  37. context.EmitLoadContext();
  38. }
  39. else
  40. {
  41. context.EmitLdc_I8(op.Position + 4);
  42. context.Emit(OpCodes.Ret);
  43. }
  44. }
  45. public static void Und(ILEmitterCtx context)
  46. {
  47. OpCode64 op = context.CurrOp;
  48. context.EmitStoreContext();
  49. context.EmitLdarg(TranslatedSub.StateArgIdx);
  50. context.EmitLdc_I8(op.Position);
  51. context.EmitLdc_I4(op.RawOpCode);
  52. context.EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.OnUndefined));
  53. if (context.CurrBlock.Next != null)
  54. {
  55. context.EmitLoadContext();
  56. }
  57. else
  58. {
  59. context.EmitLdc_I8(op.Position + 4);
  60. context.Emit(OpCodes.Ret);
  61. }
  62. }
  63. }
  64. }