[pypy-commit] pypy jit-singlefloat: Add byte-by-byte conversion between ints and singlefloats.
arigo
noreply at buildbot.pypy.org
Thu Jul 28 21:47:36 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: jit-singlefloat
Changeset: r46058:619cf7b82467
Date: 2011-07-28 15:42 +0200
http://bitbucket.org/pypy/pypy/changeset/619cf7b82467/
Log: Add byte-by-byte conversion between ints and singlefloats.
diff --git a/pypy/rlib/longlong2float.py b/pypy/rlib/longlong2float.py
--- a/pypy/rlib/longlong2float.py
+++ b/pypy/rlib/longlong2float.py
@@ -11,6 +11,8 @@
# -------- implement longlong2float and float2longlong --------
DOUBLE_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.DOUBLE))
LONGLONG_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.LONGLONG))
+INT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.INT))
+FLOAT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.FLOAT))
# these definitions are used only in tests, when not translated
def longlong2float_emulator(llval):
@@ -29,6 +31,22 @@
lltype.free(d_array, flavor='raw')
return llval
+def int2singlefloat_emulator(ival):
+ f_array = lltype.malloc(FLOAT_ARRAY_PTR.TO, 1, flavor='raw')
+ i_array = rffi.cast(INT_ARRAY_PTR, f_array)
+ i_array[0] = ival
+ singlefloatval = f_array[0]
+ lltype.free(f_array, flavor='raw')
+ return singlefloatval
+
+def singlefloat2int_emulator(singlefloatval):
+ f_array = lltype.malloc(FLOAT_ARRAY_PTR.TO, 1, flavor='raw')
+ i_array = rffi.cast(INT_ARRAY_PTR, f_array)
+ f_array[0] = singlefloatval
+ ival = i_array[0]
+ lltype.free(f_array, flavor='raw')
+ return ival
+
from pypy.translator.tool.cbuild import ExternalCompilationInfo
eci = ExternalCompilationInfo(includes=['string.h', 'assert.h'],
post_include_bits=["""
@@ -44,6 +62,18 @@
memcpy(&ll, &x, 8);
return ll;
}
+static float pypy__int2singlefloat(int x) {
+ float ff;
+ assert(sizeof(float) == 4 && sizeof(int) == 4);
+ memcpy(&ff, &x, 4);
+ return ff;
+}
+static int pypy__singlefloat2int(float x) {
+ int ii;
+ assert(sizeof(float) == 4 && sizeof(int) == 4);
+ memcpy(&ii, &x, 4);
+ return ii;
+}
"""])
longlong2float = rffi.llexternal(
@@ -55,3 +85,13 @@
"pypy__float2longlong", [rffi.DOUBLE], rffi.LONGLONG,
_callable=float2longlong_emulator, compilation_info=eci,
_nowrapper=True, elidable_function=True)
+
+int2singlefloat = rffi.llexternal(
+ "pypy__int2singlefloat", [rffi.INT], rffi.FLOAT,
+ _callable=int2singlefloat_emulator, compilation_info=eci,
+ _nowrapper=True, elidable_function=True)
+
+singlefloat2int = rffi.llexternal(
+ "pypy__singlefloat2int", [rffi.FLOAT], rffi.INT,
+ _callable=singlefloat2int_emulator, compilation_info=eci,
+ _nowrapper=True, elidable_function=True)
diff --git a/pypy/rlib/test/test_longlong2float.py b/pypy/rlib/test/test_longlong2float.py
--- a/pypy/rlib/test/test_longlong2float.py
+++ b/pypy/rlib/test/test_longlong2float.py
@@ -1,5 +1,7 @@
from pypy.translator.c.test.test_genc import compile
from pypy.rlib.longlong2float import longlong2float, float2longlong
+from pypy.rlib.longlong2float import int2singlefloat, singlefloat2int
+from pypy.rlib.rarithmetic import r_singlefloat
def fn(f1):
@@ -28,3 +30,23 @@
for x in enum_floats():
res = fn2(x)
assert repr(res) == repr(x)
+
+# ____________________________________________________________
+
+def fnsingle(f1):
+ sf1 = r_singlefloat(f1)
+ ii = singlefloat2int(sf1)
+ sf2 = int2singlefloat(ii)
+ f2 = float(sf2)
+ return f2
+
+def test_int_as_singlefloat():
+ for x in enum_floats():
+ res = fnsingle(x)
+ assert repr(res) == repr(float(r_singlefloat(x)))
+
+def test_compiled_single():
+ fn2 = compile(fnsingle, [float])
+ for x in enum_floats():
+ res = fn2(x)
+ assert repr(res) == repr(float(r_singlefloat(x)))
More information about the pypy-commit
mailing list