public static DebugInterfaceDeclarationToken Parse(DebugBytecodeReader reader)
        {
            uint token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("DynamicallyIndex", token0.DecodeValue(11, 11) == 1);
            var result = new DebugInterfaceDeclarationToken
            {
                DynamicallyIndexed          = (token0.DecodeValue(11, 11) == 1),
                Identifier                  = reader.ReadUInt32("Identifier"),
                ExpectedFunctionTableLength = reader.ReadUInt32("ExpectedFunctionTableLength")
            };

            uint token3 = reader.ReadUInt32("token3");

            result.TableLength = token3.DecodeValue <ushort>(00, 15);
            result.ArrayLength = token3.DecodeValue <ushort>(16, 31);
            reader.AddNote("TableLength", result.TableLength);
            reader.AddNote("ArrayLength", result.ArrayLength);

            for (int i = 0; i < result.TableLength; i++)
            {
                result.FunctionTableIdentifiers.Add(reader.ReadUInt32($"FunctionTableIdentifiers[{i}]"));
            }

            return(result);
        }
        public static DebugFxlcToken Parse(DebugBytecodeReader reader)
        {
            var result = new DebugFxlcToken();

            var token = reader.ReadUInt32($"Token");
            var tokenComponentCount = token.DecodeValue(0, 2);

            result.Type = (FxlcOpcode)token.DecodeValue(20, 30);
            result.IsScalarInstruction = token.DecodeValue <bool>(31, 31);

            Debug.Assert(Enum.IsDefined(typeof(FxlcOpcode), result.Type),
                         $"Unknown FxlcTokenType {result.Type}");

            Debug.Assert(token.DecodeValue(3, 19) == 0,
                         $"Unexpected data in FxlcToken bits 3-19 {token.DecodeValue(3, 19)}");

            reader.AddNote("Token", result.Type);
            reader.AddNote("TokenComponentCount", tokenComponentCount);
            reader.AddNote("IsScalarInstruction", result.IsScalarInstruction);

            var operandCount = result.OperandCount = reader.ReadUInt32("OperandCount");

            for (int i = 0; i < operandCount; i++)
            {
                var isScalarOp = i == 0 && result.IsScalarInstruction;
                result.Operands.Add(DebugFxlcOperand.Parse(reader, tokenComponentCount, isScalarOp));
            }
            // destination operand
            result.Operands.Insert(0, DebugFxlcOperand.Parse(reader, tokenComponentCount, false));
            return(result);
        }
        public static void AddNotes(DebugBytecodeReader reader, uint opcodeToken0)
        {
            var opcodeType = opcodeToken0.DecodeValue <OpcodeType>(0, 10);
            var length     = opcodeToken0.DecodeValue(24, 30);
            var isExtended = (opcodeToken0.DecodeValue(31, 31) == 1);

            reader.AddNote("OpcodeType", opcodeType);
            reader.AddNote("Length", length);
            reader.AddNote("IsExtended", isExtended);
        }
        bool ReadCommentToken(DebugBytecodeReader reader)
        {
            var fourCC = reader.PeakUInt32Ahead(4);

            if (KnownCommentTypes.ContainsKey(fourCC))
            {
                reader.AddIndent(KnownCommentTypes[fourCC].ToString());
            }
            else
            {
                return(false);
            }
            var    instructionToken = reader.ReadUInt32("Token");
            var    startPosition    = reader._reader.BaseStream.Position;
            Opcode opcode           = (Opcode)(instructionToken & 0xffff);

            reader.AddNote("TokenOpcode", opcode);
            var size = (int)((instructionToken >> 16) & 0x7FFF);

            reader.AddNote("TokenSize", size);
            reader.ReadBytes("FourCC", 4);

            switch (KnownCommentTypes[fourCC])
            {
            case CommentType.CTAB:
                ConstantTable = DebugConstantTable.Parse(reader);
                break;

            case CommentType.C**T:
                Cli = DebugCliToken.Parse(reader);
                break;

            case CommentType.FXLC:
                Fxlc = DebugFxlc.Parse(reader, (uint)size * 4);
                break;

            case CommentType.PRES:
                Preshader = DebugPreshader.Parse(reader);
                break;

            case CommentType.PRSI:
                Prsi = DebugPrsiToken.Parse(reader, (uint)size);
                break;

            default:
                return(false);
            }
            reader.RemoveIndent();
            reader._reader.BaseStream.Position = startPosition + size * 4;
            return(true);
        }
