annotate python/target/arminstructionselector.py @ 322:44f336460c2a

Half of use of burg spec for arm
author Windel Bouwman
date Mon, 27 Jan 2014 19:58:07 +0100
parents e84047f29c78
children e9fe6988497c
rev   line source
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
1 import os
301
6753763d3bec merge codegen into ppci package
Windel Bouwman
parents: 300
diff changeset
2 from ppci import ir
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:
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
15 spec_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'arm.brg')
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
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
18 class ArmMatcher(arm_matcher.Matcher):
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
19 def __init__(self):
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
20 super().__init__()
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
21
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
22 def newTmp(self):
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
23 pass
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
24
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
25 def emit(self, *args, **kwargs):
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
26 pass
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
27
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
28
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
29 class ArmInstructionSelector(InstructionSelector):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
30 """ Instruction selector for the arm architecture """
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
31 def __init__(self):
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
32 super().__init__()
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
33 self.matcher = ArmMatcher()
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
34
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
35 def munchExpr(self, e):
322
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
36 #t = makeTree(e)
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
37 #print(t)
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
38 #return self.matcher.gen(t)
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
39
44f336460c2a Half of use of burg spec for arm
Windel Bouwman
parents: 318
diff changeset
40 # TODO: below is obsolete:
318
e84047f29c78 Add burg and yacc initial attempts
Windel Bouwman
parents: 316
diff changeset
41 if isinstance(e, ir.Binop) and e.operation == '+' and \
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
42 isinstance(e.b, ir.Const) and e.b.value < 8:
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
43 a = self.munchExpr(e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
44 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
45 c = Imm3(e.b.value)
300
Windel Bouwman
parents: 292
diff changeset
46 self.emit(Add2, others=[c], dst=[d], src=[a])
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
47 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
48 elif isinstance(e, ir.Binop) and e.operation == '+':
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
49 a = self.munchExpr(e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
50 b = self.munchExpr(e.b)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
51 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
52 self.emit(Add, dst=[d], src=[a, b])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
53 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
54 elif isinstance(e, ir.Binop) and e.operation == '-' and \
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
55 isinstance(e.b, ir.Const) and e.b.value < 8:
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
56 a = self.munchExpr(e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
57 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
58 c = Imm3(e.b.value)
300
Windel Bouwman
parents: 292
diff changeset
59 self.emit(Sub2, others=[c], dst=[d], src=[a])
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
60 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
61 elif isinstance(e, ir.Binop) and e.operation == '-':
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
62 a = self.munchExpr(e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
63 b = self.munchExpr(e.b)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
64 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
65 self.emit(Sub, dst=[d], src=[a, b])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
66 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
67 elif isinstance(e, ir.Binop) and e.operation == '|':
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
68 a = self.munchExpr(e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
69 b = self.munchExpr(e.b)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
70 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
71 self.move(d, a)
316
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 305
diff changeset
72 self.emit(Orr, dst=[], src=[d, b])
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
73 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
74 elif isinstance(e, ir.Binop) and e.operation == '<<':
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
75 a = self.munchExpr(e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
76 b = self.munchExpr(e.b)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
77 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
78 self.move(d, a)
316
56e6ff84f646 Fixed burn led demo
Windel Bouwman
parents: 305
diff changeset
79 self.emit(Lsl, dst=[], src=[d, b]) # TODO: is d a source variable?
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
80 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
81 elif isinstance(e, ir.Binop) and e.operation == '*':
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
82 a = self.munchExpr(e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
83 b = self.munchExpr(e.b)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
84 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
85 self.move(d, a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
86 # this mul instruction has operands swapped:
300
Windel Bouwman
parents: 292
diff changeset
87 self.emit(Mul, dst=[d], src=[b, d])
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
88 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
89 elif isinstance(e, ir.Const) and e.value < 256:
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
90 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
91 self.emit(Mov3, others=[Imm8(e.value)], dst=[d])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
92 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
93 elif isinstance(e, ir.Const) and e.value < (2**31):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
94 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
95 ln = LabelRef(self.frame.addConstant(e.value))
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
96 self.emit(Ldr3, others=[ln], dst=[d])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
97 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
98 elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
99 e.e.operation == '+' and isinstance(e.e.b, ir.Const):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
100 base = self.munchExpr(e.e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
101 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
102 c = e.e.b.value
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
103 self.emit(Ldr2, others=[c], src=[base], dst=[d])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
104 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
105 elif isinstance(e, ir.Mem):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
106 # Load from memory
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
107 base = self.munchExpr(e.e)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
108 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
109 self.emit(Ldr2, others=[0], src=[base], dst=[d])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
110 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
111 elif isinstance(e, ir.Temp):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
112 return e
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
113 elif isinstance(e, ir.Call):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
114 # Move arguments into proper locations:
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
115 reguses = []
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
116 for i, a in enumerate(e.arguments):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
117 loc = self.frame.argLoc(i)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
118 m = ir.Move(loc, a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
119 self.munchStm(m)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
120 if isinstance(loc, ir.Temp):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
121 reguses.append(loc)
305
0615b5308710 Updated docs
Windel Bouwman
parents: 301
diff changeset
122 self.emit(Bl(LabelRef(e.f)), src=reguses, dst=[self.frame.rv])
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
123 d = self.newTmp()
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
124 self.move(d, self.frame.rv)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
125 return d
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
126 else:
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
127 raise NotImplementedError('Expr --> {}'.format(e))
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
128
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
129 def munchStm(self, s):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
130 if isinstance(s, ir.Terminator):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
131 pass
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
132 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem) and \
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
133 isinstance(s.dst.e, ir.Binop) and s.dst.e.operation == '+' and \
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
134 isinstance(s.dst.e.b, ir.Const):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
135 a = self.munchExpr(s.dst.e.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
136 val = self.munchExpr(s.src)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
137 c = s.dst.e.b.value
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
138 self.emit(Str2, others=[c], src=[a, val])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
139 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Mem):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
140 memloc = self.munchExpr(s.dst.e)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
141 val = self.munchExpr(s.src)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
142 self.emit(Str2, others=[0], src=[memloc, val])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
143 elif isinstance(s, ir.Move) and isinstance(s.dst, ir.Temp):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
144 val = self.munchExpr(s.src)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
145 dreg = s.dst
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
146 self.move(dreg, val)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
147 elif isinstance(s, ir.Exp):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
148 # Generate expression code and discard the result.
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
149 x = self.munchExpr(s.e)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
150 self.emit(Nop(), src=[x])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
151 elif isinstance(s, ir.Jump):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
152 tgt = self.targets[s.target]
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
153 self.emit(B(LabelRef(s.target.name)), jumps=[tgt])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
154 elif isinstance(s, ir.CJump):
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
155 a = self.munchExpr(s.a)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
156 b = self.munchExpr(s.b)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
157 self.emit(Cmp, src=[a, b])
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
158 ntgt = self.targets[s.lab_no]
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
159 ytgt = self.targets[s.lab_yes]
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
160 jmp_ins = makeIns(B(LabelRef(s.lab_no.name)), jumps=[ntgt])
305
0615b5308710 Updated docs
Windel Bouwman
parents: 301
diff changeset
161 opnames = {'<': Blt, '>':Bgt, '==':Beq, '!=':Bne}
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
162 op = opnames[s.cond](LabelRef(s.lab_yes.name))
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
163 self.emit(op, jumps=[ytgt, jmp_ins]) # Explicitely add fallthrough
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
164 self.emit2(jmp_ins)
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
165 else:
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
166 raise NotImplementedError('Stmt --> {}'.format(s))
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
167
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents:
diff changeset
168 def move(self, dst, src):
318
e84047f29c78 Add burg and yacc initial attempts
Windel Bouwman
parents: 316
diff changeset
169 self.emit(Mov2, src=[src], dst=[dst], ismove=True)