[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