annotate python/target/arminstructionselector.py @ 336:d1ecc493384e

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