InstEmitAlu32.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. using ARMeilleure.Decoders;
  2. using ARMeilleure.IntermediateRepresentation;
  3. using ARMeilleure.State;
  4. using ARMeilleure.Translation;
  5. using static ARMeilleure.Instructions.InstEmitHelper;
  6. using static ARMeilleure.Instructions.InstEmitAluHelper;
  7. using static ARMeilleure.IntermediateRepresentation.OperandHelper;
  8. namespace ARMeilleure.Instructions
  9. {
  10. static partial class InstEmit32
  11. {
  12. public static void Add(ArmEmitterContext context)
  13. {
  14. IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
  15. Operand n = GetAluN(context);
  16. Operand m = GetAluM(context, setCarry: false);
  17. Operand res = context.Add(n, m);
  18. if (op.SetFlags)
  19. {
  20. EmitNZFlagsCheck(context, res);
  21. EmitAddsCCheck(context, n, res);
  22. EmitAddsVCheck(context, n, m, res);
  23. }
  24. EmitAluStore(context, res);
  25. }
  26. public static void Cmp(ArmEmitterContext context)
  27. {
  28. IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
  29. Operand n = GetAluN(context);
  30. Operand m = GetAluM(context, setCarry: false);
  31. Operand res = context.Subtract(n, m);
  32. EmitNZFlagsCheck(context, res);
  33. EmitSubsCCheck(context, n, res);
  34. EmitSubsVCheck(context, n, m, res);
  35. }
  36. public static void Mov(ArmEmitterContext context)
  37. {
  38. IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
  39. Operand m = GetAluM(context);
  40. if (op.SetFlags)
  41. {
  42. EmitNZFlagsCheck(context, m);
  43. }
  44. EmitAluStore(context, m);
  45. }
  46. public static void Sub(ArmEmitterContext context)
  47. {
  48. IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
  49. Operand n = GetAluN(context);
  50. Operand m = GetAluM(context, setCarry: false);
  51. Operand res = context.Subtract(n, m);
  52. if (op.SetFlags)
  53. {
  54. EmitNZFlagsCheck(context, res);
  55. EmitSubsCCheck(context, n, res);
  56. EmitSubsVCheck(context, n, m, res);
  57. }
  58. EmitAluStore(context, res);
  59. }
  60. private static void EmitAluStore(ArmEmitterContext context, Operand value)
  61. {
  62. IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
  63. if (op.Rd == RegisterAlias.Aarch32Pc)
  64. {
  65. if (op.SetFlags)
  66. {
  67. // TODO: Load SPSR etc.
  68. Operand isThumb = GetFlag(PState.TFlag);
  69. Operand lblThumb = Label();
  70. context.BranchIfTrue(lblThumb, isThumb);
  71. context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~3))));
  72. context.MarkLabel(lblThumb);
  73. context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~1))));
  74. }
  75. else
  76. {
  77. EmitAluWritePc(context, value);
  78. }
  79. }
  80. else
  81. {
  82. SetIntA32(context, op.Rd, value);
  83. }
  84. }
  85. private static void EmitAluWritePc(ArmEmitterContext context, Operand value)
  86. {
  87. context.StoreToContext();
  88. if (IsThumb(context.CurrOp))
  89. {
  90. context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~1))));
  91. }
  92. else
  93. {
  94. EmitBxWritePc(context, value);
  95. }
  96. }
  97. }
  98. }