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

mwh at codespeak.net mwh at codespeak.net
Tue Jan 16 13:49:55 CET 2007


Author: mwh
Date: Tue Jan 16 13:49:54 2007
New Revision: 36801

Modified:
   pypy/dist/pypy/jit/codegen/ppc/rgenop.py
   pypy/dist/pypy/jit/codegen/test/operation_tests.py
Log:
still more tests in operation_tests, more fixes in ppc/rgenop.py
managed to confuse myself doing arithmetic right shift, but not that bad in the
end.


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 13:49:54 2007
@@ -757,16 +757,15 @@
 
     def op_int_lshift(self, gv_x, gv_y):
         if gv_y.fits_in_immediate():
-            if abs(gv_y.value) > 32:
+            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)
+        # (we can assume y >= 0 though)
         # here's the plan:
         #
-        # z = ngeu(y, 32) (as per cwg)
+        # z = nltu(y, 32) (as per cwg)
         # w = x << y
         # r = w&z
         gv_a = self._arg_imm_op(gv_y, self.rgenop.genconst(32), _PPC.subfic)
@@ -778,7 +777,30 @@
     ## 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)
+        if gv_y.fits_in_immediate():
+            if abs(gv_y.value) >= 32:
+                gv_y = rgenop.genconst(31)
+            return self._arg_imm_op(gv_x, gv_y, _PPC.srawi)
+        # computing x >> y when you don't know y is <=32
+        # (we can assume y >= 0 though)
+        # here's the plan:
+        #
+        # ntlu_y_32 = nltu(y, 32) (as per cwg)
+        # o = srawi(x, 31) & ~ntlu_y_32
+        # w = (x >> y) & ntlu_y_32
+        # r = w|o
+        gv_a = self._arg_imm_op(gv_y, self.rgenop.genconst(32), _PPC.subfic)
+        gv_b = self._arg_op(gv_y, _PPC.addze)
+        gv_ntlu_y_32 = self._arg_arg_op(gv_b, gv_y, _PPC.subf)
+
+        gv_c = self._arg_imm_op(gv_x, self.rgenop.genconst(31), _PPC.srawi)
+        gv_d = self._arg_op(gv_ntlu_y_32, _PPC.not_)
+        gv_o = self._arg_arg_op(gv_c, gv_d, _PPC.and_)
+
+        gv_e = self._arg_arg_op(gv_x, gv_y, _PPC.sraw)
+        gv_w = self._arg_arg_op(gv_e, gv_ntlu_y_32, _PPC.and_)
+
+        return self._arg_arg_op(gv_o, gv_w, _PPC.or_)
 
     ## def op_int_rshift_val(self, gv_x, gv_y):
 
@@ -830,7 +852,23 @@
 
     op_uint_lshift = op_int_lshift
     def op_uint_rshift(self, gv_x, gv_y):
-        return self._arg_arg_op_with_imm(gv_x, gv_y, _PPC.srw, _PPC.srwi)
+        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.srwi)
+        # 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(y, 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.srw)
+        return self._arg_arg_op(gv_z, gv_w, _PPC.and_)
 
     ## def op_uint_lshift_val(self, gv_x, gv_y):
     ## def op_uint_rshift(self, gv_x, gv_y):

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 13:49:54 2007
@@ -50,12 +50,30 @@
             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, 65) == intmask(fn(149, 65))
             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, 65) == intmask(fn(-149, 65))
             assert fp(-149, 150) == intmask(fn(-149, 150))
+            try:
+                fn(40, -2)
+            except ValueError:
+                # the shift tests with negative y are invalid
+                continue
+            else:
+                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 op, fn in [('int(x <  y)', lambda x, y: int(x <  y)),
@@ -197,8 +215,17 @@
                        ('~y', lambda x, y: ~y),
                        ]:
             fp = self.rgen(fn, [r_uint, r_uint])
-            assert fp(40, 2) == fn(40, 2), op
-            assert fp(25, 3) == fn(25, 3), op
+            print op
+            fn1 = lambda x, y: fn(r_uint(x), r_uint(y))
+            fp1 = lambda x, y: r_uint(fp(x, y))
+            assert fp1(40, 2) == fn1(40, 2)
+            assert fp1(25, 3) == fn1(25, 3)
+            assert fp1(40, 2) == fn1(40, 2)
+            assert fp1(25, 3) == fn1(25, 3)
+            assert fp1(149, 32) == fn1(149, 32)
+            assert fp1(149, 33) == fn1(149, 33)
+            assert fp1(149, 65) == fn1(149, 65)
+            assert fp1(149, 150) == fn1(149, 150)
 
     def test_float_arithmetic(self):
         for op, fn in [('x + y', lambda x, y: x + y),



More information about the Pypy-commit mailing list