Exemple #5
0
        public static SystemValueName Parse(DebugBytecodeReader reader)
        {
            uint token = reader.ReadUInt32("token");

            reader.AddNote("SystemValueName", token.DecodeValue <SystemValueName>(0, 15));
            return(token.DecodeValue <SystemValueName>(0, 15));
        }
Exemple #6
0
        public static DebugResourceReturnTypeToken Parse(DebugBytecodeReader reader)
        {
            var token  = reader.ReadUInt32("token");
            var result = new DebugResourceReturnTypeToken
            {
                X = token.DecodeValue <ResourceReturnType>(00, 03),
                Y = token.DecodeValue <ResourceReturnType>(04, 07),
                Z = token.DecodeValue <ResourceReturnType>(08, 11),
                W = token.DecodeValue <ResourceReturnType>(12, 15)
            };

            reader.AddNote("X", result.X);
            reader.AddNote("Y", result.Y);
            reader.AddNote("Z", result.Z);
            reader.AddNote("W", result.W);
            return(result);
        }
        public static DebugTessellatorOutputPrimitiveDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("OutputPrimitive", token0.DecodeValue <TessellatorOutputPrimitive>(11, 13));
            return(new DebugTessellatorOutputPrimitiveDeclarationToken
            {
                OutputPrimitive = token0.DecodeValue <TessellatorOutputPrimitive>(11, 13)
            });
        }
        public static DebugGeometryShaderOutputPrimitiveTopologyDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("PriomitiveTopology", token0.DecodeValue <PrimitiveTopology>(11, 17));
            return(new DebugGeometryShaderOutputPrimitiveTopologyDeclarationToken
            {
                PrimitiveTopology = token0.DecodeValue <PrimitiveTopology>(11, 17)
            });
        }
Exemple #9
0
        public static DebugTessellatorPartitioningDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("Partitioning", token0.DecodeValue <TessellatorPartitioning>(11, 13));
            return(new DebugTessellatorPartitioningDeclarationToken
            {
                Partitioning = token0.DecodeValue <TessellatorPartitioning>(11, 13)
            });
        }
Exemple #10
0
        public static DebugStreamDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("OpcodeType", token0.DecodeValue <OpcodeType>(0, 10));
            return(new DebugStreamDeclarationToken
            {
                Operand = DebugOperand.Parse(reader, token0.DecodeValue <OpcodeType>(0, 10))
            });
        }
Exemple #11
0
        public static DebugGlobalFlagsDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            var result = new DebugGlobalFlagsDeclarationToken();

            result.Flags = token0.DecodeValue <GlobalFlags>(11, 18);
            reader.AddNote("Flags", result.Flags);
            return(result);
        }
