AInstEmitCsel.cs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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.EmitStintzr(Op.Rd);
  40. Context.Emit(OpCodes.Br_S, LblEnd);
  41. Context.MarkLabel(LblTrue);
  42. Context.EmitLdintzr(Op.Rn);
  43. Context.EmitStintzr(Op.Rd);
  44. Context.MarkLabel(LblEnd);
  45. }
  46. }
  47. }