comparison 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
comparison
equal deleted inserted replaced
341:4d204f6f7d4e 342:86b02c98a717
1 from ... import ir, same_dir
2 from ppci.irmach import AbstractInstruction as makeIns
3 from ppci.ir2tree import makeTree
4 import pyburg
5 from ..basetarget import Nop
6 from ..instructionselector import InstructionSelector
7 from .instructions import Orr, Lsl, Str2, Ldr2, Ldr3
8 from .instructions import B, Bl, Bgt, Blt, Beq, Bne
9 from .instructions import Mov2, Mov3
10 from .instructions import Cmp, Sub2, Mul
11
12 # Import BURG spec for arm:
13 spec_file = same_dir(__file__, 'arm.brg')
14 arm_matcher = pyburg.load_as_module(spec_file)
15
16
17 class ArmMatcher(arm_matcher.Matcher):
18 """ Matcher that derives from a burg spec generated matcher """
19 def __init__(self, selector):
20 super().__init__()
21 self.newTmp = selector.newTmp
22 self.emit = selector.emit
23 self.selector = selector
24
25
26 class ArmInstructionSelector(InstructionSelector):
27 """ Instruction selector for the arm architecture """
28 def __init__(self):
29 super().__init__()
30 self.matcher = ArmMatcher(self)
31
32 def munchExpr(self, e):
33 # Use BURG system here:
34 t = makeTree(e)
35 return self.matcher.gen(t)
36
37 def munchCall(self, e):
38 """ Generate code for call sequence """
39 # Move arguments into proper locations:
40 reguses = []
41 for i, a in enumerate(e.arguments):
42 loc = self.frame.argLoc(i)
43 m = ir.Move(loc, a)
44 self.munchStm(m)
45 if isinstance(loc, ir.Temp):
46 reguses.append(loc)
47 self.emit(Bl(e.f), src=reguses, dst=[self.frame.rv])
48 d = self.newTmp()
49 self.move(d, self.frame.rv)
50 return d
51
52 def munchStm(self, s):
53 if isinstance(s, ir.Terminator):
54 pass
55 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
56 isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
57 isinstance(s.dst.e.b, ir.Const):
58 a = self.munchExpr(s.dst.e.a)
59 val = self.munchExpr(s.src)
60 c = s.dst.e.b.value
61 self.emit(Str2, others=[c], src=[a, val])
62 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
63 memloc = self.munchExpr(s.dst.e)
64 val = self.munchExpr(s.src)
65 self.emit(Str2, others=[0], src=[memloc, val])
66 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
67 val = self.munchExpr(s.src)
68 dreg = s.dst
69 self.move(dreg, val)
70 elif isinstance(s, ir.Exp):
71 # Generate expression code and discard the result.
72 x = self.munchExpr(s.e)
73 self.emit(Nop(), src=[x])
74 elif isinstance(s, ir.Jump):
75 tgt = self.targets[s.target]
76 self.emit(B(ir.label_name(s.target)), jumps=[tgt])
77 elif isinstance(s, ir.CJump):
78 a = self.munchExpr(s.a)
79 b = self.munchExpr(s.b)
80 self.emit(Cmp, src=[a, b])
81 ntgt = self.targets[s.lab_no]
82 ytgt = self.targets[s.lab_yes]
83 jmp_ins = makeIns(B(ir.label_name(s.lab_no)), jumps=[ntgt])
84 opnames = {'<': Blt, '>':Bgt, '==':Beq, '!=':Bne}
85 op = opnames[s.cond](ir.label_name(s.lab_yes))
86 self.emit(op, jumps=[ytgt, jmp_ins]) # Explicitely add fallthrough
87 self.emit2(jmp_ins)
88 else:
89 raise NotImplementedError('Stmt --> {}'.format(s))
90
91 def move(self, dst, src):
92 self.emit(Mov2, src=[src], dst=[dst], ismove=True)