Changeset View
Changeset View
Standalone View
Standalone View
lib/msun/src/s_fma.c
Show All 29 Lines | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <fenv.h> | #include <fenv.h> | ||||
#include <float.h> | #include <float.h> | ||||
#include <math.h> | #include <math.h> | ||||
#include "math_private.h" | #include "math_private.h" | ||||
#ifdef USE_BUILTIN_FMA | |||||
double | |||||
fma(double x, double y, double z) | |||||
{ | |||||
return (__builtin_fma(x, y, z)); | |||||
} | |||||
#else | |||||
/* | /* | ||||
* A struct dd represents a floating-point number with twice the precision | * A struct dd represents a floating-point number with twice the precision | ||||
* of a double. We maintain the invariant that "hi" stores the 53 high-order | * of a double. We maintain the invariant that "hi" stores the 53 high-order | ||||
* bits of the result. | * bits of the result. | ||||
*/ | */ | ||||
struct dd { | struct dd { | ||||
double hi; | double hi; | ||||
double lo; | double lo; | ||||
▲ Show 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | fma(double x, double y, double z) | ||||
} | } | ||||
adj = add_adjusted(r.lo, xy.lo); | adj = add_adjusted(r.lo, xy.lo); | ||||
if (spread + ilogb(r.hi) > -1023) | if (spread + ilogb(r.hi) > -1023) | ||||
return (ldexp(r.hi + adj, spread)); | return (ldexp(r.hi + adj, spread)); | ||||
else | else | ||||
return (add_and_denormalize(r.hi, adj, spread)); | return (add_and_denormalize(r.hi, adj, spread)); | ||||
} | } | ||||
#endif /* !USE_BUILTIN_FMA */ | |||||
#if (LDBL_MANT_DIG == 53) | #if (LDBL_MANT_DIG == 53) | ||||
__weak_reference(fma, fmal); | __weak_reference(fma, fmal); | ||||
#endif | #endif |