diff options
author | crux <crux@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-06-24 19:26:42 +0000 |
---|---|---|
committer | crux <crux@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-06-24 19:26:42 +0000 |
commit | 8a95ab857c0aa88461aa4f10944825c98f32d0df (patch) | |
tree | db94b2c1a07d5c04365806edf03c813ecba575c1 /gcc | |
parent | 2323093ea57b891515a0792298d5e3998ee8218d (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/c-convert.c | 2 | ||||
-rw-r--r-- | gcc/convert.c | 39 | ||||
-rw-r--r-- | gcc/convert.h | 1 | ||||
-rw-r--r-- | gcc/expmed.c | 3 | ||||
-rw-r--r-- | gcc/expr.c | 17 | ||||
-rw-r--r-- | gcc/stor-layout.c | 11 | ||||
-rw-r--r-- | gcc/tree.def | 4 | ||||
-rw-r--r-- | gcc/tree.h | 8 |
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) |