[pypy-commit] pypy default: cast_uint_to_float and cast_float_to_uint are needed for

arigo noreply at buildbot.pypy.org
Mon Oct 24 15:32:26 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r48374:9977c322a23b
Date: 2011-10-24 15:32 +0200
http://bitbucket.org/pypy/pypy/changeset/9977c322a23b/

Log:	cast_uint_to_float and cast_float_to_uint are needed for micronumpy.
	Implement them (hopefully correctly now) as a residual call for now.

diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -443,6 +443,8 @@
     rewrite_op_gc_identityhash = _do_builtin_call
     rewrite_op_gc_id           = _do_builtin_call
     rewrite_op_uint_mod        = _do_builtin_call
+    rewrite_op_cast_float_to_uint = _do_builtin_call
+    rewrite_op_cast_uint_to_float = _do_builtin_call
 
     # ----------
     # getfield/setfield/mallocs etc.
@@ -850,38 +852,43 @@
             size1, unsigned1 = rffi.size_and_sign(v_arg.concretetype)
             assert size1 <= rffi.sizeof(lltype.Signed), (
                 "not implemented: cast_longlong_to_float")
-            assert size1 < rffi.sizeof(lltype.Signed) or not unsigned1, (
-                "not implemented: cast_uint_to_float")
+            from_uint = (unsigned1 and size1 == rffi.sizeof(lltype.Signed))
             #
             ops = []
-            v1 = varoftype(lltype.Signed)
-            oplist = self.rewrite_operation(
-                SpaceOperation('force_cast', [v_arg], v1)
-            )
-            if oplist:
-                ops.extend(oplist)
+            v2 = varoftype(lltype.Float)
+            if not from_uint:
+                v1 = varoftype(lltype.Signed)
+                oplist = self.rewrite_operation(
+                    SpaceOperation('force_cast', [v_arg], v1)
+                )
+                if oplist:
+                    ops.extend(oplist)
+                else:
+                    v1 = v_arg
+                op = self.rewrite_operation(
+                    SpaceOperation('cast_int_to_float', [v1], v2)
+                )
+                ops.append(op)
             else:
-                v1 = v_arg
-            v2 = varoftype(lltype.Float)
-            op = self.rewrite_operation(
-                SpaceOperation('cast_int_to_float', [v1], v2)
-            )
-            ops.append(op)
+                ops1 = self.rewrite_operation(
+                    SpaceOperation('cast_uint_to_float', [v_arg], v2)
+                )
+                if not isinstance(ops1, list): ops1 = [ops1]
+                ops.extend(ops1)
             op2 = self.rewrite_operation(
                 SpaceOperation('force_cast', [v2], v_result)
             )
             if op2:
                 ops.append(op2)
             else:
-                op.result = v_result
+                ops[-1].result = v_result
             return ops
         elif float_arg and not float_res:
             # some float -> some int
             size2, unsigned2 = rffi.size_and_sign(v_result.concretetype)
             assert size2 <= rffi.sizeof(lltype.Signed), (
                 "not implemented: cast_float_to_longlong")
-            assert size2 < rffi.sizeof(lltype.Signed) or not unsigned2, (
-                "not implemented: cast_float_to_uint")
+            to_uint = (unsigned2 and size2 == rffi.sizeof(lltype.Signed))
             #
             ops = []
             v1 = varoftype(lltype.Float)
@@ -892,18 +899,25 @@
                 ops.append(op1)
             else:
                 v1 = v_arg
-            v2 = varoftype(lltype.Signed)
-            op = self.rewrite_operation(
-                SpaceOperation('cast_float_to_int', [v1], v2)
-            )
-            ops.append(op)
-            oplist = self.rewrite_operation(
-                SpaceOperation('force_cast', [v2], v_result)
-            )
-            if oplist:
-                ops.extend(oplist)
+            if not to_uint:
+                v2 = varoftype(lltype.Signed)
+                op = self.rewrite_operation(
+                    SpaceOperation('cast_float_to_int', [v1], v2)
+                )
+                ops.append(op)
+                oplist = self.rewrite_operation(
+                    SpaceOperation('force_cast', [v2], v_result)
+                )
+                if oplist:
+                    ops.extend(oplist)
+                else:
+                    op.result = v_result
             else:
-                op.result = v_result
+                ops1 = self.rewrite_operation(
+                    SpaceOperation('cast_float_to_uint', [v1], v_result)
+                )
+                if not isinstance(ops1, list): ops1 = [ops1]
+                ops.extend(ops1)
             return ops
         else:
             assert False
