This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PPC libgcc IEEE128 soft-fp exception/rounding fixes
- From: "Paul E. Murphy" <murphyp at linux dot vnet dot ibm dot com>
- To: meissner at linux dot vnet dot ibm dot com, Joseph Myers <joseph at codesourcery dot com>, wschmidt at linux dot vnet dot ibm dot com, gcc-patches at gcc dot gnu dot org
- Cc: "munroesj at linux dot vnet dot ibm dot com" <munroesj at linux dot vnet dot ibm dot com>
- Date: Wed, 17 Feb 2016 17:40:01 -0600
- Subject: PPC libgcc IEEE128 soft-fp exception/rounding fixes
- Authentication-results: sourceware.org; auth=none
Hi all,
I am fairly new to IBM and recently appointed maintainer of libdfp,
and work on glibc on ppc. This is my first foray into libgcc.
libdfp implements many common transcendental functions, overrides
type conversions between decimal float and other GCC types with more
optimized variants for dpd encoding.
While investigating some rounding issues with conversions, I tried out
the recent IEEE128 soft-fp support for PPC using a supporting compiler,
while building some of the soft-fp parts locally.
I ran into the following issues which I have attempted to correct with
the attached patch for rs6000/sfp-machine.h:
- FP_INIT_ROUNDMODE writes junk to the fpscr. I assume this should be
reading the fpscr and initializing the local rounding mode variable
declared via _FP_DECL_EX.
- FP_TRAPPING_EXCEPTIONS evaluates to zero where used. It seems like it
should return a bit field of FP_EX_* bits indicating which trap is
enabled. Likewise, when these bits are set in the fpscr, the trap is
enabled.
libgcc
* config/rs6000/sfp-machine.h:
(_FP_DECL_EX): Declare _fpsr as union of u64 and double.
(FP_TRAPPING_EXCEPTIONS): Remove this, FP_HANDLE_EXCEPTIONS
will do them implicitly later on.
(FP_INIT_ROUNDMODE): Read the fpscr instead of writing
mystery value.
(FP_ROUNDMODE): Update type of _fpscr.
diff --git a/libgcc/config/rs6000/sfp-machine.h b/libgcc/config/rs6000/sfp-machine.h
index 75d5e1a..4bc0040 100644
--- a/libgcc/config/rs6000/sfp-machine.h
+++ b/libgcc/config/rs6000/sfp-machine.h
@@ -130,9 +130,9 @@ void __sfp_handle_exceptions (int);
if (__builtin_expect (_fex, 0)) \
__sfp_handle_exceptions (_fex); \
} while (0);
-/* A set bit indicates an exception is masked and a clear bit indicates it is
- trapping. */
-# define FP_TRAPPING_EXCEPTIONS (~_fpscr & (FP_EX_ALL >> 22))
+
+/* A set bit indicates an exception is trapping. */
+# define FP_TRAPPING_EXCEPTIONS ((_fpscr.i << 22) & FP_EX_ALL)
# define FP_RND_NEAREST 0x0
# define FP_RND_ZERO 0x1
@@ -141,16 +141,16 @@ void __sfp_handle_exceptions (int);
# define FP_RND_MASK 0x3
# define _FP_DECL_EX \
- unsigned long long _fpscr __attribute__ ((unused)) = FP_RND_NEAREST
+ union { unsigned long long i; double d; } _fpscr __attribute__ ((unused)) = \
+ { .i = FP_RND_NEAREST }
#define FP_INIT_ROUNDMODE \
do { \
- __asm__ __volatile__ ("mtfsf 255, %0" \
- : \
- : "f" (_fpscr)); \
+ __asm__ __volatile__ ("mffs %0" \
+ : "=f" (_fpscr.d)); \
} while (0)
-# define FP_ROUNDMODE (_fpscr & FP_RND_MASK)
+# define FP_ROUNDMODE (_fpscr.i & FP_RND_MASK)
#endif /* !__FLOAT128__ */
/* Define ALIASNAME as a strong alias for NAME. */