diff mbox

PPC libgcc IEEE128 soft-fp exception/rounding fixes

Message ID 56C78132.7070706@linux.vnet.ibm.com
State New
Headers show

Commit Message

Paul E. Murphy Feb. 19, 2016, 8:55 p.m. UTC
On 02/17/2016 08:37 PM, Alan Modra wrote:
>> +/* A set bit indicates an exception is trapping.  */
>> +# define FP_TRAPPING_EXCEPTIONS ((_fpscr.i << 22) & FP_EX_ALL)
> 
> why then a shift here, since FP_EX_* are defined as the actual
> register bits?  Oh, I see.  FP_EX_* are the status bits, and you want
> the enable bits.  ie. bit 56 rather than bit 34, bit 57 rather than
> bit 35 and so on (bits numbered from 0 as msb).  A comment to that
> effect might reduce head scratching.

Thanks for taking a look Alan, and Joseph.  I've expanded the comment
to clarify the otherwise mysterious shift with the updated patch.

libgcc
	* config/rs6000/sfp-machine.h:
	(_FP_DECL_EX): Declare _fpsr as a union of u64 and double.
	(FP_TRAPPING_EXCEPTIONS): Return a bitmask of trapping
	exceptions.
	(FP_INIT_ROUNDMODE): Read the fpscr instead of writing
	a mystery value.
	(FP_ROUNDMODE): Update the usage of _fpscr.
diff mbox

Patch

diff --git a/libgcc/config/rs6000/sfp-machine.h b/libgcc/config/rs6000/sfp-machine.h
index 75d5e1a..8dd8ea3 100644
--- a/libgcc/config/rs6000/sfp-machine.h
+++ b/libgcc/config/rs6000/sfp-machine.h
@@ -130,9 +130,13 @@  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))
+
+/* The FP_EX_* bits track whether the exception has occurred.  This macro
+   must set the FP_EX_* bits of those exceptions which are configured to
+   trap.  The FPSCR bit which indicates this is 22 ISA bits above the
+   respective FP_EX_* bit.  Note, the ISA labels bits from msb to lsb,
+   so 22 ISA bits above is 22 bits below when counted from the lsb.  */
+# define FP_TRAPPING_EXCEPTIONS ((_fpscr.i << 22) & FP_EX_ALL)
 
 # define FP_RND_NEAREST	0x0
 # define FP_RND_ZERO	0x1
@@ -141,16 +145,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.  */