From cb4c41dd4d9b0cf349e9c51c23492113dea975a6 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Tue, 19 May 2015 17:41:21 +0000 Subject: [PATCH] S/390 Invalid vector binary ops 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 | 6 +++++ gcc/config/s390/s390.c | 61 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) 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" -- 2.30.2