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)")