public void WriteConstantTable(ConstantTable constantTable)
        {
            if (constantTable == null)
            {
                return;
            }
            WriteLine("//");
            WriteLine("// Generated by {0}", constantTable.Creator);
            if (constantTable.ConstantDeclarations.Count == 0)
            {
                return;
            }
            WriteLine("//");
            WriteLine("// Parameters:");
            WriteLine("//");
            foreach (var declaration in constantTable.ConstantDeclarations)
            {
                string arraySubscript = "";
                if (declaration.Elements > 1)
                {
                    arraySubscript = $"[{declaration.Elements}]";
                }
                WriteLine("//   {0} {1}{2};",
                          declaration.GetTypeName(),
                          declaration.Name,
                          arraySubscript
                          );
            }
            WriteLine("//");
            WriteLine("//");
            WriteLine("// Registers:");
            WriteLine("//");
            var maxNameLength = constantTable.ConstantDeclarations.Max(cd => cd.Name.Length);

            if (maxNameLength < 12)
            {
                maxNameLength = 12;
            }
            WriteLine("//   Name{0} Reg   Size", new string(' ', maxNameLength - 4));
            WriteLine("//   {0} ----- ----", new string('-', maxNameLength));
            foreach (var declaration in constantTable.ConstantDeclarations
                     .OrderBy(cd => (int)cd.RegisterSet * 1000 + cd.RegisterIndex))
            {
                var size = declaration.Rows * declaration.Columns / 4;
                if (size == 0)
                {
                    size = 1;
                }
                size = declaration.RegisterCount;
                WriteLine(string.Format("//   {0} {1,-5} {2,4}",
                                        declaration.Name.PadRight(maxNameLength, ' '),
                                        declaration.GetRegisterName(),
                                        size));
            }
            WriteLine("//");
            WriteLine("");
        }
        internal ConstantTable ParseConstantTable()
        {
            var constantDeclarations = new List <ConstantDeclaration>();

            byte[] constantTable = GetConstantTableData();
            if (constantTable == null)
            {
                return(null);
            }

            var ctabStream = new MemoryStream(constantTable);

            using (var ctabReader = new BinaryReader(ctabStream))
            {
                int ctabSize = ctabReader.ReadInt32();
                System.Diagnostics.Debug.Assert(ctabSize == 0x1C);
                long creatorPosition = ctabReader.ReadInt32();

                int minorVersion = ctabReader.ReadByte();
                int majorVersion = ctabReader.ReadByte();
                System.Diagnostics.Debug.Assert(majorVersion == MajorVersion);
                System.Diagnostics.Debug.Assert(minorVersion == MinorVersion);

                var shaderType = (ShaderType)ctabReader.ReadUInt16();
                System.Diagnostics.Debug.Assert(shaderType == Type);

                int         numConstants         = ctabReader.ReadInt32();
                long        constantInfoPosition = ctabReader.ReadInt32();
                ShaderFlags shaderFlags          = (ShaderFlags)ctabReader.ReadInt32();

                long shaderModelPosition = ctabReader.ReadInt32();
                //Console.WriteLine("ctabStart = {0}, shaderModelPosition = {1}", ctabStart, shaderModelPosition);


                ctabStream.Position = creatorPosition;
                string compilerInfo = ReadStringNullTerminated(ctabStream);

                ctabStream.Position = shaderModelPosition;
                string shaderModel = ReadStringNullTerminated(ctabStream);


                for (int i = 0; i < numConstants; i++)
                {
                    ctabStream.Position = constantInfoPosition + i * 20;
                    ConstantDeclaration declaration = ReadConstantDeclaration(ctabReader);
                    constantDeclarations.Add(declaration);
                }
                var ct = new ConstantTable(compilerInfo, shaderModel, majorVersion, minorVersion, constantDeclarations);
                ConstantTable = ct;
                return(ConstantTable);
            }
        }
        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)
                    {
                    }
                    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] = 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 #4
0
 public AsmWriter(ShaderModel shader)
 {
     this.shader   = shader;
     constantTable = shader.ParseConstantTable();
 }