[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