aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--sysdeps/powerpc/bits/fenvinline.h37
-rw-r--r--sysdeps/powerpc/fpu/fegetexcept.c2
-rw-r--r--sysdeps/powerpc/fpu/fegetmode.c2
-rw-r--r--sysdeps/powerpc/fpu/fenv_libc.h21
-rw-r--r--sysdeps/powerpc/fpu_control.h44
6 files changed, 94 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index aece032..abab02f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2019-06-30 Paul A. Clarke <pc@us.ibm.com>
+
+ * 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.
+
2019-06-28 Wilco Dijkstra <wdijkstr@arm.com>
* benchtests/bench-math-inlines.c: Increase iterations.
diff --git a/sysdeps/powerpc/bits/fenvinline.h b/sysdeps/powerpc/bits/fenvinline.h
index 7079d1a..56ac0f3 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
diff --git a/sysdeps/powerpc/fpu/fegetexcept.c b/sysdeps/powerpc/fpu/fegetexcept.c
index 2173d77..10a37f0 100644
--- a/sysdeps/powerpc/fpu/fegetexcept.c
+++ b/sysdeps/powerpc/fpu/fegetexcept.c
@@ -24,7 +24,7 @@ __fegetexcept (void)
{
fenv_union_t fe;
- fe.fenv = fegetenv_register ();
+ fe.fenv = fegetenv_status ();
return fenv_reg_to_exceptions (fe.l);
}
diff --git a/sysdeps/powerpc/fpu/fegetmode.c b/sysdeps/powerpc/fpu/fegetmode.c
index f43ab60..466f5b7 100644
--- a/sysdeps/powerpc/fpu/fegetmode.c
+++ b/sysdeps/powerpc/fpu/fegetmode.c
@@ -21,6 +21,6 @@
int
fegetmode (femode_t *modep)
{
- *modep = fegetenv_register ();
+ *modep = fegetenv_status ();
return 0;
}
diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
index f66bf24..55b1697 100644
--- a/sysdeps/powerpc/fpu/fenv_libc.h
+++ b/sysdeps/powerpc/fpu/fenv_libc.h
@@ -34,6 +34,27 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
pointer. */
#define fegetenv_register() __builtin_mffs()
+/* Equivalent to fegetenv_register, but only returns bits for
+ status, exception enables, and mode. */
+
+#define fegetenv_status_ISA300() \
+ ({register double __fr; \
+ __asm__ __volatile__ ( \
+ ".machine push; .machine \"power9\"; mffsl %0; .machine pop" \
+ : "=f" (__fr)); \
+ __fr; \
+ })
+
+#ifdef _ARCH_PWR9
+# define fegetenv_status() fegetenv_status_ISA300()
+#else
+# define fegetenv_status() \
+ (__glibc_likely (__builtin_cpu_supports ("arch_3_00")) \
+ ? fegetenv_status_ISA300() \
+ : fegetenv_register() \
+ )
+#endif
+
/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */
#define fesetenv_register(env) \
do { \
diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h
index fa04a67..d0fdad7 100644
--- a/sysdeps/powerpc/fpu_control.h
+++ b/sysdeps/powerpc/fpu_control.h
@@ -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; \