public EmitterContext(DecodedProgram program, ShaderConfig config, bool isNonMain) { Program = program; Config = config; IsNonMain = isNonMain; _operations = new List <Operation>(); _labels = new Dictionary <ulong, Operand>(); }
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); }
internal TranslatorContext(ulong address, DecodedProgram program, ShaderConfig config) { Address = address; _program = program; _config = config; }
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; } } } }