gcc/ChangeLog:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 May 2004 07:23:00 +0000 (07:23 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 May 2004 07:23:00 +0000 (07:23 +0000)
2004-05-04  Paolo Bonzini  <bonzini@gnu.org>
            Richard Henderson  <rth@redhat.com>

        PR target/14899

        * c-common.c (vector_types_convertible_p): New function.
        * c-typeck.c (comptypes): Recurse on vector types.
        (convert_for_assignment): Use vector_types_convertible_p.
        (digest_init): Use vector_types_convertible_p to check
        validness of constant vector initializers; otherwise treat
        them as scalars.
        * tree.c (make_or_reuse_type): New.
        (build_common_tree_nodes): Use it.
        * cp/call.c (standard_conversion): Likewise.
        * cp/typeck.c (comptypes): Recurse on vector types.
        (convert_for_assignment): Use vector_types_convertible_p.
        * config/rs6000/rs6000.c (build_opaque_vector_type):
        New function.
        (rs6000_init_builtins): Use it.

gcc/testsuite/ChangeLog:
2004-05-04  Paolo Bonzini  <bonzini@gnu.org>

* g++.dg/ext/spe1.C: New testcase.

git-svn-id: svn://gcc.gnu.org/svn/gcc/trunk@81504 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-typeck.c
gcc/cp/call.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/spe1.C [new file with mode: 0644]
gcc/tree.c

index 7547050..d82a2de 100644 (file)
@@ -1,3 +1,23 @@
+2004-05-04  Paolo Bonzini  <bonzini@gnu.org>
+           Richard Henderson  <rth@redhat.com>
+
+       PR target/14899
+
+       * c-common.c (vector_types_convertible_p): New function.
+       * c-typeck.c (comptypes): Recurse on vector types.
+       (convert_for_assignment): Use vector_types_convertible_p.
+       (digest_init): Use vector_types_convertible_p to check
+       validness of constant vector initializers; otherwise treat
+       them as scalars.
+       * tree.c (make_or_reuse_type): New.
+       (build_common_tree_nodes): Use it.
+       * cp/call.c (standard_conversion): Likewise.
+       * cp/typeck.c (comptypes): Recurse on vector types.
+       (convert_for_assignment): Use vector_types_convertible_p.
+       * config/rs6000/rs6000.c (build_opaque_vector_type):
+       New function.
+       (rs6000_init_builtins): Use it.
+
 2004-05-04  Chris Demetriou  <cgd@broadcom.com>
 
        * config/mips/mips.c (override_options): Default to no
index c4f0129..15d7e68 100644 (file)
@@ -1277,6 +1277,16 @@ constant_fits_type_p (tree c, tree type)
   return !TREE_OVERFLOW (c);
 }
 
+/* Nonzero if vector types T1 and T2 can be converted to each other
+   without an explicit cast.  */
+int
+vector_types_convertible_p (tree t1, tree t2)
+{
+  return targetm.vector_opaque_p (t1)
+        || targetm.vector_opaque_p (t2)
+        || TYPE_MODE (t1) == TYPE_MODE (t2);
+}
+
 /* Convert EXPR to TYPE, warning about conversion problems with constants.
    Invoke this function on every expression that is converted implicitly,
    i.e. because of language rules and not because of an explicit cast.  */
index 6e9099a..7a0a6e6 100644 (file)
@@ -1257,6 +1257,8 @@ extern tree finish_label_address_expr (tree);
    different implementations.  Used in c-common.c.  */
 extern tree lookup_label (tree);
 
+extern int vector_types_convertible_p (tree t1, tree t2);
+
 extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
 
 extern int c_safe_from_p (rtx, tree);
index 2170222..c744cd6 100644 (file)
@@ -592,10 +592,8 @@ comptypes (tree type1, tree type2, int flags)
       break;
 
     case VECTOR_TYPE:
-      /* The target might allow certain vector types to be compatible.  */
-      val = targetm.vector_opaque_p (t1)
-       || targetm.vector_opaque_p (t2)
-       || TYPE_MODE (t1) == TYPE_MODE (t2);
+      val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+           && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 0);
       break;
 
     default:
@@ -3292,7 +3290,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
     }
   /* Some types can interconvert without explicit casts.  */
   else if (codel == VECTOR_TYPE
-           && comptypes (type, TREE_TYPE (rhs), COMPARE_STRICT) == 1)
+           && vector_types_convertible_p (type, TREE_TYPE (rhs)))
     return convert (type, rhs);
   /* Arithmetic types all interconvert, and enum is treated like int.  */
   else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
@@ -3937,11 +3935,11 @@ digest_init (tree type, tree init, int require_constant)
      vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
      below and handle as a constructor.  */
     if (code == VECTOR_TYPE
-        && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
+        && vector_types_convertible_p (TREE_TYPE (inside_init), type)
         && TREE_CONSTANT (inside_init))
       {
        if (TREE_CODE (inside_init) == VECTOR_CST
-           && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
+            && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
                          TYPE_MAIN_VARIANT (type),
                          COMPARE_STRICT))
          return inside_init;