Exemple #12
0
        public static DebugDestinationOperand Parse(DebugBytecodeReader reader, uint index)
        {
            var token  = reader.ReadUInt32($"Operand {index}");
            var result = new DebugDestinationOperand();

            result.WordCount = 1;

            result.RegisterNumber       = token & 0x7FF;
            result.RegisterType         = (RegisterType)(((token >> 28) & 0x7) | ((token >> 8) & 0x18));
            result.MinPrecision         = (token >> 12) & 0XC;
            result.DestinationWriteMask = (ComponentFlags)((token >> 16) & 0xF);
            result.ResultModifier       = (ResultModifier)((token >> 20) & 0xF);

            reader.AddNote("RegisterNumber", result.RegisterNumber);
            reader.AddNote("RegisterType", result.RegisterType);
            reader.AddNote("MinPrecision", result.MinPrecision);
            reader.AddNote("DestinationWriteMask", result.DestinationWriteMask);
            reader.AddNote("ResultModifier", result.ResultModifier);
            return(result);
        }
        public static DebugGeometryShaderInputPrimitiveDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("Primitive", token0.DecodeValue <Primitive>(11, 16));
            return(new DebugGeometryShaderInputPrimitiveDeclarationToken
            {
                Primitive = token0.DecodeValue <Primitive>(11, 16)
            });
        }
        public static DebugTessellatorDomainDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("Domain", token0.DecodeValue <TessellatorDomain>(11, 12));
            return(new DebugTessellatorDomainDeclarationToken
            {
                Domain = token0.DecodeValue <TessellatorDomain>(11, 12)
            });
        }
Exemple #15
0
        private static void ReadExtendedOperand(DebugOperand operand, DebugBytecodeReader reader)
        {
            uint token1 = reader.ReadUInt32("token1");
            var  type   = token1.DecodeValue <ExtendedOperandType>(0, 5);

            reader.AddNote("type", type);
            switch (type)
            {
            case ExtendedOperandType.Modifier:
                operand.Modifier     = token1.DecodeValue <OperandModifier>(6, 13);
                operand.MinPrecision = token1.DecodeValue <OperandMinPrecision>(14, 16);
                operand.NonUniform   = token1.DecodeValue <bool>(17, 17);
                reader.AddNote("Modifier", operand.Modifier);
                reader.AddNote("MinPrecision", operand.MinPrecision);
                reader.AddNote("NonUniform", operand.NonUniform);
                break;

            default:
                throw new Exception($"Unknown Extended modifier {type}");
            }
        }
Exemple #16
0
        public static DebugResourceDeclarationToken Parse(DebugBytecodeReader reader, DebugShaderVersion version)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            var resourceDimension = token0.DecodeValue <ResourceDimension>(11, 15);

            reader.AddNote("resourceDimension", resourceDimension);

            byte sampleCount;

            switch (resourceDimension)
            {
            case ResourceDimension.Texture2DMultiSampled:
            case ResourceDimension.Texture2DMultiSampledArray:
                sampleCount = token0.DecodeValue <byte>(16, 22);
                reader.AddNote("SampleCount", sampleCount);
                break;

            default:
                sampleCount = 0;
                break;
            }

            var operand    = DebugOperand.Parse(reader, token0.DecodeValue <OpcodeType>(0, 10));
            var returnType = DebugResourceReturnTypeToken.Parse(reader);
            var result     = new DebugResourceDeclarationToken
            {
                ResourceDimension = resourceDimension,
                SampleCount       = sampleCount,
                Operand           = operand,
                ReturnType        = returnType
            };

            if (version.IsSM51)
            {
                result.SpaceIndex = reader.ReadUInt32("SpaceIndex");
            }
            return(result);
        }
Exemple #17
0
        public static DebugRawUnorderedAccessViewDeclarationToken Parse(DebugBytecodeReader reader, DebugShaderVersion version)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("Coherency", token0.DecodeValue <UnorderedAccessViewCoherency>(16, 16));
            reader.AddNote("IsRasterOrderedAccess", token0.DecodeValue <bool>(17, 17));
            reader.AddNote("OpcodeType", token0.DecodeValue <OpcodeType>(0, 10));

            var result = new DebugRawUnorderedAccessViewDeclarationToken
            {
                Coherency             = token0.DecodeValue <UnorderedAccessViewCoherency>(16, 16),
                IsRasterOrderedAccess = token0.DecodeValue <bool>(17, 17),
                Operand = DebugOperand.Parse(reader, token0.DecodeValue <OpcodeType>(0, 10))
            };

            if (version.IsSM51)
            {
                result.SpaceIndex = reader.ReadUInt32("SpaceIndex");
            }
            return(result);
        }
