InstEmitAluHelper.cs 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using Ryujinx.Graphics.Shader.Decoders;
  2. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  3. using Ryujinx.Graphics.Shader.Translation;
  4. using System;
  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 class InstEmitAluHelper
  10. {
  11. public static long GetIntMin(IntegerType type)
  12. {
  13. switch (type)
  14. {
  15. case IntegerType.U8: return byte.MinValue;
  16. case IntegerType.S8: return sbyte.MinValue;
  17. case IntegerType.U16: return ushort.MinValue;
  18. case IntegerType.S16: return short.MinValue;
  19. case IntegerType.U32: return uint.MinValue;
  20. case IntegerType.S32: return int.MinValue;
  21. }
  22. throw new ArgumentException($"The type \"{type}\" is not a supported int type.");
  23. }
  24. public static long GetIntMax(IntegerType type)
  25. {
  26. switch (type)
  27. {
  28. case IntegerType.U8: return byte.MaxValue;
  29. case IntegerType.S8: return sbyte.MaxValue;
  30. case IntegerType.U16: return ushort.MaxValue;
  31. case IntegerType.S16: return short.MaxValue;
  32. case IntegerType.U32: return uint.MaxValue;
  33. case IntegerType.S32: return int.MaxValue;
  34. }
  35. throw new ArgumentException($"The type \"{type}\" is not a supported int type.");
  36. }
  37. public static Operand GetPredLogicalOp(
  38. EmitterContext context,
  39. LogicalOperation logicalOp,
  40. Operand input,
  41. Operand pred)
  42. {
  43. switch (logicalOp)
  44. {
  45. case LogicalOperation.And: return context.BitwiseAnd (input, pred);
  46. case LogicalOperation.Or: return context.BitwiseOr (input, pred);
  47. case LogicalOperation.ExclusiveOr: return context.BitwiseExclusiveOr(input, pred);
  48. }
  49. return input;
  50. }
  51. public static void SetZnFlags(EmitterContext context, Operand dest, bool setCC, bool extended = false)
  52. {
  53. if (!setCC)
  54. {
  55. return;
  56. }
  57. if (extended)
  58. {
  59. // When the operation is extended, it means we are doing
  60. // the operation on a long word with any number of bits,
  61. // so we need to AND the zero flag from result with the
  62. // previous result when extended is specified, to ensure
  63. // we have ZF set only if all words are zero, and not just
  64. // the last one.
  65. Operand oldZF = GetZF();
  66. Operand res = context.BitwiseAnd(context.ICompareEqual(dest, Const(0)), oldZF);
  67. context.Copy(GetZF(), res);
  68. }
  69. else
  70. {
  71. context.Copy(GetZF(), context.ICompareEqual(dest, Const(0)));
  72. }
  73. context.Copy(GetNF(), context.ICompareLess(dest, Const(0)));
  74. }
  75. public static void SetFPZnFlags(EmitterContext context, Operand dest, bool setCC)
  76. {
  77. if (setCC)
  78. {
  79. context.Copy(GetZF(), context.FPCompareEqual(dest, ConstF(0)));
  80. context.Copy(GetNF(), context.FPCompareLess (dest, ConstF(0)));
  81. }
  82. }
  83. }
  84. }