view python/ppci/codegen/codegen.py @ 307:e609d5296ee9

Massive rewrite of codegenerator
author Windel Bouwman
date Thu, 12 Dec 2013 20:42:56 +0100
parents 6753763d3bec
children 2c9768114877
line wrap: on
line source

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