Mercurial > lcfOS
comparison python/codegen.py @ 290:7b38782ed496
File moves
author | Windel Bouwman |
---|---|
date | Sun, 24 Nov 2013 11:24:15 +0100 |
parents | 02385f62f250 |
children | 534b94b40aa8 |
comparison
equal
deleted
inserted
replaced
289:bd2593de3ff8 | 290:7b38782ed496 |
---|---|
1 import ir, target | 1 import ir |
2 import target | |
2 from ppci import CompilerError | 3 from ppci import CompilerError |
4 import transform | |
5 import canon | |
3 | 6 |
7 | |
8 # TODO: this class could be target independent: | |
4 class CodeGenerator: | 9 class CodeGenerator: |
5 """ Target independent code generator """ | 10 def __init__(self, outs, target): |
6 def __init__(self, tg): | 11 # TODO: schedule traces in better order. |
12 # This is optional! | |
7 assert isinstance(tg, target.Target) | 13 assert isinstance(tg, target.Target) |
8 self.tg = tg | 14 self.target = target |
15 self.ins_sel = ArmInstructionSelector() | |
16 self.ra = registerallocator.RegisterAllocator() | |
17 self.outs = outs | |
18 self.outs.getSection('code').address = 0x08000000 | |
19 self.outs.getSection('data').address = 0x20000000 | |
9 | 20 |
10 def tryMap(self, ii): | 21 def generateFunc(self, irfunc): |
11 for mi in self.tg.instructions: | 22 """ Generate code for one function into a frame """ |
12 if mi.irpattern is ii: | 23 # Cleanup function: |
13 return mi.FromIr(ii) | 24 transform.removeEmptyBlocks(irfunc) |
14 raise CompilerError('Cannot map {0}'.format(ii)) | 25 |
26 # Create a frame for this function: | |
27 frame = ArmFrame(irfunc.name) | |
28 | |
29 # Canonicalize the intermediate language: | |
30 canon.make(irfunc, frame) | |
31 self.ins_sel.munchFunction(irfunc, frame) | |
15 | 32 |
33 # Do register allocation: | |
34 self.ra.allocFrame(frame) | |
35 # TODO: Peep-hole here? | |
36 | |
37 # Can we materialize here?? | |
38 | |
39 # Add label and return and stack adjustment: | |
40 frame.EntryExitGlue3() | |
41 | |
42 # Materialize assembly | |
43 # Materialize the register allocated instructions into a stream of | |
44 # real instructions. | |
45 frame.lower_to(self.outs) | |
46 return frame | |
47 | |
16 def generate(self, ircode): | 48 def generate(self, ircode): |
17 assert isinstance(ircode, ir.Module) | 49 assert isinstance(ircode, ir.Module) |
18 obj = object() | 50 self.outs.selectSection('code') |
19 for gvar in ircode.Variables: | 51 # assembly glue to make it work: |
20 print(gvar) | 52 # TODO: this must be in source code, not in compiler |
21 raise Exception() # TODO | 53 self.outs.emit(arm.dcd_ins(Imm32(0x20000678))) # initial SP |
22 for f in ircode.Functions: | 54 self.outs.emit(arm.dcd_ins(Imm32(0x08000009))) # reset vector |
23 for bb in f.Blocks: | 55 self.outs.emit(arm.b_ins(LabelRef('main'))) |
24 for ins in bb.Instructions: | |
25 # Instruction selection: | |
26 #mi = self.tryMap(ins) | |
27 pass | |
28 return obj | |
29 | |
30 | 56 |
57 # Munch program into a bunch of frames. One frame per function. | |
58 # Each frame has a flat list of abstract instructions. | |
59 # Generate code for all functions: | |
60 self.frames = [self.generateFunc(func) for func in ircode.Functions] | |
61 | |
62 # TODO: fixup references, do this in another way? | |
63 self.outs.backpatch() | |
64 self.outs.backpatch() # Why two times? | |
65 return self.frames |