[pypy-svn] pypy jit-longlong: In-progress. Basic tests pass on the x86 backend.

arigo commits-noreply at bitbucket.org
Fri Jan 7 14:54:40 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: jit-longlong
Changeset: r40451:2918d584d963
Date: 2011-01-07 14:54 +0100
http://bitbucket.org/pypy/pypy/changeset/2918d584d963/

Log:	In-progress. Basic tests pass on the x86 backend.

diff --git a/pypy/jit/metainterp/test/test_basic.py b/pypy/jit/metainterp/test/test_basic.py
--- a/pypy/jit/metainterp/test/test_basic.py
+++ b/pypy/jit/metainterp/test/test_basic.py
@@ -14,7 +14,8 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.ootypesystem import ootype
 
-def _get_jitcodes(testself, CPUClass, func, values, type_system):
+def _get_jitcodes(testself, CPUClass, func, values, type_system,
+                  supports_longlong=False, **kwds):
     from pypy.jit.codewriter import support, codewriter
     from pypy.jit.metainterp import simple_optimize
 
@@ -58,7 +59,7 @@
     cw = codewriter.CodeWriter(cpu, [FakeJitDriverSD()])
     testself.cw = cw
     policy = JitPolicy()
-    policy.set_supports_longlong(True)
+    policy.set_supports_longlong(supports_longlong)
     cw.find_all_graphs(policy)
     #
     testself.warmrunnerstate = FakeWarmRunnerState()
@@ -158,7 +159,7 @@
 
     def interp_operations(self, f, args, **kwds):
         # get the JitCodes for the function f
-        _get_jitcodes(self, self.CPUClass, f, args, self.type_system)
+        _get_jitcodes(self, self.CPUClass, f, args, self.type_system, **kwds)
         # try to run it with blackhole.py
         result1 = _run_with_blackhole(self, args)
         # try to run it with pyjitpl.py
@@ -1268,14 +1269,20 @@
         def g(n, m, o, p):
             # On 64-bit platforms, long longs == longs.  On 32-bit platforms,
             # this function should be either completely marked as residual
