/* Fused multiply-add.
- Copyright (C) 2007, 2009, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2009, 2011-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
# define LDEXP ldexpl
# define MIN_EXP LDBL_MIN_EXP
# define MANT_BIT LDBL_MANT_BIT
-# define DECL_ROUNDING DECL_LONG_DOUBLE_ROUNDING
-# define BEGIN_ROUNDING() BEGIN_LONG_DOUBLE_ROUNDING ()
-# define END_ROUNDING() END_LONG_DOUBLE_ROUNDING ()
# define L_(literal) literal##L
#elif ! defined USE_FLOAT
# define FUNC fma
# define LDEXP ldexp
# define MIN_EXP DBL_MIN_EXP
# define MANT_BIT DBL_MANT_BIT
-# define DECL_ROUNDING
-# define BEGIN_ROUNDING()
-# define END_ROUNDING()
# define L_(literal) literal
#else /* defined USE_FLOAT */
# define FUNC fmaf
# define LDEXP ldexpf
# define MIN_EXP FLT_MIN_EXP
# define MANT_BIT FLT_MANT_BIT
-# define DECL_ROUNDING
-# define BEGIN_ROUNDING()
-# define END_ROUNDING()
# define L_(literal) literal##f
#endif
#undef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
+/* MSVC with option -fp:strict refuses to compile constant initializers that
+ contain floating-point operations. Pacify this compiler. */
+#ifdef _MSC_VER
+# pragma fenv_access (off)
+#endif
+
+/* Work around GCC 4.2.1 bug on OpenBSD 5.1/SPARC64. */
+#if defined __GNUC__ && defined __sparc__
+# define VOLATILE volatile
+#else
+# define VOLATILE
+#endif
+
/* It is possible to write an implementation of fused multiply-add with
floating-point operations alone. See
Sylvie Boldo, Guillaume Melquiond:
else
{
/* First loop round. */
- fsum = (DOUBLE)
- ((sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
- | (sum_len >= k + 2 ? sum[sum_len - k - 2] >> shift : 0));
+ {
+ VOLATILE mp_limb_t chunk =
+ (sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
+ | (sum_len >= k + 2 ? sum[sum_len - k - 2] >> shift : 0);
+ fsum = (DOUBLE) chunk;
+ }
/* General loop. */
while (--k >= 0)
{
fsum *= chunk_multiplier;
- fsum += (DOUBLE)
- ((sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
- | (sum[sum_len - k - 2] >> shift));
+ {
+ VOLATILE mp_limb_t chunk =
+ (sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
+ | (sum[sum_len - k - 2] >> shift);
+ fsum += (DOUBLE) chunk;
+ }
}
}
}