InstEmitAlu32.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using ChocolArm64.Decoders;
  2. using ChocolArm64.State;
  3. using ChocolArm64.Translation;
  4. using System.Reflection.Emit;
  5. using static ChocolArm64.Instructions.InstEmit32Helper;
  6. using static ChocolArm64.Instructions.InstEmitAluHelper;
  7. namespace ChocolArm64.Instructions
  8. {
  9. static partial class InstEmit32
  10. {
  11. public static void Add(ILEmitterCtx context)
  12. {
  13. IOpCodeAlu32 op = (IOpCodeAlu32)context.CurrOp;
  14. EmitAluLoadOpers(context, setCarry: false);
  15. context.Emit(OpCodes.Add);
  16. if (op.SetFlags)
  17. {
  18. context.EmitZnFlagCheck();
  19. EmitAddsCCheck(context);
  20. EmitAddsVCheck(context);
  21. }
  22. EmitAluStore(context);
  23. }
  24. public static void Mov(ILEmitterCtx context)
  25. {
  26. IOpCodeAlu32 op = (IOpCodeAlu32)context.CurrOp;
  27. EmitAluLoadOper2(context);
  28. if (op.SetFlags)
  29. {
  30. context.EmitZnFlagCheck();
  31. }
  32. EmitAluStore(context);
  33. }
  34. public static void Sub(ILEmitterCtx context)
  35. {
  36. IOpCodeAlu32 op = (IOpCodeAlu32)context.CurrOp;
  37. EmitAluLoadOpers(context, setCarry: false);
  38. context.Emit(OpCodes.Sub);
  39. if (op.SetFlags)
  40. {
  41. context.EmitZnFlagCheck();
  42. EmitSubsCCheck(context);
  43. EmitSubsVCheck(context);
  44. }
  45. EmitAluStore(context);
  46. }
  47. private static void EmitAluStore(ILEmitterCtx context)
  48. {
  49. IOpCodeAlu32 op = (IOpCodeAlu32)context.CurrOp;
  50. if (op.Rd == RegisterAlias.Aarch32Pc)
  51. {
  52. if (op.SetFlags)
  53. {
  54. //TODO: Load SPSR etc.
  55. context.EmitLdflg((int)PState.TBit);
  56. ILLabel lblThumb = new ILLabel();
  57. ILLabel lblEnd = new ILLabel();
  58. context.Emit(OpCodes.Brtrue_S, lblThumb);
  59. context.EmitLdc_I4(~3);
  60. context.Emit(OpCodes.Br_S, lblEnd);
  61. context.MarkLabel(lblThumb);
  62. context.EmitLdc_I4(~1);
  63. context.MarkLabel(lblEnd);
  64. context.Emit(OpCodes.And);
  65. context.Emit(OpCodes.Conv_U8);
  66. context.Emit(OpCodes.Ret);
  67. }
  68. else
  69. {
  70. EmitAluWritePc(context);
  71. }
  72. }
  73. else
  74. {
  75. context.EmitStint(GetRegisterAlias(context.Mode, op.Rd));
  76. }
  77. }
  78. private static void EmitAluWritePc(ILEmitterCtx context)
  79. {
  80. if (IsThumb(context.CurrOp))
  81. {
  82. context.EmitLdc_I4(~1);
  83. context.Emit(OpCodes.And);
  84. context.Emit(OpCodes.Conv_U8);
  85. context.Emit(OpCodes.Ret);
  86. }
  87. else
  88. {
  89. EmitBxWritePc(context);
  90. }
  91. }
  92. }
  93. }