Mercurial > lcfOS
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