InstructionInfo.cs
1 using Ryujinx.Graphics.Shader.IntermediateRepresentation; 2 using Ryujinx.Graphics.Shader.Translation; 3 using System; 4 5 namespace Ryujinx.Graphics.Shader.StructuredIr 6 { 7 static class InstructionInfo 8 { 9 private readonly struct InstInfo 10 { 11 public AggregateType DestType { get; } 12 13 public AggregateType[] SrcTypes { get; } 14 15 public InstInfo(AggregateType destType, params AggregateType[] srcTypes) 16 { 17 DestType = destType; 18 SrcTypes = srcTypes; 19 } 20 } 21 22 private static readonly InstInfo[] _infoTbl; 23 24 static InstructionInfo() 25 { 26 _infoTbl = new InstInfo[(int)Instruction.Count]; 27 28 #pragma warning disable IDE0055 // Disable formatting 29 // Inst Destination type Source 1 type Source 2 type Source 3 type Source 4 type 30 Add(Instruction.AtomicAdd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); 31 Add(Instruction.AtomicAnd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); 32 Add(Instruction.AtomicCompareAndSwap, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32, AggregateType.U32); 33 Add(Instruction.AtomicMaxS32, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32); 34 Add(Instruction.AtomicMaxU32, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); 35 Add(Instruction.AtomicMinS32, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32); 36 Add(Instruction.AtomicMinU32, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); 37 Add(Instruction.AtomicOr, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); 38 Add(Instruction.AtomicSwap, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); 39 Add(Instruction.AtomicXor, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); 40 Add(Instruction.Absolute, AggregateType.Scalar, AggregateType.Scalar); 41 Add(Instruction.Add, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 42 Add(Instruction.Ballot, AggregateType.U32, AggregateType.Bool); 43 Add(Instruction.BitCount, AggregateType.S32, AggregateType.S32); 44 Add(Instruction.BitfieldExtractS32, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32); 45 Add(Instruction.BitfieldExtractU32, AggregateType.U32, AggregateType.U32, AggregateType.S32, AggregateType.S32); 46 Add(Instruction.BitfieldInsert, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32); 47 Add(Instruction.BitfieldReverse, AggregateType.S32, AggregateType.S32); 48 Add(Instruction.BitwiseAnd, AggregateType.S32, AggregateType.S32, AggregateType.S32); 49 Add(Instruction.BitwiseExclusiveOr, AggregateType.S32, AggregateType.S32, AggregateType.S32); 50 Add(Instruction.BitwiseNot, AggregateType.S32, AggregateType.S32); 51 Add(Instruction.BitwiseOr, AggregateType.S32, AggregateType.S32, AggregateType.S32); 52 Add(Instruction.BranchIfTrue, AggregateType.Void, AggregateType.Bool); 53 Add(Instruction.BranchIfFalse, AggregateType.Void, AggregateType.Bool); 54 Add(Instruction.Call, AggregateType.Scalar); 55 Add(Instruction.Ceiling, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 56 Add(Instruction.Clamp, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 57 Add(Instruction.ClampU32, AggregateType.U32, AggregateType.U32, AggregateType.U32, AggregateType.U32); 58 Add(Instruction.CompareEqual, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); 59 Add(Instruction.CompareGreater, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); 60 Add(Instruction.CompareGreaterOrEqual, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); 61 Add(Instruction.CompareGreaterOrEqualU32, AggregateType.Bool, AggregateType.U32, AggregateType.U32); 62 Add(Instruction.CompareGreaterU32, AggregateType.Bool, AggregateType.U32, AggregateType.U32); 63 Add(Instruction.CompareLess, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); 64 Add(Instruction.CompareLessOrEqual, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); 65 Add(Instruction.CompareLessOrEqualU32, AggregateType.Bool, AggregateType.U32, AggregateType.U32); 66 Add(Instruction.CompareLessU32, AggregateType.Bool, AggregateType.U32, AggregateType.U32); 67 Add(Instruction.CompareNotEqual, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); 68 Add(Instruction.ConditionalSelect, AggregateType.Scalar, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); 69 Add(Instruction.ConvertFP32ToFP64, AggregateType.FP64, AggregateType.FP32); 70 Add(Instruction.ConvertFP64ToFP32, AggregateType.FP32, AggregateType.FP64); 71 Add(Instruction.ConvertFP32ToS32, AggregateType.S32, AggregateType.FP32); 72 Add(Instruction.ConvertFP32ToU32, AggregateType.U32, AggregateType.FP32); 73 Add(Instruction.ConvertFP64ToS32, AggregateType.S32, AggregateType.FP64); 74 Add(Instruction.ConvertFP64ToU32, AggregateType.U32, AggregateType.FP64); 75 Add(Instruction.ConvertS32ToFP32, AggregateType.FP32, AggregateType.S32); 76 Add(Instruction.ConvertS32ToFP64, AggregateType.FP64, AggregateType.S32); 77 Add(Instruction.ConvertU32ToFP32, AggregateType.FP32, AggregateType.U32); 78 Add(Instruction.ConvertU32ToFP64, AggregateType.FP64, AggregateType.U32); 79 Add(Instruction.Cosine, AggregateType.Scalar, AggregateType.Scalar); 80 Add(Instruction.Ddx, AggregateType.FP32, AggregateType.FP32); 81 Add(Instruction.Ddy, AggregateType.FP32, AggregateType.FP32); 82 Add(Instruction.Divide, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 83 Add(Instruction.ExponentB2, AggregateType.Scalar, AggregateType.Scalar); 84 Add(Instruction.FindLSB, AggregateType.S32, AggregateType.S32); 85 Add(Instruction.FindMSBS32, AggregateType.S32, AggregateType.S32); 86 Add(Instruction.FindMSBU32, AggregateType.S32, AggregateType.U32); 87 Add(Instruction.Floor, AggregateType.Scalar, AggregateType.Scalar); 88 Add(Instruction.FusedMultiplyAdd, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 89 Add(Instruction.ImageLoad, AggregateType.FP32); 90 Add(Instruction.ImageStore, AggregateType.Void); 91 Add(Instruction.ImageAtomic, AggregateType.S32); 92 Add(Instruction.IsNan, AggregateType.Bool, AggregateType.Scalar); 93 Add(Instruction.Load, AggregateType.FP32); 94 Add(Instruction.Lod, AggregateType.FP32); 95 Add(Instruction.LogarithmB2, AggregateType.Scalar, AggregateType.Scalar); 96 Add(Instruction.LogicalAnd, AggregateType.Bool, AggregateType.Bool, AggregateType.Bool); 97 Add(Instruction.LogicalExclusiveOr, AggregateType.Bool, AggregateType.Bool, AggregateType.Bool); 98 Add(Instruction.LogicalNot, AggregateType.Bool, AggregateType.Bool); 99 Add(Instruction.LogicalOr, AggregateType.Bool, AggregateType.Bool, AggregateType.Bool); 100 Add(Instruction.Maximum, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 101 Add(Instruction.MaximumU32, AggregateType.U32, AggregateType.U32, AggregateType.U32); 102 Add(Instruction.Minimum, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 103 Add(Instruction.MinimumU32, AggregateType.U32, AggregateType.U32, AggregateType.U32); 104 Add(Instruction.Modulo, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 105 Add(Instruction.Multiply, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 106 Add(Instruction.MultiplyHighS32, AggregateType.S32, AggregateType.S32, AggregateType.S32); 107 Add(Instruction.MultiplyHighU32, AggregateType.U32, AggregateType.U32, AggregateType.U32); 108 Add(Instruction.Negate, AggregateType.Scalar, AggregateType.Scalar); 109 Add(Instruction.PackDouble2x32, AggregateType.FP64, AggregateType.U32, AggregateType.U32); 110 Add(Instruction.PackHalf2x16, AggregateType.U32, AggregateType.FP32, AggregateType.FP32); 111 Add(Instruction.ReciprocalSquareRoot, AggregateType.Scalar, AggregateType.Scalar); 112 Add(Instruction.Return, AggregateType.Void, AggregateType.U32); 113 Add(Instruction.Round, AggregateType.Scalar, AggregateType.Scalar); 114 Add(Instruction.ShiftLeft, AggregateType.S32, AggregateType.S32, AggregateType.S32); 115 Add(Instruction.ShiftRightS32, AggregateType.S32, AggregateType.S32, AggregateType.S32); 116 Add(Instruction.ShiftRightU32, AggregateType.U32, AggregateType.U32, AggregateType.S32); 117 Add(Instruction.Shuffle, AggregateType.FP32, AggregateType.FP32, AggregateType.U32); 118 Add(Instruction.ShuffleDown, AggregateType.FP32, AggregateType.FP32, AggregateType.U32); 119 Add(Instruction.ShuffleUp, AggregateType.FP32, AggregateType.FP32, AggregateType.U32); 120 Add(Instruction.ShuffleXor, AggregateType.FP32, AggregateType.FP32, AggregateType.U32); 121 Add(Instruction.Sine, AggregateType.Scalar, AggregateType.Scalar); 122 Add(Instruction.SquareRoot, AggregateType.Scalar, AggregateType.Scalar); 123 Add(Instruction.Store, AggregateType.Void); 124 Add(Instruction.Subtract, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); 125 Add(Instruction.SwizzleAdd, AggregateType.FP32, AggregateType.FP32, AggregateType.FP32, AggregateType.S32); 126 Add(Instruction.TextureSample, AggregateType.FP32); 127 Add(Instruction.TextureQuerySamples, AggregateType.S32, AggregateType.S32); 128 Add(Instruction.TextureQuerySize, AggregateType.S32, AggregateType.S32, AggregateType.S32); 129 Add(Instruction.Truncate, AggregateType.Scalar, AggregateType.Scalar); 130 Add(Instruction.UnpackDouble2x32, AggregateType.U32, AggregateType.FP64); 131 Add(Instruction.UnpackHalf2x16, AggregateType.FP32, AggregateType.U32); 132 Add(Instruction.VectorExtract, AggregateType.Scalar, AggregateType.Vector4, AggregateType.S32); 133 Add(Instruction.VoteAll, AggregateType.Bool, AggregateType.Bool); 134 Add(Instruction.VoteAllEqual, AggregateType.Bool, AggregateType.Bool); 135 Add(Instruction.VoteAny, AggregateType.Bool, AggregateType.Bool); 136 #pragma warning restore IDE0055 137 } 138 139 private static void Add(Instruction inst, AggregateType destType, params AggregateType[] srcTypes) 140 { 141 _infoTbl[(int)inst] = new InstInfo(destType, srcTypes); 142 } 143 144 public static AggregateType GetDestVarType(Instruction inst) 145 { 146 return GetFinalVarType(_infoTbl[(int)(inst & Instruction.Mask)].DestType, inst); 147 } 148 149 public static AggregateType GetSrcVarType(Instruction inst, int index) 150 { 151 // TODO: Return correct type depending on source index, 152 // that can improve the decompiler output. 153 if (inst == Instruction.ImageLoad || 154 inst == Instruction.ImageStore || 155 inst == Instruction.ImageAtomic || 156 inst == Instruction.Lod || 157 inst == Instruction.TextureSample) 158 { 159 return AggregateType.FP32; 160 } 161 else if (inst == Instruction.Call || inst == Instruction.Load || inst == Instruction.Store || inst.IsAtomic()) 162 { 163 return AggregateType.S32; 164 } 165 166 return GetFinalVarType(_infoTbl[(int)(inst & Instruction.Mask)].SrcTypes[index], inst); 167 } 168 169 private static AggregateType GetFinalVarType(AggregateType type, Instruction inst) 170 { 171 if (type == AggregateType.Scalar) 172 { 173 if ((inst & Instruction.FP32) != 0) 174 { 175 return AggregateType.FP32; 176 } 177 else if ((inst & Instruction.FP64) != 0) 178 { 179 return AggregateType.FP64; 180 } 181 else 182 { 183 return AggregateType.S32; 184 } 185 } 186 else if (type == AggregateType.Void) 187 { 188 throw new ArgumentException($"Invalid operand for instruction \"{inst}\"."); 189 } 190 191 return type; 192 } 193 194 public static bool IsUnary(Instruction inst) 195 { 196 if (inst == Instruction.Copy) 197 { 198 return true; 199 } 200 else if (inst == Instruction.TextureSample) 201 { 202 return false; 203 } 204 205 return _infoTbl[(int)(inst & Instruction.Mask)].SrcTypes.Length == 1; 206 } 207 } 208 }