aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2003-04-01 13:40:11 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2003-04-01 13:40:11 +0000
commitd744e06e5edeb7dca7bf021559b3bdfdabe12a28 (patch)
tree8129a959cc2632337ea9823f4d5298efac0ea6e5 /gcc/expr.c
parent46e33d43a2f80c82284832820287e118c7e7c65c (diff)
downloadgcc-d744e06e5edeb7dca7bf021559b3bdfdabe12a28.zip
gcc-d744e06e5edeb7dca7bf021559b3bdfdabe12a28.tar.gz
gcc-d744e06e5edeb7dca7bf021559b3bdfdabe12a28.tar.bz2
simd-3.c: New.
* testsuite/gcc.c-torture/execute/simd-3.c: New. * expr.c (expand_expr): Handle VECTOR_CST. (const_vector_from_tree): New. * varasm.c (output_constant): Handle VECTOR_CST. * c-typeck.c (digest_init): Build a vector constant from a VECTOR_TYPE. * config/rs6000/rs6000.c: Remove prototype for easy_vector_constant. (easy_vector_constant): Add mode parameter. Rewrite to handle more easy constants. (rs6000_emit_move): Pass mode to easy_vector_constant. Call emit_easy_vector_insn for SPE V2SI vector constant moves. (emit_easy_vector_insn): New. (easy_vector_same): New. (EASY_VECTOR_15): New macro. (EASY_VECTOR_15_ADD_SELF): New macro. (bdesc_2arg): Rename to xorv2si3. (easy_vector_constant_add_self): New. (input_operand): Allow vector constants. * config/rs6000/rs6000.h (PREDICATE_CODES): Add easy_vector_constant, easy_vector_constant_add_self. (EXTRA_CONSTRAINT): Add 'W'. * config/rs6000/rs6000-protos.h: Add prototype for easy_vector_constant, emit_easy_vector_insn. * config/rs6000/altivec.md (xorv8hi3): New. (xorv16qi3): New. Remove all _const0 patterns. (movv4si_internal): Rewrite to use code. Add vector constant to vector alternative. Add splitter. (movv8hi_internal): Same. (movv16qi_internal): Same. (movv4sf_internal): Same. Change the unspecs for vspltis* to use constants. * config/rs6000/spe.md ("xorv4hi3"): New. ("spe_evxor"): Rename to xorv2si3. ("xorv1di3"): New. Remove all _const0 patterns. (movv2si_internal): Rewrite to use code. Add vector constant to alternatives. Add splitter. (movv4hi_internal): Add vector constant to alternatives. (movv1di_internal): Same. (movv2sf_internal): Same. From-SVN: r65130
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index a957dd7..e9d0ee5 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -155,7 +155,7 @@ static rtx clear_storage_via_libcall PARAMS ((rtx, rtx));
static tree clear_storage_libcall_fn PARAMS ((int));
static rtx compress_float_constant PARAMS ((rtx, rtx));
static rtx get_subtarget PARAMS ((rtx));
-static int is_zeros_p PARAMS ((tree));
+static int is_zeros_p PARAMS ((tree));
static int mostly_zeros_p PARAMS ((tree));
static void store_constructor_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, enum machine_mode,
@@ -175,6 +175,7 @@ static rtx do_store_flag PARAMS ((tree, rtx, enum machine_mode, int));
static void emit_single_push_insn PARAMS ((enum machine_mode, rtx, tree));
#endif
static void do_tablejump PARAMS ((rtx, enum machine_mode, rtx, rtx, rtx));
+static rtx const_vector_from_tree PARAMS ((tree));
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
@@ -6842,6 +6843,9 @@ expand_expr (exp, target, tmode, modifier)
return temp;
+ case VECTOR_CST:
+ return const_vector_from_tree (exp);
+
case CONST_DECL:
return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
@@ -10329,4 +10333,41 @@ vector_mode_valid_p (mode)
return mov_optab->handlers[innermode].insn_code != CODE_FOR_nothing;
}
+/* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */
+static rtx
+const_vector_from_tree (exp)
+ tree exp;
+{
+ rtvec v;
+ int units, i;
+ tree link, elt;
+ enum machine_mode inner, mode;
+
+ mode = TYPE_MODE (TREE_TYPE (exp));
+
+ if (is_zeros_p (exp))
+ return CONST0_RTX (mode);
+
+ units = GET_MODE_NUNITS (mode);
+ inner = GET_MODE_INNER (mode);
+
+ v = rtvec_alloc (units);
+
+ link = TREE_VECTOR_CST_ELTS (exp);
+ for (i = 0; link; link = TREE_CHAIN (link), ++i)
+ {
+ elt = TREE_VALUE (link);
+
+ if (TREE_CODE (elt) == REAL_CST)
+ RTVEC_ELT (v, i) = CONST_DOUBLE_FROM_REAL_VALUE (TREE_REAL_CST (elt),
+ inner);
+ else
+ RTVEC_ELT (v, i) = immed_double_const (TREE_INT_CST_LOW (elt),
+ TREE_INT_CST_HIGH (elt),
+ inner);
+ }
+
+ return gen_rtx_raw_CONST_VECTOR (mode, v);
+}
+
#include "gt-expr.h"