diff options
author | Joseph Myers <joseph@codesourcery.com> | 2016-09-07 16:40:09 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2016-09-07 16:40:09 +0000 |
commit | ec94343f592df68ba1ba49bb2c558f7d2629387c (patch) | |
tree | 7430394b9a38cb5527558363186ffdb4546761b7 /sysdeps/powerpc | |
parent | fb0f7a6755c1bfaec38f490fbfcaa39a66ee3604 (diff) | |
download | glibc-ec94343f592df68ba1ba49bb2c558f7d2629387c.tar.gz glibc-ec94343f592df68ba1ba49bb2c558f7d2629387c.tar.xz glibc-ec94343f592df68ba1ba49bb2c558f7d2629387c.zip |
Add femode_t functions.
TS 18661-1 defines a type femode_t to represent the set of dynamic floating-point control modes (such as the rounding mode and trap enablement modes), and functions fegetmode and fesetmode to manipulate those modes (without affecting other state such as the raised exception flags) and a corresponding macro FE_DFL_MODE. This patch series implements those interfaces for glibc. This first patch adds the architecture-independent pieces, the x86 and x86_64 implementations, and the <bits/fenv.h> and ABI baseline updates for all architectures so glibc keeps building and passing the ABI tests on all architectures. Subsequent patches add the fegetmode and fesetmode implementations for other architectures. femode_t is generally an integer type - the same type as fenv_t, or as the single element of fenv_t where fenv_t is a structure containing a single integer (or the single relevant element, where it has elements for both status and control registers) - except where architecture properties or consistency with the fenv_t implementation indicate otherwise. FE_DFL_MODE follows FE_DFL_ENV in whether it's a magic pointer value (-1 cast to const femode_t *), a value that can be distinguished from valid pointers by its high bits but otherwise contains a representation of the desired register contents, or a pointer to a constant variable (the powerpc case; __fe_dfl_mode is added as an exported constant object, an alias to __fe_dfl_env). Note that where architectures (that share a register between control and status bits) gain definitions of new floating-point control or status bits in future, the implementations of fesetmode for those architectures may need updating (depending on whether the new bits are control or status bits and what the implementation does with previously unknown bits), just like existing implementations of <fenv.h> functions that take care not to touch reserved bits may need updating when the set of reserved bits changes. (As any new bits are outside the scope of ISO C, that's just a quality-of-implementation issue for supporting them, not a conformance issue.) As with fenv_t, femode_t should properly include any software DFP rounding mode (and for both fenv_t and femode_t I'd consider that fragment of DFP support appropriate for inclusion in glibc even in the absence of the rest of libdfp; hardware DFP rounding modes should already be included if the definitions of which bits are status / control bits are correct). Tested for x86_64, x86, mips64 (hard float, and soft float to test the fallback version), arm (hard float) and powerpc (hard float, soft float and e500). Other architecture versions are untested. * math/fegetmode.c: New file. * math/fesetmode.c: Likewise. * sysdeps/i386/fpu/fegetmode.c: Likewise. * sysdeps/i386/fpu/fesetmode.c: Likewise. * sysdeps/x86_64/fpu/fegetmode.c: Likewise. * sysdeps/x86_64/fpu/fesetmode.c: Likewise. * math/fenv.h: Update comment on inclusion of <bits/fenv.h>. [__GLIBC_USE (IEC_60559_BFP_EXT)] (fegetmode): New function declaration. [__GLIBC_USE (IEC_60559_BFP_EXT)] (fesetmode): Likewise. * bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/aarch64/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/alpha/fpu/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/arm/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/hppa/fpu/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/ia64/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/m68k/fpu/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/microblaze/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/mips/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/nios2/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/powerpc/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (__fe_dfl_mode): New variable declaration. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/s390/fpu/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/sh/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/sparc/fpu/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/tile/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * sysdeps/x86/fpu/bits/fenv.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (femode_t): New typedef. [__GLIBC_USE (IEC_60559_BFP_EXT)] (FE_DFL_MODE): New macro. * manual/arith.texi (FE_DFL_MODE): Document macro. (fegetmode): Document function. (fesetmode): Likewise. * math/Versions (fegetmode): New libm symbol at version GLIBC_2.25. (fesetmode): Likewise. * math/Makefile (libm-support): Add fegetmode and fesetmode. (tests): Add test-femode and test-femode-traps. * math/test-femode-traps.c: New file. * math/test-femode.c: Likewise. * sysdeps/powerpc/fpu/fenv_const.c (__fe_dfl_mode): Declare as alias for __fe_dfl_env. * sysdeps/powerpc/nofpu/fenv_const.c (__fe_dfl_mode): Likewise. * sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c (__fe_dfl_mode): Likewise. * sysdeps/powerpc/Versions (__fe_dfl_mode): New libm symbol at version GLIBC_2.25. * sysdeps/nacl/libm.abilist: Update. * sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.
Diffstat (limited to 'sysdeps/powerpc')
-rw-r--r-- | sysdeps/powerpc/Versions | 3 | ||||
-rw-r--r-- | sysdeps/powerpc/bits/fenv.h | 9 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fenv_const.c | 4 | ||||
-rw-r--r-- | sysdeps/powerpc/nofpu/fenv_const.c | 4 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c | 4 |
5 files changed, 24 insertions, 0 deletions
diff --git a/sysdeps/powerpc/Versions b/sysdeps/powerpc/Versions index b959ea49fe..95849668f2 100644 --- a/sysdeps/powerpc/Versions +++ b/sysdeps/powerpc/Versions @@ -3,6 +3,9 @@ libm { # symbols used in macros from sysdeps/powerpc/bits/fenv.h __fe_dfl_env; __fe_enabled_env; __fe_nonieee_env; __fe_nomask_env; } + GLIBC_2.25 { + __fe_dfl_mode; + } } libc { diff --git a/sysdeps/powerpc/bits/fenv.h b/sysdeps/powerpc/bits/fenv.h index d2a6d34a99..8d2bf3d163 100644 --- a/sysdeps/powerpc/bits/fenv.h +++ b/sysdeps/powerpc/bits/fenv.h @@ -169,3 +169,12 @@ extern const fenv_t __fe_nonieee_env; # define FE_MASK_ENV FE_DFL_ENV #endif + +#if __GLIBC_USE (IEC_60559_BFP_EXT) +/* Type representing floating-point control modes. */ +typedef double femode_t; + +/* Default floating-point control modes. */ +extern const femode_t __fe_dfl_mode; +# define FE_DFL_MODE (&__fe_dfl_mode) +#endif diff --git a/sysdeps/powerpc/fpu/fenv_const.c b/sysdeps/powerpc/fpu/fenv_const.c index b061daf578..93a4375430 100644 --- a/sysdeps/powerpc/fpu/fenv_const.c +++ b/sysdeps/powerpc/fpu/fenv_const.c @@ -23,6 +23,10 @@ const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) = 0xfff8000000000000ULL; +/* The same representation is used for femode_t. */ +extern const unsigned long long __fe_dfl_mode + __attribute__ ((aligned (8), alias ("__fe_dfl_env"))); + /* Floating-point environment where none of the exceptions are masked. */ const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) = 0xfff80000000000f8ULL; diff --git a/sysdeps/powerpc/nofpu/fenv_const.c b/sysdeps/powerpc/nofpu/fenv_const.c index ebf5c68fc5..ce1da3c197 100644 --- a/sysdeps/powerpc/nofpu/fenv_const.c +++ b/sysdeps/powerpc/nofpu/fenv_const.c @@ -25,6 +25,10 @@ const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) = 0x000000003e000000ULL; +/* The same representation is used for femode_t. */ +extern const unsigned long long __fe_dfl_mode + __attribute__ ((aligned (8), alias ("__fe_dfl_env"))); + /* Floating-point environment where none of the exceptions are masked. */ const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) = 0x0000000000000000ULL; diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c index 11e24ca182..eab47c8c0f 100644 --- a/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c +++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c @@ -28,6 +28,10 @@ const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) = 0x3cULL; +/* The same representation is used for femode_t. */ +extern const unsigned long long __fe_dfl_mode + __attribute__ ((aligned (8), alias ("__fe_dfl_env"))); + /* Floating-point environment where none of the exceptions are masked. */ const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) = (((unsigned long long) (PR_FP_EXC_DIV |