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