コード例 #1
0
 public EmitterContext(DecodedProgram program, ShaderConfig config, bool isNonMain)
 {
     Program     = program;
     Config      = config;
     IsNonMain   = isNonMain;
     _operations = new List <Operation>();
     _labels     = new Dictionary <ulong, Operand>();
 }
コード例 #2
0
        internal static FunctionCode[] EmitShader(DecodedProgram program, ShaderConfig config, bool initializeOutputs, out int initializationOperations)
        {
            initializationOperations = 0;

            FunctionMatch.RunPass(program);

            foreach (DecodedFunction function in program.OrderBy(x => x.Address).Where(x => !x.IsCompilerGenerated))
            {
                program.AddFunctionAndSetId(function);
            }

            FunctionCode[] functions = new FunctionCode[program.FunctionsWithIdCount];

            for (int index = 0; index < functions.Length; index++)
            {
                EmitterContext context = new EmitterContext(program, config, index != 0);

                if (initializeOutputs && index == 0)
                {
                    EmitOutputsInitialization(context, config);
                    initializationOperations = context.OperationsCount;
                }

                DecodedFunction function = program.GetFunctionById(index);

                foreach (Block block in function.Blocks)
                {
                    context.CurrBlock = block;

                    context.MarkLabel(context.GetLabel(block.Address));

                    EmitOps(context, block);
                }

                functions[index] = new FunctionCode(context.GetOperations());
            }

            return(functions);
        }
コード例 #3
0
 internal TranslatorContext(ulong address, DecodedProgram program, ShaderConfig config)
 {
     Address  = address;
     _program = program;
     _config  = config;
 }
コード例 #4
0
        public static void RunPass(DecodedProgram program)
        {
            byte[] externalRegs  = new byte[4];
            bool   hasGetAddress = false;

            foreach (DecodedFunction function in program)
            {
                if (function == program.MainFunction)
                {
                    continue;
                }

                int externalReg4 = 0;

                TreeNode[] functionTree = BuildTree(function.Blocks);

                if (Matches(_fsiGetAddressTree, functionTree))
                {
                    externalRegs[1] = functionTree[0].GetRd();
                    externalRegs[2] = functionTree[2].GetRd();
                    externalRegs[3] = functionTree[1].GetRd();
                    externalReg4    = functionTree[3].GetRd();
                }
                else if (Matches(_fsiGetAddressV2Tree, functionTree))
                {
                    externalRegs[1] = functionTree[2].GetRd();
                    externalRegs[2] = functionTree[1].GetRd();
                    externalRegs[3] = functionTree[0].GetRd();
                    externalReg4    = functionTree[3].GetRd();
                }

                // Ensure the register allocation is valid.
                // If so, then we have a match.
                if (externalRegs[1] != externalRegs[2] &&
                    externalRegs[2] != externalRegs[3] &&
                    externalRegs[1] != externalRegs[3] &&
                    externalRegs[1] + 1 != externalRegs[2] &&
                    externalRegs[1] + 1 != externalRegs[3] &&
                    externalRegs[1] + 1 == externalReg4 &&
                    externalRegs[2] != RegisterConsts.RegisterZeroIndex &&
                    externalRegs[3] != RegisterConsts.RegisterZeroIndex &&
                    externalReg4 != RegisterConsts.RegisterZeroIndex)
                {
                    hasGetAddress = true;
                    function.Type = FunctionType.Unused;
                    break;
                }
            }

            foreach (DecodedFunction function in program)
            {
                if (function.IsCompilerGenerated || function == program.MainFunction)
                {
                    continue;
                }

                if (hasGetAddress)
                {
                    TreeNode[] functionTree = BuildTree(function.Blocks);

                    if (MatchesFsi(_fsiBeginPatternTree, program, function, functionTree, externalRegs))
                    {
                        function.Type = FunctionType.BuiltInFSIBegin;
                        continue;
                    }
                    else if (MatchesFsi(_fsiEndPatternTree, program, function, functionTree, externalRegs))
                    {
                        function.Type = FunctionType.BuiltInFSIEnd;
                        continue;
                    }
                }
            }
        }