[pypy-commit] pypy float-bytes: turn float2longlong into something that creates an llop

alex_gaynor noreply at buildbot.pypy.org
Thu Mar 15 20:01:01 CET 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: float-bytes
Changeset: r53690:d0bae406922f
Date: 2012-03-15 10:42 -0700
http://bitbucket.org/pypy/pypy/changeset/d0bae406922f/

Log:	turn float2longlong into something that creates an llop

diff --git a/pypy/rlib/bitmanipulation.py b/pypy/rlib/bitmanipulation.py
--- a/pypy/rlib/bitmanipulation.py
+++ b/pypy/rlib/bitmanipulation.py
@@ -1,5 +1,6 @@
 from pypy.rlib import unroll
 
+
 class BitSplitter(dict):
     def __getitem__(self, lengths):
         if isinstance(lengths, int):
diff --git a/pypy/rlib/longlong2float.py b/pypy/rlib/longlong2float.py
--- a/pypy/rlib/longlong2float.py
+++ b/pypy/rlib/longlong2float.py
@@ -5,7 +5,12 @@
 long long to a float and back to a long long.  There are corner cases
 in which it does not work.
 """
+
+from pypy.annotation import model as annmodel
+from pypy.rlib.rarithmetic import r_int64
 from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
 
 # -------- implement longlong2float and float2longlong --------
@@ -22,7 +27,7 @@
         floatval = d_array[0]
         return floatval
 
-def float2longlong_emulator(floatval):
+def float2longlong(floatval):
     with lltype.scoped_alloc(DOUBLE_ARRAY_PTR.TO, 1) as d_array:
         ll_array = rffi.cast(LONGLONG_ARRAY_PTR, d_array)
         d_array[0] = floatval
@@ -43,7 +48,6 @@
         ival = i_array[0]
         return ival
 
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
 eci = ExternalCompilationInfo(includes=['string.h', 'assert.h'],
                               post_include_bits=["""
 static double pypy__longlong2float(long long x) {
@@ -52,12 +56,6 @@
     memcpy(&dd, &x, 8);
     return dd;
 }
-static long long pypy__float2longlong(double x) {
-    long long ll;
-    assert(sizeof(double) == 8 && sizeof(long long) == 8);
-    memcpy(&ll, &x, 8);
-    return ll;
-}
 static float pypy__uint2singlefloat(unsigned int x) {
     float ff;
     assert(sizeof(float) == 4 && sizeof(unsigned int) == 4);
@@ -78,12 +76,6 @@
     _nowrapper=True, elidable_function=True, sandboxsafe=True,
     oo_primitive="pypy__longlong2float")
 
-float2longlong = rffi.llexternal(
-    "pypy__float2longlong", [rffi.DOUBLE], rffi.LONGLONG,
-    _callable=float2longlong_emulator, compilation_info=eci,
-    _nowrapper=True, elidable_function=True, sandboxsafe=True,
-    oo_primitive="pypy__float2longlong")
-
 uint2singlefloat = rffi.llexternal(
     "pypy__uint2singlefloat", [rffi.UINT], rffi.FLOAT,
     _callable=uint2singlefloat_emulator, compilation_info=eci,
@@ -95,3 +87,15 @@
     _callable=singlefloat2uint_emulator, compilation_info=eci,
     _nowrapper=True, elidable_function=True, sandboxsafe=True,
     oo_primitive="pypy__singlefloat2uint")
+
+
+class Float2LongLongEntry(ExtRegistryEntry):
+    _about_ = float2longlong
+
+    def compute_result_annotation(self, s_float):
+        assert annmodel.SomeFloat().contains(s_float)
+        return annmodel.SomeInteger(knowntype=r_int64)
+
+    def specialize_call(self, hop):
+        [v_float] = hop.inputargs(lltype.Float)
+        return hop.genop("convert_float_bytes_to_longlong", [v_float], resulttype=hop.r_result)
diff --git a/pypy/rlib/rfloat.py b/pypy/rlib/rfloat.py
--- a/pypy/rlib/rfloat.py
+++ b/pypy/rlib/rfloat.py
@@ -1,11 +1,13 @@
 """Float constants"""
 
 import math
+
+from pypy.annotation.model import SomeString
+from pypy.rlib import objectmodel
+from pypy.rpython.extfunc import register_external
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.rlib import objectmodel
-from pypy.rpython.extfunc import register_external
-from pypy.annotation.model import SomeString
+
 
 USE_SHORT_FLOAT_REPR = True # XXX make it a translation option?
 
@@ -74,7 +76,7 @@
         while i < len(s) and s[i] in '0123456789':
             after_point += s[i]
             i += 1
-            
+
         if i == len(s):
             return sign, before_point, after_point, exponent
 
@@ -91,7 +93,7 @@
 
     if i == len(s):
         raise ValueError
-    
+
     while i < len(s) and s[i] in '0123456789':
         exponent += s[i]
         i += 1
diff --git a/pypy/translator/c/src/float.h b/pypy/translator/c/src/float.h
--- a/pypy/translator/c/src/float.h
+++ b/pypy/translator/c/src/float.h
@@ -27,7 +27,7 @@
 #define OP_FLOAT_SUB(x,y,r)     r = x - y
 #define OP_FLOAT_MUL(x,y,r)     r = x * y
 #define OP_FLOAT_TRUEDIV(x,y,r) r = x / y
-#define OP_FLOAT_POW(x,y,r)     r = pow(x, y) 
+#define OP_FLOAT_POW(x,y,r)     r = pow(x, y)
 
 /*** conversions ***/
 
@@ -42,5 +42,6 @@
 #ifdef HAVE_LONG_LONG
 #define OP_CAST_FLOAT_TO_LONGLONG(x,r) r = (long long)(x)
 #define OP_CAST_FLOAT_TO_ULONGLONG(x,r) r = (unsigned long long)(x)
+#define OP_CONVERT_FLOAT_BYTES_TO_LONGLONG(x,r) memcpy(&r, &x, sizeof(double))
 #endif
 


More information about the pypy-commit mailing list