Vector conversions support
authorBernd Schmidt <bernds@cygnus.co.uk>
Sat, 24 Jun 2000 19:26:42 +0000 (19:26 +0000)
committerBernd Schmidt <crux@gcc.gnu.org>
Sat, 24 Jun 2000 19:26:42 +0000 (19:26 +0000)
From-SVN: r34680

gcc/ChangeLog
gcc/c-convert.c
gcc/convert.c
gcc/convert.h
gcc/expmed.c
gcc/expr.c
gcc/stor-layout.c
gcc/tree.def
gcc/tree.h

index 7e39f84..9633f0b 100644 (file)
@@ -1,3 +1,16 @@
+2000-06-24  Bernd Schmidt  <bernds@cygnus.co.uk>
+
+       * tree.def (VECTOR_TYPE): New node type.
+       * tree.h: Adjust some comments to reflect addition of vector types.
+       (TYPE_VECTOR_SUBPARTS): New macro.
+       * stor-layout.c (layout_type): Handle VECTOR_TYPE.
+       * c-convert.c (convert): Likewise.
+       * convert.c (convert_to_integer): Handle vector modes.
+       (convert_to_vector): New function.
+       * convert.h (convert_to_vector): Declare.
+       * expr.c (convert_move): Handle vector modes.
+       * expmed.c (extract_bit_field): Don't abort for vector modes.
+
 2000-06-24  Marek Michalkiewicz  <marekm@linux.org.pl>
 
        * config/avr/avr-protos.h (avr_hard_regno_mode_ok): New prototype.
index 8dc8550..5d7ea00 100644 (file)
@@ -94,6 +94,8 @@ convert (type, expr)
     return fold (convert_to_real (type, e));
   if (code == COMPLEX_TYPE)
     return fold (convert_to_complex (type, e));
+  if (code == VECTOR_TYPE)
+    return fold (convert_to_vector (type, e));
 
   error ("conversion to non-scalar type requested");
   return error_mark_node;
index 56a9e82..6eea7d6 100644 (file)
@@ -108,8 +108,8 @@ convert_to_real (type, expr)
 
 /* Convert EXPR to some integer (or enum) type TYPE.
 
-   EXPR must be pointer, integer, discrete (enum, char, or bool), or float;
-   in other cases error is called.
+   EXPR must be pointer, integer, discrete (enum, char, or bool), float, or
+   vector; in other cases error is called.
 
    The result of this is always supposed to be a newly created tree node
    not in use in any existing structure.  */
@@ -383,6 +383,15 @@ convert_to_integer (type, expr)
                      fold (build1 (REALPART_EXPR,
                                    TREE_TYPE (TREE_TYPE (expr)), expr)));
 
+    case VECTOR_TYPE:
+      if (GET_MODE_SIZE (TYPE_MODE (type))
+         != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
+       {
+         error ("can't convert between vector values of different size");
+         return error_mark_node;
+       }
+      return build1 (NOP_EXPR, type, expr);
+
     default:
       error ("aggregate value used where an integer was expected");
       return convert (type, integer_zero_node);
@@ -444,3 +453,29 @@ convert_to_complex (type, expr)
       return convert_to_complex (type, integer_zero_node);
     }
 }
+
+/* Convert EXPR to the vector type TYPE in the usual ways.  */
+
+tree
+convert_to_vector (type, expr)
+     tree type, expr;
+{
+  tree subtype = TREE_TYPE (type);
+  
+  switch (TREE_CODE (TREE_TYPE (expr)))
+    {
+    case INTEGER_TYPE:
+    case VECTOR_TYPE:
+      if (GET_MODE_SIZE (TYPE_MODE (type))
+         != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
+       {
+         error ("can't convert between vector values of different size");
+         return error_mark_node;
+       }
+      return build1 (NOP_EXPR, type, expr);
+
+    default:
+      error ("can't convert value to a vector");
+      return convert_to_vector (type, integer_zero_node);
+    }
+}
index 28ca161..ed93c4b 100644 (file)
@@ -22,3 +22,4 @@ extern tree convert_to_integer PARAMS ((tree, tree));
 extern tree convert_to_pointer PARAMS ((tree, tree));
 extern tree convert_to_real PARAMS ((tree, tree));
 extern tree convert_to_complex PARAMS ((tree, tree));
+extern tree convert_to_vector PARAMS ((tree, tree));
index c230a33..883d33f 100644 (file)
@@ -1072,7 +1072,8 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
                  : bitpos == 0))))
     {
       enum machine_mode mode1
-       = mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0);
+       = (VECTOR_MODE_P (tmode) ? mode
+          : mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0));
 
       if (mode1 != GET_MODE (op0))
        {
index 07fa592..02a7a35 100644 (file)
@@ -545,6 +545,23 @@ convert_move (to, from, unsignedp)
       return;
     }
 
