summary refs log tree commit diff
path: root/sysdeps/powerpc/bits/fenvinline.h
diff options
context:
space:
mode:
authorPaul A. Clarke <pc@us.ibm.com>2019-06-20 11:57:18 -0500
committerTulio Magno Quites Machado Filho <tuliom@linux.ibm.com>2019-06-30 08:40:44 -0300
commit3db85a9814784a74536a1f0e7b7ddbfef7dc84bb (patch)
tree38c7cbbeae1d517b1fd54e723bf55e0d8887abe1 /sysdeps/powerpc/bits/fenvinline.h
parentd064591266634a8ff55b645181167b8626c793c9 (diff)
downloadglibc-3db85a9814784a74536a1f0e7b7ddbfef7dc84bb.tar.gz
glibc-3db85a9814784a74536a1f0e7b7ddbfef7dc84bb.tar.xz
glibc-3db85a9814784a74536a1f0e7b7ddbfef7dc84bb.zip
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>
Diffstat (limited to 'sysdeps/powerpc/bits/fenvinline.h')
-rw-r--r--sysdeps/powerpc/bits/fenvinline.h37
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