This patch fixes PR target/77993, which is a bug preventing bootstrapping on
32-bit PowerPC Linux targets.

The issue is that some of the insns that support IFmode (IBM extended double
mode when long double is IEEE 128-bit floating point in the future) did not
check for -msoft-float, and disable IFmode, while others did get disabled.  On
64-bit Linux target systems, the soft-float multilib is no longer build, but on
32-bit Linux target systems, it is built.

The fix is to add checks for hardware floating point in the 3 macros used by
IFmode instructions.

I built this on a little endian Power8 system (64-bit only), big endian Power8
system (64-bit only), and a big endian Power7 system (32-bit and 64-bit).
There were no regressions in the test.  In addition, Eric Botcazou, who
reported the bug, says that he can now bootstrap his compiler.  Is this patch
ok to install?

2016-11-03  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        PR target/77993
        * config/rs6000/rs6000.h (FLOAT128_IBM_P): Do not allow IFmode or
        ICmode unless we have standard PowerPC floating point.
        * config/rs6000/rs6000.md (FP iterator): Likewise.
        (FMOVE128 iterator): Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h  (revision 241715)
+++ gcc/config/rs6000/rs6000.h  (working copy)
@@ -442,14 +442,15 @@
    point.  KFmode was added as a way to represent IEEE 128-bit floating point,
    even if the default for long double is the IBM long double format.
    Similarly IFmode is the IBM long double format even if the default is IEEE
-   128-bit.  */
+   128-bit.  Don't allow IFmode if -msoft-float.  */
 #define FLOAT128_IEEE_P(MODE)                                          \
   ((TARGET_IEEEQUAD && ((MODE) == TFmode || (MODE) == TCmode))         \
    || ((MODE) == KFmode) || ((MODE) == KCmode))
 
 #define FLOAT128_IBM_P(MODE)                                           \
   ((!TARGET_IEEEQUAD && ((MODE) == TFmode || (MODE) == TCmode))                
\
-   || ((MODE) == IFmode) || ((MODE) == ICmode))
+   || (TARGET_HARD_FLOAT && TARGET_FPRS                                        
\
+       && ((MODE) == IFmode || (MODE) == ICmode)))
 
 /* Helper macros to say whether a 128-bit floating point type can go in a
    single vector register, or whether it needs paired scalar values.  */
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 241715)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -376,7 +376,7 @@
   (TF "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128")
-  (IF "TARGET_LONG_DOUBLE_128")
+  (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")
   (KF "TARGET_FLOAT128_TYPE")
   (DD "TARGET_DFP")
   (TD "TARGET_DFP")])
@@ -398,7 +398,7 @@
 (define_mode_iterator FMOVE64 [DF DD])
 (define_mode_iterator FMOVE64X [DI DF DD])
 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
-                               (IF "TARGET_LONG_DOUBLE_128")
+                               (IF "FLOAT128_IBM_P (IFmode)")
                                (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
 
 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")

Reply via email to