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

mwh at codespeak.net mwh at codespeak.net
Tue Jan 16 12:31:21 CET 2007


Author: mwh
Date: Tue Jan 16 12:31:17 2007
New Revision: 36794

Modified:
   pypy/dist/pypy/jit/codegen/ppc/rgenop.py
   pypy/dist/pypy/jit/codegen/test/operation_tests.py
Log:
beef up operation_tests considerably.
update ppc/rgenop.py to match (strangely, division is more painful than
shifting, not what i expected).
will run tests on intel on wyvern imminently.


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	Tue Jan 16 12:31:17 2007
@@ -48,7 +48,7 @@
 
     def __init__(self, value):
         self.value = value
-        
+
     @specialize.arg(1)
     def revealconst(self, T):
         if isinstance(T, lltype.Ptr):
@@ -344,11 +344,7 @@
         return r
 
     def jump_if_false(self, gv_condition, args_gv):
-        #print 'jump_if_false', [id(v) for v in args_gv]
-        #print id(self)
-        t = self._jump(gv_condition, False, args_gv)
-        #print '->', id(t)
-        return t
+        return self._jump(gv_condition, False, args_gv)
 
     def jump_if_true(self, gv_condition, args_gv):
         return self._jump(gv_condition, True, args_gv)
@@ -569,16 +565,6 @@
         self.asm.stw(rFP, rSP, 0)
         # branch to "here"
 
-##     def patch_stack_adjustment(self, newsize):
-##         if self.stack_adj_addr == 0:
-##             return
-##         #print "patch_stack_adjustment at:", self.stack_adj_addr, newsize
-##         # we build an addi instruction by hand here
-##         mc = self.asm.mc
-##         self.asm.mc = self.rgenop.ExistingCodeBlock(self.stack_adj_addr, self.stack_adj_addr+4)
-##         self.asm.addi(rSCRATCH, rFP, -newsize)
-##         self.asm.mc = mc
-
     def _arg_op(self, gv_arg, opcode):
         gv_result = Var()
         self.insns.append(
@@ -702,7 +688,28 @@
                                          commutative=True)
 
     def op_int_floordiv(self, gv_x, gv_y):
-        return self._arg_arg_op(gv_x, gv_y, _PPC.divw)
+        # grumble, the powerpc handles division when the signs of x
+        # and y differ the other way to how cpython wants it.  this
+        # crawling horror is a branch-free way of computing the right
+        # remainder in all cases.  it's probably not optimal.
+
+        # we need to adjust the result iff the remainder is non-zero
+        # and the signs of x and y differ.  in the standard-ish PPC
+        # way, we compute boolean values as either all-bits-0 or
+        # all-bits-1 and "and" them together, resulting in either
+        # adding 0 or -1 as needed in the final step.
+
+        gv_dividend = self._arg_arg_op(gv_x, gv_y, _PPC.divw)
+        gv_remainder = self.op_int_sub(gv_x, self.op_int_mul(gv_dividend, gv_y))
+
+        gv_t = self._arg_arg_op(gv_y, gv_x, _PPC.xor)
+        gv_signs_differ = self._arg_imm_op(gv_t, self.rgenop.genconst(31), _PPC.srawi)
+
+        gv_foo = self._arg_imm_op(gv_remainder, self.rgenop.genconst(0), _PPC.subfic)
+        gv_remainder_non_zero = self._arg_arg_op(gv_foo, gv_foo, _PPC.subfe)
+
+        gv_b = self._arg_arg_op(gv_remainder_non_zero, gv_signs_differ, _PPC.and_)
+        return self._arg_arg_op(gv_dividend, gv_b, _PPC.add)
 
     ## def op_int_floordiv_zer(self, gv_x, gv_y):
 
@@ -749,11 +756,30 @@
                                          commutative=True)
 
     def op_int_lshift(self, gv_x, gv_y):