+  if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
+    {
+      if (GET_MODE_BITSIZE (from_mode) != GET_MODE_BITSIZE (to_mode))
+       abort ();
+      
+      if (VECTOR_MODE_P (to_mode))
+       from = gen_rtx_SUBREG (to_mode, from, 0);
+      else
+       to = gen_rtx_SUBREG (from_mode, to, 0);
+
+      emit_move_insn (to, from);
+      return;
+    }
+
+  if (to_real != from_real)
+    abort ();
+
   if (to_real)
     {
       rtx value;
index 65ac15b..12162e7 100644 (file)
@@ -1286,6 +1286,17 @@ layout_type (type)
       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
       break;
 
+    case VECTOR_TYPE:
+      {
+       tree subtype;
+
+       subtype = TREE_TYPE (type);
+       TREE_UNSIGNED (type) = TREE_UNSIGNED (subtype);
+       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
+       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
+      }
+      break;
+
     case VOID_TYPE:
       /* This is an incomplete type and so doesn't have a size.  */
       TYPE_ALIGN (type) = 1;
index e3fb8b4..28c47d9 100644 (file)
@@ -150,6 +150,10 @@ DEFTREECODE (REAL_TYPE, "real_type", 't', 0)
    of the real and imaginary parts.  */
 DEFTREECODE (COMPLEX_TYPE, "complex_type", 't', 0)
 
+/* Vector types.  The TREE_TYPE field is the data type of the vector
+   elements.  */
+DEFTREECODE (VECTOR_TYPE, "vector_type", 't', 0)
+
 /* C enums.  The type node looks just like an INTEGER_TYPE node.
    The symbols for the values of the enum type are defined by
    CONST_DECL nodes, but the type does not point to them;
index 1b68a46..f683357 100644 (file)
@@ -332,7 +332,8 @@ extern void tree_class_check_failed PARAMS ((const tree, int,
 
 /* In all nodes that are expressions, this is the data type of the expression.
    In POINTER_TYPE nodes, this is the type that the pointer points to.
-   In ARRAY_TYPE nodes, this is the type of the elements.  */
+   In ARRAY_TYPE nodes, this is the type of the elements.
+   In VECTOR_TYPE nodes, this is the type of the elements.  */
 #define TREE_TYPE(NODE) ((NODE)->common.type)
 
 /* Nodes are chained together for many purposes.
@@ -1012,7 +1013,10 @@ struct tree_block
    object of the given ARRAY_TYPE.  This allows temporaries to be allocated. */
 #define TYPE_ARRAY_MAX_SIZE(ARRAY_TYPE) TYPE_MAX_VALUE (ARRAY_TYPE)
 
-/* Indicates that objects of this type must be initialized by calling a
+/* For a VECTOR_TYPE, this is the number of sub-parts of the vector.  */
+#define TYPE_VECTOR_SUBPARTS(VECTOR_TYPE) (GET_MODE_NUNITS (TYPE_CHECK (VECTOR_TYPE)->type.mode))
+
+  /* Indicates that objects of this type must be initialized by calling a
    function when they are created.  */
 #define TYPE_NEEDS_CONSTRUCTING(NODE) \
   (TYPE_CHECK (NODE)->type.needs_constructing_flag)