[pypy-svn] pypy default: Copy the logic of CPython to fix the precision around
arigo
commits-noreply at bitbucket.org
Sun Feb 13 13:46:34 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r41872:1ea103d126e9
Date: 2011-02-13 13:03 +0100
http://bitbucket.org/pypy/pypy/changeset/1ea103d126e9/
Log: Copy the logic of CPython to fix the precision around calls to
dtoa.c, on x87 fpus.
diff --git a/pypy/translator/c/src/asm.h b/pypy/translator/c/src/asm.h
new file mode 100644
--- /dev/null
+++ b/pypy/translator/c/src/asm.h
@@ -0,0 +1,13 @@
+
+/* optional assembler bits */
+#if defined(__GNUC__) && defined(__i386__)
+# include "src/asm_gcc_x86.h"
+#endif
+
+#if defined(__GNUC__) && defined(__amd64__)
+# include "src/asm_gcc_x86_64.h"
+#endif
+
+#if defined(__GNUC__) && defined(__ppc__)
+# include "src/asm_ppc.h"
+#endif
diff --git a/pypy/jit/backend/x86/support.py b/pypy/jit/backend/x86/support.py
--- a/pypy/jit/backend/x86/support.py
+++ b/pypy/jit/backend/x86/support.py
@@ -39,7 +39,8 @@
ensure_sse2_floats = lambda : None
else:
_sse2_eci = ExternalCompilationInfo(
- compile_extra = ['-msse2', '-mfpmath=sse'],
+ compile_extra = ['-msse2', '-mfpmath=sse',
+ '-DPYPY_CPU_HAS_STANDARD_PRECISION'],
separate_module_sources = ['void PYPY_NO_OP(void) {}'],
)
ensure_sse2_floats = rffi.llexternal('PYPY_NO_OP', [], lltype.Void,
diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h
--- a/pypy/translator/c/src/g_include.h
+++ b/pypy/translator/c/src/g_include.h
@@ -37,19 +37,7 @@
#include "src/llgroup.h"
#include "src/instrument.h"
-
-/* optional assembler bits */
-#if defined(__GNUC__) && defined(__i386__)
-# include "src/asm_gcc_x86.h"
-#endif
-
-#if defined(__GNUC__) && defined(__amd64__)
-# include "src/asm_gcc_x86_64.h"
-#endif
-
-#if defined(__GNUC__) && defined(__ppc__)
-# include "src/asm_ppc.h"
-#endif
+#include "src/asm.h"
/*** modules ***/
diff --git a/pypy/translator/c/src/asm_gcc_x86.h b/pypy/translator/c/src/asm_gcc_x86.h
--- a/pypy/translator/c/src/asm_gcc_x86.h
+++ b/pypy/translator/c/src/asm_gcc_x86.h
@@ -71,6 +71,37 @@
// I don't know how important it is, comment talks about time warps
+#ifndef PYPY_CPU_HAS_STANDARD_PRECISION
+/* On x86-32, we have to use the following hacks to set and restore
+ * the CPU's precision to 53 bits around calls to dtoa.c. The macro
+ * PYPY_CPU_HAS_STANDARD_PRECISION is defined if we are compiling
+ * with -mss2 -mfpmath=sse anyway, in which case the precision is
+ * already ok.
+ */
+#define _PyPy_SET_53BIT_PRECISION_HEADER \
+ unsigned short old_387controlword, new_387controlword
+#define _PyPy_SET_53BIT_PRECISION_START \
+ do { \
+ old_387controlword = _PyPy_get_387controlword(); \
+ new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \
+ if (new_387controlword != old_387controlword) \
+ _PyPy_set_387controlword(new_387controlword); \
+ } while (0)
+#define _PyPy_SET_53BIT_PRECISION_END \
+ if (new_387controlword != old_387controlword) \
+ _PyPy_set_387controlword(old_387controlword)
+
+static unsigned short _PyPy_get_387controlword(void) {
+ unsigned short cw;
+ __asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
+ return cw;
+}
+static void _PyPy_set_387controlword(unsigned short cw) {
+ __asm__ __volatile__ ("fldcw %0" : : "m" (cw));
+}
+#endif /* !PYPY_CPU_HAS_STANDARD_PRECISION */
+
+
/* implementations */
#ifndef PYPY_NOT_MAIN_FILE
diff --git a/pypy/translator/c/src/dtoa.c b/pypy/translator/c/src/dtoa.c
--- a/pypy/translator/c/src/dtoa.c
+++ b/pypy/translator/c/src/dtoa.c
@@ -130,11 +130,9 @@
#include <string.h>
#define PYPY_NOT_MAIN_FILE
#include "src/allocator.h"
+#include "src/asm.h"
#define PyMem_Malloc PyObject_Malloc
#define PyMem_Free PyObject_Free
-#define _Py_dg_strtod _PyPy_dg_strtod
-#define _Py_dg_dtoa _PyPy_dg_dtoa
-#define _Py_dg_freedtoa _PyPy_dg_freedtoa
/* End PYPY hacks */
@@ -1508,7 +1506,7 @@
return 0;
}
-double
+static double
_Py_dg_strtod(const char *s00, char **se)
{
int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error;
@@ -2286,7 +2284,7 @@
* when MULTIPLE_THREADS is not defined.
*/
-void
+static void
_Py_dg_freedtoa(char *s)
{
Bigint *b = (Bigint *)((int *)s - 1);
@@ -2332,7 +2330,7 @@
leakage, a successful call to _Py_dg_dtoa should always be matched by a
call to _Py_dg_freedtoa. */
-char *
+static char *
_Py_dg_dtoa(double dd, int mode, int ndigits,
int *decpt, int *sign, char **rve)
{
@@ -2933,6 +2931,47 @@
_Py_dg_freedtoa(s0);
return NULL;
}
+
+
+/* Begin PYPY hacks */
+#ifndef _PyPy_SET_53BIT_PRECISION_HEADER
+# define _PyPy_SET_53BIT_PRECISION_HEADER /* nothing */
+#endif
+#ifndef _PyPy_SET_53BIT_PRECISION_START
+# define _PyPy_SET_53BIT_PRECISION_START /* nothing */
+#endif
+#ifndef _PyPy_SET_53BIT_PRECISION_END
+# define _PyPy_SET_53BIT_PRECISION_END /* nothing */
+#endif
+double _PyPy_dg_strtod(const char *s00, char **se)
+{
+ double result;
+ _PyPy_SET_53BIT_PRECISION_HEADER;
+
+ _PyPy_SET_53BIT_PRECISION_START;
+ result = _Py_dg_strtod(s00, se);
+ _PyPy_SET_53BIT_PRECISION_END;
+ return result;
+}
+
+char * _PyPy_dg_dtoa(double dd, int mode, int ndigits,
+ int *decpt, int *sign, char **rve)
+{
+ char* result;
+ _PyPy_SET_53BIT_PRECISION_HEADER;
+
+ _PyPy_SET_53BIT_PRECISION_START;
+ result = _Py_dg_dtoa(dd, mode, ndigits, decpt, sign, rve);
+ _PyPy_SET_53BIT_PRECISION_END;
+ return result;
+}
+
+void _PyPy_dg_freedtoa(char *s)
+{
+ _Py_dg_freedtoa(s);
+}
+/* End PYPY hacks */
+
#ifdef __cplusplus
}
#endif
More information about the Pypy-commit
mailing list