[pypy-svn] r79707 - in pypy/branch/jitypes2/pypy: jit/metainterp/test rlib rlib/test

antocuni at codespeak.net antocuni at codespeak.net
Wed Dec 1 14:25:58 CET 2010


Author: antocuni
Date: Wed Dec  1 14:25:51 2010
New Revision: 79707

Modified:
   pypy/branch/jitypes2/pypy/jit/metainterp/test/test_fficall.py
   pypy/branch/jitypes2/pypy/rlib/libffi.py
   pypy/branch/jitypes2/pypy/rlib/test/test_libffi.py
Log:
add support for single float parameters and result to rlib.libffi. A bit
hackish because we have to work around the limitation of the JIT which does
not support single floats



Modified: pypy/branch/jitypes2/pypy/jit/metainterp/test/test_fficall.py
==============================================================================
--- pypy/branch/jitypes2/pypy/jit/metainterp/test/test_fficall.py	(original)
+++ pypy/branch/jitypes2/pypy/jit/metainterp/test/test_fficall.py	Wed Dec  1 14:25:51 2010
@@ -1,5 +1,6 @@
 
 import py
+from pypy.rlib.rarithmetic import r_singlefloat
 from pypy.rlib.jit import JitDriver, hint
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.libffi import ArgChain
@@ -35,7 +36,10 @@
                 func = hint(func, promote=True)
                 argchain = ArgChain()
                 for argval in args: # this loop is unrolled
-                    argchain.arg(argval)
+                    if type(argval) is r_singlefloat:
+                        argchain.arg_singlefloat(float(argval))
+                    else:
+                        argchain.arg(argval)
                 res = func.call(argchain, RESULT)
                 n += 1
             return res

Modified: pypy/branch/jitypes2/pypy/rlib/libffi.py
==============================================================================
--- pypy/branch/jitypes2/pypy/rlib/libffi.py	(original)
+++ pypy/branch/jitypes2/pypy/rlib/libffi.py	Wed Dec  1 14:25:51 2010
@@ -1,6 +1,6 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rlib.objectmodel import specialize, enforceargs, we_are_translated
-from pypy.rlib.rarithmetic import intmask, r_uint
+from pypy.rlib.rarithmetic import intmask, r_uint, r_singlefloat
 from pypy.rlib import jit
 from pypy.rlib import clibffi
 from pypy.rlib.clibffi import get_libc_name, FUNCFLAG_CDECL, AbstractFuncPtr, \
@@ -40,6 +40,7 @@
         """
         if   ffi_type is types.void:    return 'v'
         elif ffi_type is types.double:  return 'f'
+        elif ffi_type is types.float:   return 'f'
         elif ffi_type is types.pointer: return 'i'
         #
         elif ffi_type is types.schar:   return 'i'
@@ -104,11 +105,21 @@
             val = rffi.cast(rffi.LONG, val)
         elif TYPE is rffi.DOUBLE:
             cls = FloatArg
+        elif TYPE is rffi.FLOAT:
+            raise TypeError, 'r_singlefloat not supported by arg(), use arg_singlefloat()'
         else:
             raise TypeError, 'Unsupported argument type: %s' % TYPE
         self._append(cls(val))
         return self
 
+    def arg_singlefloat(self, val):
+        """
+        Note: you must pass a python Float (rffi.DOUBLE), not a r_singlefloat
+        (else the jit complains).  Note that if you use single floats, the
+        call won't be jitted at all.
+        """
+        self._append(SingleFloatArg(val))
+
     def _append(self, arg):
         if self.first is None:
             self.first = self.last = arg
@@ -132,7 +143,7 @@
         func._push_int(self.intval, ll_args, i)
 
 class FloatArg(AbstractArg):
-    """ An argument holding a float
+    """ An argument holding a python float (i.e. a C double)
     """
 
     def __init__(self, floatval):
@@ -142,6 +153,17 @@
         func._push_float(self.floatval, ll_args, i)
 
 
