diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fcde7439948..9676e38c765 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-05-19 Andreas Krebbel + + * 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 * loop-invariant.c (create_new_invariant): Don't calculate address cost diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 7fd59699410..6648597fe44 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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"