Example #1
0
        public static CFGNode[] ConstructCFG(List <IInstruction> instructions)
        {
            CFGNode[] nodes = new CFGNode[instructions.Count];

            int end = instructions.Count - 1;

            for (int i = end; i >= 0; i--)
            {
                nodes[i] = new CFGNode(instructions[i], i == end ? null : nodes[i + 1]);
            }

            // Map Labels to instructions
            Dictionary <LabelInstruction, CFGNode> labels = new Dictionary <LabelInstruction, CFGNode>();

            List <LabelInstruction> activeLabels = new List <LabelInstruction>();

            for (int i = 0; i < instructions.Count; i++)
            {
                if (instructions[i] is LabelInstruction label)
                {
                    activeLabels.Add(label);
                }
                else if (activeLabels.Count > 0)
                {
                    foreach (var activeLabel in activeLabels)
                    {
                        labels[activeLabel] = nodes[i];
                    }
                    activeLabels.Clear();
                }
            }

            foreach (var node in nodes)
            {
                LabelInstruction?target = node.Instruction switch
                {
                    ConditionalJump conditionalJump =>
                    conditionalJump.Target,

                    UnconditionalJump unconditionalJump =>
                    unconditionalJump.Target,

                         _ => null,
                };

                if (target != null && labels.TryGetValue(target.Value, out var successor))
                {
                    node.Successors.Add(successor);
                }
            }

            return(nodes);
        }
Example #2
0
        private IEnumerable <NasmInstruction> CompileInstruction(int i, IInstruction instruction)
        {
            yield return(NasmInstruction.Comment(instruction.ToString()));

            yield return(NasmInstruction.Comment("In = { " + string.Join(", ", RegisterAllocation.GetAllInAt(i)) + " }"));

            foreach (var inst in instruction switch
            {
                UnaryComputationAssignment inst => CompileCore(inst),
                BinaryComputationAssignment inst => CompileCore(inst),
                ConditionalJump inst => CompileCore(inst),
                UnconditionalJump inst => CompileCore(inst),
                LabelInstruction inst => CompileCore(inst),
                CallInstruction inst => CompileCore(i, inst),
                ReturnInstruction inst => CompileCore(inst),
                ParameterQueryAssignment inst => CompileCore(inst),
                _ => throw new ArgumentException(nameof(instruction))
            })