diff python/codegen.py @ 290:7b38782ed496

File moves
author Windel Bouwman
date Sun, 24 Nov 2013 11:24:15 +0100
parents 02385f62f250
children 534b94b40aa8
line wrap: on
line diff
--- a/python/codegen.py	Thu Nov 21 15:46:50 2013 +0100
+++ b/python/codegen.py	Sun Nov 24 11:24:15 2013 +0100
@@ -1,30 +1,65 @@
-import ir, target
+import ir
+import target
 from ppci import CompilerError
+import transform
+import canon
 
+
+# TODO: this class could be target independent:
 class CodeGenerator:
-    """ Target independent code generator """
-    def __init__(self, tg):
+    def __init__(self, outs, target):
+        # TODO: schedule traces in better order.
+        # This is optional!
         assert isinstance(tg, target.Target)
-        self.tg = tg
+        self.target = target
+        self.ins_sel = ArmInstructionSelector()
+        self.ra = registerallocator.RegisterAllocator()
+        self.outs = outs
+        self.outs.getSection('code').address = 0x08000000
+        self.outs.getSection('data').address = 0x20000000
+
+    def generateFunc(self, irfunc):
+        """ Generate code for one function into a frame """
+        # Cleanup function:
+        transform.removeEmptyBlocks(irfunc)
+
+        # Create a frame for this function:
+        frame = ArmFrame(irfunc.name)
 
-    def tryMap(self, ii):
-        for mi in self.tg.instructions:
-            if mi.irpattern is ii:
-                return mi.FromIr(ii)
-        raise CompilerError('Cannot map {0}'.format(ii))
+        # Canonicalize the intermediate language:
+        canon.make(irfunc, frame)
+        self.ins_sel.munchFunction(irfunc, frame)
         
+        # Do register allocation:
+        self.ra.allocFrame(frame)
+        # TODO: Peep-hole here?
+
+        # Can we materialize here??
+
+        # Add label and return and stack adjustment:
+        frame.EntryExitGlue3()
+
+        # Materialize assembly
+        # Materialize the register allocated instructions into a stream of
+        # real instructions.
+        frame.lower_to(self.outs)
+        return frame
+
     def generate(self, ircode):
         assert isinstance(ircode, ir.Module)
-        obj = object()
-        for gvar in ircode.Variables:
-            print(gvar)
-            raise Exception() # TODO
-        for f in ircode.Functions:
-            for bb in f.Blocks:
-                for ins in bb.Instructions:
-                    # Instruction selection:
-                    #mi = self.tryMap(ins)
-                    pass
-        return obj
-                        
+        self.outs.selectSection('code')
+        # assembly glue to make it work:
+        # TODO: this must be in source code, not in compiler
+        self.outs.emit(arm.dcd_ins(Imm32(0x20000678)))   # initial SP
+        self.outs.emit(arm.dcd_ins(Imm32(0x08000009)))   # reset vector
+        self.outs.emit(arm.b_ins(LabelRef('main')))
 
+        # 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(func) for func in ircode.Functions]
+
+        # TODO: fixup references, do this in another way?
+        self.outs.backpatch()
+        self.outs.backpatch()  # Why two times?
+        return self.frames