AInstEmitCsel.cs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. using ChocolArm64.Decoder;
  2. using ChocolArm64.Translation;
  3. using System.Reflection.Emit;
  4. namespace ChocolArm64.Instruction
  5. {
  6. static partial class AInstEmit
  7. {
  8. private enum CselOperation
  9. {
  10. None,
  11. Increment,
  12. Invert,
  13. Negate
  14. }
  15. public static void Csel(AILEmitterCtx Context) => EmitCsel(Context, CselOperation.None);
  16. public static void Csinc(AILEmitterCtx Context) => EmitCsel(Context, CselOperation.Increment);
  17. public static void Csinv(AILEmitterCtx Context) => EmitCsel(Context, CselOperation.Invert);
  18. public static void Csneg(AILEmitterCtx Context) => EmitCsel(Context, CselOperation.Negate);
  19. private static void EmitCsel(AILEmitterCtx Context, CselOperation CselOp)
  20. {
  21. AOpCodeCsel Op = (AOpCodeCsel)Context.CurrOp;
  22. AILLabel LblTrue = new AILLabel();
  23. AILLabel LblEnd = new AILLabel();
  24. Context.EmitCondBranch(LblTrue, Op.Cond);
  25. Context.EmitLdintzr(Op.Rm);
  26. if (CselOp == CselOperation.Increment)
  27. {
  28. Context.EmitLdc_I(1);
  29. Context.Emit(OpCodes.Add);
  30. }
  31. else if (CselOp == CselOperation.Invert)
  32. {
  33. Context.Emit(OpCodes.Not);
  34. }
  35. else if (CselOp == CselOperation.Negate)
  36. {
  37. Context.Emit(OpCodes.Neg);
  38. }
  39. Context.Emit(OpCodes.Br_S, LblEnd);
  40. Context.MarkLabel(LblTrue);
  41. Context.EmitLdintzr(Op.Rn);
  42. Context.MarkLabel(LblEnd);
  43. Context.EmitStintzr(Op.Rd);
  44. }
  45. }
  46. }