InstEmitCsel.cs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. using ARMeilleure.Decoders;
  2. using ARMeilleure.IntermediateRepresentation;
  3. using ARMeilleure.Translation;
  4. using static ARMeilleure.Instructions.InstEmitFlowHelper;
  5. using static ARMeilleure.Instructions.InstEmitHelper;
  6. using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
  7. namespace ARMeilleure.Instructions
  8. {
  9. static partial class InstEmit
  10. {
  11. private enum CselOperation
  12. {
  13. None,
  14. Increment,
  15. Invert,
  16. Negate
  17. }
  18. public static void Csel(ArmEmitterContext context) => EmitCsel(context, CselOperation.None);
  19. public static void Csinc(ArmEmitterContext context) => EmitCsel(context, CselOperation.Increment);
  20. public static void Csinv(ArmEmitterContext context) => EmitCsel(context, CselOperation.Invert);
  21. public static void Csneg(ArmEmitterContext context) => EmitCsel(context, CselOperation.Negate);
  22. private static void EmitCsel(ArmEmitterContext context, CselOperation cselOp)
  23. {
  24. OpCodeCsel op = (OpCodeCsel)context.CurrOp;
  25. Operand n = GetIntOrZR(context, op.Rn);
  26. Operand m = GetIntOrZR(context, op.Rm);
  27. if (cselOp == CselOperation.Increment)
  28. {
  29. m = context.Add(m, Const(m.Type, 1));
  30. }
  31. else if (cselOp == CselOperation.Invert)
  32. {
  33. m = context.BitwiseNot(m);
  34. }
  35. else if (cselOp == CselOperation.Negate)
  36. {
  37. m = context.Negate(m);
  38. }
  39. Operand condTrue = GetCondTrue(context, op.Cond);
  40. Operand d = context.ConditionalSelect(condTrue, n, m);
  41. SetIntOrZR(context, op.Rd, d);
  42. }
  43. }
  44. }