[pypy-svn] r53028 - in pypy/branch/jit-hotpath/pypy/jit/codegen/ia32: . test

fijal at codespeak.net fijal at codespeak.net
Fri Mar 28 01:01:29 CET 2008


Author: fijal
Date: Fri Mar 28 01:01:26 2008
New Revision: 53028

Added:
   pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/operation.py   (contents, props changed)
   pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/regalloc.py   (contents, props changed)
   pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/rgenop.py   (contents, props changed)
   pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/test/test_rgenop.py   (contents, props changed)
Log:
First test passes. Not sure why yet, but will look at it.


Added: pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/operation.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/operation.py	Fri Mar 28 01:01:26 2008
@@ -0,0 +1,77 @@
+
+from pypy.jit.codegen.i386.ri386 import *
+from pypy.jit.codegen.model import GenVar
+from pypy.rlib.objectmodel import specialize
+from pypy.rpython.lltypesystem import lltype
+
+class Operation(GenVar):
+    pass
+
+class Op1(Operation):
+    def __init__(self, x):
+        self.x = x
+
+class Op2(Operation):
+    def __init__(self, x, y):
+        self.x = x
+        self.y = y
+
+class OpIntAdd(Op2):
+    opname = "int_add"
+
+    def render(self, allocator, mc):
+        p1 = allocator.get_position(self.x)
+        p2 = allocator.get_position(self.y)
+        mc.ADD(p1, p2)
+        allocator.set_position(self, p1)
+
+def setup_opclasses(base):
+    d = {}
+    for name, value in globals().items():
+        if type(value) is type(base) and issubclass(value, base):
+            opnames = getattr(value, 'opname', ())
+            if isinstance(opnames, str):
+                opnames = (opnames,)
+            for opname in opnames:
+                assert opname not in d
+                d[opname] = value
+    return d
+OPCLASSES1 = setup_opclasses(Op1)
+OPCLASSES2 = setup_opclasses(Op2)
+del setup_opclasses
+
+ at specialize.memo()
+def getopclass1(opname):
+    try:
+        return OPCLASSES1[opname]
+    except KeyError:
+        raise MissingBackendOperation(opname)
+
+ at specialize.memo()
+def getopclass2(opname):
+    try:
+        return OPCLASSES2[opname]
+    except KeyError:
+        raise MissingBackendOperation(opname)
+
+class OpCall(Operation):
+    def __init__(self, sigtoken, gv_fnptr, args_gv):
+        self.sigtoken = sigtoken
+        self.gv_fnptr = gv_fnptr
+        self.args_gv = args_gv
+
+    def render(self, allocator, mc):
+        fnptr = self.gv_fnptr
+        assert fnptr.is_const
+        stack_pos = 0
+        for i in range(len(self.args_gv)):
+            gv = self.args_gv[i]
+            src = allocator.get_position(gv)
+            if not isinstance(src, MODRM):
+                mc.MOV(mem(esp, stack_pos), src)
+            else:
+                mc.MOV(eax, src)
+                mc.MOV(mem(esp, stack_pos), eax)
+            stack_pos += gv.SIZE
+        mc.CALL(rel32(fnptr.value))
+        allocator.set_position(self, eax)

Added: pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/regalloc.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/regalloc.py	Fri Mar 28 01:01:26 2008
@@ -0,0 +1,24 @@
+
+from pypy.jit.codegen.i386.ri386 import *
+
+class RegAlloc(object):
+    def __init__(self, operations):
+        self.operations = operations
+        self.positions = {}
+
+    def set_position(self, var, pos):
+        self.positions[var] = pos
+
+    def get_position(self, v):
+        from pypy.jit.codegen.ia32.rgenop import IntConst
+        if v.is_const:
+            if type(v) is IntConst: 
+                return imm(v.value)
+            else:
+                xxx
+        else:
+            return self.positions[v]
+
+    def generate_operations(self, mc):
+        for operation in self.operations:
+            operation.render(self, mc)

