diff options
Diffstat (limited to 'sysdeps/powerpc/fpu/fenv_libc.h')
-rw-r--r-- | sysdeps/powerpc/fpu/fenv_libc.h | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h index 6f116b60d5..c70f85130d 100644 --- a/sysdeps/powerpc/fpu/fenv_libc.h +++ b/sysdeps/powerpc/fpu/fenv_libc.h @@ -21,6 +21,8 @@ #define _FENV_LIBC_H 1 #include <fenv.h> +#include <ldsodefs.h> +#include <sysdep.h> libm_hidden_proto (__fe_nomask_env) @@ -34,7 +36,13 @@ libm_hidden_proto (__fe_nomask_env) /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ #define fesetenv_register(env) \ - ({ double d = (env); asm volatile ("mtfsf 0xff,%0" : : "f" (d)); }) + do { \ + double d = (env); \ + if(GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \ + asm volatile ("mtfsf 0xff,%0,1,0" : : "f" (d)); \ + else \ + asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \ + } while(0) /* This very handy macro: - Sets the rounding mode to 'round to nearest'; @@ -42,7 +50,12 @@ libm_hidden_proto (__fe_nomask_env) - Prevents exceptions from being raised for inexact results. These things happen to be exactly what you need for typical elementary functions. */ -#define relax_fenv_state() asm ("mtfsfi 7,0") +#define relax_fenv_state() \ + do { \ + if(GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \ + asm ("mtfsfi 7,0,1"); \ + asm ("mtfsfi 7,0"); \ + } while(0) /* Set/clear a particular FPSCR bit (for instance, reset_fpscr_bit(FPSCR_VE); @@ -122,10 +135,19 @@ enum { FPSCR_UE, /* underflow exception enable */ FPSCR_ZE, /* zero divide exception enable */ FPSCR_XE, /* inexact exception enable */ +#ifdef _ARCH_PWR6 + FPSCR_29, /* Reserved in ISA 2.05 */ +#else FPSCR_NI /* non-IEEE mode (typically, no denormalised numbers) */ +#endif /* _ARCH_PWR6 */ /* the remaining two least-significant bits keep the rounding mode */ }; +#ifdef _ARCH_PWR6 + /* Not supported in ISA 2.05. Provided for source compat only. */ +# define FPSCR_NI 29 +#endif /* _ARCH_PWR6 */ + /* This operation (i) sets the appropriate FPSCR bits for its parameter, (ii) converts SNaN to the corresponding NaN, and (iii) otherwise passes its parameter through unchanged (in particular, -0 |