1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00

powerpc: Use faster means to access FPSCR when possible in some cases

Using 'mffs' instruction to read the Floating Point Status Control Register
(FPSCR) can force a processor flush in some cases, with undesirable
performance impact.  If the values of the bits in the FPSCR which force the
flush are not needed, an instruction that is new to POWER9 (ISA version 3.0),
'mffsl' can be used instead.

Cases included:  get_rounding_mode, fegetround, fegetmode, fegetexcept.

	* sysdeps/powerpc/bits/fenvinline.h (__fegetround): Use
	__fegetround_ISA300() or __fegetround_ISA2() as appropriate.
	(__fegetround_ISA300) New.
	(__fegetround_ISA2) New.
	* sysdeps/powerpc/fpu_control.h (IS_ISA300): New.
	(_FPU_MFFS): Move implementation...
	(_FPU_GETCW): Here.
	(_FPU_MFFSL): Move implementation....
	(_FPU_GET_RC_ISA300): Here. New.
	(_FPU_GET_RC): Use _FPU_GET_RC_ISA300() or _FPU_GETCW() as appropriate.
	* sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_status_ISA300): New.
	(fegetenv_status): New.
	* sysdeps/powerpc/fpu/fegetmode.c (fegetmode): Use fegetenv_status()
	instead of fegetenv_register().
	* sysdeps/powerpc/fpu/fegetexcept.c (__fegetexcept): Likewise.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
This commit is contained in:
Paul A. Clarke
2019-06-20 11:57:18 -05:00
committed by Tulio Magno Quites Machado Filho
parent d064591266
commit 3db85a9814
6 changed files with 94 additions and 30 deletions

View File

@ -65,35 +65,37 @@ extern fpu_control_t __fpu_control;
typedef unsigned int fpu_control_t;
/* Macros for accessing the hardware control word. */
# define __FPU_MFFS() \
({register double __fr; \
__asm__ __volatile__("mffs %0" : "=f" (__fr)); \
__fr; \
})
# define _FPU_GETCW(cw) \
({union { double __d; unsigned long long __ll; } __u; \
__u.__d = __FPU_MFFS(); \
__asm__ __volatile__("mffs %0" : "=f" (__u.__d)); \
(cw) = (fpu_control_t) __u.__ll; \
(fpu_control_t) __u.__ll; \
})
#ifdef _ARCH_PWR9
# define __FPU_MFFSL() \
({register double __fr; \
__asm__ __volatile__("mffsl %0" : "=f" (__fr)); \
__fr; \
# define _FPU_GET_RC_ISA300() \
({union { double __d; unsigned long long __ll; } __u; \
__asm__ __volatile__( \
".machine push; .machine \"power9\"; mffsl %0; .machine pop" \
: "=f" (__u.__d)); \
(fpu_control_t) (__u.__ll & _FPU_MASK_RC); \
})
#else
# define __FPU_MFFSL() __FPU_MFFS()
#endif
# define _FPU_GET_RC() \
({union { double __d; unsigned long long __ll; } __u; \
__u.__d = __FPU_MFFSL(); \
__u.__ll &= _FPU_MASK_RC; \
(fpu_control_t) __u.__ll; \
# ifdef _ARCH_PWR9
# define _FPU_GET_RC() _FPU_GET_RC_ISA300()
# elif defined __BUILTIN_CPU_SUPPORTS__
# define _FPU_GET_RC() \
({fpu_control_t __rc; \
__rc = __glibc_likely (__builtin_cpu_supports ("arch_3_00")) \
? _FPU_GET_RC_ISA300 () \
: _FPU_GETCW (__rc) & _FPU_MASK_RC; \
__rc; \
})
# else
# define _FPU_GET_RC() \
({fpu_control_t __rc = _FPU_GETCW (__rc) & _FPU_MASK_RC; \
__rc; \
})
# endif
# define _FPU_SETCW(cw) \
{ union { double __d; unsigned long long __ll; } __u; \