InstEmitBitfield.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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.InstEmitHelper;
  5. using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
  6. namespace Ryujinx.Graphics.Shader.Instructions
  7. {
  8. static partial class InstEmit
  9. {
  10. public static void BfeR(EmitterContext context)
  11. {
  12. InstBfeR op = context.GetOp<InstBfeR>();
  13. var srcA = GetSrcReg(context, op.SrcA);
  14. var srcB = GetSrcReg(context, op.SrcB);
  15. EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
  16. }
  17. public static void BfeI(EmitterContext context)
  18. {
  19. InstBfeI op = context.GetOp<InstBfeI>();
  20. var srcA = GetSrcReg(context, op.SrcA);
  21. var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
  22. EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
  23. }
  24. public static void BfeC(EmitterContext context)
  25. {
  26. InstBfeC op = context.GetOp<InstBfeC>();
  27. var srcA = GetSrcReg(context, op.SrcA);
  28. var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
  29. EmitBfe(context, srcA, srcB, op.Dest, op.Brev, op.Signed);
  30. }
  31. public static void BfiR(EmitterContext context)
  32. {
  33. InstBfiR op = context.GetOp<InstBfiR>();
  34. var srcA = GetSrcReg(context, op.SrcA);
  35. var srcB = GetSrcReg(context, op.SrcB);
  36. var srcC = GetSrcReg(context, op.SrcC);
  37. EmitBfi(context, srcA, srcB, srcC, op.Dest);
  38. }
  39. public static void BfiI(EmitterContext context)
  40. {
  41. InstBfiI op = context.GetOp<InstBfiI>();
  42. var srcA = GetSrcReg(context, op.SrcA);
  43. var srcB = GetSrcImm(context, Imm20ToSInt(op.Imm20));
  44. var srcC = GetSrcReg(context, op.SrcC);
  45. EmitBfi(context, srcA, srcB, srcC, op.Dest);
  46. }
  47. public static void BfiC(EmitterContext context)
  48. {
  49. InstBfiC op = context.GetOp<InstBfiC>();
  50. var srcA = GetSrcReg(context, op.SrcA);
  51. var srcB = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
  52. var srcC = GetSrcReg(context, op.SrcC);
  53. EmitBfi(context, srcA, srcB, srcC, op.Dest);
  54. }
  55. public static void BfiRc(EmitterContext context)
  56. {
  57. InstBfiRc op = context.GetOp<InstBfiRc>();
  58. var srcA = GetSrcReg(context, op.SrcA);
  59. var srcB = GetSrcReg(context, op.SrcC);
  60. var srcC = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
  61. EmitBfi(context, srcA, srcB, srcC, op.Dest);
  62. }
  63. public static void FloR(EmitterContext context)
  64. {
  65. InstFloR op = context.GetOp<InstFloR>();
  66. EmitFlo(context, GetSrcReg(context, op.SrcB), op.Dest, op.NegB, op.Sh, op.Signed);
  67. }
  68. public static void FloI(EmitterContext context)
  69. {
  70. InstFloI op = context.GetOp<InstFloI>();
  71. EmitFlo(context, GetSrcImm(context, Imm20ToSInt(op.Imm20)), op.Dest, op.NegB, op.Sh, op.Signed);
  72. }
  73. public static void FloC(EmitterContext context)
  74. {
  75. InstFloC op = context.GetOp<InstFloC>();
  76. EmitFlo(context, GetSrcCbuf(context, op.CbufSlot, op.CbufOffset), op.Dest, op.NegB, op.Sh, op.Signed);
  77. }
  78. public static void PopcR(EmitterContext context)
  79. {
  80. InstPopcR op = context.GetOp<InstPopcR>();
  81. EmitPopc(context, GetSrcReg(context, op.SrcB), op.Dest, op.NegB);
  82. }
  83. public static void PopcI(EmitterContext context)
  84. {
  85. InstPopcI op = context.GetOp<InstPopcI>();
  86. EmitPopc(context, GetSrcImm(context, Imm20ToSInt(op.Imm20)), op.Dest, op.NegB);
  87. }
  88. public static void PopcC(EmitterContext context)
  89. {
  90. InstPopcC op = context.GetOp<InstPopcC>();
  91. EmitPopc(context, GetSrcCbuf(context, op.CbufSlot, op.CbufOffset), op.Dest, op.NegB);
  92. }
  93. private static void EmitBfe(
  94. EmitterContext context,
  95. Operand srcA,
  96. Operand srcB,
  97. int rd,
  98. bool bitReverse,
  99. bool isSigned)
  100. {
  101. if (bitReverse)
  102. {
  103. srcA = context.BitfieldReverse(srcA);
  104. }
  105. Operand position = context.BitwiseAnd(srcB, Const(0xff));
  106. Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8));
  107. Operand res = isSigned
  108. ? context.BitfieldExtractS32(srcA, position, size)
  109. : context.BitfieldExtractU32(srcA, position, size);
  110. context.Copy(GetDest(rd), res);
  111. // TODO: CC, X, corner cases.
  112. }
  113. private static void EmitBfi(EmitterContext context, Operand srcA, Operand srcB, Operand srcC, int rd)
  114. {
  115. Operand position = context.BitwiseAnd(srcB, Const(0xff));
  116. Operand size = context.BitfieldExtractU32(srcB, Const(8), Const(8));
  117. Operand res = context.BitfieldInsert(srcC, srcA, position, size);
  118. context.Copy(GetDest(rd), res);
  119. }
  120. private static void EmitFlo(EmitterContext context, Operand src, int rd, bool invert, bool sh, bool isSigned)
  121. {
  122. Operand srcB = context.BitwiseNot(src, invert);
  123. Operand res;
  124. if (sh)
  125. {
  126. res = context.FindLSB(context.BitfieldReverse(srcB));
  127. }
  128. else
  129. {
  130. res = isSigned
  131. ? context.FindMSBS32(srcB)
  132. : context.FindMSBU32(srcB);
  133. }
  134. context.Copy(GetDest(rd), res);
  135. }
  136. private static void EmitPopc(EmitterContext context, Operand src, int rd, bool invert)
  137. {
  138. Operand srcB = context.BitwiseNot(src, invert);
  139. Operand res = context.BitCount(srcB);
  140. context.Copy(GetDest(rd), res);
  141. }
  142. }
  143. }