summaryrefslogtreecommitdiff
path: root/gcc/stor-layout.c
diff options
context:
space:
mode:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-22 08:20:40 +0000
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-22 08:20:40 +0000
commit83e2a11b2613ddd8dfc024700b1c86729b058300 (patch)
tree4646f9e5e0b2387d4bcc7fc94aff9d320ae0030d /gcc/stor-layout.c
parent280450faa1152c283c0bb88b31337cee8e569ff5 (diff)
downloadgcc-83e2a11b2613ddd8dfc024700b1c86729b058300.tar.gz
2004-07-22 Paolo Bonzini <bonzini@gnu.org>
* tree-cfg.c (gimplify_val): Move from tree-complex.c. (gimplify_build1): Move from tree-complex.c do_unop. (gimplify_build2): Move from tree-complex.c do_binop. (gimplify_build3): New. * tree-complex.c (gimplify_val, do_unop, do_binop): Remove. Adjust throughout to call the functions above. * tree-flow.h: Declare the functions above. * tree-nested.c (gimplify_val): Rename to... (tsi_gimplify_val): ... this. * Makefile.in (tree_complex.o): Update dependencies. (stor-layout.o): Depend on regs.h. * c-common.c (handle_vector_size_attribute): Update for vector types without corresponding vector modes. * expr.c (expand_expr): Treat VECTOR_CST's like CONSTRUCTORS if a corresponding vector mode is not available. * print-tree.c (print_node): Print nunits for vector types * regclass.c (have_regs_of_mode): New. (init_reg_sets_1): Initialize it and use it instead of allocatable_regs_of_mode. * regs.h (have_regs_of_mode): Declare it. * stor-layout.c (layout_type): Pick a mode for vector types. * tree-complex.c (build_word_mode_vector_type, tree_vec_extract, build_replicated_const, do_unop, do_binop, do_plus_minus, do_negate, expand_vector_piecewise, expand_vector_parallel, expand_vector_addition, expand_vector_operations_1, expand_vector_operations, tree_lower_operations, pass_lower_vector_ssa, pass_pre_expand): New. (expand_complex_operations, pass_lower_complex): Remove. * tree-optimize.c (init_tree_optimization_passes): Adjust pass ordering for changes in tree-complex.c. * tree-pass.h: Declare new passes. * tree.c (finish_vector_type): Remove. (make_vector_type): New. (build_vector_type_for_mode, build_vector_type): Rewritten. * tree.def (VECTOR_TYPE): Document where the number of subparts is stored. * tree.h (TYPE_VECTOR_SUBPARTS): Use TYPE_PRECISION field. (make_vector): Remove declaration. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85039 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r--gcc/stor-layout.c51
1 files changed, 47 insertions, 4 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 0ca26c238f7..139ba510435 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "target.h"
#include "langhooks.h"
+#include "regs.h"
/* Set to one when set_sizetype has been called. */
static int sizetype_set;
@@ -1582,10 +1583,52 @@ layout_type (tree type)
break;
case VECTOR_TYPE:
- TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
- TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
- TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
- break;
+ {
+ int nunits = TYPE_VECTOR_SUBPARTS (type);
+ tree nunits_tree = build_int_2 (nunits, 0);
+ tree innertype = TREE_TYPE (type);
+
+ if (nunits & (nunits - 1))
+ abort ();
+
+ /* Find an appropriate mode for the vector type. */
+ if (TYPE_MODE (type) == VOIDmode)
+ {
+ enum machine_mode innermode = TYPE_MODE (innertype);
+ enum machine_mode mode;
+
+ /* First, look for a supported vector type. */
+ if (GET_MODE_CLASS (innermode) == MODE_FLOAT)
+ mode = MIN_MODE_VECTOR_FLOAT;
+ else
+ mode = MIN_MODE_VECTOR_INT;
+
+ for (; mode != VOIDmode ; mode = GET_MODE_WIDER_MODE (mode))
+ if (GET_MODE_NUNITS (mode) == nunits
+ && GET_MODE_INNER (mode) == innermode
+ && VECTOR_MODE_SUPPORTED_P (mode))
+ break;
+
+ /* For integers, try mapping it to a same-sized scalar mode. */
+ if (mode == VOIDmode
+ && GET_MODE_CLASS (innermode) == MODE_INT)
+ mode = mode_for_size (nunits * GET_MODE_BITSIZE (innermode),
+ MODE_INT, 0);
+
+ if (mode == VOIDmode || !have_regs_of_mode[mode])
+ TYPE_MODE (type) = BLKmode;
+ else
+ TYPE_MODE (type) = mode;
+ }
+
+ TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
+ TYPE_SIZE_UNIT (type) = int_const_binop (MULT_EXPR,
+ TYPE_SIZE_UNIT (innertype),
+ nunits_tree, 0);
+ TYPE_SIZE (type) = int_const_binop (MULT_EXPR, TYPE_SIZE (innertype),
+ nunits_tree, 0);
+ break;
+ }
case VOID_TYPE:
/* This is an incomplete type and so doesn't have a size. */