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.  */

Reply via email to