This change should prevent compilers from
optimizing away the structure used for checking
strings in the binary by also using it to produce
a return values. There are now also clearer
warnings, and if IEEE754 cannot be detected we
fall by to using the OS versions of erf/erfc()
in double precision. Fixes compiles on Power7.
Change-Id: I8ed834d5b87baf33e03725d2ab93a60a76c34a12
{
/* Check that a double is 8 bytes - compilation dies if it isnt */
extern char xyz [sizeof(double) == 8 ? 1 : -1];
{
/* Check that a double is 8 bytes - compilation dies if it isnt */
extern char xyz [sizeof(double) == 8 ? 1 : -1];
/* Zero-terminated strings encoded as floating-point numbers */
/* "GROMACSX" in ascii */
(double) 3.80279098314984902657e+35 , (double) 0.0,
/* Zero-terminated strings encoded as floating-point numbers */
/* "GROMACSX" in ascii */
(double) 3.80279098314984902657e+35 , (double) 0.0,
(double) -5.22995989424860458374e+10 , (double) 0.0,
};
(double) -5.22995989424860458374e+10 , (double) 0.0,
};
+ /* Make sure some compilers do not optimize away the entire structure
+ * with floating-point data by using it to produce a return value.
+ */
+ for(i=0,d=0;i<10;i++)
+ {
+ d+=abc[i];
+ }
+
+ return (d==12345.0);
MESSAGE(STATUS "Checking floating point format - IEEE754 (LE byte, LE word)")
else()
MESSAGE(STATUS "Checking floating point format - unknown")
MESSAGE(STATUS "Checking floating point format - IEEE754 (LE byte, LE word)")
else()
MESSAGE(STATUS "Checking floating point format - unknown")
+ MESSAGE(WARNING "Cannot detect your floating-point format. It is extremely unlikely to be anything else than IEEE754, but if we do not know the endian we need to rely on your OS providing the math functions erfd() and erfcd() rather than using our built-in ones.")
endif()
ENDIF()
ENDMACRO(GMX_TEST_FLOAT_FORMAT FP_IEEE754 FP_BIG_ENDIAN_BYTE FP_BIG_ENDIAN_WORD)
endif()
ENDIF()
ENDMACRO(GMX_TEST_FLOAT_FORMAT FP_IEEE754 FP_BIG_ENDIAN_BYTE FP_BIG_ENDIAN_WORD)
double gmx_erfd(double x)
{
double gmx_erfd(double x)
{
+#ifdef GMX_FLOAT_FORMAT_IEEE754
gmx_int32_t hx, ix, i;
double R, S, P, Q, s, y, z, r;
gmx_int32_t hx, ix, i;
double R, S, P, Q, s, y, z, r;
- /* In release-4-6 and later branches, only the test for
- * GMX_IEEE754_BIG_ENDIAN_WORD_ORDER will be required. */
-#if defined(IEEE754_BIG_ENDIAN_WORD_ORDER) || defined(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
+#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
hx = conv.i[0];
#else
hx = conv.i[1];
hx = conv.i[0];
#else
hx = conv.i[1];
- /* In release-4-6 and later branches, only the test for
- * GMX_IEEE754_BIG_ENDIAN_WORD_ORDER will be required. */
-#if defined(IEEE754_BIG_ENDIAN_WORD_ORDER) || defined(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
+#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
conv.i[1] = 0;
#else
conv.i[0] = 0;
conv.i[1] = 0;
#else
conv.i[0] = 0;
+#else
+ /* No IEEE754 information. We need to trust that the OS provides erf(). */
+ return erf(x);
+#endif
}
double gmx_erfcd(double x)
{
}
double gmx_erfcd(double x)
{
+#ifdef GMX_FLOAT_FORMAT_IEEE754
gmx_int32_t hx, ix;
double R, S, P, Q, s, y, z, r;
gmx_int32_t hx, ix;
double R, S, P, Q, s, y, z, r;
- /* In release-4-6 and later branches, only the test for
- * GMX_IEEE754_BIG_ENDIAN_WORD_ORDER will be required. */
-#if defined(IEEE754_BIG_ENDIAN_WORD_ORDER) || defined(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
+#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
hx = conv.i[0];
#else
hx = conv.i[1];
hx = conv.i[0];
#else
hx = conv.i[1];
- /* In release-4-6 and later branches, only the test for
- * GMX_IEEE754_BIG_ENDIAN_WORD_ORDER will be required. */
-#if defined(IEEE754_BIG_ENDIAN_WORD_ORDER) || defined(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
+#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
conv.i[1] = 0;
#else
conv.i[0] = 0;
conv.i[1] = 0;
#else
conv.i[0] = 0;
+#else
+ /* No IEEE754 information. We need to trust that the OS provides erfc(). */
+ return erfc(x);
+#endif