-        # could be messy if shift is not in 0 <= ... < 32
-        return self._arg_arg_op_with_imm(gv_x, gv_y, _PPC.slw, _PPC.slwi)
+        if gv_y.fits_in_immediate():
+            if abs(gv_y.value) > 32:
+                return self.rgenop.genconst(0)
+            else:
+                return self._arg_imm_op(gv_x, gv_y, _PPC.slwi)
+        gv_abs_y = self.op_int_abs(gv_y)
+        # computing x << y when you don't know y is <=32
+        # (we can assume y >=0 though, i think)
+        # here's the plan:
+        #
+        # z = ngeu(x, 32) (as per cwg)
+        # w = x << y
+        # r = w&z
+        gv_a = self._arg_imm_op(gv_y, self.rgenop.genconst(32), _PPC.subfic)
+        gv_b = self._arg_op(gv_y, _PPC.addze)
+        gv_z = self._arg_arg_op(gv_b, gv_y, _PPC.subf)
+        gv_w = self._arg_arg_op(gv_x, gv_y, _PPC.slw)
+        return self._arg_arg_op(gv_z, gv_w, _PPC.and_)
+
     ## def op_int_lshift_val(self, gv_x, gv_y):
+
     def op_int_rshift(self, gv_x, gv_y):
         return self._arg_arg_op_with_imm(gv_x, gv_y, _PPC.sraw, _PPC.srawi)
+
     ## def op_int_rshift_val(self, gv_x, gv_y):
 
     def op_int_xor(self, gv_x, gv_y):
@@ -866,7 +892,7 @@
 
     def __init__(self):
         self.mcs = []   # machine code blocks where no-one is currently writing
-        self.keepalive_gc_refs = [] 
+        self.keepalive_gc_refs = []
 
     # ----------------------------------------------------------------
     # the public RGenOp interface

Modified: pypy/dist/pypy/jit/codegen/test/operation_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/operation_tests.py	(original)
+++ pypy/dist/pypy/jit/codegen/test/operation_tests.py	Tue Jan 16 12:31:17 2007
@@ -29,88 +29,95 @@
         return fp
 
     def test_arithmetic(self):
