public void CompileMethod(Z80MethodCodeNode methodCodeNodeNeedingCode) { var method = methodCodeNodeNeedingCode.Method; _parameterCount = method.Parameters.Count; SetupLocalVariableTable(method); if (!method.IsIntrinsic() && !method.IsPinvokeImpl) { var ilImporter = _phaseFactory.Create <IILImporter>(); // Main phases of the compiler live here var basicBlocks = ilImporter.Import(_parameterCount, _returnBufferArgIndex, method, _localVariableTable); if (_configuration.DumpIRTrees) { _logger.LogInformation("METHOD: {methodFullName}", method.FullName); int lclNum = 0; StringBuilder sb = new StringBuilder(); foreach (var lclVar in _localVariableTable) { sb.AppendLine($"LCLVAR {lclNum} {lclVar.Name} {lclVar.IsParameter} {lclVar.Kind}"); lclNum++; } _logger.LogInformation("{localVars}", sb.ToString()); var treeDumper = new TreeDumper(); var treedump = treeDumper.Dump(basicBlocks); _logger.LogInformation("{treedump}", treedump); } var flowgraph = _phaseFactory.Create <IFlowgraph>(); flowgraph.SetBlockOrder(basicBlocks); var ssaBuilder = _phaseFactory.Create <ISsaBuilder>(); ssaBuilder.Build(basicBlocks, _localVariableTable); if (_configuration.DumpIRTrees) { // Dump LIR here var lirDumper = new LIRDumper(); var lirDump = lirDumper.Dump(basicBlocks); _logger.LogInformation("{lirDump}", lirDump); } // Lower var lowering = _phaseFactory.Create <ILowering>(); lowering.Run(basicBlocks); var codeGenerator = _phaseFactory.Create <ICodeGenerator>(); var instructions = codeGenerator.Generate(basicBlocks, _localVariableTable, methodCodeNodeNeedingCode); methodCodeNodeNeedingCode.MethodCode = instructions; } }
private void OutputMethodNode(Z80MethodCodeNode methodCodeNode) { if (methodCodeNode.MethodCode != null) { foreach (var instruction in methodCodeNode.MethodCode) { _out.WriteLine(instruction.ToString()); } } }
public void OutputCode(Z80MethodCodeNode root, string inputFilePath, string outputFilePath) { _inputFilePath = inputFilePath; _outputFilePath = outputFilePath; _out = new StreamWriter(new FileStream(outputFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, 4096, false), Encoding.ASCII); OutputProlog(root.Method); OutputCodeForNode(root); OutputEpilog(); _out.Dispose(); _logger.LogDebug($"Written compiled file to {_outputFilePath}"); }
private void CompileNode(Z80MethodCodeNode node) { if (!node.Compiled) { _logger.LogDebug("Compiling method {method.Name}", node.Method.Name); var methodCompiler = _methodCompilerFactory.Create(); methodCompiler.CompileMethod(node); node.Compiled = true; if (node.Dependencies != null) { foreach (var dependentNode in node.Dependencies) { CompileNode(dependentNode); } } } }
private void OutputCodeForNode(Z80MethodCodeNode node) { if (!node.CodeEmitted) { if (node.MethodCode != null) { _out.WriteLine($"; {node.Method.FullName}"); OutputMethodNode(node); } if (node.Dependencies != null) { foreach (var dependentNodes in node.Dependencies) { OutputCodeForNode(dependentNodes); } } node.CodeEmitted = true; } }
public IList <Instruction> Generate(IList <BasicBlock> blocks, IList <LocalVariableDescriptor> localVariableTable, Z80MethodCodeNode methodCodeNode) { _context = new CodeGeneratorContext(localVariableTable, methodCodeNode, _configuration); AssignFrameOffsets(); var methodInstructions = new List <Instruction>(); GenerateStringMap(blocks); GenerateStringData(_context.Assembler); _context.Assembler.AddInstruction(new LabelInstruction(_nameMangler.GetMangledMethodName(_context.Method))); GenerateProlog(_context.Assembler); methodInstructions.AddRange(_context.Assembler.Instructions); foreach (var block in blocks) { _context.Assembler.Reset(); _context.Assembler.AddInstruction(new LabelInstruction(block.Label)); var visitorAdapter = new GenericStackEntryAdapter(this); var currentNode = block.FirstNode; while (currentNode != null) { currentNode.Accept(visitorAdapter); currentNode = currentNode.Next; } Optimize(_context.Assembler.Instructions); methodInstructions.AddRange(_context.Assembler.Instructions); } return(methodInstructions); }