+class SingleFloatArg(AbstractArg):
+    """ An argument holding a C float
+    """
+
+    def __init__(self, floatval):
+        self.floatval = floatval
+
+    def push(self, func, ll_args, i):
+        func._push_single_float(self.floatval, ll_args, i)
+
+
 # ======================================================================
 
 
@@ -190,6 +212,10 @@
             res = self._do_call_int(self.funcsym, ll_args)
         elif RESULT is rffi.DOUBLE:
             return self._do_call_float(self.funcsym, ll_args)
+        elif RESULT is rffi.FLOAT:
+            # XXX: even if RESULT is FLOAT, we still return a DOUBLE, else the
+            # jit complains. Note that the jit is disabled in this case
+            return self._do_call_single_float(self.funcsym, ll_args)
         elif RESULT is lltype.Void:
             return self._do_call_void(self.funcsym, ll_args)
         else:
@@ -223,6 +249,10 @@
     def _push_float(self, value, ll_args, i):
         self._push_arg(value, ll_args, i)
 
+    @jit.dont_look_inside
+    def _push_single_float(self, value, ll_args, i):
+        self._push_arg(r_singlefloat(value), ll_args, i)
+
     @jit.oopspec('libffi_call_int(self, funcsym, ll_args)')
     def _do_call_int(self, funcsym, ll_args):
         return self._do_call(funcsym, ll_args, rffi.LONG)
@@ -231,6 +261,11 @@
     def _do_call_float(self, funcsym, ll_args):
         return self._do_call(funcsym, ll_args, rffi.DOUBLE)
 
+    @jit.dont_look_inside
+    def _do_call_single_float(self, funcsym, ll_args):
+        single_res = self._do_call(funcsym, ll_args, rffi.FLOAT)
+        return float(single_res)
+
     @jit.oopspec('libffi_call_void(self, funcsym, ll_args)')
     def _do_call_void(self, funcsym, ll_args):
         return self._do_call(funcsym, ll_args, lltype.Void)

Modified: pypy/branch/jitypes2/pypy/rlib/test/test_libffi.py
==============================================================================
--- pypy/branch/jitypes2/pypy/rlib/test/test_libffi.py	(original)
+++ pypy/branch/jitypes2/pypy/rlib/test/test_libffi.py	Wed Dec  1 14:25:51 2010
@@ -2,6 +2,7 @@
 import sys
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rpython.lltypesystem.ll2ctypes import ALLOCATED
+from pypy.rlib.rarithmetic import r_singlefloat
 from pypy.rlib.test.test_clibffi import BaseFfiTest, get_libm_name
 from pypy.rlib.libffi import CDLL, Func, get_libc_name, ArgChain, types
 
@@ -110,7 +111,10 @@
         func = lib.getpointer(name, argtypes, restype)
         chain = ArgChain()
         for arg in args:
-            chain.arg(arg)
+            if isinstance(arg, r_singlefloat):
+                chain.arg_singlefloat(float(arg))
+            else:
+                chain.arg(arg)
         return func.call(chain, RESULT)
 
     def check_loops(self, *args, **kwds):
@@ -262,3 +266,19 @@
         #
         res = self.call(get_dummy, [], rffi.LONG)
         assert res == initval+1
+
+    def test_single_float_args(self):
+        """
+            float sum_xy_float(float x, float y)
+            {
+                return x+y;
+            }
+        """
+        from ctypes import c_float # this is used only to compute the expected result
+        libfoo = self.get_libfoo()
+        func = (libfoo, 'sum_xy_float', [types.float, types.float], types.float)
+        x = r_singlefloat(12.34)
+        y = r_singlefloat(56.78)
+        res = self.call(func, [x, y], rffi.FLOAT, init_result=0.0)
+        expected = c_float(c_float(12.34).value + c_float(56.78).value).value
+        assert res == expected



More information about the Pypy-commit mailing list