[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'.
This commit is contained in:
Paul A. Clarke 2019-08-20 15:57:35 -05:00
parent fec2bd2c2d
commit 0b3c9e57a4
2 changed files with 11 additions and 15 deletions

View File

@ -1,3 +1,8 @@
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

View File

@ -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 { \