Mercurial > lcfOS
comparison python/codegenarm.py @ 277:046017431c6a
Started register allocator
author | Windel Bouwman |
---|---|
date | Thu, 26 Sep 2013 21:14:25 +0200 |
parents | 56d37ed4b4d2 |
children | 2ccd57b1d78c |
comparison
equal
deleted
inserted
replaced
276:56d37ed4b4d2 | 277:046017431c6a |
---|---|
1 import logging | 1 import logging |
2 import ir | 2 import ir |
3 from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo | 3 from target import Label, Comment, Alignment, LabelRef, Imm32, DebugInfo |
4 import cortexm3 as arm | 4 import cortexm3 as arm |
5 from ppci import CompilerError | 5 from ppci import CompilerError |
6 import flowgraph | |
7 import registerallocator | 6 import registerallocator |
8 from instructionselector import InstructionSelector | 7 from instructionselector import InstructionSelector |
9 import irmach | 8 import irmach |
10 from irmach import makeIns | 9 from irmach import makeIns |
11 import canon | 10 import canon |
208 class ArmCodeGenerator: | 207 class ArmCodeGenerator: |
209 def __init__(self, outs): | 208 def __init__(self, outs): |
210 # TODO: schedule traces in better order. | 209 # TODO: schedule traces in better order. |
211 # This is optional! | 210 # This is optional! |
212 self.ins_sel = ArmInstructionSelector() | 211 self.ins_sel = ArmInstructionSelector() |
212 self.ra = registerallocator.RegisterAllocator() | |
213 self.outs = outs | 213 self.outs = outs |
214 self.outs.getSection('code').address = 0x08000000 | 214 self.outs.getSection('code').address = 0x08000000 |
215 self.outs.getSection('data').address = 0x20000000 | 215 self.outs.getSection('data').address = 0x20000000 |
216 | 216 |
217 def useUnused(self, inslist): | |
218 # Use unused temporaries at the end of the list | |
219 defTemps = [] | |
220 useTemps = [] | |
221 for i in inslist: | |
222 for d in iter(i.dst): | |
223 defTemps.append(d) | |
224 for s in iter(i.src): | |
225 useTemps.append(s) | |
226 defTemps = set(defTemps) | |
227 useTemps = set(useTemps) | |
228 unUsed = defTemps - useTemps | |
229 assert not unUsed | |
230 for uu in unUsed: | |
231 inslist.append(irmach.AbstractInstruction('use %s0', src=[uu])) | |
232 #print(useTemps) | |
233 | |
234 def allocFrame(self, f): | |
235 """ | |
236 Do register allocation for a single stack frame. | |
237 """ | |
238 ilist = f.instructions | |
239 self.useUnused(ilist) | |
240 cfg = flowgraph.FlowGraph(ilist) | |
241 f.cfg = cfg | |
242 ig = registerallocator.InterferenceGraph(cfg) | |
243 f.ig = ig | |
244 | |
245 ra = registerallocator.RegisterAllocator() | |
246 regMap = ra.registerAllocate(ig, f.regs, f.tempMap) | |
247 # Use allocated registers: | |
248 for i in ilist: | |
249 i.src = tuple(regMap[t] for t in i.src) | |
250 i.dst = tuple(regMap[t] for t in i.dst) | |
251 | |
252 def generateFunc(self, irfunc): | 217 def generateFunc(self, irfunc): |
253 # Create a frame for this function: | 218 # Create a frame for this function: |
254 frame = ArmFrame(irfunc.name) | 219 frame = ArmFrame(irfunc.name) |
220 | |
255 # Canonicalize the intermediate language: | 221 # Canonicalize the intermediate language: |
256 canon.make(irfunc, frame) | 222 canon.make(irfunc, frame) |
257 # print('after canonicalize:') | 223 print('after canonicalize:') |
258 # irfunc.dump() | 224 irfunc.dump() |
259 self.ins_sel.munchFunction(irfunc, frame) | 225 self.ins_sel.munchFunction(irfunc, frame) |
260 # print('Selected instructions:') | 226 print('Selected instructions:') |
261 #for i in frame.instructions: | 227 for i in frame.instructions: |
262 # print(i) | 228 print(i) |
263 | 229 |
264 # Do register allocation: | 230 # Do register allocation: |
265 self.allocFrame(frame) | 231 self.ra.allocFrame(frame) |
266 # TODO: Peep-hole here? | 232 # TODO: Peep-hole here? |
267 | 233 |
268 # Add label and return and stack adjustment: | 234 # Add label and return and stack adjustment: |
269 frame.EntryExitGlue3() | 235 frame.EntryExitGlue3() |
270 return frame | 236 return frame |