annotate python/ppci/ir.py @ 307:e609d5296ee9

Massive rewrite of codegenerator
author Windel Bouwman
date Thu, 12 Dec 2013 20:42:56 +0100
parents 0615b5308710
children 68b01c8abf8a
rev   line source
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
1 """
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
2 Intermediate representation (IR) code classes.
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
3 """
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
4
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
5 class Module:
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
6 """ Container unit for variables and functions. """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
7 def __init__(self, name):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
8 self.name = name
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
9 self.funcs = []
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
10 self.variables = []
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
11
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
12 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
13 return 'IR-module [{0}]'.format(self.name)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
14
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
15 def addFunc(self, f):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
16 self.funcs.append(f)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
17
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
18 addFunction = addFunc
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
19
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
20 def addVariable(self, v):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
21 self.variables.append(v)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
22
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
23 def getVariables(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
24 return self.variables
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
25
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
26 Variables = property(getVariables)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
27
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
28 def getFunctions(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
29 return self.funcs
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
30
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
31 Functions = property(getFunctions)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
32
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
33 def findFunction(self, name):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
34 for f in self.funcs:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
35 if f.name == name:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
36 return f
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
37 raise KeyError(name)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
38
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
39 getFunction = findFunction
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
40
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
41 def dump(self, indent=' '):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
42 print(self)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
43 for v in self.Variables:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
44 print(indent, v)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
45 for fn in self.Functions:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
46 fn.dump(indent=indent+' ')
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
47
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
48 # Analysis functions:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
49 def check(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
50 """ Perform sanity check on module """
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
51 for f in self.Functions:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
52 f.check()
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
53
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
54
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
55 class Function:
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
56 """ Represents a function. """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
57 def __init__(self, name):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
58 self.name = name
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
59 self.entry = Block('{}_entry'.format(name))
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
60 self.entry.function = self
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
61 self.epiloog = Block('{}_epilog'.format(name))
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
62 self.epiloog.function = self
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
63 self.epiloog.addInstruction(Terminator())
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
64 self.return_value = Temp('{}_retval'.format(name))
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
65 self.arguments = []
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
66 self.localvars = []
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
67
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
68 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
69 args = ','.join(str(a) for a in self.arguments)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
70 return 'Function {}({})'.format(self.name, args)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
71
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
72 def addBlock(self, bb):
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
73 self.bbs.append(bb)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
74 bb.function = self
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
75
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
76 def removeBlock(self, bb):
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
77 #self.bbs.remove(bb)
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
78 bb.function = None
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
79
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
80 def getBlocks(self):
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
81 bbs = [self.entry]
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
82 worklist = [self.entry]
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
83 while worklist:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
84 b = worklist.pop()
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
85 for sb in b.Successors:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
86 if sb not in bbs:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
87 bbs.append(sb)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
88 worklist.append(sb)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
89 bbs.remove(self.entry)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
90 if self.epiloog in bbs:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
91 bbs.remove(self.epiloog)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
92 bbs.insert(0, self.entry)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
93 bbs.append(self.epiloog)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
94 return bbs
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
95
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
96 def findBasicBlock(self, name):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
97 for bb in self.bbs:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
98 if bb.name == name:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
99 return bb
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
100 raise KeyError(name)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
101
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
102 Blocks = property(getBlocks)
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
103
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
104 @property
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
105 def Entry(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
106 return self.entry
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
107
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
108 def check(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
109 for b in self.Blocks:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
110 b.check()
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
111
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
112 def addParameter(self, p):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
113 assert type(p) is Parameter
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
114 p.num = len(self.arguments)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
115 self.arguments.append(p)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
116
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
117 def addLocal(self, l):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
118 assert type(l) is LocalVariable
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
119 self.localvars.append(l)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
120
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
121 def dump(self, indent=''):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
122 print(indent+str(self))
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
123 for bb in self.Blocks:
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
124 print(indent+' ' + str(bb))
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
125 for ins in bb.Instructions:
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
126 print(indent + ' ' * 2 + str(ins))
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
127
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
128
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
129 class Block:
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
130 """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
131 Uninterrupted sequence of instructions with a label at the start.
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
132 """
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
133 def __init__(self, name):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
134 self.name = name
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
135 self.function = None
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
136 self.instructions = []
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
137
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
138 parent = property(lambda s: s.function)
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
139
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
140 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
141 return 'Block {0}'.format(self.name)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
142
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
143 def addInstruction(self, i):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
144 i.parent = self
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
145 assert not isinstance(self.LastInstruction, LastStatement)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
146 self.instructions.append(i)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
147
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
148 def replaceInstruction(self, i1, i2):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
149 idx = self.instructions.index(i1)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
150 i1.parent = None
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
151 i1.delete()
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
152 i2.parent = self
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
153 self.instructions[idx] = i2
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
154
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
155 def removeInstruction(self, i):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
156 i.parent = None
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
157 i.delete()
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
158 self.instructions.remove(i)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
159
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
160 @property
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
161 def Instructions(self):
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
162 return self.instructions
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
163
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
164 @property
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
165 def LastInstruction(self):
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
166 if not self.Empty:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
167 return self.instructions[-1]
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
168
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
169 @property
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
170 def Empty(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
171 return len(self.instructions) == 0
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
172
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
173 @property
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
174 def FirstInstruction(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
175 return self.instructions[0]
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
176
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
177 def getSuccessors(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
178 if not self.Empty:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
179 return self.LastInstruction.Targets
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
180 return []
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
181 Successors = property(getSuccessors)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
182
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
183 def getPredecessors(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
184 preds = []
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
185 for bb in self.parent.Blocks:
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
186 if self in bb.Successors:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
187 preds.append(bb)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
188 return preds
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
189 Predecessors = property(getPredecessors)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
190
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
191 def precedes(self, other):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
192 raise NotImplementedError()
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
193
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
194 def check(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
195 assert isinstance(self.LastInstruction, LastStatement)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
196 for i in self.instructions[:-1]:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
197 assert not isinstance(i, LastStatement)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
198
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
199
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
200 # Instructions:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
201 class Term:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
202 def __init__(self, x):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
203 self.x = x
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
204
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
205
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
206 def match_tree(tree, pattern):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
207 if type(pattern) is Term:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
208 return True, {pattern: tree}
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
209 elif type(pattern) is Binop and type(tree) is Binop and \
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
210 tree.operation == pattern.operation:
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
211 res_a, mp_a = match_tree(tree.a, pattern.a)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
212 res_b, mp_b = match_tree(tree.b, pattern.b)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
213 assert not (mp_a.keys() & mp_b.keys())
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
214 mp_a.update(mp_b)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
215 return res_a and res_b, mp_a
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
216 elif type(pattern) is Const and type(tree) is Const and \
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
217 pattern.value == tree.value:
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
218 return True, {}
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
219 else:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
220 return False, {}
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
221
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
222
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
223 class Expression:
304
fa99f36fabb5 Fix docs
Windel Bouwman
parents: 303
diff changeset
224 """ Base class for an expression """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
225 pass
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
226
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
227
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
228 class Const(Expression):
304
fa99f36fabb5 Fix docs
Windel Bouwman
parents: 303
diff changeset
229 """ Represents a constant value """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
230 def __init__(self, value):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
231 self.value = value
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
232
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
233 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
234 return 'Const {}'.format(self.value)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
235
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
236
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
237 class Call(Expression):
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
238 """ Call a function with some arguments """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
239 def __init__(self, f, arguments):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
240 self.f = f
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
241 self.arguments = arguments
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
242
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
243 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
244 args = ', '.join([str(arg) for arg in self.arguments])
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
245 return '{}({})'.format(self.f, args)
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
246
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
247
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
248 # Data operations
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
249 class Binop(Expression):
304
fa99f36fabb5 Fix docs
Windel Bouwman
parents: 303
diff changeset
250 """ Generic binary operation """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
251 ops = ['+', '-', '*', '/', '|', '&', '<<', '>>']
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
252
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
253 def __init__(self, value1, operation, value2):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
254 assert operation in Binop.ops
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
255 self.a = value1
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
256 self.b = value2
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
257 self.operation = operation
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
258
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
259 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
260 a, b = self.a, self.b
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
261 return '({} {} {})'.format(a, self.operation, b)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
262
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
263
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
264 def Add(a, b):
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
265 """ Add a and b """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
266 return Binop(a, '+', b)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
267
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents: 280
diff changeset
268
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
269 def Sub(a, b):
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
270 """ Substract b from a """
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
271 return Binop(a, '-', b)
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
272
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents: 280
diff changeset
273
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
274 def Mul(a, b):
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
275 return Binop(a, '*', b)
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
276
292
534b94b40aa8 Fixup reorganize
Windel Bouwman
parents: 280
diff changeset
277
279
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
278 def Div(a, b):
2ccd57b1d78c Fix register allocator to do burn2 OK
Windel Bouwman
parents: 277
diff changeset
279 return Binop(a, '/', b)
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
280
303
be7f60545368 Final fixups
Windel Bouwman
parents: 301
diff changeset
281
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
282 class Eseq(Expression):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
283 """ Sequence of instructions where the last is an expression """
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
284 def __init__(self, stmt, e):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
285 self.stmt = stmt
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
286 self.e = e
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
287
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
288 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
289 return '({}, {})'.format(self.stmt, self.e)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
290
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
291
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
292 class Alloc(Expression):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
293 """ Allocates space on the stack """
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
294 def __init__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
295 super().__init__()
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
296
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
297 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
298 return 'Alloc'
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
299
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
300
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
301 class Variable(Expression):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
302 def __init__(self, name):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
303 self.name = name
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
304
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
305 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
306 return 'Var {}'.format(self.name)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
307
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
308
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
309 class LocalVariable(Variable):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
310 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
311 return 'Local {}'.format(self.name)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
312
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
313
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
314 class Parameter(Variable):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
315 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
316 return 'Param {}'.format(self.name)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
317
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
318
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
319 class Temp(Expression):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
320 """ Temporary storage, same as register """
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
321 def __init__(self, name):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
322 self.name = name
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
323
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
324 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
325 return 'TMP_{}'.format(self.name)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
326
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
327
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
328 class Mem(Expression):
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
329 """ Memory access """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
330 def __init__(self, e):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
331 self.e = e
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
332
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
333 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
334 return '[{}]'.format(self.e)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
335
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
336
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
337 class Statement:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
338 """ Base class for all instructions. """
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
339 pass
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
340
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
341
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
342 class Move(Statement):
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
343 """ Move source to destination """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
344 def __init__(self, dst, src):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
345 self.dst = dst
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
346 self.src = src
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
347
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
348 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
349 return '{} = {}'.format(self.dst, self.src)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
350
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
351
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
352 class Exp(Statement):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
353 def __init__(self, e):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
354 self.e = e
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
355
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
356 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
357 return '{}'.format(self.e)
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
358
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
359
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
360 # Branching:
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
361 class LastStatement(Statement):
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
362 def changeTarget(self, old, new):
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
363 idx = self.Targets.index(old)
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
364 self.Targets[idx] = new
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
365
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
366
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
367 class Terminator(LastStatement):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
368 """ Instruction that terminates the terminal block """
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
369 def __init__(self):
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
370 self.Targets = []
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
371
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
372 def __repr__(self):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
373 return 'Terminator'
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
374
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
375
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
376 class Jump(LastStatement):
304
fa99f36fabb5 Fix docs
Windel Bouwman
parents: 303
diff changeset
377 """ Jump statement to some target location """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
378 def __init__(self, target):
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
379 self.Targets = [target]
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
380
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
381 def setTarget(self, t):
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
382 self.Targets[0] = t
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
383 target = property(lambda s: s.Targets[0], setTarget)
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
384
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
385 def __repr__(self):
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
386 return 'JUMP {}'.format(self.target.name)
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
387
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
388
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
389 class CJump(LastStatement):
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
390 """ Conditional jump to true or false labels. """
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
391 conditions = ['==', '<', '>', '>=', '<=', '!=']
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
392
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
393 def __init__(self, a, cond, b, lab_yes, lab_no):
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
394 assert cond in CJump.conditions
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
395 self.a = a
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
396 self.cond = cond
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
397 self.b = b
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
398 self.Targets = [lab_yes, lab_no]
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
399
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
400 lab_yes = property(lambda s: s.Targets[0])
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
401 lab_no = property(lambda s: s.Targets[1])
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 279
diff changeset
402
277
046017431c6a Started register allocator
Windel Bouwman
parents:
diff changeset
403 def __repr__(self):
305
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
404 return 'IF {} {} {} THEN {} ELSE {}'\
0615b5308710 Updated docs
Windel Bouwman
parents: 304
diff changeset
405 .format(self.a, self.cond, self.b, self.lab_yes, self.lab_no)