Mercurial > lcfOS
diff python/ppci/target/thumb/arminstructionselector.py @ 342:86b02c98a717 devel
Moved target directory
author | Windel Bouwman |
---|---|
date | Sat, 01 Mar 2014 15:40:31 +0100 |
parents | python/target/arminstructionselector.py@4d204f6f7d4e |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ppci/target/thumb/arminstructionselector.py Sat Mar 01 15:40:31 2014 +0100 @@ -0,0 +1,92 @@ +from ... import ir, same_dir +from ppci.irmach import AbstractInstruction as makeIns +from ppci.ir2tree import makeTree +import pyburg +from ..basetarget import Nop +from ..instructionselector import InstructionSelector +from .instructions import Orr, Lsl, Str2, Ldr2, Ldr3 +from .instructions import B, Bl, Bgt, Blt, Beq, Bne +from .instructions import Mov2, Mov3 +from .instructions import Cmp, Sub2, Mul + +# Import BURG spec for arm: +spec_file = same_dir(__file__, 'arm.brg') +arm_matcher = pyburg.load_as_module(spec_file) + + +class ArmMatcher(arm_matcher.Matcher): + """ Matcher that derives from a burg spec generated matcher """ + def __init__(self, selector): + super().__init__() + self.newTmp = selector.newTmp + self.emit = selector.emit + self.selector = selector + + +class ArmInstructionSelector(InstructionSelector): + """ Instruction selector for the arm architecture """ + def __init__(self): + super().__init__() + self.matcher = ArmMatcher(self) + + def munchExpr(self, e): + # Use BURG system here: + t = makeTree(e) + return self.matcher.gen(t) + + def munchCall(self, e): + """ Generate code for call sequence """ + # Move arguments into proper locations: + reguses = [] + for i, a in enumerate(e.arguments): + loc = self.frame.argLoc(i) + m = ir.Move(loc, a) + self.munchStm(m) + if isinstance(loc, ir.Temp): + reguses.append(loc) + self.emit(Bl(e.f), src=reguses, dst=[self.frame.rv]) + d = self.newTmp() + self.move(d, self.frame.rv) + return d + + def munchStm(self, s): + if isinstance(s, ir.Terminator): + pass + elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \ + isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \ + isinstance(s.dst.e.b, ir.Const): + a = self.munchExpr(s.dst.e.a) + val = self.munchExpr(s.src) + c = s.dst.e.b.value + self.emit(Str2, others=[c], src=[a, val]) + elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem): + memloc = self.munchExpr(s.dst.e) + val = self.munchExpr(s.src) + self.emit(Str2, others=[0], src=[memloc, val]) + elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp): + val = self.munchExpr(s.src) + dreg = s.dst + self.move(dreg, val) + elif isinstance(s, ir.Exp): + # Generate expression code and discard the result. + x = self.munchExpr(s.e) + self.emit(Nop(), src=[x]) + elif isinstance(s, ir.Jump): + tgt = self.targets[s.target] + self.emit(B(ir.label_name(s.target)), jumps=[tgt]) + elif isinstance(s, ir.CJump): + a = self.munchExpr(s.a) + b = self.munchExpr(s.b) + self.emit(Cmp, src=[a, b]) + ntgt = self.targets[s.lab_no] + ytgt = self.targets[s.lab_yes] + jmp_ins = makeIns(B(ir.label_name(s.lab_no)), jumps=[ntgt]) + opnames = {'<': Blt, '>':Bgt, '==':Beq, '!=':Bne} + op = opnames[s.cond](ir.label_name(s.lab_yes)) + self.emit(op, jumps=[ytgt, jmp_ins]) # Explicitely add fallthrough + self.emit2(jmp_ins) + else: + raise NotImplementedError('Stmt --> {}'.format(s)) + + def move(self, dst, src): + self.emit(Mov2, src=[src], dst=[dst], ismove=True)