ieee754: provide gcc builtins based generic fma functions

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
This commit is contained in:
Vineet Gupta 2020-05-29 15:58:33 -07:00
parent 3374868668
commit 628d90c5f9
7 changed files with 34 additions and 0 deletions

View File

@ -63,4 +63,9 @@
#define USE_SQRT_BUILTIN 0 #define USE_SQRT_BUILTIN 0
#define USE_SQRTF_BUILTIN 0 #define USE_SQRTF_BUILTIN 0
#define USE_FMA_BUILTIN 0
#define USE_FMAF_BUILTIN 0
#define USE_FMAL_BUILTIN 0
#define USE_FMAF128_BUILTIN 0
#endif /* math-use-builtins.h */ #endif /* math-use-builtins.h */

View File

@ -25,6 +25,7 @@
#include <fenv_private.h> #include <fenv_private.h>
#include <libm-alias-double.h> #include <libm-alias-double.h>
#include <tininess.h> #include <tininess.h>
#include <math-use-builtins.h>
/* This implementation uses rounding to odd to avoid problems with /* This implementation uses rounding to odd to avoid problems with
double rounding. See a paper by Boldo and Melquiond: double rounding. See a paper by Boldo and Melquiond:
@ -33,6 +34,10 @@
double double
__fma (double x, double y, double z) __fma (double x, double y, double z)
{ {
#if USE_FMA_BUILTIN
return __builtin_fma (x, y, z);
#else
/* Use generic implementation. */
union ieee754_double u, v, w; union ieee754_double u, v, w;
int adjust = 0; int adjust = 0;
u.d = x; u.d = x;
@ -292,6 +297,7 @@ __fma (double x, double y, double z)
v.ieee.mantissa1 |= j; v.ieee.mantissa1 |= j;
return v.d * 0x1p-108; return v.d * 0x1p-108;
} }
#endif /* ! USE_FMA_BUILTIN */
} }
#ifndef __fma #ifndef __fma
libm_alias_double (__fma, fma) libm_alias_double (__fma, fma)

View File

@ -23,6 +23,7 @@
#include <math-barriers.h> #include <math-barriers.h>
#include <fenv_private.h> #include <fenv_private.h>
#include <libm-alias-float.h> #include <libm-alias-float.h>
#include <math-use-builtins.h>
/* This implementation relies on double being more than twice as /* This implementation relies on double being more than twice as
precise as float and uses rounding to odd in order to avoid problems precise as float and uses rounding to odd in order to avoid problems
@ -33,6 +34,10 @@
float float
__fmaf (float x, float y, float z) __fmaf (float x, float y, float z)
{ {
#if USE_FMAF_BUILTIN
return __builtin_fmaf (x, y, z);
#else
/* Use generic implementation. */
fenv_t env; fenv_t env;
/* Multiplication is always exact. */ /* Multiplication is always exact. */
@ -60,6 +65,7 @@ __fmaf (float x, float y, float z)
/* And finally truncation with round to nearest. */ /* And finally truncation with round to nearest. */
return (float) u.d; return (float) u.d;
#endif /* ! USE_FMAF_BUILTIN */
} }
#ifndef __fmaf #ifndef __fmaf
libm_alias_float (__fma, fma) libm_alias_float (__fma, fma)

View File

@ -154,6 +154,8 @@
#define USE_ROUNDL_BUILTIN USE_ROUNDF128_BUILTIN #define USE_ROUNDL_BUILTIN USE_ROUNDF128_BUILTIN
#undef USE_COPYSIGNL_BUILTIN #undef USE_COPYSIGNL_BUILTIN
#define USE_COPYSIGNL_BUILTIN USE_COPYSIGNF128_BUILTIN #define USE_COPYSIGNL_BUILTIN USE_COPYSIGNF128_BUILTIN
#undef USE_FMAL_BUILTIN
#define USE_FMAL_BUILTIN USE_FMAF128_BUILTIN
/* IEEE function renames. */ /* IEEE function renames. */
#define __ieee754_acoshl __ieee754_acoshf128 #define __ieee754_acoshl __ieee754_acoshf128

View File

@ -21,6 +21,7 @@
#include <fenv.h> #include <fenv.h>
#include <ieee754.h> #include <ieee754.h>
#include <libm-alias-double.h> #include <libm-alias-double.h>
#include <math-use-builtins.h>
/* This implementation relies on long double being more than twice as /* This implementation relies on long double being more than twice as
precise as double and uses rounding to odd in order to avoid problems precise as double and uses rounding to odd in order to avoid problems
@ -31,6 +32,9 @@
double double
__fma (double x, double y, double z) __fma (double x, double y, double z)
{ {
#if USE_FMA_BUILTIN
return __builtin_fma (x, y, z);
#else
fenv_t env; fenv_t env;
/* Multiplication is always exact. */ /* Multiplication is always exact. */
long double temp = (long double) x * (long double) y; long double temp = (long double) x * (long double) y;
@ -50,6 +54,7 @@ __fma (double x, double y, double z)
feupdateenv (&env); feupdateenv (&env);
/* And finally truncation with round to nearest. */ /* And finally truncation with round to nearest. */
return (double) u.d; return (double) u.d;
#endif /* ! USE_FMA_BUILTIN */
} }
#ifndef __fma #ifndef __fma
libm_alias_double (__fma, fma) libm_alias_double (__fma, fma)

View File

@ -25,6 +25,7 @@
#include <math_private.h> #include <math_private.h>
#include <libm-alias-ldouble.h> #include <libm-alias-ldouble.h>
#include <tininess.h> #include <tininess.h>
#include <math-use-builtins.h>
/* This implementation uses rounding to odd to avoid problems with /* This implementation uses rounding to odd to avoid problems with
double rounding. See a paper by Boldo and Melquiond: double rounding. See a paper by Boldo and Melquiond:
@ -33,6 +34,9 @@
_Float128 _Float128
__fmal (_Float128 x, _Float128 y, _Float128 z) __fmal (_Float128 x, _Float128 y, _Float128 z)
{ {
#if USE_FMAL_BUILTIN
return __builtin_fmal (x, y, z);
#else
union ieee854_long_double u, v, w; union ieee854_long_double u, v, w;
int adjust = 0; int adjust = 0;
u.d = x; u.d = x;
@ -296,5 +300,6 @@ __fmal (_Float128 x, _Float128 y, _Float128 z)
v.ieee.mantissa3 |= j; v.ieee.mantissa3 |= j;
return v.d * L(0x1p-228); return v.d * L(0x1p-228);
} }
#endif /* ! USE_FMAL_BUILTIN */
} }
libm_alias_ldouble (__fma, fma) libm_alias_ldouble (__fma, fma)

View File

@ -111,4 +111,9 @@
#define USE_SQRT_BUILTIN 0 #define USE_SQRT_BUILTIN 0
#define USE_SQRTF_BUILTIN 0 #define USE_SQRTF_BUILTIN 0
#define USE_FMA_BUILTIN 0
#define USE_FMAF_BUILTIN 0
#define USE_FMAL_BUILTIN 0
#define USE_FMAF128_BUILTIN 0
#endif /* math-use-builtins.h */ #endif /* math-use-builtins.h */