Mercurial > lcfOS
view 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 source
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)