Changeset View
Changeset View
Standalone View
Standalone View
lib/msun/src/s_fmaf.c
Show All 28 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <fenv.h> | #include <fenv.h> | ||||
#include "math.h" | #include "math.h" | ||||
#include "math_private.h" | #include "math_private.h" | ||||
#ifdef USE_BUILTIN_FMAF | |||||
float | |||||
fmaf(float x, float y, float z) | |||||
{ | |||||
return (__builtin_fmaf(x, y, z)); | |||||
} | |||||
#else | |||||
/* | /* | ||||
* Fused multiply-add: Compute x * y + z with a single rounding error. | * Fused multiply-add: Compute x * y + z with a single rounding error. | ||||
* | * | ||||
* A double has more than twice as much precision than a float, so | * A double has more than twice as much precision than a float, so | ||||
* direct double-precision arithmetic suffices, except where double | * direct double-precision arithmetic suffices, except where double | ||||
* rounding occurs. | * rounding occurs. | ||||
*/ | */ | ||||
float | float | ||||
Show All 19 Lines | fmaf(float x, float y, float z) | ||||
fesetround(FE_TOWARDZERO); | fesetround(FE_TOWARDZERO); | ||||
volatile double vxy = xy; /* XXX work around gcc CSE bug */ | volatile double vxy = xy; /* XXX work around gcc CSE bug */ | ||||
double adjusted_result = vxy + z; | double adjusted_result = vxy + z; | ||||
fesetround(FE_TONEAREST); | fesetround(FE_TONEAREST); | ||||
if (result == adjusted_result) | if (result == adjusted_result) | ||||
SET_LOW_WORD(adjusted_result, lr + 1); | SET_LOW_WORD(adjusted_result, lr + 1); | ||||
return (adjusted_result); | return (adjusted_result); | ||||
} | } | ||||
#endif /* !USE_BUILTIN_FMAF */ |