InstEmitCcmp.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. using ARMeilleure.Decoders;
  2. using ARMeilleure.IntermediateRepresentation;
  3. using ARMeilleure.State;
  4. using ARMeilleure.Translation;
  5. using static ARMeilleure.Instructions.InstEmitAluHelper;
  6. using static ARMeilleure.Instructions.InstEmitFlowHelper;
  7. using static ARMeilleure.Instructions.InstEmitHelper;
  8. using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
  9. namespace ARMeilleure.Instructions
  10. {
  11. static partial class InstEmit
  12. {
  13. public static void Ccmn(ArmEmitterContext context) => EmitCcmp(context, isNegated: true);
  14. public static void Ccmp(ArmEmitterContext context) => EmitCcmp(context, isNegated: false);
  15. private static void EmitCcmp(ArmEmitterContext context, bool isNegated)
  16. {
  17. OpCodeCcmp op = (OpCodeCcmp)context.CurrOp;
  18. Operand lblTrue = Label();
  19. Operand lblEnd = Label();
  20. EmitCondBranch(context, lblTrue, op.Cond);
  21. SetFlag(context, PState.VFlag, Const((op.Nzcv >> 0) & 1));
  22. SetFlag(context, PState.CFlag, Const((op.Nzcv >> 1) & 1));
  23. SetFlag(context, PState.ZFlag, Const((op.Nzcv >> 2) & 1));
  24. SetFlag(context, PState.NFlag, Const((op.Nzcv >> 3) & 1));
  25. context.Branch(lblEnd);
  26. context.MarkLabel(lblTrue);
  27. Operand n = GetAluN(context);
  28. Operand m = GetAluM(context);
  29. if (isNegated)
  30. {
  31. Operand d = context.Add(n, m);
  32. EmitNZFlagsCheck(context, d);
  33. EmitAddsCCheck(context, n, d);
  34. EmitAddsVCheck(context, n, m, d);
  35. }
  36. else
  37. {
  38. Operand d = context.Subtract(n, m);
  39. EmitNZFlagsCheck(context, d);
  40. EmitSubsCCheck(context, n, m);
  41. EmitSubsVCheck(context, n, m, d);
  42. }
  43. context.MarkLabel(lblEnd);
  44. }
  45. }
  46. }