summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorcrux <crux@138bc75d-0d04-0410-961f-82ee72b054a4>2000-06-24 19:26:42 +0000
committercrux <crux@138bc75d-0d04-0410-961f-82ee72b054a4>2000-06-24 19:26:42 +0000
commit8a95ab857c0aa88461aa4f10944825c98f32d0df (patch)
treedb94b2c1a07d5c04365806edf03c813ecba575c1 /gcc
parent2323093ea57b891515a0792298d5e3998ee8218d (diff)
downloadgcc-8a95ab857c0aa88461aa4f10944825c98f32d0df.tar.gz
Vector conversions support
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34680 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/c-convert.c2
-rw-r--r--gcc/convert.c39
-rw-r--r--gcc/convert.h1
-rw-r--r--gcc/expmed.c3
-rw-r--r--gcc/expr.c17
-rw-r--r--gcc/stor-layout.c11
-rw-r--r--gcc/tree.def4
-rw-r--r--gcc/tree.h8
9 files changed, 93 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7e39f84db45..9633f0bc9e9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-convert.c b/gcc/c-convert.c
index 8dc85509d74..5d7ea00f82b 100644
--- a/gcc/c-convert.c
+++ b/gcc/c-convert.c
@@ -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;
diff --git a/gcc/convert.c b/gcc/convert.c
index 56a9e829e70..6eea7d684c6 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -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);
+ }
+}
diff --git a/gcc/convert.h b/gcc/convert.h
index 28ca1617022..ed93c4b9e57 100644
--- a/gcc/convert.h
+++ b/gcc/convert.h
@@ -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));
diff --git a/gcc/expmed.c b/gcc/expmed.c
index c230a338356..883d33f470c 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -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))
{
diff --git a/gcc/expr.c b/gcc/expr.c
index 07fa592a76f..02a7a354861 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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;
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 65ac15b12bc..12162e7f14b 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -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;
diff --git a/gcc/tree.def b/gcc/tree.def
index e3fb8b4962b..28c47d97a79 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -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;
diff --git a/gcc/tree.h b/gcc/tree.h
index 1b68a461d7f..f683357f148 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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)