comparison python/ppci/frontends/ks/irgenerator.py @ 104:ed230e947dc6

Added hexviewer
author windel
date Sun, 30 Dec 2012 22:31:55 +0100
parents 28a35161ef23
children f2d980eef509
comparison
equal deleted inserted replaced
103:28a35161ef23 104:ed230e947dc6
4 4
5 from .nodes import * 5 from .nodes import *
6 from ...core.errors import Error 6 from ...core.errors import Error
7 from ... import core 7 from ... import core
8 from .builtin import real, integer, boolean, char 8 from .builtin import real, integer, boolean, char
9 #from .assembler import *
10 9
11 class KsIrGenerator: 10 class KsIrGenerator:
12 def __init__(self): 11 def __init__(self):
13 pass 12 pass
14 13
24 self.genexprcode(node.a) 23 self.genexprcode(node.a)
25 self.genexprcode(node.b) 24 self.genexprcode(node.b)
26 25
27 if node.op == 'mod': 26 if node.op == 'mod':
28 assert(node.typ.isType(integer)) 27 assert(node.typ.isType(integer))
29 self.addCode(mov('rax', node.a.reg))
30 elif node.op == 'div': 28 elif node.op == 'div':
31 assert(node.typ.isType(integer)) 29 assert(node.typ.isType(integer))
32 self.addCode(mov('rax', node.a.reg))
33 elif node.op == '*': 30 elif node.op == '*':
34 if node.typ.isType(integer): 31 if node.typ.isType(integer):
35 self.addCode(imulreg64(node.a.reg, node.b.reg)) 32 pass
36 elif node.op == '+': 33 elif node.op == '+':
37 if node.typ.isType(integer): 34 if node.typ.isType(integer):
38 self.addCode(addreg64(node.a.reg, node.b.reg)) 35 pass
39 elif node.op == '-': 36 elif node.op == '-':
40 if node.typ.isType(integer): 37 if node.typ.isType(integer):
41 self.addCode(subreg64(node.a.reg, node.b.reg)) 38 pass
42 else: 39 else:
43 Error('Unknown Binop {0}'.format(node.op)) 40 Error('Unknown Binop {0}'.format(node.op))
44 41
45 elif type(node) is Unop: 42 elif type(node) is Unop:
46 if node.op == 'INTTOREAL': 43 if node.op == 'INTTOREAL':
76 if node.obj.typ.isType(integer): 73 if node.obj.typ.isType(integer):
77 if type(node.obj) is Constant: 74 if type(node.obj) is Constant:
78 self.genexprcode(node.obj) 75 self.genexprcode(node.obj)
79 node.reg = node.obj.reg 76 node.reg = node.obj.reg
80 else: 77 else:
81 self.getreg(node) 78 pass
82 # Get a register to store the integer value 79 # Get a register to store the integer value
83 if node.obj.isLocal:
84 # relative to rbp:
85 self.addCode( mov(node.reg, ['rbp', node.obj.offset]) )
86 else:
87 self.addCode(mov(node.reg, ['RIP', 0x0]))
88 self.fixCode(self.rip-4, imm32(node.obj.offset - self.rip))
89 else: 80 else:
90 Error('Cannot load variable type {0}'.format(node.typ)) 81 Error('Cannot load variable type {0}'.format(node.typ))
91 82
92 elif isinstance(node, Relop): 83 elif isinstance(node, Relop):
93 # Create a boolean from operands 84 # Create a boolean from operands
99 self.freereg(node.b) 90 self.freereg(node.b)
100 else: 91 else:
101 Error('Relop not implemented for {0}'.format(node.a.typ)) 92 Error('Relop not implemented for {0}'.format(node.a.typ))
102 93
103 elif type(node) is Constant: 94 elif type(node) is Constant:
104 if node.typ.isType(integer): 95 print('TODO: constant')
105 self.getreg(node)
106 96
107 elif type(node) is ProcedureCall: 97 elif type(node) is ProcedureCall:
108 if type(node.proc.obj) is BuiltinProcedure: 98 Error('TODO: proc call')
109 # Handle builtin procedures different, these not always call
110 # a function, but generate code.
111 bi = node.proc.obj
112 if bi.name == 'chr':
113 arg = node.args[0]
114 self.genexprcode(arg)
115 # Store character in full width register:
116 # TODO: store in char only register
117 node.reg = arg.reg
118 else:
119 Error('Unknown builtin function {0}'.format(bi.name))
120 else:
121 # Use generic procedure call first
122 self.gencode(node)
123 # Retrieve result:
124 if node.typ.isType(integer):
125 # Store result!
126 self.getreg(node)
127 self.addCode( mov(node.reg, 'rax') )
128 else:
129 Error('Return type not supported {0}'.format(node.typ))
130 else: 99 else:
131 Error('Cannot generate expression code for: {0}'.format(node)) 100 Error('Cannot generate expression code for: {0}'.format(node))
132 101
133 def gencode(self, node): 102 def gencode(self, node):
134 """ Code generation function for AST nodes """ 103 """ Code generation function for AST nodes """
135 if isinstance(node, Module): 104 if isinstance(node, Module):
136 # TODO: recurse! 105 # TODO: recurse!
137 return core.Module() 106
107 self.mod = core.Module()
108 # Create a function called init for this module:
109 ftype = core.FunctionType(self.context.VoidType, [])
110 func = core.Function(ftype, "init", self.mod)
111 bb = self.gencode(node.initcode)
112 self.mod.dump()
113 return self.mod
138 114
139 elif type(node) is Procedure: 115 elif type(node) is Procedure:
140 # calculate offsets for local variables and parameters 116 # calculate offsets for local variables and parameters
141 # Variable location relative to 'rbp' register 117 # Variable location relative to 'rbp' register
142 variables = node.symtable.getAllLocal(Variable) 118 variables = node.symtable.getAllLocal(Variable)
143 offset = 0
144 paramoffset = 16
145 for var in variables:
146 var.isLocal = True
147 if not var.isParameter:
148 offset += var.typ.size
149 # Offset is negative of rbp in stack frame
150 var.offset = -offset
151 node.framesize = offset
152 # Calculate offsets of parameters relative to rbp register
153 for par in reversed(node.typ.parameters):
154 pvar = node.symtable.getLocal(Variable, par.name)
155 pvar.offset = paramoffset
156 paramoffset += pvar.typ.size
157
158 # code generation
159 node.entrypoint = self.rip
160 self.addCode(push('rbp'))
161 self.addCode(mov('rbp', 'rsp')) # Setup the base pointer
162 self.addCode(subreg64('rsp', node.framesize)) # reserve space for locals
163 self.gencode(node.block)
164 if node.retexpr:
165 if node.retexpr.typ.isType(integer):
166 self.genexprcode(node.retexpr)
167 self.addCode( mov('rax', node.retexpr.reg) )
168 self.freereg(node.retexpr)
169 else:
170 Error('Cannot return this kind yet {0}'.format(node.retexpr.typ))
171 self.addCode( addreg64('rsp', node.framesize) )
172 self.addCode( pop('rbp') )
173 self.addCode( ret() )
174 assert(len(self.usedregs) == 0)
175 119
176 elif isinstance(node, StatementSequence): 120 elif isinstance(node, StatementSequence):
177 for s in node.statements: 121 for s in node.statements:
178 self.gencode(s) 122 self.gencode(s)
179 123
180 elif type(node) is ProcedureCall: 124 elif type(node) is ProcedureCall:
181 # Prepare parameters on the stack: 125 # Prepare parameters on the stack:
182 stacksize = 0
183 assert(len(node.args) == len(node.proc.typ.parameters)) 126 assert(len(node.args) == len(node.proc.typ.parameters))
184 for arg, param in zip(node.args, node.proc.typ.parameters): 127 for arg, param in zip(node.args, node.proc.typ.parameters):
185 128
186 if param.kind == 'value': 129 if param.kind == 'value':
187 self.genexprcode(arg) 130 self.genexprcode(arg)
189 self.freereg( arg ) 132 self.freereg( arg )
190 stacksize += 8 133 stacksize += 8
191 else: 134 else:
192 Error('Parameter kind other than value') 135 Error('Parameter kind other than value')
193 136
194 # Calculate address using designator
195 if type(node.proc.obj) is Procedure:
196 self.addCode( call(0x0) )
197 self.fixCode( self.rip - 4, imm32(node.proc.obj.entrypoint - self.rip))
198 elif type(node.proc.obj) is ImportedSymbol:
199 # Load the entry point of the import table
200 self.getreg(node.proc.obj)
201 # Load the address of the procedure:
202 self.addCode( mov(node.proc.obj.reg, ['RIP', 0x0]) )
203 self.fixCode( self.rip - 4, imm32(node.proc.obj.offset - self.rip) )
204 # Call to the address in register:
205 self.addCode( call(node.proc.obj.reg) )
206 # Free register that holds the address of the object
207 self.freereg( node.proc.obj )
208 elif type(node.proc.obj) is BuiltinProcedure:
209 if node.proc.obj.name == 'chr':
210 print('int to char')
211 else:
212 Error('Unknown builtin function {0}'.format(node.proc.obj.name))
213 else:
214 Error('Cannot call designator of type {0}'.format(node.proc.obj))
215
216 # Restore stack (pop all arguments of):
217 self.addCode(addreg64('rsp', stacksize))
218
219 elif type(node) is Assignment: 137 elif type(node) is Assignment:
220 if node.lval.typ.isType(integer): 138 if node.lval.typ.isType(integer):
221 # TODO if node.rval is Constant of some datatype, move it to mem directly 139 # TODO if node.rval is Constant of some datatype, move it to mem directly
222 self.genexprcode(node.rval) # Calculate the value that has to be stored. 140 self.genexprcode(node.rval) # Calculate the value that has to be stored.
223 self.storeRegInDesignator(node.rval.reg, node.lval) 141 print("TODO")
224 self.freereg(node.rval)
225 else: 142 else:
226 Error('Assignments of other types not implemented') 143 Error('Assignments of other types not implemented')
227 # TODO if left and right are designators, do some sort of memcpy. 144 # TODO if left and right are designators, do some sort of memcpy.
228 145
229 elif type(node) is IfStatement: 146 elif type(node) is IfStatement:
230 self.genexprcode(node.condition) 147 self.genexprcode(node.condition)
231 self.addCode( cmpreg64(node.condition.reg, 1) ) 148 print("TODO IF")
232 self.freereg(node.condition)
233 if node.falsestatement: 149 if node.falsestatement:
234 # If with else clause 150 # If with else clause
235 self.addCode( nearjump(0x0, condition='NE') ) # if Not Equal jump to false 151 pass
236 rip1 = self.rip
237 fixloc1 = self.rip - 4
238 self.gencode(node.truestatement)
239 self.addCode( nearjump( 0x0 ) ) # jump over false code
240 fixloc2 = self.rip - 4
241 self.fixCode(fixloc1, imm32(self.rip - rip1))
242 rip2 = self.rip
243 self.gencode(node.falsestatement)
244 self.fixCode(fixloc2, imm32(self.rip - rip2))
245 else: 152 else:
246 # If without else clause 153 # If without else clause
247 self.addCode( nearjump(0x0, condition='NE') ) # if Not Equal jump to false 154 pass
248 rip1 = self.rip
249 fixloc1 = self.rip - 4
250 self.gencode(node.truestatement)
251 self.fixCode(fixloc1, imm32(self.rip - rip1)) # Fixup near jump over true code.
252 155
253 elif isinstance(node, WhileStatement): 156 elif isinstance(node, WhileStatement):
254 rip1 = self.rip # Store the start of the while loop
255 self.genexprcode(node.condition) 157 self.genexprcode(node.condition)
256 self.addCode( cmpreg64(node.condition.reg, 1) ) # Test condition for true-ness
257 self.freereg(node.condition)
258 self.addCode( nearjump(0x0, condition='NE') ) # If Not Equal jump over while code AND jump back (fix later)
259 fixloc1 = self.rip - 4
260 rip2 = self.rip
261 self.gencode(node.dostatements) 158 self.gencode(node.dostatements)
262 self.addCode( nearjump(0x0) ) # JMP to condition, fix exact jump position below
263 fixloc2 = self.rip - 4
264 rip3 = self.rip # end of while loop
265 self.fixCode(fixloc2, imm32(rip1 - rip3)) # Fixup jump to start of while loop
266 self.fixCode(fixloc1, imm32(rip3 - rip2)) # Fixup jump out of while loop
267
268 elif type(node) is ForStatement: 159 elif type(node) is ForStatement:
269 # Initial load of iterator variable: 160 # Initial load of iterator variable:
270 self.genexprcode(node.begin) 161 self.genexprcode(node.begin)
271 self.genexprcode(node.end) 162 self.genexprcode(node.end)
272 # TODO: link reg with variable so that a register is used instead of a variable
273 iterreg = node.begin.reg # Get the register used for the loop
274 #self.addCode(cmpreg64(iterreg, node.endvalue))
275 rip1 = self.rip
276 self.gencode(node.statements) 163 self.gencode(node.statements)
277 #self.loadDesignatorInReg(node.
278 #self.addCode( addreg64(node.variable, node.increment) )
279 self.addCode(nearjump(0x0))
280 fixloc1 = self.rip - 4
281 rip2 = self.rip
282 self.fixCode(fixloc1, imm32(rip1 - rip2))
283
284 self.freereg(node.begin) # Release register used in loop
285 self.freereg(node.end)
286 Error('No implementation of FOR statement') 164 Error('No implementation of FOR statement')
287 165
288 elif type(node) is AsmCode: 166 elif type(node) is AsmCode:
289 def processOperand(op): 167 def processOperand(op):
290 if type(op) is list: 168 if type(op) is list:
323 # Loop over all designators.. 201 # Loop over all designators..
324 for selector in node.selectors: 202 for selector in node.selectors:
325 if type(selector) is Index: 203 if type(selector) is Index:
326 # Deref an array index 204 # Deref an array index
327 self.genexprcode(selector.index) 205 self.genexprcode(selector.index)
328 self.getreg(selector)
329 self.addCode( mov(selector.reg, selector.typ.elementType.size) )
330 self.addCode( imulreg64(selector.reg, selector.index.reg ) )
331 self.freereg(selector.index)
332 self.addCode(addreg64(node.reg, selector.reg))
333 self.freereg(selector) 206 self.freereg(selector)
334 elif type(selector) is Field: 207 elif type(selector) is Field:
335 print('Field') 208 print('Field')
336 Error('Field not implemented') 209 Error('Field not implemented')
337 else: 210 else:
338 Error('Unknown selector') 211 Error('Unknown selector')
339 else: 212 else:
340 Error('Can only gencode for designator with selectors') 213 Error('Can only gencode for designator with selectors')
341
342 else: 214 else:
343 print('not generating code for {0}'.format(node)) 215 print('not generating code for {0}'.format(node))
344 216
345 def generateIr(self, ast): 217 def generateIr(self, context, ast):
346 """ ir generation front end """ 218 """ ir generation front end """
219 # Create a new context for this code.
220 self.context = context
347 return self.gencode(ast) 221 return self.gencode(ast)
348 222