[pypy-svn] r56879 - in pypy/branch/oo-jit/pypy/jit/codegen/x86_64: . test

witulski at codespeak.net witulski at codespeak.net
Thu Jul 31 17:31:49 CEST 2008


Author: witulski
Date: Thu Jul 31 17:31:48 2008
New Revision: 56879

Added:
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py
   pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py
Log:
(cfbolz, witulski) start the actual jit backend.
a very simple example adding two integers works.


Added: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py
==============================================================================
--- (empty file)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/codebuf.py	Thu Jul 31 17:31:48 2008
@@ -0,0 +1,34 @@
+import os
+from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.jit.codegen.x86_64.assembler import X86_64CodeBuilder
+#from ri386 import I386CodeBuilder
+
+modname = 'pypy.jit.codegen.i386.codebuf_' + os.name
+memhandler = __import__(modname, globals(), locals(), ['__doc__'])
+
+PTR = memhandler.PTR
+
+class InMemoryCodeBuilder(X86_64CodeBuilder):
+
+    def __init__(self, map_size):
+        data = memhandler.alloc(map_size)
+        self._data = data
+        self._size = map_size
+        self._pos = 0
+        self._all = []
+
+    def write(self, data):
+        p = self._pos
+        if p + len(data) > self._size:
+            raise CodeBlockOverflow
+        for c in data:
+            self._data[p] = c
+            p += 1
+        self._all.append(data)
+        self._pos = p
+
+    def tell(self):
+        baseaddr = rffi.cast(lltype.Signed, self._data)
+        return baseaddr + self._pos
+
+

Added: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py
==============================================================================
--- (empty file)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/objmodel.py	Thu Jul 31 17:31:48 2008
@@ -0,0 +1,10 @@
+from pypy.jit.codegen import model
+
+
+class IntVar(model.GenVar):
+    def __init__(self, reg):
+        self.reg = reg
+
+class Const(model.GenConst):
+    def __init__(self, value):
+        self.value = value
\ No newline at end of file

Added: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py
==============================================================================
--- (empty file)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/rgenop.py	Thu Jul 31 17:31:48 2008
@@ -0,0 +1,74 @@
+from pypy.jit.codegen import model
+from pypy.rlib.objectmodel import specialize
+from pypy.jit.codegen.x86_64.objmodel import IntVar, Const
+from pypy.jit.codegen.x86_64.codebuf import InMemoryCodeBuilder
+
+class Builder(model.GenBuilder):
+
+    MC_SIZE = 65536
+
+    def __init__(self):
+        self.mc = InMemoryCodeBuilder(self.MC_SIZE)
+        self.freeregisters ={        
+                "rax":None,
+                "rcx":None,
+                "rdx":None,
+              #  "rbx":None,
+                "rsi":None,
+                "rdi":None,
+                "r8": None,
+                "r9": None,
+                "r10":None,
+               # "r11":None,
+               # "r12":None,
+               # "r13":None,
+               # "r14":None,
+               # "r15":None,
+               }
+        
+    @specialize.arg(1)
+    def genop1(self, opname, gv_arg):
+        genmethod = getattr(self, 'op_' + opname)
+        return genmethod(gv_arg)
+
+    @specialize.arg(1)
+    def genop2(self, opname, gv_arg1, gv_arg2):
+        genmethod = getattr(self, 'op_' + opname)
+        return genmethod(gv_arg1, gv_arg2)
+    
+    def op_int_add(self, gv_x, gv_y):
+        gv_z = self.allocate_register()
+        self.mc.MOV(gv_z.reg, gv_x.reg)
+        self.mc.ADD(gv_z.reg, gv_y.reg)
+        return gv_z
+    
+    def finish_and_return(self, sigtoken, gv_returnvar):
+        #self.mc.write("\xB8\x0F\x00\x00\x00")
+        self.mc.MOV("rax", gv_returnvar.reg)
+        self.mc.RET()
+    
+    def allocate_register(self, register=None):
+        if register is None:
+            return IntVar(self.freeregisters.popitem()[0])
+        else:
+            del self.freeregisters[register]
+            return IntVar(register)
+        
+
+class RX86_64GenOp(model.AbstractRGenOp):
+
+
+    @staticmethod
+    @specialize.memo()
+    def sigToken(FUNCTYPE):
+        return None
+    
+    def newgraph(self, sigtoken, name):
+        # XXX for now assume that all functions take two ints and return an int
+        builder = Builder()
+        inputargs_gv = [builder.allocate_register("rdi"),
+                        builder.allocate_register("rsi")]
+        #XXX
+        entrypoint = Const(builder.mc.tell())
+        return builder, entrypoint, inputargs_gv
+    

Added: pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py
==============================================================================
--- (empty file)
+++ pypy/branch/oo-jit/pypy/jit/codegen/x86_64/test/test_simple.py	Thu Jul 31 17:31:48 2008
@@ -0,0 +1,32 @@
+from pypy.jit.codegen.x86_64.rgenop import RX86_64GenOp
+from pypy.rpython.lltypesystem import lltype
+from ctypes import cast, c_void_p, CFUNCTYPE, c_long, c_double
+
+def make_testbuilder():
+    rgenop = RX86_64GenOp()
+    FUNC = lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed) #the funtiontype(arguments,returntype) of the graph we will create
+    token = rgenop.sigToken(FUNC)
+    builder, entrypoint, inputargs_gv = rgenop.newgraph(token, "test")
+    builder.start_writing() 
+    ctypestypes = [c_long, c_long]
+    fp = cast(c_void_p(entrypoint.value),
+              CFUNCTYPE(c_long, *ctypestypes))
+    return builder, fp, inputargs_gv, token
+
+def test_add():
+    builder, fp, inputargs_gv, token = make_testbuilder()
+    genv0 = inputargs_gv[0] #the first argument "place"
+    genv1 = inputargs_gv[1] 
+    genv_result = builder.genop2("int_add", genv0, genv1) #creates the addition and returns the place(register) of the result in genv_result
+    builder.finish_and_return(token, genv_result)
+    ten = fp(4, 6)
+    assert ten == 10
+    print ten
+    
+def test_ret():
+    builder, fp, inputargs_gv, token = make_testbuilder()
+    builder.finish_and_return(token, inputargs_gv[0])
+    print repr("".join(builder.mc._all))
+    four = fp(4, 17)
+    assert four == 4
+    print four
\ No newline at end of file



More information about the Pypy-commit mailing list