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)