[pypy-svn] pypy jit-longlong: Support (u)llong_add in codewriter, by writing them as

arigo commits-noreply at bitbucket.org
Thu Jan 6 21:35:48 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: jit-longlong
Changeset: r40428:089ae20fbd5e
Date: 2011-01-06 20:47 +0100
http://bitbucket.org/pypy/pypy/changeset/089ae20fbd5e/

Log:	Support (u)llong_add in codewriter, by writing them as an oopspec
	call.

diff --git a/pypy/jit/codewriter/test/test_longlong.py b/pypy/jit/codewriter/test/test_longlong.py
--- a/pypy/jit/codewriter/test/test_longlong.py
+++ b/pypy/jit/codewriter/test/test_longlong.py
@@ -5,12 +5,26 @@
 from pypy.translator.unsimplify import varoftype
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.codewriter.jtransform import Transformer, NotSupported
+from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter.test.test_jtransform import const
 
 
+class FakeRTyper:
+    pass
+
+class FakeBuiltinCallControl:
+    def guess_call_kind(self, op):
+        return 'builtin'
+    def getcalldescr(self, op, oopspecindex=None):
+        assert oopspecindex is not None    # in this test
+        return 'calldescr-%d' % oopspecindex
+    def calldescr_canraise(self, calldescr):
+        return False
+
 class FakeCPU:
     def __init__(self, supports_longlong):
         self.supports_longlong = supports_longlong
+        self.rtyper = FakeRTyper()
 
 
 class TestLongLong:
@@ -18,20 +32,24 @@
         if sys.maxint > 2147483647:
             py.test.skip("only for 32-bit platforms")
 
-    def test_unsupported_op(self):
-        tr = Transformer(FakeCPU([]))
-        # without a long long
-        op = SpaceOperation('foobar', [const(123)], varoftype(lltype.Signed))
-        op1 = tr.rewrite_operation(op)
-        assert op1 == op
-        # with a long long argument
-        op = SpaceOperation('foobar', [const(r_longlong(123))],
-                            varoftype(lltype.Signed))
-        py.test.raises(NotSupported, tr.rewrite_operation, op)
-        # with a long long result
-        op = SpaceOperation('foobar', [const(123)],
-                            varoftype(lltype.SignedLongLong))
-        py.test.raises(NotSupported, tr.rewrite_operation, op)
+    def test_unsupported_binary_op(self):
+        tr = Transformer(FakeCPU([]), FakeBuiltinCallControl())
+        for opname, oopspecindex in [
+                ('llong_add', EffectInfo.OS_LLONG_ADD),
+                ('ullong_add', EffectInfo.OS_LLONG_ADD),
+            ]:
+            v1 = varoftype(lltype.SignedLongLong)
+            v2 = varoftype(lltype.SignedLongLong)
+            v3 = varoftype(lltype.SignedLongLong)
+            op = SpaceOperation(opname, [v1, v2], v3)
+            op1 = tr.rewrite_operation(op)
+            assert op1.opname == 'residual_call_irf_f'
+            assert op1.args[0].value == opname.lstrip('u')
+            assert op1.args[1] == 'calldescr-%d' % oopspecindex
+            assert list(op1.args[2]) == []
+            assert list(op1.args[3]) == []
+            assert list(op1.args[4]) == [v1, v2]
+            assert op1.result == v3
 
     def test_prebuilt_constant_32(self):
         c_x = const(r_longlong(-171))

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
@@ -19,6 +19,8 @@
 from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
 from pypy.jit.metainterp.typesystem import deref
 from pypy.rlib import rgc
+from pypy.rlib.rarithmetic import r_longlong, r_ulonglong
+from pypy.rlib.longlong2float import longlong2float, float2longlong
 
 def getargtypes(annotator, values):
     if values is None:    # for backend tests producing stand-alone exe's
@@ -222,6 +224,16 @@
         return x
 
 
+# long long support
+# -----------------
+
+def _ll_2_llong_add(xf, yf):
+    x = float2longlong(xf)
+    y = float2longlong(yf)
+    z = x + y
+    return longlong2float(z)
+
+
 # libffi support
 # --------------
 

diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -46,6 +46,8 @@
     OS_LIBFFI_PREPARE           = 60
     OS_LIBFFI_PUSH_ARG          = 61
     OS_LIBFFI_CALL              = 62
+    #
+    OS_LLONG_ADD                = 70
 
     def __new__(cls, readonly_descrs_fields,
                 write_descrs_fields, write_descrs_arrays,

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
@@ -779,6 +779,21 @@
         return result
 
     # ----------
+    # Long longs, for 32-bit only.  Supported operations are left unmodified,
+    # and unsupported ones are turned into a call to a function from
+    # jit.codewriter.support.
+
+    def rewrite_op_llong_add(self, op):
+        if 'add' in self.cpu.supports_longlong:
+            return op
+        else:
+            op1 = self.prepare_builtin_call(op, 'llong_add', op.args)
+            return self._handle_oopspec_call(op1, op.args,
+                                             EffectInfo.OS_LLONG_ADD)
+
+    rewrite_op_ullong_add = rewrite_op_llong_add
+
+    # ----------
     # Renames, from the _old opname to the _new one.
     # The new operation is optionally further processed by rewrite_operation().
     for _old, _new in [('bool_not', 'int_is_zero'),


More information about the Pypy-commit mailing list