diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/internal/libm.h | 71 | 
1 files changed, 65 insertions, 6 deletions
diff --git a/src/internal/libm.h b/src/internal/libm.h index f7dd9678..5669c046 100644 --- a/src/internal/libm.h +++ b/src/internal/libm.h @@ -5,6 +5,7 @@  #include <float.h>  #include <math.h>  #include <endian.h> +#include "fp_arch.h"  #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024  #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN @@ -58,16 +59,74 @@ union ldshape {  #error Unsupported long double representation  #endif +/* fp_barrier returns its input, but limits code transformations +   as if it had a side-effect (e.g. observable io) and returned +   an arbitrary value.  */ + +#ifndef fp_barrierf +#define fp_barrierf fp_barrierf +static inline float fp_barrierf(float x) +{ +	volatile float y = x; +	return y; +} +#endif + +#ifndef fp_barrier +#define fp_barrier fp_barrier +static inline double fp_barrier(double x) +{ +	volatile double y = x; +	return y; +} +#endif + +#ifndef fp_barrierl +#define fp_barrierl fp_barrierl +static inline long double fp_barrierl(long double x) +{ +	volatile long double y = x; +	return y; +} +#endif + +/* fp_force_eval ensures that the input value is computed when that's +   otherwise unused.  To prevent the constant folding of the input +   expression, an additional fp_barrier may be needed or a compilation +   mode that does so (e.g. -frounding-math in gcc). Then it can be +   used to evaluate an expression for its fenv side-effects only.   */ + +#ifndef fp_force_evalf +#define fp_force_evalf fp_force_evalf +static inline void fp_force_evalf(float x) +{ +	volatile float y = x; +} +#endif + +#ifndef fp_force_eval +#define fp_force_eval fp_force_eval +static inline void fp_force_eval(double x) +{ +	volatile double y = x; +} +#endif + +#ifndef fp_force_evall +#define fp_force_evall fp_force_evall +static inline void fp_force_evall(long double x) +{ +	volatile long double y = x; +} +#endif +  #define FORCE_EVAL(x) do {                        \  	if (sizeof(x) == sizeof(float)) {         \ -		volatile float __x;               \ -		__x = (x);                        \ +		fp_force_evalf(x);                \  	} else if (sizeof(x) == sizeof(double)) { \ -		volatile double __x;              \ -		__x = (x);                        \ +		fp_force_eval(x);                 \  	} else {                                  \ -		volatile long double __x;         \ -		__x = (x);                        \ +		fp_force_evall(x);                \  	}                                         \  } while(0)  | 