Exemple #18
0
        public static DebugRawThreadGroupSharedMemoryDeclarationToken Parse(DebugBytecodeReader reader)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("OpcodeType", token0.DecodeValue <OpcodeType>(0, 10));

            var result = new DebugRawThreadGroupSharedMemoryDeclarationToken
            {
                Operand      = DebugOperand.Parse(reader, token0.DecodeValue <OpcodeType>(0, 10)),
                ElementCount = reader.ReadUInt32("ElementCount")
            };

            return(result);
        }
Exemple #19
0
        public static DebugInputRegisterDeclarationToken Parse(DebugBytecodeReader reader)
        {
            uint token0     = reader.ReadUInt32("token0");
            var  opcodeType = token0.DecodeValue <OpcodeType>(0, 10);

            DebugOpcodeHeader.AddNotes(reader, token0);

            DebugInputRegisterDeclarationToken result;

            switch (opcodeType)
            {
            case OpcodeType.DclInput:
            case OpcodeType.DclInputSgv:
            case OpcodeType.DclInputSiv:
                result = new DebugInputRegisterDeclarationToken();
                break;

            case OpcodeType.DclInputPs:
            case OpcodeType.DclInputPsSgv:
            case OpcodeType.DclInputPsSiv:
                result = new DebugPixelShaderInputRegisterDeclarationToken
                {
                    InterpolationMode = token0.DecodeValue <InterpolationMode>(11, 14)
                };
                reader.AddNote("InterpolationMode", token0.DecodeValue <InterpolationMode>(11, 14));
                break;

            default:
                throw new ParseException("Unrecognised opcode type: " + opcodeType);
            }

            result.Operand = DebugOperand.Parse(reader, opcodeType);

            switch (opcodeType)
            {
            case OpcodeType.DclInputSgv:
            case OpcodeType.DclInputSiv:
            case OpcodeType.DclInputPsSgv:
            case OpcodeType.DclInputPsSiv:
                result.SystemValueName = DebugNameToken.Parse(reader);
                break;
            }

            return(result);
        }
        public static DebugSamplerDeclarationToken Parse(DebugBytecodeReader reader, DebugShaderVersion version)
        {
            var token0 = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("SamplerMode", token0.DecodeValue <SamplerMode>(11, 14));
            var operand = DebugOperand.Parse(reader, token0.DecodeValue <OpcodeType>(0, 10));
            var result  = new DebugSamplerDeclarationToken
            {
                SamplerMode = token0.DecodeValue <SamplerMode>(11, 14),
                Operand     = operand
            };

            if (version.IsSM51)
            {
                result.SpaceIndex = reader.ReadUInt32("SpaceIndex");
            }
            return(result);
        }
Exemple #21
0
        public static DebugConstantBufferDeclarationToken Parse(DebugBytecodeReader reader, DebugShaderVersion version)
        {
            var token0 = reader.ReadUInt32("Token0");

            DebugOpcodeHeader.AddNotes(reader, token0);
            reader.AddNote("AccessPattern", token0.DecodeValue <ConstantBufferAccessPattern>(11, 11));
            var result = new DebugConstantBufferDeclarationToken
            {
                AccessPattern = token0.DecodeValue <ConstantBufferAccessPattern>(11, 11),
                Operand       = DebugOperand.Parse(reader, token0.DecodeValue <OpcodeType>(0, 10))
            };

            if (version.IsSM51)
            {
                result.m_ConstantBufferSize = reader.ReadUInt32("SM51_ConstantBufferSize");
                result.SpaceIndex           = reader.ReadUInt32("SpaceIndex");
            }
            return(result);
        }
