summaryrefslogtreecommitdiffstats
path: root/lib/msun
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2005-03-07 05:02:09 +0000
committerdas <das@FreeBSD.org>2005-03-07 05:02:09 +0000
commit59658f6dc58fa80026c43252d70aa8ac6cf4825d (patch)
treecf46a485cb6eb9edb275118b15a9dba085c98c78 /lib/msun
parent3e55f968bf19fb0ab9c572df59efd5b2403a16ea (diff)
downloadFreeBSD-src-59658f6dc58fa80026c43252d70aa8ac6cf4825d.zip
FreeBSD-src-59658f6dc58fa80026c43252d70aa8ac6cf4825d.tar.gz
- If z is 0, one of x or y is 0, and the other is infinite, raise
an invalid exception and return an NaN. - If a long double has 113 bits of precision, implement fma in terms of simple long double arithmetic instead of complicated double arithmetic. - If a long double is the same as a double, alias fma as fmal.
Diffstat (limited to 'lib/msun')
-rw-r--r--lib/msun/src/s_fma.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/msun/src/s_fma.c b/lib/msun/src/s_fma.c
index 401c2c7..2f7db3a 100644
--- a/lib/msun/src/s_fma.c
+++ b/lib/msun/src/s_fma.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
* XXX On machines supporting quad precision, we should use that, but
* see the caveat in s_fmaf.c.
*/
+#if LDBL_MANT_DIG != 113
double
fma(double x, double y, double z)
{
@@ -66,10 +67,10 @@ fma(double x, double y, double z)
int ex, ey, ez;
int spread;
- if (x == 0.0 || y == 0.0)
- return (z);
if (z == 0.0)
return (x * y);
+ if (x == 0.0 || y == 0.0)
+ return (x * y + z);
/* Results of frexp() are undefined for these cases. */
if (!isfinite(x) || !isfinite(y) || !isfinite(z))
@@ -176,3 +177,18 @@ fma(double x, double y, double z)
fesetround(oround);
return (ldexp(r + rr, ex + ey));
}
+#else /* LDBL_MANT_DIG == 113 */
+/*
+ * 113 bits of precision is more than twice the precision of a double,
+ * so it is enough to represent the intermediate product exactly.
+ */
+double
+fma(double x, double y, double z)
+{
+ return ((long double)x * y + z);
+}
+#endif /* LDBL_MANT_DIG != 113 */
+
+#if (LDBL_MANT_DIG == 53)
+__strong_reference(fma, fmal);
+#endif
OpenPOWER on IntegriCloud