@@ -4042,7 +4040,8 @@ digest_init (tree type, tree init, int require_constant)
   /* Handle scalar types, including conversions.  */
 
   if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
-      || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE)
+      || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
+      || code == VECTOR_TYPE)
     {
       /* Note that convert_for_assignment calls default_conversion
         for arrays and functions.  We must not call it in the
index 56e089d..4f38c7e 100644 (file)
@@ -660,8 +660,7 @@ standard_conversion (tree to, tree from, tree expr)
   else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
           && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
           && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
-          && ((*targetm.vector_opaque_p) (TREE_TYPE (to))
-              || (*targetm.vector_opaque_p) (TREE_TYPE (from))))
+          && vector_types_convertible_p (TREE_TYPE (to), TREE_TYPE (from)))
     conv = build_conv (ck_std, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
           || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
@@ -820,8 +819,7 @@ standard_conversion (tree to, tree from, tree expr)
        conv->rank = cr_promotion;
     }
   else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (from)
-         || (*targetm.vector_opaque_p) (to)))
+          && vector_types_convertible_p (from, to))
     return build_conv (ck_std, to, conv);
   else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
           && is_properly_derived_from (from, to))
index 5544f22..dedf495 100644 (file)
@@ -1058,6 +1058,11 @@ comptypes (tree t1, tree t2, int strict)
     case COMPLEX_TYPE:
       return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
 
+    case VECTOR_TYPE:
+      return TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+            && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
+      break;
+
     default:
       break;
     }
@@ -5600,8 +5605,7 @@ convert_for_assignment (tree type, tree rhs,
   coder = TREE_CODE (rhstype);
 
   if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (type)
-         || (*targetm.vector_opaque_p) (rhstype)))
+      && vector_types_convertible_p (type, rhstype))
     return convert (type, rhs);
 
   if (rhs == error_mark_node || rhstype == error_mark_node)
index 2fe6026..1cf06c4 100644 (file)
@@ -1,3 +1,7 @@
+2004-05-04  Paolo Bonzini  <bonzini@gnu.org>
+
+       * g++.dg/ext/spe1.C: New testcase.
+
 2004-05-04  Ziemowit Laski  <zlaski@apple.com>
 
        * objc.dg/image-info.m: Allow additional attributes
diff --git a/gcc/testsuite/g++.dg/ext/spe1.C b/gcc/testsuite/g++.dg/ext/spe1.C
new file mode 100644 (file)
index 0000000..b9ae5e7
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target powerpc-*-eabi* } } */
+/* { dg-options "-mcpu=8540 -mabi=spe -O0" } */
+
+typedef int v2si __attribute__ ((vector_size (8)));
+
+/* The two specializations must be considered different.  */
+template <class T> class X                 { };
+template <>        class X<__ev64_opaque__> { };
+template <>        class X<v2si>           { };
index e7435a7..0e159c3 100644 (file)
@@ -5195,6 +5195,27 @@ finish_vector_type (tree t)
   }
 }
 
+static tree
+make_or_reuse_type (unsigned size, int unsignedp)
+{
+  if (size == INT_TYPE_SIZE)
+    return unsignedp ? unsigned_type_node : integer_type_node;
+  if (size == CHAR_TYPE_SIZE)
+    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+  if (size == SHORT_TYPE_SIZE)
+    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+  if (size == LONG_TYPE_SIZE)
+    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+  if (size == LONG_LONG_TYPE_SIZE)
+    return (unsignedp ? long_long_unsigned_type_node
+            : long_long_integer_type_node);
+
+  if (unsignedp)
+    return make_unsigned_type (size);
+  else
+    return make_signed_type (size);
+}
+
 /* Create nodes for all integer types (and error_mark_node) using the sizes
    of C datatypes.  The caller should call set_sizetype soon after calling
    this function to select one of the types as sizetype.  */
@@ -5237,17 +5258,19 @@ build_common_tree_nodes (int signed_char)
   TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node;
   TYPE_PRECISION (boolean_type_node) = 1;
 
-  intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode));
-  intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode));
-  intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode));
-  intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
-  intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
-
-  unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
-  unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
-  unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode));
-  unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
-  unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
+  /* Fill in the rest of the sized types.  Reuse existing type nodes
+     when possible.  */
+  intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
+  intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 0);
+  intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);
+  intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);
+  intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);
+
+  unsigned_intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 1);
+  unsigned_intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 1);
+  unsigned_intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 1);
+  unsigned_intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 1);
+  unsigned_intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 1);
   
   access_public_node = get_identifier ("public");
   access_protected_node = get_identifier ("protected");