@@ -1109,8 +1123,6 @@
     # The new operation is optionally further processed by rewrite_operation().
     for _old, _new in [('bool_not', 'int_is_zero'),
                        ('cast_bool_to_float', 'cast_int_to_float'),
-                       ('cast_uint_to_float', 'cast_primitive'),
-                       ('cast_float_to_uint', 'cast_primitive'),
 
                        ('int_add_nonneg_ovf', 'int_add_ovf'),
                        ('keepalive', '-live-'),
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -229,6 +229,13 @@
     else:
         return x
 
+def _ll_1_cast_uint_to_float(x):
+    return llop.cast_uint_to_float(lltype.Float, x)
+
+def _ll_1_cast_float_to_uint(x):
+    return llop.cast_float_to_uint(lltype.Unsigned, x)
+
+
 # math support
 # ------------
 
diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py
--- a/pypy/jit/codewriter/test/test_flatten.py
+++ b/pypy/jit/codewriter/test/test_flatten.py
@@ -70,7 +70,8 @@
         return 'residual'
     def getcalldescr(self, op, oopspecindex=None, extraeffect=None):
         try:
-            if 'cannot_raise' in op.args[0].value._obj.graph.name:
+            name = op.args[0].value._obj._name
+            if 'cannot_raise' in name or name.startswith('cast_'):
                 return self._descr_cannot_raise
         except AttributeError:
             pass
@@ -900,6 +901,35 @@
             int_return %i4
         """, transform=True)
 
+        def f(dbl):
+            return rffi.cast(rffi.UCHAR, dbl)
+        self.encoding_test(f, [12.456], """
+            cast_float_to_int %f0 -> %i0
+            int_and %i0, $255 -> %i1
+            int_return %i1
+        """, transform=True)
+
+        def f(dbl):
+            return rffi.cast(lltype.Unsigned, dbl)
+        self.encoding_test(f, [12.456], """
+            residual_call_irf_i $<* fn cast_float_to_uint>, <Descr>, I[], R[], F[%f0] -> %i0
+            int_return %i0
+        """, transform=True)
+
+        def f(i):
+            return rffi.cast(lltype.Float, chr(i))    # "char -> float"
+        self.encoding_test(f, [12], """
+            cast_int_to_float %i0 -> %f0
+            float_return %f0
+        """, transform=True)
+
+        def f(i):
+            return rffi.cast(lltype.Float, r_uint(i))    # "uint -> float"
+        self.encoding_test(f, [12], """
+            residual_call_irf_f $<* fn cast_uint_to_float>, <Descr>, I[%i0], R[], F[] -> %f0
+            float_return %f0
+        """, transform=True)
+
 
     def test_direct_ptradd(self):
         from pypy.rpython.lltypesystem import rffi
diff --git a/pypy/jit/metainterp/test/test_float.py b/pypy/jit/metainterp/test/test_float.py
--- a/pypy/jit/metainterp/test/test_float.py
+++ b/pypy/jit/metainterp/test/test_float.py
@@ -55,11 +55,10 @@
     def test_cast_float_to_uint(self):
         def g(f):
             return intmask(r_uint(f))
-        raises(AssertionError, self.interp_operations, g, [0.0])   # for now
-        #res = self.interp_operations(g, [sys.maxint*2.0])
-        #assert res == intmask(long(sys.maxint*2.0))
-        #res = self.interp_operations(g, [-12345.9])
-        #assert res == -12345
+        res = self.interp_operations(g, [sys.maxint*2.0])
+        assert res == intmask(long(sys.maxint*2.0))
+        res = self.interp_operations(g, [-12345.9])
+        assert res == -12345
 
     def test_cast_int_to_float(self):
         def g(i):
@@ -70,11 +69,10 @@
     def test_cast_uint_to_float(self):
         def g(i):
             return float(r_uint(i))
-        raises(AssertionError, self.interp_operations, g, [0])    # for now
-        #res = self.interp_operations(g, [sys.maxint*2])
-        #assert type(res) is float and res == float(sys.maxint*2)
-        #res = self.interp_operations(g, [-12345])
-        #assert type(res) is float and res == float(long(r_uint(-12345)))
+        res = self.interp_operations(g, [intmask(sys.maxint*2)])
+        assert type(res) is float and res == float(sys.maxint*2)
+        res = self.interp_operations(g, [-12345])
+        assert type(res) is float and res == float(long(r_uint(-12345)))
 
     #def test_cast_longlong_to_float(self):
     #def test_cast_ulonglong_to_float(self):


More information about the pypy-commit mailing list