Added: pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/rgenop.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/rgenop.py	Fri Mar 28 01:01:26 2008
@@ -0,0 +1,163 @@
+
+from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
+from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
+from pypy.jit.codegen.model import ReplayBuilder, dummy_var
+from pypy.rlib.objectmodel import specialize
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.jit.codegen.ia32.operation import *
+from pypy.jit.codegen.ia32.regalloc import RegAlloc
+# XXX explain
+from pypy.jit.codegen.i386.regalloc import write_stack_reserve
+
+WORD = 4
+PROLOGUE_FIXED_WORDS = 5
+
+class IntConst(GenConst):
+    def __init__(self, value):
+        self.value = value
+
+    def repr(self):
+        return "const=$%s" % (self.value,)
+
+class IntVar(GenVar):
+    token = "i"
+    ll_type = lltype.Signed
+    SIZE = WORD
+
+class FloatVar(GenVar):
+    token = "f"
+    ll_type = lltype.Float
+    SIZE = 8 # XXX really?
+
+LL_TO_GENVAR = {}
+TOKEN_TO_GENVAR = {}
+for value in locals().values():
+    if hasattr(value, 'll_type'):
+        LL_TO_GENVAR[value.ll_type] = value.token
+        TOKEN_TO_GENVAR[value.token] = value
+
+class Builder(GenBuilder):
+    def __init__(self, rgenop, inputoperands, inputvars):
+        self.rgenop = rgenop
+        self.operations = []
+        self.inputoperands = inputoperands
+        self.inputvars = inputvars
+
+    def genop_call(self, sigtoken, gv_fnptr, args_gv):
+        op = OpCall(sigtoken, gv_fnptr, list(args_gv))
+        self.operations.append(op)
+        return op
+
+    def start_mc(self):
+        mc = self.rgenop.open_mc()
+        # XXX we completely ignore additional logic that would generate a jump
+        #     to another block if we run out of space
+        return mc
+
+    @specialize.arg(1)
+    def genop2(self, opname, gv_arg1, gv_arg2):
+        cls = getopclass2(opname)
+        op = cls(gv_arg1, gv_arg2)
+        self.operations.append(op)
+        return op
+
+    def finish_and_return(self, sigtoken, gv_returnvar):
+        mc = self.start_mc()
+        regalloc = RegAlloc(self.operations)
+        for i in range(len(self.inputoperands)):
+            inp_loc = self.inputoperands[i]
+            inp_gv = self.inputvars[i]
+            regalloc.set_position(inp_gv, inp_loc)
+        regalloc.generate_operations(mc)
+        # --- epilogue ---
+        mc.MOV(esp, ebp)
+        mc.POP(ebp)
+        mc.POP(edi)
+        mc.POP(esi)
+        mc.POP(ebx)
+        mc.RET()
+        # ----------------
+        mc.done()
+        self.rgenop.close_mc(mc)
+
+    def end(self):
+        pass
+
+class RI386GenOp(AbstractRGenOp):
+    from pypy.jit.codegen.i386.codebuf import MachineCodeBlock
+    from pypy.jit.codegen.i386.codebuf import InMemoryCodeBuilder
+
+    MC_SIZE = 65536 * 16
+
+    def __init__(self):
+        self.allocated_mc = None
+        self.keepalive_gc_refs = [] 
+
+    def open_mc(self):
+        # XXX supposed infinite for now
+        mc = self.allocated_mc
+        if mc is None:
+            return self.MachineCodeBlock(self.MC_SIZE)
+        else:
+            self.allocated_mc = None
+            return mc
+
+    def close_mc(self, mc):
+        assert self.allocated_mc is None
+        self.allocated_mc = mc
+
+    @specialize.genconst(1)
+    def genconst(self, llvalue):
+        T = lltype.typeOf(llvalue)
+        if T is llmemory.Address:
+            return AddrConst(llvalue)
+        elif T is lltype.Signed:
+            return IntConst(llvalue)
+        elif isinstance(T, lltype.Ptr):
+            lladdr = llmemory.cast_ptr_to_adr(llvalue)
+            if T.TO._gckind == 'gc':
+                self.keepalive_gc_refs.append(lltype.cast_opaque_ptr(llmemory.GCREF, llvalue))
+            return AddrConst(lladdr)
+        else:
+            raise NotImplementedError(llvalue)
+
+    def newgraph(self, sigtoken, name):
+        mc = self.open_mc()
+        entrypoint = mc.tell()
+        # push on stack some registers
+        mc.PUSH(ebx)
+        mc.PUSH(esi)
+        mc.PUSH(edi)
+        mc.PUSH(ebp)
+        mc.MOV(ebp, esp)
+        # XXX <I don't understand this>
+        write_stack_reserve(mc, 4)
+        # XXX <I don't understand this/>
+        inputargs_gv = [TOKEN_TO_GENVAR[i]() for i in sigtoken[0]]
+        ofs = WORD * PROLOGUE_FIXED_WORDS
+        inputoperands = []
+        for i in range(len(inputargs_gv)):
+            input_gv = inputargs_gv[i]
+            inputoperands.append(mem(ebp, ofs))
+            ofs += input_gv.SIZE
+        builder = Builder(self, inputoperands, inputargs_gv)
+        mc.done()
+        self.close_mc(mc)
+        # XXX copy?
+        return builder, IntConst(entrypoint), inputargs_gv
+
+    @staticmethod
+    @specialize.memo()
+    def kindToken(T):
+        # XXX this will die eventually
+        return None
+
+    @staticmethod
+    @specialize.memo()
+    def sigToken(FUNCTYPE):
+        # XXX we need to make this RPython probably
+        return ([LL_TO_GENVAR[arg] for arg in FUNCTYPE.ARGS],
+                LL_TO_GENVAR[FUNCTYPE.RESULT])
+
+    def check_no_open_mc(self):
+        pass

Added: pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/test/test_rgenop.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-hotpath/pypy/jit/codegen/ia32/test/test_rgenop.py	Fri Mar 28 01:01:26 2008
@@ -0,0 +1,11 @@
+import py
+from pypy.rpython.lltypesystem import lltype
+from pypy.jit.codegen.ia32.rgenop import RI386GenOp
+from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests
+
+class TestRI386Genop(AbstractRGenOpTests):
+    RGenOp = RI386GenOp
+    from pypy.jit.codegen.i386.test.test_operation import RGenOpPacked
+
+    # for the individual tests see
+    # ====> ../../test/rgenop_tests.py



More information about the Pypy-commit mailing list