Mercurial > lcfOS
diff 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 |
line wrap: on
line diff
--- a/python/ppci/frontends/ks/irgenerator.py Wed Dec 26 10:53:33 2012 +0100 +++ b/python/ppci/frontends/ks/irgenerator.py Sun Dec 30 22:31:55 2012 +0100 @@ -6,7 +6,6 @@ from ...core.errors import Error from ... import core from .builtin import real, integer, boolean, char -#from .assembler import * class KsIrGenerator: def __init__(self): @@ -26,19 +25,17 @@ if node.op == 'mod': assert(node.typ.isType(integer)) - self.addCode(mov('rax', node.a.reg)) elif node.op == 'div': assert(node.typ.isType(integer)) - self.addCode(mov('rax', node.a.reg)) elif node.op == '*': if node.typ.isType(integer): - self.addCode(imulreg64(node.a.reg, node.b.reg)) + pass elif node.op == '+': if node.typ.isType(integer): - self.addCode(addreg64(node.a.reg, node.b.reg)) + pass elif node.op == '-': if node.typ.isType(integer): - self.addCode(subreg64(node.a.reg, node.b.reg)) + pass else: Error('Unknown Binop {0}'.format(node.op)) @@ -78,14 +75,8 @@ self.genexprcode(node.obj) node.reg = node.obj.reg else: - self.getreg(node) + pass # Get a register to store the integer value - if node.obj.isLocal: - # relative to rbp: - self.addCode( mov(node.reg, ['rbp', node.obj.offset]) ) - else: - self.addCode(mov(node.reg, ['RIP', 0x0])) - self.fixCode(self.rip-4, imm32(node.obj.offset - self.rip)) else: Error('Cannot load variable type {0}'.format(node.typ)) @@ -101,32 +92,10 @@ Error('Relop not implemented for {0}'.format(node.a.typ)) elif type(node) is Constant: - if node.typ.isType(integer): - self.getreg(node) + print('TODO: constant') elif type(node) is ProcedureCall: - if type(node.proc.obj) is BuiltinProcedure: - # Handle builtin procedures different, these not always call - # a function, but generate code. - bi = node.proc.obj - if bi.name == 'chr': - arg = node.args[0] - self.genexprcode(arg) - # Store character in full width register: - # TODO: store in char only register - node.reg = arg.reg - else: - Error('Unknown builtin function {0}'.format(bi.name)) - else: - # Use generic procedure call first - self.gencode(node) - # Retrieve result: - if node.typ.isType(integer): - # Store result! - self.getreg(node) - self.addCode( mov(node.reg, 'rax') ) - else: - Error('Return type not supported {0}'.format(node.typ)) + Error('TODO: proc call') else: Error('Cannot generate expression code for: {0}'.format(node)) @@ -134,44 +103,19 @@ """ Code generation function for AST nodes """ if isinstance(node, Module): # TODO: recurse! - return core.Module() + + self.mod = core.Module() + # Create a function called init for this module: + ftype = core.FunctionType(self.context.VoidType, []) + func = core.Function(ftype, "init", self.mod) + bb = self.gencode(node.initcode) + self.mod.dump() + return self.mod elif type(node) is Procedure: # calculate offsets for local variables and parameters # Variable location relative to 'rbp' register variables = node.symtable.getAllLocal(Variable) - offset = 0 - paramoffset = 16 - for var in variables: - var.isLocal = True - if not var.isParameter: - offset += var.typ.size - # Offset is negative of rbp in stack frame - var.offset = -offset - node.framesize = offset - # Calculate offsets of parameters relative to rbp register - for par in reversed(node.typ.parameters): - pvar = node.symtable.getLocal(Variable, par.name) - pvar.offset = paramoffset - paramoffset += pvar.typ.size - - # code generation - node.entrypoint = self.rip - self.addCode(push('rbp')) - self.addCode(mov('rbp', 'rsp')) # Setup the base pointer - self.addCode(subreg64('rsp', node.framesize)) # reserve space for locals - self.gencode(node.block) - if node.retexpr: - if node.retexpr.typ.isType(integer): - self.genexprcode(node.retexpr) - self.addCode( mov('rax', node.retexpr.reg) ) - self.freereg(node.retexpr) - else: - Error('Cannot return this kind yet {0}'.format(node.retexpr.typ)) - self.addCode( addreg64('rsp', node.framesize) ) - self.addCode( pop('rbp') ) - self.addCode( ret() ) - assert(len(self.usedregs) == 0) elif isinstance(node, StatementSequence): for s in node.statements: @@ -179,7 +123,6 @@ elif type(node) is ProcedureCall: # Prepare parameters on the stack: - stacksize = 0 assert(len(node.args) == len(node.proc.typ.parameters)) for arg, param in zip(node.args, node.proc.typ.parameters): @@ -191,98 +134,33 @@ else: Error('Parameter kind other than value') - # Calculate address using designator - if type(node.proc.obj) is Procedure: - self.addCode( call(0x0) ) - self.fixCode( self.rip - 4, imm32(node.proc.obj.entrypoint - self.rip)) - elif type(node.proc.obj) is ImportedSymbol: - # Load the entry point of the import table - self.getreg(node.proc.obj) - # Load the address of the procedure: - self.addCode( mov(node.proc.obj.reg, ['RIP', 0x0]) ) - self.fixCode( self.rip - 4, imm32(node.proc.obj.offset - self.rip) ) - # Call to the address in register: - self.addCode( call(node.proc.obj.reg) ) - # Free register that holds the address of the object - self.freereg( node.proc.obj ) - elif type(node.proc.obj) is BuiltinProcedure: - if node.proc.obj.name == 'chr': - print('int to char') - else: - Error('Unknown builtin function {0}'.format(node.proc.obj.name)) - else: - Error('Cannot call designator of type {0}'.format(node.proc.obj)) - - # Restore stack (pop all arguments of): - self.addCode(addreg64('rsp', stacksize)) - elif type(node) is Assignment: if node.lval.typ.isType(integer): # TODO if node.rval is Constant of some datatype, move it to mem directly self.genexprcode(node.rval) # Calculate the value that has to be stored. - self.storeRegInDesignator(node.rval.reg, node.lval) - self.freereg(node.rval) + print("TODO") else: Error('Assignments of other types not implemented') # TODO if left and right are designators, do some sort of memcpy. elif type(node) is IfStatement: self.genexprcode(node.condition) - self.addCode( cmpreg64(node.condition.reg, 1) ) - self.freereg(node.condition) + print("TODO IF") if node.falsestatement: # If with else clause - self.addCode( nearjump(0x0, condition='NE') ) # if Not Equal jump to false - rip1 = self.rip - fixloc1 = self.rip - 4 - self.gencode(node.truestatement) - self.addCode( nearjump( 0x0 ) ) # jump over false code - fixloc2 = self.rip - 4 - self.fixCode(fixloc1, imm32(self.rip - rip1)) - rip2 = self.rip - self.gencode(node.falsestatement) - self.fixCode(fixloc2, imm32(self.rip - rip2)) + pass else: # If without else clause - self.addCode( nearjump(0x0, condition='NE') ) # if Not Equal jump to false - rip1 = self.rip - fixloc1 = self.rip - 4 - self.gencode(node.truestatement) - self.fixCode(fixloc1, imm32(self.rip - rip1)) # Fixup near jump over true code. + pass elif isinstance(node, WhileStatement): - rip1 = self.rip # Store the start of the while loop self.genexprcode(node.condition) - self.addCode( cmpreg64(node.condition.reg, 1) ) # Test condition for true-ness - self.freereg(node.condition) - self.addCode( nearjump(0x0, condition='NE') ) # If Not Equal jump over while code AND jump back (fix later) - fixloc1 = self.rip - 4 - rip2 = self.rip self.gencode(node.dostatements) - self.addCode( nearjump(0x0) ) # JMP to condition, fix exact jump position below - fixloc2 = self.rip - 4 - rip3 = self.rip # end of while loop - self.fixCode(fixloc2, imm32(rip1 - rip3)) # Fixup jump to start of while loop - self.fixCode(fixloc1, imm32(rip3 - rip2)) # Fixup jump out of while loop - elif type(node) is ForStatement: # Initial load of iterator variable: self.genexprcode(node.begin) self.genexprcode(node.end) - # TODO: link reg with variable so that a register is used instead of a variable - iterreg = node.begin.reg # Get the register used for the loop - #self.addCode(cmpreg64(iterreg, node.endvalue)) - rip1 = self.rip self.gencode(node.statements) - #self.loadDesignatorInReg(node. - #self.addCode( addreg64(node.variable, node.increment) ) - self.addCode(nearjump(0x0)) - fixloc1 = self.rip - 4 - rip2 = self.rip - self.fixCode(fixloc1, imm32(rip1 - rip2)) - - self.freereg(node.begin) # Release register used in loop - self.freereg(node.end) Error('No implementation of FOR statement') elif type(node) is AsmCode: @@ -325,11 +203,6 @@ if type(selector) is Index: # Deref an array index self.genexprcode(selector.index) - self.getreg(selector) - self.addCode( mov(selector.reg, selector.typ.elementType.size) ) - self.addCode( imulreg64(selector.reg, selector.index.reg ) ) - self.freereg(selector.index) - self.addCode(addreg64(node.reg, selector.reg)) self.freereg(selector) elif type(selector) is Field: print('Field') @@ -338,11 +211,12 @@ Error('Unknown selector') else: Error('Can only gencode for designator with selectors') - else: print('not generating code for {0}'.format(node)) - def generateIr(self, ast): + def generateIr(self, context, ast): """ ir generation front end """ + # Create a new context for this code. + self.context = context return self.gencode(ast)