Token ReadInstruction(BytecodeReader reader)
        {
            uint   instructionToken = reader.ReadUInt32();
            Opcode opcode           = (Opcode)(instructionToken & 0xffff);
            int    size;

            if (opcode == Opcode.Comment)
            {
                size = (int)((instructionToken >> 16) & 0x7FFF);
            }
            else
            {
                size = (int)((instructionToken >> 24) & 0x0f);
            }
            Token token = null;

            if (opcode == Opcode.Comment)
            {
                var fourCC = reader.ReadUInt32();
                if (KnownCommentTypes.ContainsKey(fourCC))
                {
                    var commentReader = reader.CopyAtCurrentPosition();
                    reader.ReadBytes(size * 4 - 4);
                    switch (KnownCommentTypes[fourCC])
                    {
                    case CommentType.CTAB:
                        ConstantTable = ConstantTable.Parse(commentReader);
                        return(null);

                    case CommentType.C**T:
                        Cli = CliToken.Parse(commentReader);
                        return(null);

                    case CommentType.FXLC:
                        Fxlc = FxlcBlock.Parse(commentReader);
                        return(null);

                    case CommentType.PRES:
                        Preshader = Preshader.Parse(commentReader);
                        return(null);

                    case CommentType.PRSI:
                        Prsi = PrsiToken.Parse(commentReader);
                        return(null);
                    }
                }
                token         = new CommentToken(opcode, size, this);
                token.Data[0] = fourCC;
                for (int i = 1; i < size; i++)
                {
                    token.Data[i] = reader.ReadUInt32();
                }
            }
            else
            {
                token = new InstructionToken(opcode, size, this);
                var inst = token as InstructionToken;

                for (int i = 0; i < size; i++)
                {
                    token.Data[i] = reader.ReadUInt32();
                    if (opcode == Opcode.Def || opcode == Opcode.DefB || opcode == Opcode.DefI)
                    {
                        if (i == 0)
                        {
                            inst.Operands.Add(new DestinationOperand(token.Data[i]));
                        }
                    }
                    else if (opcode == Opcode.Dcl)
                    {
                        if (i == 0)
                        {
                            inst.Operands.Add(new DeclarationOperand(token.Data[i]));
                        }
                        else
                        {
                            inst.Operands.Add(new DestinationOperand(token.Data[i]));
                        }
                    }
                    else if (i == 0 && opcode.HasDestination())
                    {
                        if ((token.Data[i] & (1 << 13)) != 0)
                        {
                            //Relative Address mode
                            token.Data[i + 1] = reader.ReadUInt32();
                            inst.Operands.Add(new DestinationOperand(token.Data[i], token.Data[i + 1]));
                            i++;
                        }
                        else
                        {
                            inst.Operands.Add(new DestinationOperand(token.Data[i]));
                        }
                    }
                    else if ((token.Data[i] & (1 << 13)) != 0)
                    {
                        //Relative Address mode
                        token.Data[i + 1] = reader.ReadUInt32();
                        inst.Operands.Add(new SourceOperand(token.Data[i], token.Data[i + 1]));
                        i++;
                    }
                    else
                    {
                        inst.Operands.Add(new SourceOperand(token.Data[i]));
                    }
                }
                if (opcode != Opcode.Comment)
                {
                    token.Modifier   = (int)((instructionToken >> 16) & 0xff);
                    token.Predicated = (instructionToken & 0x10000000) != 0;
                    token.CoIssue    = (instructionToken & 0x40000000) != 0;
                    Debug.Assert((instructionToken & 0xA0000000) == 0, $"Instruction has unexpected bits set {instructionToken & 0xE0000000}");
                }
            }
            return(token);
        }
Exemple #2
0
        private Token ReadInstruction(ShaderModel shaderModel)
        {
            uint   instructionToken = ReadUInt32();
            Opcode opcode           = (Opcode)(instructionToken & 0xffff);

            Debug.Assert(opcode <= Opcode.Breakp || (opcode >= Opcode.Phase && opcode <= Opcode.End), $"Invalid opcode {opcode}");
            int size;

            if (opcode == Opcode.Comment)
            {
                size = (int)((instructionToken >> 16) & 0x7FFF);
            }
            else
            {
                size = (int)((instructionToken >> 24) & 0x0f);
            }
            Token token = null;

            if (opcode == Opcode.Comment)
            {
                token = new CommentToken(opcode, size, shaderModel);
                for (int i = 0; i < size; i++)
                {
                    token.Data[i] = ReadUInt32();
                }
            }
            else
            {
                token = new InstructionToken(opcode, size, shaderModel);
                var inst = token as InstructionToken;
                for (int i = 0; i < size; i++)
                {
                    token.Data[i] = ReadUInt32();
                    if (opcode == Opcode.Def || opcode == Opcode.DefB || opcode == Opcode.DefI)
                    {
                    }
                    else if (opcode == Opcode.Dcl)
                    {
                        if (i == 0)
                        {
                            inst.Operands.Add(new DeclarationOperand(token.Data[i]));
                        }
                        else
                        {
                            inst.Operands.Add(new DestinationOperand(token.Data[i]));
                        }
                    }
                    else if (i == 0 && opcode != Opcode.BreakC && opcode != Opcode.IfC && opcode != Opcode.If)
                    {
                        inst.Operands.Add(new DestinationOperand(token.Data[i]));
                    }
                    else if ((token.Data[i] & (1 << 13)) != 0)
                    {
                        //Relative Address mode
                        token.Data[i + 1] = ReadUInt32();
                        inst.Operands.Add(new SourceOperand(token.Data[i], token.Data[i + 1]));
                        i++;
                    }
                    else
                    {
                        inst.Operands.Add(new SourceOperand(token.Data[i]));
                    }
                }
            }

            if (opcode != Opcode.Comment)
            {
                token.Modifier   = (int)((instructionToken >> 16) & 0xff);
                token.Predicated = (instructionToken & 0x10000000) != 0;
                token.CoIssue    = (instructionToken & 0x40000000) != 0;
                Debug.Assert((instructionToken & 0xA0000000) == 0, $"Instruction has unexpected bits set {instructionToken & 0xE0000000}");
            }

            return(token);
        }