-            # (backends with supports_longlong==False), or be compiled as a
+            # (with supports_longlong==False), or be compiled as a
             # sequence of residual calls (with long long arguments).
             n = r_longlong(n)
             m = r_longlong(m)
             return intmask((n*m + p) // o)
         def f(n, m, o, p):
             return g(n, m, o, p) // 3
-        res = self.interp_operations(f, [1000000000, 90, 91, -17171])
+        #
+        res = self.interp_operations(f, [1000000000, 90, 91, -17171],
+                                     supports_longlong=False)
+        assert res == ((1000000000 * 90 - 17171) // 91) // 3
+        #
+        res = self.interp_operations(f, [1000000000, 90, 91, -17171],
+                                     supports_longlong=True)
         assert res == ((1000000000 * 90 - 17171) // 91) // 3
 
     def test_long_long_field(self):
@@ -1289,7 +1296,13 @@
             return intmask(a.n)
         def f(n, m):
             return g(A(), n, m)
-        res = self.interp_operations(f, [2147483647, -21474])
+        #
+        res = self.interp_operations(f, [2147483647, -21474],
+                                     supports_longlong=False)
+        assert res == intmask(2147483647 + 21474)
+        #
+        res = self.interp_operations(f, [2147483647, -21474],
+                                     supports_longlong=True)
         assert res == intmask(2147483647 + 21474)
 
     def test_free_object(self):

diff --git a/pypy/jit/backend/llsupport/test/test_descr.py b/pypy/jit/backend/llsupport/test/test_descr.py
--- a/pypy/jit/backend/llsupport/test/test_descr.py
+++ b/pypy/jit/backend/llsupport/test/test_descr.py
@@ -5,7 +5,7 @@
 from pypy.rpython.annlowlevel import llhelper
 from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr
 from pypy.jit.metainterp import history
-import struct
+import sys, struct, py
 
 def test_get_size_descr():
     c0 = GcCache(False)
@@ -95,6 +95,16 @@
             descr_x = get_field_descr(c2, S, 'x')
             assert descr_x.is_field_signed() == signed
 
+def test_get_field_descr_longlong():
+    if sys.maxint > 2147483647:
+        py.test.skip("long long: for 32-bit only")
+    c0 = GcCache(False)
+    S = lltype.GcStruct('S', ('y', lltype.UnsignedLongLong))
+    descr = get_field_descr(c0, S, 'y')
+    assert not descr.is_pointer_field()
+    assert descr.is_float_field()
+    assert descr.get_field_size(False) == 8
+
 
 def test_get_array_descr():
     U = lltype.Struct('U')
@@ -226,6 +236,21 @@
     assert descr4.get_return_type() == history.FLOAT
     assert descr4.arg_classes == "ff"
 
+def test_get_call_descr_not_translated_longlong():
+    if sys.maxint > 2147483647:
+        py.test.skip("long long: for 32-bit only")
+    c0 = GcCache(False)
+    #
+    descr5 = get_call_descr(c0, [lltype.SignedLongLong], lltype.Signed)
+    assert descr5.get_result_size(False) == 4
+    assert descr5.get_return_type() == history.INT
+    assert descr5.arg_classes == "L"
+    #
+    descr6 = get_call_descr(c0, [lltype.Signed], lltype.SignedLongLong)
+    assert descr6.get_result_size(False) == 8
+    assert descr6.get_return_type() == history.FLOAT
+    assert descr6.arg_classes == "i"
+
 def test_get_call_descr_translated():
     c1 = GcCache(True)
     T = lltype.GcStruct('T')

diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -6,6 +6,8 @@
 from pypy.jit.metainterp import history
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.codewriter import heaptracker
+from pypy.rlib.rarithmetic import r_longlong, r_ulonglong
+from pypy.rlib.longlong2float import longlong2float, float2longlong
 
 # The point of the class organization in this file is to make instances
 # as compact as possible.  This is done by not storing the field size or
@@ -29,6 +31,14 @@
         assert isinstance(ARRAY, lltype.GcArray)
 
 
+if lltype.SignedLongLong is lltype.Signed:
+    def is_longlong(TYPE):
+        return False
+else:
+    assert rffi.sizeof(lltype.SignedLongLong) == rffi.sizeof(lltype.Float)
+    def is_longlong(TYPE):
+        return TYPE in (lltype.SignedLongLong, lltype.UnsignedLongLong)
+
 # ____________________________________________________________
 # SizeDescrs
 
@@ -264,6 +274,8 @@
 
     def create_call_stub(self, rtyper, RESULT):
         def process(c):
+            if c == 'L':
+                return 'float2longlong(%s)' % (process('f'),)
             arg = 'args_%s[%d]' % (c, seen[c])
             seen[c] += 1
             return arg
@@ -277,6 +289,10 @@
                 return llmemory.GCREF
             elif arg == 'v':
                 return lltype.Void
+            elif arg == 'L':
+                return lltype.SignedLongLong
+            else:
+                raise AssertionError(arg)
 
         seen = {'i': 0, 'r': 0, 'f': 0}
         args = ", ".join([process(c) for c in self.arg_classes])
@@ -286,7 +302,7 @@
         elif self.get_return_type() == history.REF:
             result = 'lltype.cast_opaque_ptr(llmemory.GCREF, res)'
         elif self.get_return_type() == history.FLOAT:
-            result = 'res'
+            result = 'cast_to_float(res)'
         elif self.get_return_type() == history.VOID:
             result = 'None'
         else:
@@ -308,11 +324,21 @@
         assert self._return_type == return_type
         assert self.arg_classes.count('i') == len(args_i or ())
         assert self.arg_classes.count('r') == len(args_r or ())
-        assert self.arg_classes.count('f') == len(args_f or ())
+        assert (self.arg_classes.count('f') +
+                self.arg_classes.count('L')) == len(args_f or ())
 
     def repr_of_descr(self):
         return '<%s>' % self._clsname
 
+def cast_to_float(x):
+    if isinstance(x, r_longlong):
+        return longlong2float(x)
+    if isinstance(x, r_ulonglong):
+        return longlong2float(r_longlong(x))
+    assert isinstance(x, float)
+    return x
+cast_to_float._annspecialcase_ = 'specialize:arg(0)'
+
 
 class BaseIntCallDescr(BaseCallDescr):
     # Base class of the various subclasses of descrs corresponding to
@@ -371,6 +397,9 @@
     def get_result_size(self, translate_support_code):
         return symbolic.get_size(lltype.Float, translate_support_code)
 
+class LongLongCallDescr(FloatCallDescr):
+    _clsname = 'LongLongCallDescr'
+
 class VoidCallDescr(BaseCallDescr):
     _clsname = 'VoidCallDescr'
     _return_type = history.VOID
@@ -383,6 +412,8 @@
         return VoidCallDescr
     if RESULT is lltype.Float:
         return FloatCallDescr
+    if is_longlong(RESULT):
+        return LongLongCallDescr
     return getDescrClass(RESULT, BaseIntCallDescr, GcPtrCallDescr,
                          NonGcPtrCallDescr, 'Call', 'get_result_size',
                          Ellipsis,  # <= floatattrname should not be used here
@@ -394,7 +425,11 @@
         kind = getkind(ARG)
         if   kind == 'int': arg_classes.append('i')
         elif kind == 'ref': arg_classes.append('r')
-        elif kind == 'float': arg_classes.append('f')
+        elif kind == 'float':
+            if is_longlong(ARG):
+                arg_classes.append('L')
+            else:
+                arg_classes.append('f')
         else:
             raise NotImplementedError('ARG = %r' % (ARG,))
     arg_classes = ''.join(arg_classes)
@@ -432,7 +467,7 @@
             return symbolic.get_size(TYPE, translate_support_code)
         setattr(Descr, methodname, method)
         #
-        if TYPE is lltype.Float:
+        if TYPE is lltype.Float or is_longlong(TYPE):
             setattr(Descr, floatattrname, True)
         elif TYPE is not lltype.Bool and rffi.cast(TYPE, -1) == -1:
             setattr(Descr, signedattrname, True)

diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1152,7 +1152,7 @@
                     src_r += 1
                     if box.type == history.REF:
                         break
-            elif kind == history.FLOAT:
+            elif kind == history.FLOAT or kind == 'L':    # long long
                 while True:
                     box = argboxes[src_f]
                     src_f += 1


More information about the Pypy-commit mailing list