Exemple #22
0
        public static DebugSourceOperand Parse(DebugBytecodeReader reader, uint index)
        {
            var token  = reader.ReadUInt32($"Operand {index}");
            var result = new DebugSourceOperand();

            result.WordCount             = 1;
            result.RegisterNumber        = (token & 0x7FF);
            result.RegisterType          = (RegisterType)(((token >> 28) & 0x7) | ((token >> 8) & 0x18));
            result.IsRelativeAddressMode = (token & (1 << 13)) != 0;
            result.MinPrecision          = ((token >> 12) & 0XC);
            result.SwizzleComponents     = ((token >> 16) & 0xFF);
            result.SourceModifier        = (SourceModifier)((token >> 24) & 0xF);

            reader.AddNote("RegisterNumber", result.RegisterNumber);
            reader.AddNote("RegisterType", result.RegisterType);
            reader.AddNote("IsRelativeAddressMode", result.IsRelativeAddressMode);
            reader.AddNote("MinPrecision", result.MinPrecision);
            reader.AddNote("SwizzleComponents", result.SwizzleComponents);
            reader.AddNote("SourceModifier", result.SourceModifier);
            return(result);
        }
        public static DebugInstructionToken Parse(DebugBytecodeReader reader, DebugOpcodeHeader header)
        {
            var instructionToken = new DebugInstructionToken();

            // Advance to next token.
            var instructionEnd = reader.CurrentPosition + (header.Length * sizeof(uint));
            var token0         = reader.ReadUInt32("token0");

            DebugOpcodeHeader.AddNotes(reader, token0);

            if (header.OpcodeType == OpcodeType.Sync)
            {
                instructionToken.SyncFlags = token0.DecodeValue <SyncFlags>(11, 14);
                reader.AddNote("SyncFlags", instructionToken.SyncFlags);
            }
            else
            {
                instructionToken.ResInfoReturnType = token0.DecodeValue <ResInfoReturnType>(11, 12);
                instructionToken.Saturate          = (token0.DecodeValue(13, 13) == 1);
                instructionToken.TestBoolean       = token0.DecodeValue <InstructionTestBoolean>(18, 18);
                instructionToken.PreciseValueMask  = token0.DecodeValue <ComponentMask>(19, 22);
                reader.AddNote("ResInfoReturnType", instructionToken.ResInfoReturnType);
                reader.AddNote("Saturate", instructionToken.Saturate);
                reader.AddNote("TestBoolean", instructionToken.TestBoolean);
                reader.AddNote("PreciseValueMask", instructionToken.PreciseValueMask);
            }

            bool extended = header.IsExtended;

            while (extended)
            {
                uint extendedToken = reader.ReadUInt32("extendedToken");
                var  extendedType  = extendedToken.DecodeValue <InstructionTokenExtendedType>(0, 5);
                reader.AddNote("extendedType", extendedType);
                instructionToken.ExtendedTypes.Add(extendedType);
                extended = (extendedToken.DecodeValue(31, 31) == 1);
                reader.AddNote("extended", extended);

                switch (extendedType)
                {
                case InstructionTokenExtendedType.SampleControls:
                    instructionToken.SampleOffsets[0] = extendedToken.DecodeSigned4BitValue(09, 12);
                    instructionToken.SampleOffsets[1] = extendedToken.DecodeSigned4BitValue(13, 16);
                    instructionToken.SampleOffsets[2] = extendedToken.DecodeSigned4BitValue(17, 20);
                    reader.AddNote("SampleOffsets[0]", instructionToken.SampleOffsets[0]);
                    reader.AddNote("SampleOffsets[1]", instructionToken.SampleOffsets[1]);
                    reader.AddNote("SampleOffsets[2]", instructionToken.SampleOffsets[2]);
                    break;

                case InstructionTokenExtendedType.ResourceDim:
                    instructionToken.ResourceTarget = extendedToken.DecodeValue <ResourceDimension>(6, 10);
                    instructionToken.ResourceStride = extendedToken.DecodeValue <ushort>(11, 22);
                    reader.AddNote("ResourceTarget", instructionToken.ResourceTarget);
                    reader.AddNote("ResourceStride", instructionToken.ResourceStride);
                    break;

                case InstructionTokenExtendedType.ResourceReturnType:
                    instructionToken.ResourceReturnTypes[0] = extendedToken.DecodeValue <ResourceReturnType>(06, 09);
                    instructionToken.ResourceReturnTypes[1] = extendedToken.DecodeValue <ResourceReturnType>(10, 13);
                    instructionToken.ResourceReturnTypes[2] = extendedToken.DecodeValue <ResourceReturnType>(14, 17);
                    instructionToken.ResourceReturnTypes[3] = extendedToken.DecodeValue <ResourceReturnType>(18, 21);
                    reader.AddNote("ResourceReturnTypes[0]", instructionToken.ResourceReturnTypes[0]);
                    reader.AddNote("ResourceReturnTypes[1]", instructionToken.ResourceReturnTypes[1]);
                    reader.AddNote("ResourceReturnTypes[2]", instructionToken.ResourceReturnTypes[2]);
                    reader.AddNote("ResourceReturnTypes[3]", instructionToken.ResourceReturnTypes[3]);
                    break;

                default:
                    throw new ParseException("Unrecognised extended type: " + extendedType);
                }
            }

            if (header.OpcodeType == OpcodeType.InterfaceCall)
            {
                instructionToken.FunctionIndex = reader.ReadUInt32("FunctionIndex");
            }

            while (reader.CurrentPosition < instructionEnd)
            {
                reader.AddIndent($"Operand{instructionToken.Operands.Count}");
                var operand = DebugOperand.Parse(reader, header.OpcodeType);
                if (operand != null)
                {
                    instructionToken.Operands.Add(operand);
                }
                reader.RemoveIndent();
            }
            return(instructionToken);
        }
