diff options
author | Paul A. Clarke <pc@us.ibm.com> | 2019-08-20 15:57:35 -0500 |
---|---|---|
committer | Paul A. Clarke <pc@us.ibm.com> | 2019-08-28 13:53:09 -0500 |
commit | 0b3c9e57a41d9f7c26fb6aa45b99f671bef9c7e0 (patch) | |
tree | 17e86cc4b838006df6a22738a4d48f6e8f2e51e8 | |
parent | fec2bd2c2d31bc731cf61623e150d047746954bd (diff) | |
download | glibc-0b3c9e57a41d9f7c26fb6aa45b99f671bef9c7e0.tar.gz glibc-0b3c9e57a41d9f7c26fb6aa45b99f671bef9c7e0.tar.xz glibc-0b3c9e57a41d9f7c26fb6aa45b99f671bef9c7e0.zip |
[powerpc] fegetenv_status: simplify instruction generation
fegetenv_status() wants to use the lighter weight instruction 'mffsl' for reading the Floating-Point Status and Control Register (FPSCR). It currently will use it directly if compiled '-mcpu=power9', and will perform a runtime check (cpu_supports("arch_3_00")) otherwise. Nicely, it turns out that the 'mffsl' instruction will decode to 'mffs' on architectures older than "arch_3_00" because the additional bits set for 'mffsl' are "don't care" for 'mffs'. 'mffs' is a superset of 'mffsl'. So, just generate 'mffsl'.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fenv_libc.h | 21 |
2 files changed, 11 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog index 9824660f6d..ddda8700c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2019-08-28 Paul A. Clarke <pc@us.ibm.com> + * sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_status_ISA300): Delete. + (fegetenv_status): Generate 'mffsl' unconditionally. + +2019-08-28 Paul A. Clarke <pc@us.ibm.com> + * sysdeps/powerpc/fpu/fesetenv.c (__fesetenv): Utilize lightweight FPSCR read. (_FPU_MASK_ALL): Delete. diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h index 4144d413a2..b703c8d853 100644 --- a/sysdeps/powerpc/fpu/fenv_libc.h +++ b/sysdeps/powerpc/fpu/fenv_libc.h @@ -35,9 +35,12 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; #define fegetenv_register() __builtin_mffs() /* Equivalent to fegetenv_register, but only returns bits for - status, exception enables, and mode. */ - -#define fegetenv_status_ISA300() \ + status, exception enables, and mode. + Nicely, it turns out that the 'mffsl' instruction will decode to + 'mffs' on architectures older than "power9" because the additional + bits set for 'mffsl' are "don't care" for 'mffs'. 'mffs' is a superset + of 'mffsl'. */ +#define fegetenv_status() \ ({register double __fr; \ __asm__ __volatile__ ( \ ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ @@ -45,18 +48,6 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; __fr; \ }) -#ifdef _ARCH_PWR9 -# define fegetenv_status() fegetenv_status_ISA300() -#elif defined __BUILTIN_CPU_SUPPORTS__ -# define fegetenv_status() \ - (__glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ - ? fegetenv_status_ISA300() \ - : fegetenv_register() \ - ) -#else -# define fegetenv_status() fegetenv_register () -#endif - /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ #define fesetenv_register(env) \ do { \ |