annotate python/ppci/target/arm/selector.py @ 346:3bb7dcfe5529

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