Mercurial > lcfOS
annotate python/ppci/codegen/codegen.py @ 377:9667d78ba79e
Switched to xml for project description
author | Windel Bouwman |
---|---|
date | Fri, 11 Apr 2014 15:47:50 +0200 |
parents | 39bf68bf1891 |
children |
rev | line source |
---|---|
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
334
diff
changeset
|
1 from .. import ir |
312 | 2 from ..irutils import Verifier |
355 | 3 from ..transform import RemoveAddZero |
342 | 4 from ..target import Target |
346 | 5 from .. import CompilerError |
296 | 6 from .canon import make as canonicalize |
7 from .registerallocator import RegisterAllocator | |
312 | 8 import logging |
210 | 9 |
290 | 10 |
210 | 11 class CodeGenerator: |
292 | 12 """ Generic code generator """ |
13 def __init__(self, target): | |
290 | 14 # TODO: schedule traces in better order. |
15 # This is optional! | |
292 | 16 assert isinstance(target, Target), target |
312 | 17 self.logger = logging.getLogger('codegen') |
290 | 18 self.target = target |
292 | 19 self.ins_sel = target.ins_sel |
296 | 20 self.ra = RegisterAllocator() |
312 | 21 self.verifier = Verifier() |
290 | 22 |
292 | 23 def generateFunc(self, irfunc, outs): |
290 | 24 """ Generate code for one function into a frame """ |
334 | 25 self.logger.debug('Generating code for {}'.format(irfunc.name)) |
290 | 26 # Create a frame for this function: |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
334
diff
changeset
|
27 frame = self.target.FrameClass(ir.label_name(irfunc)) |
210 | 28 |
290 | 29 # Canonicalize the intermediate language: |
296 | 30 canonicalize(irfunc, frame) |
355 | 31 RemoveAddZero().run(irfunc) |
334 | 32 self.logger.debug('after canonicalize', extra={'irfunc': irfunc}) |
312 | 33 self.verifier.verify_function(irfunc) |
290 | 34 self.ins_sel.munchFunction(irfunc, frame) |
334 | 35 self.logger.debug('Selected instructions', extra={'ppci_frame': frame}) |
296 | 36 |
290 | 37 # Do register allocation: |
38 self.ra.allocFrame(frame) | |
334 | 39 self.logger.debug('Registers allocated, now adding final glue') |
290 | 40 # TODO: Peep-hole here? |
41 | |
42 # Add label and return and stack adjustment: | |
43 frame.EntryExitGlue3() | |
44 | |
45 # Materialize the register allocated instructions into a stream of | |
46 # real instructions. | |
346 | 47 self.target.lower_frame_to_stream(frame, outs) |
334 | 48 self.logger.debug('Instructions materialized') |
290 | 49 return frame |
50 | |
292 | 51 def generate(self, ircode, outs): |
296 | 52 """ Generate code into output stream """ |
336
d1ecc493384e
Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents:
334
diff
changeset
|
53 assert isinstance(ircode, ir.Module) |
364 | 54 outs.select_section('data') |
55 for global_variable in ircode.Variables: | |
56 self.target.emit_global(outs, ir.label_name(global_variable)) | |
348 | 57 outs.select_section('code') |
210 | 58 |
290 | 59 # Munch program into a bunch of frames. One frame per function. |
60 # Each frame has a flat list of abstract instructions. | |
61 # Generate code for all functions: | |
296 | 62 self.frames = [self.generateFunc(f, outs) for f in ircode.Functions] |
290 | 63 return self.frames |