AInstEmitMul.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. public static void Madd(AILEmitterCtx Context) => EmitMul(Context, OpCodes.Add);
  9. public static void Msub(AILEmitterCtx Context) => EmitMul(Context, OpCodes.Sub);
  10. private static void EmitMul(AILEmitterCtx Context, OpCode ILOp)
  11. {
  12. AOpCodeMul Op = (AOpCodeMul)Context.CurrOp;
  13. Context.EmitLdintzr(Op.Ra);
  14. Context.EmitLdintzr(Op.Rn);
  15. Context.EmitLdintzr(Op.Rm);
  16. Context.Emit(OpCodes.Mul);
  17. Context.Emit(ILOp);
  18. Context.EmitStintzr(Op.Rd);
  19. }
  20. public static void Smaddl(AILEmitterCtx Context) => EmitMull(Context, OpCodes.Add, true);
  21. public static void Smsubl(AILEmitterCtx Context) => EmitMull(Context, OpCodes.Sub, true);
  22. public static void Umaddl(AILEmitterCtx Context) => EmitMull(Context, OpCodes.Add, false);
  23. public static void Umsubl(AILEmitterCtx Context) => EmitMull(Context, OpCodes.Sub, false);
  24. private static void EmitMull(AILEmitterCtx Context, OpCode AddSubOp, bool Signed)
  25. {
  26. AOpCodeMul Op = (AOpCodeMul)Context.CurrOp;
  27. OpCode CastOp = Signed
  28. ? OpCodes.Conv_I8
  29. : OpCodes.Conv_U8;
  30. Context.EmitLdintzr(Op.Ra);
  31. Context.EmitLdintzr(Op.Rn);
  32. Context.Emit(OpCodes.Conv_I4);
  33. Context.Emit(CastOp);
  34. Context.EmitLdintzr(Op.Rm);
  35. Context.Emit(OpCodes.Conv_I4);
  36. Context.Emit(CastOp);
  37. Context.Emit(OpCodes.Mul);
  38. Context.Emit(AddSubOp);
  39. Context.EmitStintzr(Op.Rd);
  40. }
  41. public static void Smulh(AILEmitterCtx Context)
  42. {
  43. AOpCodeMul Op = (AOpCodeMul)Context.CurrOp;
  44. Context.EmitLdintzr(Op.Rn);
  45. Context.EmitLdintzr(Op.Rm);
  46. ASoftFallback.EmitCall(Context, nameof(ASoftFallback.SMulHi128));
  47. Context.EmitStintzr(Op.Rd);
  48. }
  49. public static void Umulh(AILEmitterCtx Context)
  50. {
  51. AOpCodeMul Op = (AOpCodeMul)Context.CurrOp;
  52. Context.EmitLdintzr(Op.Rn);
  53. Context.EmitLdintzr(Op.Rm);
  54. ASoftFallback.EmitCall(Context, nameof(ASoftFallback.UMulHi128));
  55. Context.EmitStintzr(Op.Rd);
  56. }
  57. }
  58. }