Exemple #24
0
        public static DebugOperand Parse(DebugBytecodeReader reader, OpcodeType parentType)
        {
            uint token0 = reader.ReadUInt32("operandToken");

            if (token0 == 0)
            {
                return(null);
            }
            var member  = reader.LocalMembers.Last();
            var operand = new DebugOperand(parentType);

            var numComponents = token0.DecodeValue <OperandNumComponents>(0, 1);

            reader.AddNote("numComponents", numComponents);
            switch (numComponents)
            {
            case OperandNumComponents.Zero:
            {
                operand.NumComponents = 0;
                break;
            }

            case OperandNumComponents.One:
            {
                operand.NumComponents = 1;
                break;
            }

            case OperandNumComponents.Four:
            {
                operand.NumComponents = 4;
                operand.SelectionMode = token0.DecodeValue <Operand4ComponentSelectionMode>(2, 3);
                member.AddNote("SelectionMode", operand.SelectionMode);
                switch (operand.SelectionMode)
                {
                case Operand4ComponentSelectionMode.Mask:
                {
                    operand.ComponentMask = token0.DecodeValue <ComponentMask>(4, 7);
                    member.AddNote("ComponentMask", operand.ComponentMask);
                    break;
                }

                case Operand4ComponentSelectionMode.Swizzle:
                {
                    var swizzle = token0.DecodeValue(4, 11);
                    Func <uint, byte, Operand4ComponentName> swizzleDecoder = (s, i) =>
                                                                              (Operand4ComponentName)((s >> (i * 2)) & 3);
                    operand.Swizzles[0] = swizzleDecoder(swizzle, 0);
                    operand.Swizzles[1] = swizzleDecoder(swizzle, 1);
                    operand.Swizzles[2] = swizzleDecoder(swizzle, 2);
                    operand.Swizzles[3] = swizzleDecoder(swizzle, 3);
                    member.AddNote("Swizzles[0]", operand.Swizzles[0]);
                    member.AddNote("Swizzles[1]", operand.Swizzles[1]);
                    member.AddNote("Swizzles[2]", operand.Swizzles[2]);
                    member.AddNote("Swizzles[3]", operand.Swizzles[3]);
                    break;
                }

                case Operand4ComponentSelectionMode.Select1:
                {
                    var swizzle = token0.DecodeValue <Operand4ComponentName>(4, 5);
                    operand.Swizzles[0] = operand.Swizzles[1] = operand.Swizzles[2] = operand.Swizzles[3] = swizzle;
                    member.AddNote("Swizzles[0]", operand.Swizzles[0]);
                    member.AddNote("Swizzles[1]", operand.Swizzles[1]);
                    member.AddNote("Swizzles[2]", operand.Swizzles[2]);
                    member.AddNote("Swizzles[3]", operand.Swizzles[3]);
                    break;
                }

                default:
                {
                    throw new ParseException("Unrecognized selection method: " + operand.SelectionMode);
                }
                }
                break;
            }

            case OperandNumComponents.N:
            {
                throw new ParseException("OperandNumComponents.N is not currently supported.");
            }
            }

            operand.OperandType = token0.DecodeValue <OperandType>(12, 19);
            member.AddNote("OperandType", operand.OperandType);
            operand.IndexDimension = token0.DecodeValue <OperandIndexDimension>(20, 21);
            member.AddNote("IndexDimension", operand.IndexDimension);

            operand.IsExtended = token0.DecodeValue(31, 31) == 1;
            member.AddNote("IsExtended", operand.IsExtended);
            if (operand.IsExtended)
            {
                ReadExtendedOperand(operand, reader);
            }

            Func <uint, byte, OperandIndexRepresentation> indexRepresentationDecoder = (t, i) =>
                                                                                       (OperandIndexRepresentation)t.DecodeValue((byte)(22 + (i * 3)), (byte)(22 + (i * 3) + 2));

            for (byte i = 0; i < (byte)operand.IndexDimension; i++)
            {
                operand.Indices[i] = new DebugOperandIndex();

                var indexRepresentation = indexRepresentationDecoder(token0, i);
                operand.Indices[i].Representation = indexRepresentation;
                member.AddNote($"Indices[{i}].Representation", operand.Indices[i].Representation);
                switch (indexRepresentation)
                {
                case OperandIndexRepresentation.Immediate32:
                    operand.Indices[i].Value = reader.ReadUInt32($"Indices[{i}].Value");
                    break;

                case OperandIndexRepresentation.Immediate64:
                    operand.Indices[i].Value = reader.ReadUInt64($"Indices[{i}].Value");
                    goto default;

                case OperandIndexRepresentation.Relative:
                    operand.Indices[i].Register = Parse(reader, parentType);
                    break;

                case OperandIndexRepresentation.Immediate32PlusRelative:
                    operand.Indices[i].Value = reader.ReadUInt32($"Indices[{i}].Value");
                    goto case OperandIndexRepresentation.Relative;

                case OperandIndexRepresentation.Immediate64PlusRelative:
                    operand.Indices[i].Value = reader.ReadUInt64($"Indices[{i}].Value");
                    goto case OperandIndexRepresentation.Relative;

                default:
                    throw new ParseException("Unrecognised index representation: " + indexRepresentation);
                }
            }

            var numberType = parentType.GetNumberType();

            switch (operand.OperandType)
            {
            case OperandType.Immediate32:
            {
                var immediateValues = new DebugNumber4();
                for (var i = 0; i < operand.NumComponents; i++)
                {
                    immediateValues.SetNumber(i, DebugNumber.Parse(reader));
                }
                operand.ImmediateValues = immediateValues;
                break;
            }

            case OperandType.Immediate64:
            {
                var immediateValues = new DebugNumber4();
                for (var i = 0; i < operand.NumComponents; i++)
                {
                    immediateValues.SetDouble(i, reader.ReadDouble($"ImmediateValues[{i}]"));
                }
                operand.ImmediateValues = immediateValues;
                break;
            }
            }
            return(operand);
        }