Mercurial > lcfOS
view python/ppci/target/thumb/arminstructionselector.py @ 385:d056b552d3f4
Made better use of layout
author | Windel Bouwman |
---|---|
date | Thu, 01 May 2014 14:03:12 +0200 |
parents | 86b02c98a717 |
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)