InstEmitFloatMinMax.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using Ryujinx.Graphics.Shader.Decoders;
  2. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  3. using Ryujinx.Graphics.Shader.Translation;
  4. using static Ryujinx.Graphics.Shader.Instructions.InstEmitAluHelper;
  5. using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper;
  6. namespace Ryujinx.Graphics.Shader.Instructions
  7. {
  8. static partial class InstEmit
  9. {
  10. public static void DmnmxR(EmitterContext context)
  11. {
  12. InstDmnmxR op = context.GetOp<InstDmnmxR>();
  13. var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
  14. var srcB = GetSrcReg(context, op.SrcB, isFP64: true);
  15. var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
  16. EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
  17. }
  18. public static void DmnmxI(EmitterContext context)
  19. {
  20. InstDmnmxI op = context.GetOp<InstDmnmxI>();
  21. var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
  22. var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20), isFP64: true);
  23. var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
  24. EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
  25. }
  26. public static void DmnmxC(EmitterContext context)
  27. {
  28. InstDmnmxC op = context.GetOp<InstDmnmxC>();
  29. var srcA = GetSrcReg(context, op.SrcA, isFP64: true);
  30. var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset, isFP64: true);
  31. var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
  32. EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC, isFP64: true);
  33. }
  34. public static void FmnmxR(EmitterContext context)
  35. {
  36. InstFmnmxR op = context.GetOp<InstFmnmxR>();
  37. var srcA = GetSrcReg(context, op.SrcA);
  38. var srcB = GetSrcReg(context, op.SrcB);
  39. var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
  40. EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
  41. }
  42. public static void FmnmxI(EmitterContext context)
  43. {
  44. InstFmnmxI op = context.GetOp<InstFmnmxI>();
  45. var srcA = GetSrcReg(context, op.SrcA);
  46. var srcB = GetSrcImm(context, Imm20ToFloat(op.Imm20));
  47. var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
  48. EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
  49. }
  50. public static void FmnmxC(EmitterContext context)
  51. {
  52. InstFmnmxC op = context.GetOp<InstFmnmxC>();
  53. var srcA = GetSrcReg(context, op.SrcA);
  54. var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
  55. var srcPred = GetPredicate(context, op.SrcPred, op.SrcPredInv);
  56. EmitFmnmx(context, srcA, srcB, srcPred, op.Dest, op.AbsA, op.AbsB, op.NegA, op.NegB, op.WriteCC);
  57. }
  58. private static void EmitFmnmx(
  59. EmitterContext context,
  60. Operand srcA,
  61. Operand srcB,
  62. Operand srcPred,
  63. int rd,
  64. bool absoluteA,
  65. bool absoluteB,
  66. bool negateA,
  67. bool negateB,
  68. bool writeCC,
  69. bool isFP64 = false)
  70. {
  71. Instruction fpType = isFP64 ? Instruction.FP64 : Instruction.FP32;
  72. srcA = context.FPAbsNeg(srcA, absoluteA, negateA, fpType);
  73. srcB = context.FPAbsNeg(srcB, absoluteB, negateB, fpType);
  74. Operand resMin = context.FPMinimum(srcA, srcB, fpType);
  75. Operand resMax = context.FPMaximum(srcA, srcB, fpType);
  76. Operand res = context.ConditionalSelect(srcPred, resMin, resMax);
  77. SetDest(context, res, rd, isFP64);
  78. SetFPZnFlags(context, res, writeCC, fpType);
  79. }
  80. }
  81. }