InstEmitMemory.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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 Ald(EmitterContext context)
  11. {
  12. OpCodeAttribute op = (OpCodeAttribute)context.CurrOp;
  13. Operand[] elems = new Operand[op.Count];
  14. for (int index = 0; index < op.Count; index++)
  15. {
  16. Operand src = Attribute(op.AttributeOffset + index * 4);
  17. context.Copy(elems[index] = Local(), src);
  18. }
  19. for (int index = 0; index < op.Count; index++)
  20. {
  21. Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
  22. if (rd.IsRZ)
  23. {
  24. break;
  25. }
  26. context.Copy(Register(rd), elems[index]);
  27. }
  28. }
  29. public static void Ast(EmitterContext context)
  30. {
  31. OpCodeAttribute op = (OpCodeAttribute)context.CurrOp;
  32. for (int index = 0; index < op.Count; index++)
  33. {
  34. if (op.Rd.Index + index > RegisterConsts.RegisterZeroIndex)
  35. {
  36. break;
  37. }
  38. Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
  39. Operand dest = Attribute(op.AttributeOffset + index * 4);
  40. context.Copy(dest, Register(rd));
  41. }
  42. }
  43. public static void Ipa(EmitterContext context)
  44. {
  45. OpCodeIpa op = (OpCodeIpa)context.CurrOp;
  46. Operand srcA = new Operand(OperandType.Attribute, op.AttributeOffset);
  47. Operand srcB = GetSrcB(context);
  48. context.Copy(GetDest(context), srcA);
  49. }
  50. public static void Ldc(EmitterContext context)
  51. {
  52. OpCodeLdc op = (OpCodeLdc)context.CurrOp;
  53. if (op.Size > IntegerSize.B64)
  54. {
  55. // TODO: Warning.
  56. }
  57. bool isSmallInt = op.Size < IntegerSize.B32;
  58. int count = op.Size == IntegerSize.B64 ? 2 : 1;
  59. Operand baseOffset = context.Copy(GetSrcA(context));
  60. for (int index = 0; index < count; index++)
  61. {
  62. Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);
  63. if (rd.IsRZ)
  64. {
  65. break;
  66. }
  67. Operand offset = context.IAdd(baseOffset, Const((op.Offset + index) * 4));
  68. Operand value = context.LoadConstant(Const(op.Slot), offset);
  69. if (isSmallInt)
  70. {
  71. Operand shift = context.BitwiseAnd(baseOffset, Const(3));
  72. value = context.ShiftRightU32(value, shift);
  73. switch (op.Size)
  74. {
  75. case IntegerSize.U8: value = ZeroExtendTo32(context, value, 8); break;
  76. case IntegerSize.U16: value = ZeroExtendTo32(context, value, 16); break;
  77. case IntegerSize.S8: value = SignExtendTo32(context, value, 8); break;
  78. case IntegerSize.S16: value = SignExtendTo32(context, value, 16); break;
  79. }
  80. }
  81. context.Copy(Register(rd), value);
  82. }
  83. }
  84. public static void Out(EmitterContext context)
  85. {
  86. OpCode op = context.CurrOp;
  87. bool emit = op.RawOpCode.Extract(39);
  88. bool cut = op.RawOpCode.Extract(40);
  89. if (!(emit || cut))
  90. {
  91. // TODO: Warning.
  92. }
  93. if (emit)
  94. {
  95. context.EmitVertex();
  96. }
  97. if (cut)
  98. {
  99. context.EndPrimitive();
  100. }
  101. }
  102. }
  103. }