view 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 source

import ir
import target
from ppci import CompilerError
import transform
import canon


# TODO: this class could be target independent:
class CodeGenerator:
    def __init__(self, outs, target):
        # TODO: schedule traces in better order.
        # This is optional!
        assert isinstance(tg, target.Target)
        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)

        # 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)
        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