[pypy-svn] r33455 - in pypy/dist/pypy/jit/codegen: ppc test

mwh at codespeak.net mwh at codespeak.net
Thu Oct 19 15:26:09 CEST 2006


Author: mwh
Date: Thu Oct 19 15:26:06 2006
New Revision: 33455

Modified:
   pypy/dist/pypy/jit/codegen/ppc/conftest.py
   pypy/dist/pypy/jit/codegen/ppc/rgenop.py
   pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
add another two tests to rgenop_tests, associated fixing and coding in
ppc/rgenop.
i'm generating _really_ bad assembly currently :)


Modified: pypy/dist/pypy/jit/codegen/ppc/conftest.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/conftest.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/conftest.py	Thu Oct 19 15:26:06 2006
@@ -14,3 +14,10 @@
                 py.test.skip('detected a %r CPU' % (processor,))
 
         return super(Directory, self).run()
+
+Option = py.test.Config.Option
+
+option = py.test.Config.addoptions("ppc options", 
+        Option('--trap', action="store_true", default=False, 
+               dest="trap", 
+               help=""))

Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py	(original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py	Thu Oct 19 15:26:06 2006
@@ -1,7 +1,8 @@
 from pypy.jit.codegen.model import AbstractRGenOp, CodeGenBlock, CodeGenerator
 from pypy.jit.codegen.model import GenVar, GenConst
 from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.objectmodel import specialize
+from pypy.rpython.objectmodel import specialize, we_are_translated
+from pypy.jit.codegen.ppc.conftest import option
 
 class VarLocation(object):
     pass
@@ -82,6 +83,33 @@
     self.mc.write(value)
 RPPCAssembler.emit = emit
 
+def prepare_for_jump(builder, outputargs_gv, targetblock):
+    assert len(targetblock.arg_locations) == len(outputargs_gv)
+    outregs = []
+    targetregs = []
+    for gv in outputargs_gv:
+        assert isinstance(gv, Var)
+        assert isinstance(gv.location, RegisterLocation)
+        outregs.append(gv.location.reg)
+    for loc in targetblock.arg_locations:
+        assert isinstance(loc, RegisterLocation)
+        targetregs.append(loc.reg)
+    for i in range(len(outregs)):
+        treg = targetregs[i]
+        oreg = outregs[i]
+        if oreg == treg:
+            continue
+        if treg in outregs:
+            outi = outregs.index(treg)
+            assert outi > i
+            builder.asm.xor(treg, treg, oreg)
+            builder.asm.xor(oreg, treg, oreg)
+            builder.asm.xor(treg, treg, oreg)
+            outregs[outi] = oreg
+            outregs[i] == treg
+        else:
+            builder.asm.mr(treg, oreg)
+
 class MachineCodeBlock:
 
     def __init__(self, map_size):
@@ -119,17 +147,20 @@
 
 class Builder(CodeGenerator):
 
-    def __init__(self, rgenop, mc, stackdepth):
+    def __init__(self, rgenop, mc, parent):
         self.rgenop = rgenop
-        self.stackdepth = stackdepth
         self.asm = RPPCAssembler()
         self.asm.mc = mc
-        self.curreg = 3
+        if parent is None:
+            self.curreg = 3
+        else:
+            self.curreg = parent.curreg
 
     def _write_prologue(self, sigtoken):
         numargs = sigtoken     # for now
         self.curreg += numargs
-        #self.asm.trap()
+        if not we_are_translated() and option.trap:
+            self.asm.trap()
         return [Var(RegisterLocation(pos)) for pos in range(3, 3+numargs)]
 
     def _close(self):
@@ -146,6 +177,14 @@
         self.asm.blr()
         self._close()
 
+    def finish_and_goto(self, outputargs_gv, targetblock):
+        prepare_for_jump(self, outputargs_gv, targetblock)
+        gv = self.newvar()
+        self.asm.load_word(gv.reg(), targetblock.startaddr)
+        self.asm.mtctr(gv.reg())
+        self.asm.bctr()
+        self._close()
+
     def enter_next_block(self, kinds, args_gv):
         arg_locations = []
         seen = {}
@@ -205,8 +244,17 @@
         self.asm.beqctr()
         return targetbuilder
 
+    def jump_if_true(self, gv_condition):
+        targetbuilder = self._fork()
+        gv = self.newvar()
+        self.asm.load_word(gv.reg(), targetbuilder.asm.mc.tell())
+        self.asm.mtctr(gv.reg())
+        self.asm.cmpwi(0, gv_condition.load(self), 0)
+        self.asm.bnectr()
+        return targetbuilder
+
     def _fork(self):
-        return self.rgenop.openbuilder(self.stackdepth)
+        return self.rgenop.openbuilder(self)
 
 
 class RPPCGenOp(AbstractRGenOp):
@@ -215,13 +263,8 @@
     def __init__(self):
         self.mcs = []   # machine code blocks where no-one is currently writing
 
-
-    def __init__(self):
-        self.mcs = []   # machine code blocks where no-one is currently writing
-
     def open_mc(self):
         if self.mcs:
-            # XXX think about inserting NOPS for alignment
             return self.mcs.pop()
         else:
             return MachineCodeBlock(65536)   # XXX supposed infinite for now
@@ -239,13 +282,13 @@
     def kindToken(T):
         return None     # for now
 
-    def openbuilder(self, stackdepth):
-        return Builder(self, self.open_mc(), stackdepth)
+    def openbuilder(self, parent):
+        return Builder(self, self.open_mc(), parent)
 
     def newgraph(self, sigtoken):
         numargs = sigtoken          # for now
         initialstackdepth = numargs+1
-        builder = self.openbuilder(initialstackdepth)
+        builder = self.openbuilder(None)
         entrypoint = builder.asm.mc.tell()
         inputargs_gv = builder._write_prologue(sigtoken)
         return builder, entrypoint, inputargs_gv

Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py	(original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py	Thu Oct 19 15:26:06 2006
@@ -95,6 +95,47 @@
     return branching_runner
 
 
+def make_goto(rgenop):
+    # while x > 0:
+    #     y += x
+    #     x -= 1
+    # return y
+    signed_kind = rgenop.kindToken(lltype.Signed)
+    sigtoken = rgenop.sigToken(FUNC2)
+    builder, entrypoint, [gv_x, gv_y] = rgenop.newgraph(sigtoken)
+
+    # loop start block
+    args_gv = [gv_x, gv_y]
+    loopblock = builder.enter_next_block([signed_kind, signed_kind], args_gv)
+    [gv_x, gv_y] = args_gv
+
+    gv_cond = builder.genop2("int_gt", gv_x, rgenop.genconst(0))
+    bodybuilder = builder.jump_if_true(gv_cond)
+    builder.finish_and_return(sigtoken, gv_y)
+
+    # loop body
+    args_gv = [gv_y, gv_x]
+    bodybuilder.enter_next_block([signed_kind, signed_kind], args_gv)
+    [gv_y, gv_x] = args_gv
+
+    gv_y2 = bodybuilder.genop2("int_add", gv_x, gv_y)
+    gv_x2 = bodybuilder.genop2("int_sub", gv_x, rgenop.genconst(1))
+    bodybuilder.finish_and_goto([gv_x2, gv_y2], loopblock)
+
+    # done
+    gv_gotofn = rgenop.gencallableconst(sigtoken, "goto", entrypoint)
+    return gv_gotofn
+
+def get_goto_runner(RGenOp):
+    def goto_runner(x, y):
+        rgenop = RGenOp()
+        gv_gotofn = make_goto(rgenop)
+        gotofn = gv_gotofn.revealconst(lltype.Ptr(FUNC2))
+        res = gotofn(x, y)
+        keepalive_until_here(rgenop)    # to keep the code blocks alive
+        return res
+    return goto_runner
+
 class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
     RGenOp = None
 
@@ -143,3 +184,21 @@
         assert res == 29
         res = fn(3, 17)
         assert res == 17
+
+    def test_goto_direct(self):
+        rgenop = self.RGenOp()
+        gv_gotofn = make_goto(rgenop)
+        print gv_gotofn.value
+        fnptr = cast(c_void_p(gv_gotofn.value), CFUNCTYPE(c_int, c_int, c_int))
+        res = fnptr(30, 17)    # <== the segfault is here
+        assert res == 31 * 15 + 17
+        res = fnptr(3, 17)    # <== or here
+        assert res == 23
+
+    def test_goto_compile(self):
+        fn = self.compile(get_goto_runner(self.RGenOp), [int, int])
+        res = fn(30, 17)
+        assert res == 31 * 15 + 17
+        res = fn(3, 17)
+        assert res == 23
+



More information about the Pypy-commit mailing list