Example #1
0
        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;
            }
        }
Example #2
0
 private void OutputMethodNode(Z80MethodCodeNode methodCodeNode)
 {
     if (methodCodeNode.MethodCode != null)
     {
         foreach (var instruction in methodCodeNode.MethodCode)
         {
             _out.WriteLine(instruction.ToString());
         }
     }
 }
Example #3
0
        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}");
        }
Example #4
0
        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);
                    }
                }
            }
        }
Example #5
0
        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;
            }
        }
Example #6
0
        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);
        }