[pypy-commit] pypy ppc-vsx-support: merge default

plan_rich pypy.commits at gmail.com
Thu Aug 4 06:45:49 EDT 2016


Author: Richard Plangger <planrichi at gmail.com>
Branch: ppc-vsx-support
Changeset: r86012:bd6d62fca9de
Date: 2016-08-04 12:44 +0200
http://bitbucket.org/pypy/pypy/changeset/bd6d62fca9de/

Log:	merge default

diff --git a/rpython/translator/c/src/float.h b/rpython/translator/c/src/float.h
--- a/rpython/translator/c/src/float.h
+++ b/rpython/translator/c/src/float.h
@@ -34,10 +34,39 @@
 #define OP_CAST_FLOAT_TO_UINT(x,r)   r = (Unsigned)(x)
 #define OP_CAST_INT_TO_FLOAT(x,r)    r = (double)(x)
 #define OP_CAST_UINT_TO_FLOAT(x,r)   r = (double)(x)
-#define OP_CAST_LONGLONG_TO_FLOAT(x,r) r = (double)(x)
-#define OP_CAST_ULONGLONG_TO_FLOAT(x,r) r = (double)(x)
+#define OP_CAST_LONGLONG_TO_FLOAT(x,r) r = rpy_cast_longlong_to_float(x)
+#define OP_CAST_ULONGLONG_TO_FLOAT(x,r) r = rpy_cast_ulonglong_to_float(x)
 #define OP_CAST_BOOL_TO_FLOAT(x,r)   r = (double)(x)
 
+#ifdef _WIN32
+/* The purpose of these two functions is to work around a MSVC bug.
+   The expression '(double)131146795334735160LL' will lead to bogus
+   rounding, but apparently everything is fine if we write instead
+   rpy_cast_longlong_to_float(131146795334735160LL).  Tested with 
+   MSVC 2008.  Note that even if the two functions contain just
+   'return (double)x;' it seems to work on MSVC 2008, but I don't
+   trust that there are no other corner cases.
+   http://stackoverflow.com/questions/33829101/incorrect-double-to-long-conversion
+*/
+static _inline double rpy_cast_longlong_to_float(long long x)
+{
+    unsigned int lo = (unsigned int)x;
+    double result = lo;
+    result += ((int)(x >> 32)) * 4294967296.0;
+    return result;
+}
+static _inline double rpy_cast_ulonglong_to_float(unsigned long long x)
+{
+    unsigned int lo = (unsigned int)x;
+    double result = lo;
+    result += ((unsigned int)(x >> 32)) * 4294967296.0;
+    return result;
+}
+#else
+#  define rpy_cast_longlong_to_float(x) ((double)(x))
+#  define rpy_cast_ulonglong_to_float(x) ((double)(x))
+#endif
+
 #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)


More information about the pypy-commit mailing list