This patch is the new patch from the last submission. It sets up a hook so that the compiler will not allow IBM extended double and IEEE 128-bit floating point to intermix in a binary expression without using an explicit conversion.
I have built the compiler with this patch and the previous subpatches (1-8). I have bootstrapped the compiler with all 16 subpatches installed, and there were no regressions. Is it ok to install in the trunk? 2015-10-22 Michael Meissner <meiss...@linux.vnet.ibm.com> * config/rs6000/rs6000.c (TARGET_INVALID_BINARY_OP): Do not allow inter-mixing of IEEE 128-bit floating point with IBM extended double floating point. (rs6000_invalid_binary_op): 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.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 229193) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -1677,6 +1677,9 @@ static const struct attribute_spec rs600 #undef TARGET_C_MODE_FOR_SUFFIX #define TARGET_C_MODE_FOR_SUFFIX rs6000_c_mode_for_suffix + +#undef TARGET_INVALID_BINARY_OP +#define TARGET_INVALID_BINARY_OP rs6000_invalid_binary_op /* Processor table. */ @@ -20283,6 +20286,47 @@ rs6000_generate_compare (rtx cmp, machin return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx); } + +/* Return the diagnostic message string if the binary operation OP is + not permitted on TYPE1 and TYPE2, NULL otherwise. */ + +static const char* +rs6000_invalid_binary_op (int op ATTRIBUTE_UNUSED, + const_tree type1, + const_tree type2) +{ + enum machine_mode mode1 = TYPE_MODE (type1); + enum machine_mode mode2 = TYPE_MODE (type2); + + /* For complex modes, use the inner type. */ + if (COMPLEX_MODE_P (mode1)) + mode1 = GET_MODE_INNER (mode1); + + if (COMPLEX_MODE_P (mode2)) + mode2 = GET_MODE_INNER (mode2); + + /* Don't allow IEEE 754R 128-bit binary floating point and IBM extended + double to intermix. */ + if (mode1 == mode2) + return NULL; + + if ((mode1 == KFmode && mode2 == IFmode) + || (mode1 == IFmode && mode2 == KFmode)) + return N_("__float128 and __ibm128 cannot be used in the same expression"); + + if (TARGET_IEEEQUAD + && ((mode1 == IFmode && mode2 == TFmode) + || (mode1 == TFmode && mode2 == IFmode))) + return N_("__ibm128 and long double cannot be used in the same expression"); + + if (!TARGET_IEEEQUAD + && ((mode1 == KFmode && mode2 == TFmode) + || (mode1 == TFmode && mode2 == KFmode))) + return N_("__float128 and long double cannot be used in the same " + "expression"); + + return NULL; +} /* Expand floating point conversion to/from __float128 and __ibm128. */