InstEmitIntegerLogical.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
  7. namespace Ryujinx.Graphics.Shader.Instructions
  8. {
  9. static partial class InstEmit
  10. {
  11. private const int PT = RegisterConsts.PredicateTrueIndex;
  12. public static void LopR(EmitterContext context)
  13. {
  14. InstLopR op = context.GetOp<InstLopR>();
  15. var srcA = GetSrcReg(context, op.SrcA);
  16. var srcB = GetSrcReg(context, op.SrcB);
  17. EmitLop(context, op.Lop, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
  18. }
  19. public static void LopI(EmitterContext context)
  20. {
  21. InstLopI op = context.GetOp<InstLopI>();
  22. var srcA = GetSrcReg(context, op.SrcA);
  23. var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
  24. EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
  25. }
  26. public static void LopC(EmitterContext context)
  27. {
  28. InstLopC op = context.GetOp<InstLopC>();
  29. var srcA = GetSrcReg(context, op.SrcA);
  30. var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
  31. EmitLop(context, op.LogicOp, op.PredicateOp, srcA, srcB, op.Dest, op.DestPred, op.NegA, op.NegB, op.X, op.WriteCC);
  32. }
  33. public static void Lop32i(EmitterContext context)
  34. {
  35. InstLop32i op = context.GetOp<InstLop32i>();
  36. var srcA = GetSrcReg(context, op.SrcA);
  37. var srcB = GetSrcImm(context, op.Imm32);
  38. EmitLop(context, op.LogicOp, PredicateOp.F, srcA, srcB, op.Dest, PT, op.NegA, op.NegB, op.X, op.WriteCC);
  39. }
  40. public static void Lop3R(EmitterContext context)
  41. {
  42. InstLop3R op = context.GetOp<InstLop3R>();
  43. var srcA = GetSrcReg(context, op.SrcA);
  44. var srcB = GetSrcReg(context, op.SrcB);
  45. var srcC = GetSrcReg(context, op.SrcC);
  46. EmitLop3(context, op.Imm, op.PredicateOp, srcA, srcB, srcC, op.Dest, op.DestPred, op.X, op.WriteCC);
  47. }
  48. public static void Lop3I(EmitterContext context)
  49. {
  50. InstLop3I op = context.GetOp<InstLop3I>();
  51. var srcA = GetSrcReg(context, op.SrcA);
  52. var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
  53. var srcC = GetSrcReg(context, op.SrcC);
  54. EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC);
  55. }
  56. public static void Lop3C(EmitterContext context)
  57. {
  58. InstLop3C op = context.GetOp<InstLop3C>();
  59. var srcA = GetSrcReg(context, op.SrcA);
  60. var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
  61. var srcC = GetSrcReg(context, op.SrcC);
  62. EmitLop3(context, op.Imm, PredicateOp.F, srcA, srcB, srcC, op.Dest, PT, false, op.WriteCC);
  63. }
  64. private static void EmitLop(
  65. EmitterContext context,
  66. LogicOp logicOp,
  67. PredicateOp predOp,
  68. Operand srcA,
  69. Operand srcB,
  70. int rd,
  71. int destPred,
  72. bool invertA,
  73. bool invertB,
  74. bool extended,
  75. bool writeCC)
  76. {
  77. srcA = context.BitwiseNot(srcA, invertA);
  78. srcB = context.BitwiseNot(srcB, invertB);
  79. Operand res = logicOp switch
  80. {
  81. LogicOp.And => res = context.BitwiseAnd(srcA, srcB),
  82. LogicOp.Or => res = context.BitwiseOr(srcA, srcB),
  83. LogicOp.Xor => res = context.BitwiseExclusiveOr(srcA, srcB),
  84. _ => srcB
  85. };
  86. EmitLopPredWrite(context, res, predOp, destPred);
  87. context.Copy(GetDest(rd), res);
  88. SetZnFlags(context, res, writeCC, extended);
  89. }
  90. private static void EmitLop3(
  91. EmitterContext context,
  92. int truthTable,
  93. PredicateOp predOp,
  94. Operand srcA,
  95. Operand srcB,
  96. Operand srcC,
  97. int rd,
  98. int destPred,
  99. bool extended,
  100. bool writeCC)
  101. {
  102. Operand res = Lop3Expression.GetFromTruthTable(context, srcA, srcB, srcC, truthTable);
  103. EmitLopPredWrite(context, res, predOp, destPred);
  104. context.Copy(GetDest(rd), res);
  105. SetZnFlags(context, res, writeCC, extended);
  106. }
  107. private static void EmitLopPredWrite(EmitterContext context, Operand result, PredicateOp predOp, int pred)
  108. {
  109. if (pred != RegisterConsts.PredicateTrueIndex)
  110. {
  111. Operand pRes;
  112. if (predOp == PredicateOp.F)
  113. {
  114. pRes = Const(IrConsts.False);
  115. }
  116. else if (predOp == PredicateOp.T)
  117. {
  118. pRes = Const(IrConsts.True);
  119. }
  120. else if (predOp == PredicateOp.Z)
  121. {
  122. pRes = context.ICompareEqual(result, Const(0));
  123. }
  124. else /* if (predOp == Pop.Nz) */
  125. {
  126. pRes = context.ICompareNotEqual(result, Const(0));
  127. }
  128. context.Copy(Register(pred, RegisterType.Predicate), pRes);
  129. }
  130. }
  131. }
  132. }