-        for fn in [lambda x, y: x + y,
-                   lambda x, y: x - y,
-                   lambda x, y: x * y,
-                   lambda x, y: x // y,
-                   lambda x, y: x % y,
-                   lambda x, y: x << y,
-                   lambda x, y: x >> y,
-                   lambda x, y: x ^ y,
-                   lambda x, y: x & y,
-                   lambda x, y: x | y,
-                   lambda x, y: -y,
-                   lambda x, y: ~y,
-                   lambda x, y: abs(y),
-                   lambda x, y: abs(-x),
-                   ]:
+        for op, fn in [('x + y', lambda x, y: x + y),
+                       ('x - y', lambda x, y: x - y),
+                       ('x * y', lambda x, y: x * y),
+                       ('x // y', lambda x, y: x // y),
+                       ('x % y', lambda x, y: x % y),
+                       ('x << y', lambda x, y: x << y),
+                       ('x >> y', lambda x, y: x >> y),
+                       ('x ^ y', lambda x, y: x ^ y),
+                       ('x & y', lambda x, y: x & y),
+                       ('x | y', lambda x, y: x | y),
+                       ('-y', lambda x, y: -y),
+                       ('~y', lambda x, y: ~y),
+                       ('abs(y)', lambda x, y: abs(y)),
+                       ('abs(-x)', lambda x, y: abs(-x)),
+                       ]:
             fp = self.rgen(fn, [int, int])
+            print op
             assert fp(40, 2) == intmask(fn(40, 2))
             assert fp(25, 3) == intmask(fn(25, 3))
             assert fp(149, 32) == intmask(fn(149, 32))
             assert fp(149, 33) == intmask(fn(149, 33))
+            assert fp(149, 150) == intmask(fn(149, 150))
+            assert fp(-40, 2) == intmask(fn(-40, 2))
+            assert fp(-25, 3) == intmask(fn(-25, 3))
+            assert fp(-149, 32) == intmask(fn(-149, 32))
+            assert fp(-149, 33) == intmask(fn(-149, 33))
+            assert fp(-149, 150) == intmask(fn(-149, 150))
 
     def test_comparison(self):
-        for fn in [lambda x, y: int(x <  y),
-                   lambda x, y: int(x <= y),
-                   lambda x, y: int(x == y),
-                   lambda x, y: int(x != y),
-                   lambda x, y: int(x >  y),
-                   lambda x, y: int(x >= y),
-                   ]:
+        for op, fn in [('int(x <  y)', lambda x, y: int(x <  y)),
+                       ('int(x <= y)', lambda x, y: int(x <= y)),
+                       ('int(x == y)', lambda x, y: int(x == y)),
+                       ('int(x != y)', lambda x, y: int(x != y)),
+                       ('int(x >  y)', lambda x, y: int(x >  y)),
+                       ('int(x >= y)', lambda x, y: int(x >= y)),
+                       ]:
             fp = self.rgen(fn, [int, int])
-            assert fp(12, 11) == fn(12, 11)
-            assert fp(12, 12) == fn(12, 12)
-            assert fp(12, 13) == fn(12, 13)
-            assert fp(-12, 11) == fn(-12, 11)
-            assert fp(-12, 12) == fn(-12, 12)
-            assert fp(-12, 13) == fn(-12, 13)
-            assert fp(12, -11) == fn(12, -11)
-            assert fp(12, -12) == fn(12, -12)
-            assert fp(12, -13) == fn(12, -13)
-            assert fp(-12, -11) == fn(-12, -11)
-            assert fp(-12, -12) == fn(-12, -12)
-            assert fp(-12, -13) == fn(-12, -13)
+            assert fp(12, 11) == fn(12, 11), op
+            assert fp(12, 12) == fn(12, 12), op
+            assert fp(12, 13) == fn(12, 13), op
+            assert fp(-12, 11) == fn(-12, 11), op
+            assert fp(-12, 12) == fn(-12, 12), op
+            assert fp(-12, 13) == fn(-12, 13), op
+            assert fp(12, -11) == fn(12, -11), op
+            assert fp(12, -12) == fn(12, -12), op
+            assert fp(12, -13) == fn(12, -13), op
+            assert fp(-12, -11) == fn(-12, -11), op
+            assert fp(-12, -12) == fn(-12, -12), op
+            assert fp(-12, -13) == fn(-12, -13), op
 
     def test_char_comparison(self):
-        for fn in [lambda x, y: int(chr(x) <  chr(y)),
-                   lambda x, y: int(chr(x) <= chr(y)),
-                   lambda x, y: int(chr(x) == chr(y)),
-                   lambda x, y: int(chr(x) != chr(y)),
-                   lambda x, y: int(chr(x) >  chr(y)),
-                   lambda x, y: int(chr(x) >= chr(y)),
-                   ]:
+        for op, fn in [('int(chr(x) <  chr(y))', lambda x, y: int(chr(x) <  chr(y))),
+                       ('int(chr(x) <= chr(y))', lambda x, y: int(chr(x) <= chr(y))),
+                       ('int(chr(x) == chr(y))', lambda x, y: int(chr(x) == chr(y))),
+                       ('int(chr(x) != chr(y))', lambda x, y: int(chr(x) != chr(y))),
+                       ('int(chr(x) >  chr(y))', lambda x, y: int(chr(x) >  chr(y))),
+                       ('int(chr(x) >= chr(y))', lambda x, y: int(chr(x) >= chr(y))),
+                       ]:
             fp = self.rgen(fn, [int, int])
-            assert fp(12, 11) == fn(12, 11)
-            assert fp(12, 12) == fn(12, 12)
-            assert fp(12, 13) == fn(12, 13)
-            assert fp(182, 11) == fn(182, 11)
-            assert fp(182, 12) == fn(182, 12)
-            assert fp(182, 13) == fn(182, 13)
-            assert fp(12, 181) == fn(12, 181)
-            assert fp(12, 182) == fn(12, 182)
-            assert fp(12, 183) == fn(12, 183)
-            assert fp(182, 181) == fn(182, 181)
-            assert fp(182, 182) == fn(182, 182)
-            assert fp(182, 183) == fn(182, 183)
+            assert fp(12, 11) == fn(12, 11), op
+            assert fp(12, 12) == fn(12, 12), op
+            assert fp(12, 13) == fn(12, 13), op
+            assert fp(182, 11) == fn(182, 11), op
+            assert fp(182, 12) == fn(182, 12), op
+            assert fp(182, 13) == fn(182, 13), op
+            assert fp(12, 181) == fn(12, 181), op
+            assert fp(12, 182) == fn(12, 182), op
+            assert fp(12, 183) == fn(12, 183), op
+            assert fp(182, 181) == fn(182, 181), op
+            assert fp(182, 182) == fn(182, 182), op
+            assert fp(182, 183) == fn(182, 183), op
 
     def test_unichar_comparison(self):
-        for fn in [lambda x, y: int(unichr(x) == unichr(y)),
-                   lambda x, y: int(unichr(x) != unichr(y)),
-                   ]:
+        for op, fn in [('int(unichr(x) == unichr(y))', lambda x, y: int(unichr(x) == unichr(y))),
+                       ('int(unichr(x) != unichr(y))', lambda x, y: int(unichr(x) != unichr(y))),
+                       ]:
             fp = self.rgen(fn, [int, int])
-            assert fp(12, 11) == fn(12, 11)
-            assert fp(12, 12) == fn(12, 12)
-            assert fp(12, 13) == fn(12, 13)
-            assert fp(53182, 11) == fn(53182, 11)
-            assert fp(53182, 12) == fn(53182, 12)
-            assert fp(53182, 13) == fn(53182, 13)
-            assert fp(12, 53181) == fn(12, 53181)
-            assert fp(12, 53182) == fn(12, 53182)
-            assert fp(12, 53183) == fn(12, 53183)
-            assert fp(53182, 53181) == fn(53182, 53181)
-            assert fp(53182, 53182) == fn(53182, 53182)
-            assert fp(53182, 53183) == fn(53182, 53183)
+            assert fp(12, 11) == fn(12, 11), op
+            assert fp(12, 12) == fn(12, 12), op
+            assert fp(12, 13) == fn(12, 13), op
+            assert fp(53182, 11) == fn(53182, 11), op
+            assert fp(53182, 12) == fn(53182, 12), op
+            assert fp(53182, 13) == fn(53182, 13), op
+            assert fp(12, 53181) == fn(12, 53181), op
+            assert fp(12, 53182) == fn(12, 53182), op
+            assert fp(12, 53183) == fn(12, 53183), op
+            assert fp(53182, 53181) == fn(53182, 53181), op
+            assert fp(53182, 53182) == fn(53182, 53182), op
+            assert fp(53182, 53183) == fn(53182, 53183), op
 
     def test_char_array(self):
         A = lltype.GcArray(lltype.Char)
@@ -176,51 +183,51 @@
         assert res == 5
 
     def test_unsigned(self):
-        for fn in [lambda x, y: x + y,
-                   lambda x, y: x - y,
-                   lambda x, y: x * y,
-                   lambda x, y: x // y,
-                   lambda x, y: x % y,
-                   lambda x, y: x << y,
-                   lambda x, y: x >> y,
-                   lambda x, y: x ^ y,
-                   lambda x, y: x & y,
-                   lambda x, y: x | y,
-                   lambda x, y: -y,
-                   lambda x, y: ~y,
-                   ]:
+        for op, fn in [('x + y', lambda x, y: x + y),
+                       ('x - y', lambda x, y: x - y),
+                       ('x * y', lambda x, y: x * y),
+                       ('x // y', lambda x, y: x // y),
+                       ('x % y', lambda x, y: x % y),
+                       ('x << y', lambda x, y: x << y),
+                       ('x >> y', lambda x, y: x >> y),
+                       ('x ^ y', lambda x, y: x ^ y),
+                       ('x & y', lambda x, y: x & y),
+                       ('x | y', lambda x, y: x | y),
+                       ('-y', lambda x, y: -y),
+                       ('~y', lambda x, y: ~y),
+                       ]:
             fp = self.rgen(fn, [r_uint, r_uint])
-            assert fp(40, 2) == fn(40, 2)
-            assert fp(25, 3) == fn(25, 3)
+            assert fp(40, 2) == fn(40, 2), op
+            assert fp(25, 3) == fn(25, 3), op
 
     def test_float_arithmetic(self):
-        for fn in [lambda x, y: x + y,
-                   lambda x, y: x - y,
-                   lambda x, y: x * y,
-                   lambda x, y: x / y,
-                   #lambda x, y: x % y,  #not used?
-                   lambda x, y: -y,
-                   #lambda x, y: ~y,    #TypeError: bad operand type for unary ~
-                   lambda x, y: abs(y),
-                   lambda x, y: abs(-x),
-                   ]:
+        for op, fn in [('x + y', lambda x, y: x + y),
+                       ('x - y', lambda x, y: x - y),
+                       ('x * y', lambda x, y: x * y),
+                       ('x / y', lambda x, y: x / y),
+                       #('x % y', lambda x, y: x % y),  #not used?
+                       ('-y', lambda x, y: -y),
+                       #('~y', lambda x, y: ~y),    #TypeError: bad operand type for unary ~
+                       ('abs(y)', lambda x, y: abs(y)),
+                       ('abs(-x)', lambda x, y: abs(-x)),
+                       ]:
             fp = self.rgen(fn, [float, float], float)
-            assert fp(40.0, 2.0) == fn(40.0, 2.0)
-            assert fp(25.125, 1.5) == fn(25.125, 1.5)
+            assert fp(40.0, 2.0) == fn(40.0, 2.0), op
+            assert fp(25.125, 1.5) == fn(25.125, 1.5), op
 
     def test_float_pow(self): #harder test for llvm
-        for fn in [lambda x, y: x ** y,    #not supported in llvm backend
-                   ]:
+        for op, fn in [('x ** y', lambda x, y: x ** y),    #not supported in llvm backend
+                       ]:
             fp = self.rgen(fn, [float, float], float)
-            assert fp(40.0, 2.0) == fn(40.0, 2.0)
-            assert fp(25.125, 1.5) == fn(25.125, 1.5)
+            assert fp(40.0, 2.0) == fn(40.0, 2.0), op
+            assert fp(25.125, 1.5) == fn(25.125, 1.5), op
 
     def test_float_cast(self): #because of different rettype
-        for fn in [lambda x: bool(x),
-                   lambda x: bool(x - 2.0),
-                   ]:
+        for op, fn in [('bool(x)', lambda x: bool(x)),
+                       ('bool(2.0 - x)', lambda x: bool(x - 2.0)),
+                       ]:
             fp = self.rgen(fn, [float], bool)
-            assert fp(6.0) == fn(6.0)
-            assert fp(2.0) == fn(2.0)
-            assert fp(0.0) == fn(0.0)
-            assert fp(-2.0) == fn(-2.0)
+            assert fp(6.0) == fn(6.0), op
+            assert fp(2.0) == fn(2.0), op
+            assert fp(0.0) == fn(0.0), op
+            assert fp(-2.0) == fn(-2.0), op



More information about the Pypy-commit mailing list