annotate python/ppci/target/thumb/arminstructionselector.py @ 362:c05ab629976a

Added CPUID for arm
author Windel Bouwman
date Sat, 15 Mar 2014 10:56:34 +0100
parents 86b02c98a717
children
rev   line source
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
1 from ... import ir, same_dir
301
6753763d3bec merge codegen into ppci package
Windel Bouwman
parents: 300
diff changeset
2 from ppci.irmach import AbstractInstruction as makeIns
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
3 from ppci.ir2tree import makeTree
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
4 import pyburg
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
5 from ..basetarget import Nop
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
6 from ..instructionselector import InstructionSelector
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
7 from .instructions import Orr, Lsl, Str2, Ldr2, Ldr3
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
8 from .instructions import B, Bl, Bgt, Blt, Beq, Bne
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
9 from .instructions import Mov2, Mov3
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
10 from .instructions import Cmp, Sub2, Mul
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
11
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
12 # Import BURG spec for arm:
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 323
diff changeset
13 spec_file = same_dir(__file__, 'arm.brg')
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
14 arm_matcher = pyburg.load_as_module(spec_file)
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
15
323
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
16
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
17 class ArmMatcher(arm_matcher.Matcher):
323
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
18 """ Matcher that derives from a burg spec generated matcher """
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
19 def __init__(self, selector):
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
20 super().__init__()
323
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
21 self.newTmp = selector.newTmp
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
22 self.emit = selector.emit
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
23 self.selector = selector
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
24
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
25
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
26 class ArmInstructionSelector(InstructionSelector):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
27 """ Instruction selector for the arm architecture """
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
28 def __init__(self):
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
29 super().__init__()
323
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
30 self.matcher = ArmMatcher(self)
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
31
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
32 def munchExpr(self, e):
323
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
33 # Use BURG system here:
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
34 t = makeTree(e)
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
35 return self.matcher.gen(t)
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
36
323
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
37 def munchCall(self, e):
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
38 """ Generate code for call sequence """
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
39 # Move arguments into proper locations:
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
40 reguses = []
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
41 for i, a in enumerate(e.arguments):
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
42 loc = self.frame.argLoc(i)
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
43 m = ir.Move(loc, a)
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
44 self.munchStm(m)
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
45 if isinstance(loc, ir.Temp):
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
46 reguses.append(loc)
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
47 self.emit(Bl(e.f), src=reguses, dst=[self.frame.rv])
323
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
48 d = self.newTmp()
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
49 self.move(d, self.frame.rv)
e9fe6988497c Used burg for generating expressions
Windel Bouwman
parents: 322
diff changeset
50 return d
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
51
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
52 def munchStm(self, s):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
53 if isinstance(s, ir.Terminator):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
54 pass
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
55 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
56 isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
57 isinstance(s.dst.e.b, ir.Const):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
58 a = self.munchExpr(s.dst.e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
59 val = self.munchExpr(s.src)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
60 c = s.dst.e.b.value
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
61 self.emit(Str2, others=[c], src=[a, val])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
62 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
63 memloc = self.munchExpr(s.dst.e)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
64 val = self.munchExpr(s.src)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
65 self.emit(Str2, others=[0], src=[memloc, val])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
66 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
67 val = self.munchExpr(s.src)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
68 dreg = s.dst
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
69 self.move(dreg, val)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
70 elif isinstance(s, ir.Exp):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
71 # Generate expression code and discard the result.
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
72 x = self.munchExpr(s.e)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
73 self.emit(Nop(), src=[x])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
74 elif isinstance(s, ir.Jump):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
75 tgt = self.targets[s.target]
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
76 self.emit(B(ir.label_name(s.target)), jumps=[tgt])
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
77 elif isinstance(s, ir.CJump):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
78 a = self.munchExpr(s.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
79 b = self.munchExpr(s.b)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
80 self.emit(Cmp, src=[a, b])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
81 ntgt = self.targets[s.lab_no]
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
82 ytgt = self.targets[s.lab_yes]
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
83 jmp_ins = makeIns(B(ir.label_name(s.lab_no)), jumps=[ntgt])
305
0615b5308710 Updated docs
Windel Bouwman
parents: 301
diff changeset
84 opnames = {'<': Blt, '>':Bgt, '==':Beq, '!=':Bne}
342
86b02c98a717 Moved target directory
Windel Bouwman
parents: 341
diff changeset
85 op = opnames[s.cond](ir.label_name(s.lab_yes))
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
86 self.emit(op, jumps=[ytgt, jmp_ins]) # Explicitely add fallthrough
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
87 self.emit2(jmp_ins)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
88 else:
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
89 raise NotImplementedError('Stmt --> {}'.format(s))
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
90
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
91 def move(self, dst, src):
318
e84047f29c78 Add burg and yacc initial attempts
Windel Bouwman
parents: 316
diff changeset
92 self.emit(Mov2, src=[src], dst=[dst], ismove=True)