};
double m = z - 0x1.7p+1;
- double i = roundeven (m);
+ double i = roundeven_finite (m);
double step = copysign (1.0, i);
double d = m - i, d2 = d * d, d4 = d2 * d2, d8 = d4 * d4;
double f = (c[0] + d * c[1]) + d2 * (c[2] + d * c[3])
converttoint (double_t x);
#endif
+#ifndef ROUNDEVEN_INTRINSICS
+/* When set, roundeven_finite will route to the internal roundeven function. */
+# define ROUNDEVEN_INTRINSICS 1
+#endif
+
+/* Round x to nearest integer value in floating-point format, rounding halfway
+ cases to even. If the input is non finite the result is unspecified. */
+static inline double
+roundeven_finite (double x)
+{
+ if (!isfinite (x))
+ __builtin_unreachable ();
+#if ROUNDEVEN_INTRINSICS
+ return roundeven (x);
+#else
+ double y = round (x);
+ if (fabs (x - y) == 0.5)
+ {
+ union { double f; uint64_t i; } u = {y};
+ union { double f; uint64_t i; } v = {y - copysign (1.0, x)};
+ if (__builtin_ctzll (v.i) > __builtin_ctzll (u.i))
+ y = v.f;
+ }
+ return y;
+#endif
+}
+
static inline uint32_t
asuint (float f)
{
return __math_oflowf (0);
}
double a = iln2 * z;
- double ia = roundeven (a);
+ double ia = roundeven_finite (a);
double h = a - ia;
double h2 = h * h;
uint64_t u = asuint64 (ia + big);
double x = z;
double idl = -0x1.b1bbead603d8bp-32 * x;
double idh = 0x1.45f306ep-1 * x;
- double id = roundeven (idh);
+ double id = roundeven_finite (idh);
*q = (int64_t) id;
return (idh - id) + idl;
}
#define _GL_HAS_BUILTIN_ILOGB 0
#endif
+#ifdef _ARCH_PWR6
+/* ISA 2.03 provides frin/round() and cntlzw/ctznll(). */
+# define ROUNDEVEN_INTRINSICS 0
+#endif
+
#endif /* _PPC_MATH_PRIVATE_H_ */