diff python/ppci/codegen/codegen.py @ 301:6753763d3bec

merge codegen into ppci package
author Windel Bouwman
date Thu, 05 Dec 2013 17:02:38 +0100
parents python/codegen/codegen.py@9417caea2eb3
children 2c9768114877
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/codegen/codegen.py	Thu Dec 05 17:02:38 2013 +0100
@@ -0,0 +1,48 @@
+from ..ir import Module
+from target import Target
+from ppci import CompilerError
+from .canon import make as canonicalize
+from .registerallocator import RegisterAllocator
+
+
+class CodeGenerator:
+    """ Generic code generator """
+    def __init__(self, target):
+        # TODO: schedule traces in better order.
+        # This is optional!
+        assert isinstance(target, Target), target
+        self.target = target
+        self.ins_sel = target.ins_sel
+        self.ra = RegisterAllocator()
+
+    def generateFunc(self, irfunc, outs):
+        """ Generate code for one function into a frame """
+        # Create a frame for this function:
+        frame = self.target.FrameClass(irfunc.name)
+
+        # Canonicalize the intermediate language:
+        canonicalize(irfunc, frame)
+        self.ins_sel.munchFunction(irfunc, frame)
+
+        # Do register allocation:
+        self.ra.allocFrame(frame)
+        # TODO: Peep-hole here?
+
+        # Add label and return and stack adjustment:
+        frame.EntryExitGlue3()
+
+        # Materialize the register allocated instructions into a stream of
+        # real instructions.
+        frame.lower_to(outs)
+        return frame
+
+    def generate(self, ircode, outs):
+        """ Generate code into output stream """
+        assert isinstance(ircode, Module)
+        outs.selectSection('code')
+
+        # Munch program into a bunch of frames. One frame per function.
+        # Each frame has a flat list of abstract instructions.
+        # Generate code for all functions:
+        self.frames = [self.generateFunc(f, outs) for f in ircode.Functions]
+        return self.frames