Mercurial > lcfOS
diff python/codegenarm.py @ 274:ea93e0a7a31e
Move docs
author | Windel Bouwman |
---|---|
date | Wed, 04 Sep 2013 17:35:06 +0200 |
parents | e64bae57cda8 |
children | 6f2423df0675 |
line wrap: on
line diff
--- a/python/codegenarm.py Mon Sep 02 17:40:21 2013 +0200 +++ b/python/codegenarm.py Wed Sep 04 17:35:06 2013 +0200 @@ -8,8 +8,19 @@ from instructionselector import InstructionSelector import irmach + +class ArmFrame(irmach.Frame): + """ + Arm specific frame for functions. + """ + pass + + class ArmInstructionSelector(InstructionSelector): """ Instruction selector for the arm architecture """ + def newFrame(self, name): + return ArmFrame(name) + def munchExpr(self, e): if isinstance(e, ir.Alloc): return 0 @@ -58,9 +69,15 @@ return d elif isinstance(e, ir.Temp): return self.getTempReg(e) + elif isinstance(e, ir.Parameter): + offset = 1337 # TODO: determine offset in frame?? + d = self.newTmp() + self.emit('ldr %d0, [sp + {}]'.format(offset), dst=[d]) + return d elif isinstance(e, ir.Call): args = [self.munchExpr(a) for a in e.arguments] - self.emit('add sp, sp, 22') + frame_size = 222 # TODO: determine frame size? + self.emit('add sp, sp, {}'.format(frame_size)) # TODO: save frame for a in args: self.emit('push %s0', src=[a]) @@ -73,28 +90,31 @@ if isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): memloc = self.munchExpr(s.dst.e) val = self.munchExpr(s.src) - self.emit('str [%s0], %s1') + self.emit('str [%s0], %s1', src=[memloc, val]) elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp): val = self.munchExpr(s.src) dreg = self.getTempReg(s.dst) self.emit('mov %d0, %s0', dst=[dreg], src=[val]) elif isinstance(s, ir.Jump): tgt = self.targets[s.target] - self.emit('jmp {}'.format(s), jumps=[tgt]) + self.emit('jmp %l0', jumps=[tgt]) elif isinstance(s, ir.CJump): a = self.munchExpr(s.a) b = self.munchExpr(s.b) self.emit('cmp %s0, %s1', src=[a, b]) ntgt = self.targets[s.lab_no] ytgt = self.targets[s.lab_yes] - jmp_ins = self.makeIns('jmp {}'.format(s.lab_no), jumps=[ntgt]) + jmp_ins = self.makeIns('jmp %l0', jumps=[ntgt]) # Explicitely add fallthrough: - self.emit('jeq {}'.format(s.lab_yes), jumps=[ytgt, jmp_ins]) + self.emit('jeq %l0', jumps=[ytgt, jmp_ins]) self.emit2(jmp_ins) + elif isinstance(s, ir.Terminator): + pass else: - raise NotImplementedError('--> {}'.format(s)) + raise NotImplementedError('Stmt --> {}'.format(s)) +# TODO: this class could be target independent: class ArmCodeGenerator: def __init__(self, outs): # TODO: schedule traces in better order. @@ -116,31 +136,42 @@ defTemps = set(defTemps) useTemps = set(useTemps) unUsed = defTemps - useTemps - #print('Unused:', unUsed) + print('Unused:', unUsed) for uu in unUsed: inslist.append(irmach.AbstractInstruction('use %s0', src=[uu])) #print(useTemps) - def generate(self, ircode, cfg_file=None, ig_file=None): - ir2 = self.ins_sel.munchProgram(ircode) - self.useUnused(ir2) - cfg = flowgraph.FlowGraph(ir2) - if cfg_file: - cfg.to_dot(cfg_file) + def allocFrame(self, f): + """ + Do register allocation for a single stack frame. + """ + ilist = f.instructions + self.useUnused(ilist) + cfg = flowgraph.FlowGraph(ilist) + f.cfg = cfg ig = registerallocator.InterferenceGraph(cfg) - if ig_file: - ig.to_dot(ig_file) + f.ig = ig regs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7'] ra = registerallocator.RegisterAllocator() regMap = ra.registerAllocate(ig, regs) #print(regMap) # Use allocated registers: - for i in ir2: + for i in ilist: i.src = tuple(regMap[t] for t in i.src) i.dst = tuple(regMap[t] for t in i.dst) #print(i) - return ir2 + + def generate(self, ircode): + # Munch program into a bunch of frames. One frame per function. + # Each frame has a flat list of abstract instructions. + frames = self.ins_sel.munchProgram(ircode) + self.frames = frames + for f in frames: + self.allocFrame(f) + + # TODO: Peep-hole here + # TODO: Materialize assembly + return frames -