S/390 Invalid vector binary ops
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Tue, 19 May 2015 17:41:21 +0000 (17:41 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Tue, 19 May 2015 17:41:21 +0000 (17:41 +0000)
This is a first try to implement at least some of the requirements
regarding the vector bool type documented for IBM XLC.

With this patch error messages will be issued for invalid uses of
vector bool types in binary operators.

vector bool types are being marked opaque in order to prevent the
front-end from complaining about "vector bool long" vs "vector bool
long long" combinations on 64 bit.  The opaque flag basically
suppresses any type checking. However, we still want vector bool to be
accepted only in contexts specified in the documentation (to be
published soon).  Implementing the invalid binary op hook does this
for binary operators at least.  But this is far from being complete :(

gcc/
* config/s390/s390.c (s390_vector_bool_type_p): New function.
(s390_invalid_binary_op): New function.
(TARGET_INVALID_BINARY_OP): Define macro.

From-SVN: r223404

gcc/ChangeLog
gcc/config/s390/s390.c

index fcde743994816c91d8cffb41e1c2c3cfac47524c..9676e38c765f5be88626d598f0248356d785056c 100644 (file)
@@ -1,3 +1,9 @@
+2015-05-19  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
+
+       * config/s390/s390.c (s390_vector_bool_type_p): New function.
+       (s390_invalid_binary_op): New function.
+       (TARGET_INVALID_BINARY_OP): Define macro.
+
 2015-05-19  David Sherwood  <david.sherwood@arm.com>
 
        * loop-invariant.c (create_new_invariant): Don't calculate address cost
index 7fd5969941043a628a5a7bc9f016a2d5c489886e..6648597fe442e55b63f1c4ca703e61084dd30afe 100644 (file)
@@ -13649,6 +13649,64 @@ s390_vector_alignment (const_tree type)
 }
 
 
+/* Return true if TYPE is a vector bool type.  */
+static inline bool
+s390_vector_bool_type_p (const_tree type)
+{
+  return TYPE_VECTOR_OPAQUE (type);
+}
+
+/* Return the diagnostic message string if the binary operation OP is
+   not permitted on TYPE1 and TYPE2, NULL otherwise.  */
+static const char*
+s390_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree type2)
+{
+  bool bool1_p, bool2_p;
+  bool plusminus_p;
+  bool muldiv_p;
+  bool compare_p;
+  machine_mode mode1, mode2;
+
+  if (!TARGET_ZVECTOR)
+    return NULL;
+
+  if (!VECTOR_TYPE_P (type1) || !VECTOR_TYPE_P (type2))
+    return NULL;
+
+  bool1_p = s390_vector_bool_type_p (type1);
+  bool2_p = s390_vector_bool_type_p (type2);
+
+  /* Mixing signed and unsigned types is forbidden for all
+     operators.  */
+  if (!bool1_p && !bool2_p
+      && TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2))
+    return N_("types differ in signess");
+
+  plusminus_p = (op == PLUS_EXPR || op == MINUS_EXPR);
+  muldiv_p = (op == MULT_EXPR || op == RDIV_EXPR || op == TRUNC_DIV_EXPR
+             || op == CEIL_DIV_EXPR || op == FLOOR_DIV_EXPR
+             || op == ROUND_DIV_EXPR);
+  compare_p = (op == LT_EXPR || op == LE_EXPR || op == GT_EXPR || op == GE_EXPR
+              || op == EQ_EXPR || op == NE_EXPR);
+
+  if (bool1_p && bool2_p && (plusminus_p || muldiv_p))
+    return N_("binary operator does not support two vector bool operands");
+
+  if (bool1_p != bool2_p && (muldiv_p || compare_p))
+    return N_("binary operator does not support vector bool operand");
+
+  mode1 = TYPE_MODE (type1);
+  mode2 = TYPE_MODE (type2);
+
+  if (bool1_p != bool2_p && plusminus_p
+      && (GET_MODE_CLASS (mode1) == MODE_VECTOR_FLOAT
+         || GET_MODE_CLASS (mode2) == MODE_VECTOR_FLOAT))
+    return N_("binary operator does not support mixing vector "
+             "bool with floating point vector operands");
+
+  return NULL;
+}
+
 /* Initialize GCC target structure.  */
 
 #undef  TARGET_ASM_ALIGNED_HI_OP
@@ -13863,6 +13921,9 @@ s390_vector_alignment (const_tree type)
 #undef TARGET_VECTOR_ALIGNMENT
 #define TARGET_VECTOR_ALIGNMENT s390_vector_alignment
 
+#undef TARGET_INVALID_BINARY_OP
+#define TARGET_INVALID_BINARY_OP s390_invalid_binary_op
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-s390.h"