[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