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

mwh at codespeak.net mwh at codespeak.net
Wed Oct 18 18:59:52 CEST 2006


Author: mwh
Date: Wed Oct 18 18:59:49 2006
New Revision: 33413

Modified:
   pypy/dist/pypy/jit/codegen/ppc/rgenop.py
   pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
two more tests for the powerpc backend + associated support code.


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	Wed Oct 18 18:59:49 2006
@@ -154,7 +154,7 @@
             # turn constants into variables; also make copies of vars that
             # are duplicate in args_gv
             if not isinstance(gv, Var):
-                gv = args_gv[i] = gv.load(self)
+                gv = args_gv[i] = Var(RegisterLocation(gv.load(self)))
             elif gv.location in seen:
                 if isinstance(gv.location, RegisterLocation):
                     new_gv = args_gv[i] = self.newvar()
@@ -162,7 +162,7 @@
                     self.asm.mr(new_gv.reg(), gv.reg())
                     gv = new_gv
                 else:
-                    gv = args_gv[i] = gv.load(self)
+                    gv = args_gv[i] = Var(RegisterLocation(gv.load(self)))
             # remember the var's location
             arg_locations.append(gv.location)
             seen[gv.location] = None
@@ -174,20 +174,41 @@
         assert d < 12
         return Var(RegisterLocation(d))
 
-    def op_int_add(self, gv_x, gv_y):
+    def new_and_load_2(self, gv_x, gv_y):
         gv_result = self.newvar()
-        self.asm.add(gv_result.load(self),
-                     gv_x.load(self),
-                     gv_y.load(self))
+        return (gv_result, gv_x.load(self), gv_y.load(self))
+
+    def op_int_add(self, gv_x, gv_y):
+        gv_result, r_x, r_y = self.new_and_load_2(gv_x, gv_y)
+        self.asm.add(gv_result.reg(), r_x, r_y)
         return gv_result
 
     def op_int_sub(self, gv_x, gv_y):
-        gv_result = self.newvar()
-        self.asm.sub(gv_result.load(self),
-                     gv_x.load(self),
-                     gv_y.load(self))
+        gv_result, r_x, r_y = self.new_and_load_2(gv_x, gv_y)
+        self.asm.sub(gv_result.reg(), r_x, r_y)
         return gv_result
 
+    def op_int_gt(self, gv_x, gv_y):
+        gv_result, r_x, r_y = self.new_and_load_2(gv_x, gv_y)
+        r_result = gv_result.reg()
+        self.asm.cmpw(0, r_x, r_y)
+        self.asm.mfcr(r_result)
+        self.asm.extrwi(r_result, r_result, 1, 1)
+        return gv_result
+
+    def jump_if_false(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.beqctr()
+        return targetbuilder
+
+    def _fork(self):
+        return self.rgenop.openbuilder(self.stackdepth)
+
+
 class RPPCGenOp(AbstractRGenOp):
     from pypy.jit.codegen.i386.codebuf import MachineCodeBlock
 

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	Wed Oct 18 18:59:49 2006
@@ -59,6 +59,42 @@
         return res
     return dummy_runner
 
+def make_branching(rgenop):
+    # 'if x > 5: return x-1
+    #  else:     return y'
+    signed_kind = rgenop.kindToken(lltype.Signed)
+    sigtoken = rgenop.sigToken(FUNC2)
+    builder, entrypoint, [gv_x, gv_y] = rgenop.newgraph(sigtoken)
+    gv_cond = builder.genop2("int_gt", gv_x, rgenop.genconst(5))
+    false_builder = builder.jump_if_false(gv_cond)
+
+    # true path
+    args_gv = [rgenop.genconst(1), gv_x, gv_y]
+    builder.enter_next_block([signed_kind, signed_kind, signed_kind], args_gv)
+    [gv_one, gv_x2, gv_y2] = args_gv
+
+    gv_s2 = builder.genop2("int_sub", gv_x2, gv_one)
+    builder.finish_and_return(sigtoken, gv_s2)
+
+    # false path
+    false_builder.finish_and_return(sigtoken, gv_y)
+
+    # done
+    gv_branchingfn = rgenop.gencallableconst(sigtoken,
+                                             "branching", entrypoint)
+    return gv_branchingfn
+
+def get_branching_runner(RGenOp):
+    def branching_runner(x, y):
+        rgenop = RGenOp()
+        gv_branchingfn = make_branching(rgenop)
+        branchingfn = gv_branchingfn.revealconst(lltype.Ptr(FUNC2))
+        res = branchingfn(x, y)
+        keepalive_until_here(rgenop)    # to keep the code blocks alive
+        return res
+    return branching_runner
+
+
 class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
     RGenOp = None
 
@@ -90,4 +126,20 @@
         fn = self.compile(get_dummy_runner(self.RGenOp), [int, int])
         res = fn(40, 37)
         assert res == 42
-        
+
+    def test_branching_direct(self):
+        rgenop = self.RGenOp()
+        gv_branchingfn = make_branching(rgenop)
+        fnptr = cast(c_void_p(gv_branchingfn.value),
+                     CFUNCTYPE(c_int, c_int, c_int))
+        res = fnptr(30, 17)
+        assert res == 29
+        res = fnptr(3, 17)
+        assert res == 17
+
+    def test_branching_compile(self):
+        fn = self.compile(get_branching_runner(self.RGenOp), [int, int])
+        res = fn(30, 17)
+        assert res == 29
+        res = fn(3, 17)
+        assert res == 17



More information about the Pypy-commit mailing list