diff options
Diffstat (limited to 'sysdeps/powerpc/bits/fenvinline.h')
-rw-r--r-- | sysdeps/powerpc/bits/fenvinline.h | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/sysdeps/powerpc/bits/fenvinline.h b/sysdeps/powerpc/bits/fenvinline.h index 7079d1a46d..56ac0f3ef3 100644 --- a/sysdeps/powerpc/bits/fenvinline.h +++ b/sysdeps/powerpc/bits/fenvinline.h @@ -18,13 +18,36 @@ #if defined __GNUC__ && !defined _SOFT_FLOAT && !defined __NO_FPRS__ -/* Inline definition for fegetround. */ -# define __fegetround() \ - (__extension__ ({ int __fegetround_result; \ - __asm__ __volatile__ \ - ("mcrfs 7,7 ; mfcr %0" \ - : "=r"(__fegetround_result) : : "cr7"); \ - __fegetround_result & 3; })) +/* Inline definitions for fegetround. */ +# define __fegetround_ISA300() \ + (__extension__ ({ \ + union { double __d; unsigned long long __ll; } __u; \ + __asm__ __volatile__ ( \ + ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \ + : "=f" (__u.__d)); \ + __u.__ll & 0x0000000000000003LL; \ + })) + +# define __fegetround_ISA2() \ + (__extension__ ({ \ + int __fegetround_result; \ + __asm__ __volatile__ ("mcrfs 7,7 ; mfcr %0" \ + : "=r"(__fegetround_result) : : "cr7"); \ + __fegetround_result & 3; \ + })) + +# ifdef _ARCH_PWR9 +# define __fegetround() __fegetround_ISA300() +# elif defined __BUILTIN_CPU_SUPPORTS__ +# define __fegetround() \ + (__glibc_likely (__builtin_cpu_supports ("arch_3_00")) \ + ? __fegetround_ISA300() \ + : __fegetround_ISA2() \ + ) +# else +# define __fegetround() __fegetround_ISA2() +# endif + # define fegetround() __fegetround () # ifndef __NO_MATH_INLINES |