]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386.md ("mmx_uavgv8qi3"): Use const_vector.
authorAldy Hernandez <aldyh@gcc.gnu.org>
Tue, 19 Feb 2002 02:53:41 +0000 (02:53 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Tue, 19 Feb 2002 02:53:41 +0000 (02:53 +0000)
2002-02-19  Aldy Hernandez  <aldyh@redhat.com>

* config/i386/i386.md ("mmx_uavgv8qi3"): Use const_vector.
("mmx_uavgv4hi3"): Same.
("pmulhrwv4hi3"): Same.

* tree-inline.c (walk_tree): Handle vectors.

* c-common.c (constant_expression_warning): Handle vectors.
(overflow_warning): Same.

* sched-deps.c (sched_analyze_2): Handle vectors.

* rtlanal.c (rtx_unstable_p): Handle vectors.
(rtx_varies_p): Same.
(count_occurrences): Same.
(regs_set_between_p): Same.
(modified_between_p): Same.
(modified_in_p): Same.
(volatile_insn_p): Same.
(volatile_refs_p): Same.
(side_effects_p): Same.
(may_trap_p): Same.
(inequality_comparisons_p): Same.
(replace_regs): Same.
(computed_jump_p_1): Same.

* rtl.c (DEF_MACHMODE): Change all definitions to accept 8th
argument.
(inner_mode_array): New.
(copy_rtx): Handle vectors.
(copy_most_rtx): Same.
(rtx_equal_p): Same.
(get_mode_alignment): Adjust for vectors.

* resource.c (mark_referenced_resources): Handle vectors.
(mark_set_resources): Same.

* reload1.c (eliminate_regs): Handle vectors.
(elimination_effects): Same.
(scan_paradoxical_subregs): Same.

* reload.c (subst_reg_equivs): Handle vectors.

* regrename.c (scan_rtx): Handle vectors.

* regclass.c (reg_scan_mark_refs): Handle vectors.

* recog.c (find_single_use_1): Handle vectors.

* local-alloc.c (equiv_init_varies_p): Handle vectors.
(contains_replace_regs): Same.
(memref_referenced_p): Same.

* integrate.c (copy_rtx_and_substitute): Handle vectors.
(subst_constants): Same.

* genattrtab.c (attr_copy_rtx): Handle vectors.
(encode_units_mask): Same.
(clear_struct_flag): Same.
(count_sub_rtxs): Same.

* gcse.c (want_to_gcse_p): Handle vectors.
(oprs_unchanged_p): Same.
(hash_expr_1): Same.
(oprs_not_set_p): Same.
(expr_killed_p): Same.
(compute_transp): Same.
(store_ops_ok): Same.

* function.c (purge_addressof_1): Do not allow paradoxical subregs
of vectors.
(fixup_var_refs_1): Same.
(instantiate_virtual_regs_1): Same.

* fold-const.c (operand_equal_p): Handle vectors.
(fold): Same.
(rtl_expr_nonnegative_p): Same.

* flow.c (mark_used_regs): Handle vectors.

* df.c (df_uses_record): Handle vectors.

* cselib.c (cselib_subst_to_values): Handle vectors.
(cselib_mem_conflict_p): Same.
(hash_rtx): Same.

* cse.c (canon_reg): Handle vectors.
(fold_rt): Same.
(cse_process_notes): Same.
(count_reg_usage): Same.
(canon_hash): Same.

* alias.c (nonlocal_mentioned_p): Add case for CONST_VECTOR.

* combine.c (mark_used_regs_combine): Add case for CONST_VECTOR.

* emit-rtl.c (init_emit_once): Generate const0_rtx for vectors.
(gen_rtx): Handle CONST_VECTOR.
(gen_const_vector_0): New.
(copy_rtx_if_shared): CONST_VECTORs can be shared.
(reset_used_flags): Same.
(copy_insn_1): Same.
(initializer_constant_valid_p): Handle VECTOR_CST.

* doc/c-tree.texi (Expression trees): Document VECTOR_CST.

* doc/rtl.texi (Constants): Document const_vector.
(CONST0_RTX): Update for vectors.
(RTL sharing): Same.

* print-tree.c (print_node): Add case for VECTOR_CST.

* tree.h (TREE_VECTOR_CST_ELTS): New.
(struct tree_vector): New.
(union tree_node): Add vector node.
(build_vector): Add prototype.

* tree.def (VECTOR_CST): New.

* tree.c (build_vector): New.

* expmed.c (make_tree): Handle CONST_VECTOR.

* rtl.h (CONSTANT_P): CONST_VECTORs are constants too.
(CONST_VECTOR_ELT): New.
(CONST_VECTOR_NUNITS): New.

* machmode.h (GET_MODE_INNER): New.
(DEF_MACHMODE): Accept 8th arg.

* machmode.def: Add 8th argument for vector inner mode.
Add inner vector modes for vectors.

* rtl.def (VEC_CONST): Remove.
(CONST_VECTOR): New.

* expr.c (clear_storage): Allow vectors.
(is_zeros_p): Handle VECTOR_CST.

* varasm.c (output_constant_pool): Handle vectors.
(rtx_const): Add veclo and vechi fields.
(kind): Add RTX_VECTOR.
(decode_rtx_const): Add case for vector.

* config/rs6000/rs6000-protos.h: Add zero_constant.

* config/rs6000/rs6000.c (rs6000_emit_move): Handle vector
constants.  Force easy vector constants into memory.
(easy_vector_constant): New.
(emit_easy_vector_constant): New.
(rs6000_legitimize_reload_address): Do not generate bad reloads on
darwin.

* config/rs6000/rs6000.md ("altivec_lvx"): Reflect what
instruction does.
("altivec_lvxl"): Same.
(altivec_lvebx): Same.
(altivec_lvehx): Same.
(altivec_lvewx): Same.
("*movv4si_const0"): New.
("*movv4sf_const0"): New.
("*movv8hi_const0"): New.
("*movv16qi_const0"): New.

From-SVN: r49853

42 files changed:
gcc/alias.c
gcc/c-common.c
gcc/combine.c
gcc/config/i386/i386.md
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/cse.c
gcc/cselib.c
gcc/df.c
gcc/doc/c-tree.texi
gcc/doc/rtl.texi
gcc/emit-rtl.c
gcc/expmed.c
gcc/expr.c
gcc/flow.c
gcc/fold-const.c
gcc/function.c
gcc/gcse.c
gcc/genattrtab.c
gcc/integrate.c
gcc/local-alloc.c
gcc/machmode.def
gcc/machmode.h
gcc/print-tree.c
gcc/recog.c
gcc/regclass.c
gcc/regrename.c
gcc/reload.c
gcc/reload1.c
gcc/resource.c
gcc/rtl.c
gcc/rtl.def
gcc/rtl.h
gcc/rtlanal.c
gcc/sched-deps.c
gcc/tree-inline.c
gcc/tree.c
gcc/tree.def
gcc/tree.h
gcc/varasm.c

index fb93d658fafd75992b8955b344657e665c9eb543..5d017eb73c953f19a45915cc665e76855ffb7675 100644 (file)
@@ -2276,6 +2276,7 @@ nonlocal_mentioned_p (x)
     case CC0:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case LABEL_REF:
       return 0;
index 3768db554ba13e287827dc35f3575a873396050d..b2bdf50ef28c12f1963882ab3f9c4bc9eb9deccd 100644 (file)
@@ -702,6 +702,7 @@ constant_expression_warning (value)
      tree value;
 {
   if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
+       || TREE_CODE (value) == VECTOR_CST
        || TREE_CODE (value) == COMPLEX_CST)
       && TREE_CONSTANT_OVERFLOW (value) && pedantic)
     pedwarn ("overflow in constant expression");
@@ -736,6 +737,12 @@ overflow_warning (value)
       if (skip_evaluation == 0)
        warning ("floating point overflow in expression");
     }
+  else if (TREE_CODE (value) == VECTOR_CST && TREE_OVERFLOW (value))
+    {
+      TREE_OVERFLOW (value) = 0;
+      if (skip_evaluation == 0)
+       warning ("vector overflow in expression");
+    }
 }
 
 /* Print a warning if a large constant is truncated to unsigned,
index 5abda2e56fe8c7d8e43319de2605637d6d89c7d0..eb825311613682bc2b83978a4bd9963a9343be57 100644 (file)
@@ -11603,6 +11603,7 @@ mark_used_regs_combine (x)
     case CONST_INT:
     case CONST:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case PC:
     case ADDR_VEC:
     case ADDR_DIFF_VEC:
index b0ec9f21368dc4993f81f04545aa76c2a9cd8438..1d7091d2d9bef9db8c2c5b438e946f3f625963c8 100644 (file)
         (plus:V8QI (plus:V8QI
                     (match_operand:V8QI 1 "register_operand" "0")
                     (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
-                   (vec_const:V8QI (parallel [(const_int 1)
-                                              (const_int 1)
-                                              (const_int 1)
-                                              (const_int 1)
-                                              (const_int 1)
-                                              (const_int 1)
-                                              (const_int 1)
-                                              (const_int 1)])))
+                   (const_vector:V8QI [(const_int 1)
+                                       (const_int 1)
+                                       (const_int 1)
+                                       (const_int 1)
+                                       (const_int 1)
+                                       (const_int 1)
+                                       (const_int 1)
+                                       (const_int 1)]))
         (const_int 1)))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pavgb\t{%2, %0|%0, %2}"
         (plus:V4HI (plus:V4HI
                     (match_operand:V4HI 1 "register_operand" "0")
                     (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
-                   (vec_const:V4HI (parallel [(const_int 1)
-                                              (const_int 1)
-                                              (const_int 1)
-                                              (const_int 1)])))
+                   (const_vector:V4HI [(const_int 1)
+                                       (const_int 1)
+                                       (const_int 1)
+                                       (const_int 1)]))
         (const_int 1)))]
   "TARGET_SSE || TARGET_3DNOW_A"
   "pavgw\t{%2, %0|%0, %2}"
                       (match_operand:V4HI 1 "register_operand" "0"))
                    (sign_extend:V4SI
                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
-             (vec_const:V4SI
-                (parallel [(const_int 32768)
-                           (const_int 32768)
-                           (const_int 32768)
-                           (const_int 32768)])))
-          (const_int 16))))]
+                (const_vector:V4SI [(const_int 32768)
+                                    (const_int 32768)
+                                    (const_int 32768)
+                                    (const_int 32768)]))
+             (const_int 16))))]
   "TARGET_3DNOW"
   "pmulhrw\\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmx")])
index a588360c36b5451145af7760e0859d03b43d8c04..19aeb07b9e0c26ca65f3142b7e20980857f6e35e 100644 (file)
@@ -52,6 +52,7 @@ extern int got_no_const_operand PARAMS ((rtx, enum machine_mode));
 extern int num_insns_constant PARAMS ((rtx, enum machine_mode));
 extern int easy_fp_constant PARAMS ((rtx, enum machine_mode));
 extern int zero_fp_constant PARAMS ((rtx, enum machine_mode));
+extern int zero_constant PARAMS ((rtx, enum machine_mode));
 extern int volatile_mem_operand PARAMS ((rtx, enum machine_mode));
 extern int offsettable_mem_operand PARAMS ((rtx, enum machine_mode));
 extern int mem_or_easy_const_operand PARAMS ((rtx, enum machine_mode));
index 8cd66463d5c046378fc75d542b7157692af3fb55..5e3a7353c3328161215153ea54a96bac2ebe9779 100644 (file)
@@ -174,6 +174,7 @@ static void is_altivec_return_reg PARAMS ((rtx, void *));
 int vrsave_operation PARAMS ((rtx, enum machine_mode));
 static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
 static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
+static int easy_vector_constant PARAMS ((rtx));
 \f
 /* Default register names.  */
 char rs6000_reg_names[][8] =
@@ -1194,6 +1195,54 @@ easy_fp_constant (op, mode)
     abort ();
 }
 
+/* Return 1 if the operand is a CONST_INT and can be put into a
+   register with one instruction.  */
+
+static int
+easy_vector_constant (op)
+     rtx op;
+{
+  rtx elt;
+  int units, i;
+
+  if (GET_CODE (op) != CONST_VECTOR)
+    return 0;
+
+  units = CONST_VECTOR_NUNITS (op);
+
+  /* We can generate 0 easily.  Look for that.  */
+  for (i = 0; i < units; ++i)
+    {
+      elt = CONST_VECTOR_ELT (op, i);
+
+      /* We could probably simplify this by just checking for equality
+        with CONST0_RTX for the current mode, but let's be safe
+        instead.  */
+
+      if (GET_CODE (elt) == CONST_INT && INTVAL (elt) != 0)
+       return 0;
+
+      if (GET_CODE (elt) == CONST_DOUBLE
+              && (CONST_DOUBLE_LOW (elt) != 0
+                  || CONST_DOUBLE_HIGH (elt) != 0))
+       return 0;
+    }
+
+  /* We could probably generate a few other constants trivially, but
+     gcc doesn't generate them yet.  FIXME later.  */
+  return 0;
+}
+
+/* Return 1 if the operand is the constant 0.  This works for scalars
+   as well as vectors.  */
+int
+zero_constant (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  return op == CONST0_RTX (mode);
+}
+
 /* Return 1 if the operand is 0.0.  */
 int
 zero_fp_constant (op, mode)
@@ -1892,6 +1941,7 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
 #if TARGET_MACHO
   if (GET_CODE (x) == SYMBOL_REF
       && DEFAULT_ABI == ABI_DARWIN
+      && !ALTIVEC_VECTOR_MODE (mode)
       && flag_pic)
     {
       /* Darwin load of floating point constant.  */
@@ -2186,9 +2236,10 @@ rs6000_emit_move (dest, source, mode)
 
   /* Handle the case where reload calls us with an invalid address;
      and the case of CONSTANT_P_RTX.  */
-  if (! general_operand (operands[1], mode)
-      || ! nonimmediate_operand (operands[0], mode)
-      || GET_CODE (operands[1]) == CONSTANT_P_RTX)
+  if (!VECTOR_MODE_P (mode)
+      && (! general_operand (operands[1], mode)
+         || ! nonimmediate_operand (operands[0], mode)
+         || GET_CODE (operands[1]) == CONSTANT_P_RTX))
     {
       emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
       return;
@@ -2218,8 +2269,8 @@ rs6000_emit_move (dest, source, mode)
     case V8HImode:
     case V4SFmode:
     case V4SImode:
-      /* fixme: aldyh -- allow vector constants when they are implemented.  */
-      if (CONSTANT_P (operands[1]))
+      if (CONSTANT_P (operands[1])
+         && !easy_vector_constant (operands[1]))
        operands[1] = force_const_mem (mode, operands[1]);
       break;
       
index ebbede46205bd866ad6b4e5388a02fc2a0486dd3..cdbe3361a91f234a8ed876ec7e650054a785f0e1 100644 (file)
@@ -638,10 +638,13 @@ extern int rs6000_altivec_abi;
 /* A bitfield declared as `int' forces `int' alignment for the struct.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
-/* Make strings word-aligned so strcpy from constants will be faster.  */
-#define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
-  (TREE_CODE (EXP) == STRING_CST       \
-   && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+/* Make strings word-aligned so strcpy from constants will be faster.
+   Make vector constants quadword aligned.  */
+#define CONSTANT_ALIGNMENT(EXP, ALIGN)                           \
+  (TREE_CODE (EXP) == STRING_CST                                \
+   && (ALIGN) < BITS_PER_WORD                                    \
+   ? BITS_PER_WORD                                               \
+   : (ALIGN))
 
 /* Make arrays of chars word-aligned for the same reasons.
    Align vectors to 128 bits.  */
index 7a5bce5b931d4499b1bf222e6b4c1d04470d1a34..d83538ba6253abbe435298e2a4db04d38854e5ed 100644 (file)
   "mtvrsave %1"
   [(set_attr "type" "altivec")])
 
+;; Vector clears
+(define_insn "*movv4si_const0"
+  [(set (match_operand:V4SI 0 "altivec_register_operand" "=v")
+       (match_operand:V4SI 1 "zero_constant" ""))]
+  "TARGET_ALTIVEC"
+  "vxor %0,%0,%0"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "*movv4sf_const0"
+  [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
+       (match_operand:V4SF 1 "zero_constant" ""))]
+                                        
+  "TARGET_ALTIVEC"
+  "vxor %0,%0,%0"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "*movv8hi_const0"
+  [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
+       (match_operand:V8HI 1 "zero_constant" ""))]
+  "TARGET_ALTIVEC"
+  "vxor %0,%0,%0"
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "*movv16qi_const0"
+  [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
+       (match_operand:V16QI 1 "zero_constant" ""))]
+  "TARGET_ALTIVEC"
+  "vxor %0,%0,%0"
+  [(set_attr "type" "vecsimple")])
+
 ;; Simple binary operations.
 
 (define_insn "addv16qi3"
   "lvsr %0,%1,%2"
   [(set_attr "type" "vecload")])
 
+;; Parallel some of the LVE* and STV*'s with unspecs because some have
+;; identical rtl but different instructions-- and gcc gets confused.
+
 (define_insn "altivec_lvebx"
-  [(set (match_operand:V16QI 0 "register_operand" "=v")
-       (unspec:V16QI [(match_operand:SI 1 "register_operand" "b")
-                      (match_operand:SI 2 "register_operand" "r")] 196))]
+  [(parallel
+    [(set (match_operand:V16QI 0 "register_operand" "=v")
+         (mem:V16QI (plus:SI (match_operand:SI 1 "register_operand" "b")
+                             (match_operand:SI 2 "register_operand" "r"))))
+     (unspec [(const_int 0)] 196)])]
   "TARGET_ALTIVEC"
   "lvebx %0,%1,%2"
   [(set_attr "type" "vecload")])
 
 (define_insn "altivec_lvehx"
-  [(set (match_operand:V8HI 0 "register_operand" "=v")
-       (unspec:V8HI [(match_operand:SI 1 "register_operand" "b")
-                     (match_operand:SI 2 "register_operand" "r")] 197))]
+  [(parallel
+    [(set (match_operand:V8HI 0 "register_operand" "=v")
+         (mem:V8HI
+          (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
+                           (match_operand:SI 2 "register_operand" "r"))
+                  (const_int -2))))
+     (unspec [(const_int 0)] 197)])]
   "TARGET_ALTIVEC"
   "lvehx %0,%1,%2"
   [(set_attr "type" "vecload")])
 
 (define_insn "altivec_lvewx"
-  [(set (match_operand:V4SI 0 "register_operand" "=v")
-       (unspec:V4SI [(match_operand:SI 1 "register_operand" "b")
-                     (match_operand:SI 2 "register_operand" "r")] 198))]
+  [(parallel
+    [(set (match_operand:V4SI 0 "register_operand" "=v")
+         (mem:V4SI
+          (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
+                           (match_operand:SI 2 "register_operand" "r"))
+                  (const_int -4))))
+     (unspec [(const_int 0)] 198)])]
   "TARGET_ALTIVEC"
   "lvewx %0,%1,%2"
   [(set_attr "type" "vecload")])
 
 (define_insn "altivec_lvxl"
-  [(set (match_operand:V4SI 0 "register_operand" "=v")
-       (unspec:V4SI [(match_operand:SI 1 "register_operand" "b")
-                     (match_operand:SI 2 "register_operand" "r")] 199))]
+  [(parallel
+    [(set (match_operand:V4SI 0 "register_operand" "=v")
+         (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b")
+                            (match_operand:SI 2 "register_operand" "r"))))
+     (unspec [(const_int 0)] 213)])]
   "TARGET_ALTIVEC"
   "lvxl %0,%1,%2"
   [(set_attr "type" "vecload")])
 
 (define_insn "altivec_lvx"
   [(set (match_operand:V4SI 0 "register_operand" "=v")
-       (unspec:V4SI [(match_operand:SI 1 "register_operand" "b")
-                     (match_operand:SI 2 "register_operand" "r")] 200))]
+       (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b")
+                          (match_operand:SI 2 "register_operand" "r"))))]
   "TARGET_ALTIVEC"
   "lvx %0,%1,%2"
   [(set_attr "type" "vecload")])
 
-;; Parallel the STV*'s with unspecs because some of them have
-;; identical rtl but are different instructions-- and gcc gets confused.
-
 (define_insn "altivec_stvx"
   [(parallel
     [(set (mem:V4SI
index b88a84c2cea390669b4d63afb3d9e8f5de7d6004..a607b0c46f34987a73eaf2e9298c3201eb812274 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2323,6 +2323,22 @@ canon_hash (x, mode)
                 + (unsigned) CONST_DOUBLE_HIGH (x));
       return hash;
 
+    case CONST_VECTOR:
+      {
+       int units;
+       rtx elt;
+
+       units = CONST_VECTOR_NUNITS (x);
+
+       for (i = 0; i < units; ++i)
+         {
+           elt = CONST_VECTOR_ELT (x, i);
+           hash += canon_hash (elt, GET_MODE (elt));
+         }
+
+       return hash;
+      }
+
       /* Assume there is only one rtx object for any given label.  */
     case LABEL_REF:
       hash += ((unsigned) LABEL_REF << 7) + (unsigned long) XEXP (x, 0);
@@ -2776,6 +2792,7 @@ canon_reg (x, insn)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case ADDR_VEC:
@@ -3317,6 +3334,7 @@ fold_rtx (x, insn)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case REG:
@@ -3727,6 +3745,7 @@ fold_rtx (x, insn)
          case SYMBOL_REF:
          case LABEL_REF:
          case CONST_DOUBLE:
+         case CONST_VECTOR:
            const_arg = arg;
            break;
 
@@ -6425,6 +6444,7 @@ cse_process_notes (x, object)
     case SYMBOL_REF:
     case LABEL_REF:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case PC:
     case CC0:
     case LO_SUM:
@@ -7416,6 +7436,7 @@ count_reg_usage (x, counts, dest, incr)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
       return;
index 64eb8a5752adb46e51576a15340ab21663fec090..0eb17b8a836224803ce6e919ac955cc28cd0afe8 100644 (file)
@@ -593,6 +593,22 @@ hash_rtx (x, mode, create)
                 + (unsigned) CONST_DOUBLE_HIGH (x));
       return hash ? hash : (unsigned int) CONST_DOUBLE;
 
+    case CONST_VECTOR:
+      {
+       int units;
+       rtx elt;
+
+       units = CONST_VECTOR_NUNITS (x);
+
+       for (i = 0; i < units; ++i)
+         {
+           elt = CONST_VECTOR_ELT (x, i);
+           hash += hash_rtx (elt, GET_MODE (elt), 0);
+         }
+
+       return hash;
+      }
+
       /* Assume there is only one rtx object for any given label.  */
     case LABEL_REF:
       hash
@@ -794,6 +810,7 @@ cselib_subst_to_values (x)
       return e->u.val_rtx;
 
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST_INT:
       return x;
 
@@ -1009,6 +1026,7 @@ cselib_mem_conflict_p (mem_base, val)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
       return 0;
index 08483ef033bbd78adbffd45e576e7138c5807c90..3d50ea79fb768c33b9a1bdf8507923070d453e32 100644 (file)
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -1032,6 +1032,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
     case CONST_INT:
     case CONST:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case PC:
     case ADDR_VEC:
     case ADDR_DIFF_VEC:
index 65b39db0bb8880a41b7afd7f5d7bac6db1a2efdd..849d07948b6718a8fc11c4c4a265455b75744db1 100644 (file)
@@ -1712,6 +1712,7 @@ This macro returns the attributes on the type @var{type}.
 @findex tree_int_cst_equal
 @tindex REAL_CST
 @tindex COMPLEX_CST
+@tindex VECTOR_CST
 @tindex STRING_CST
 @findex TREE_STRING_LENGTH
 @findex TREE_STRING_POINTER
@@ -1858,6 +1859,12 @@ These nodes are used to represent complex number constants, that is a
 @code{TREE_REALPART} and @code{TREE_IMAGPART} return the real and the
 imaginary parts respectively.
 
+@item VECTOR_CST
+These nodes are used to represent vector constants, whose parts are
+constant nodes.  Each individual constant node is either an integer or a
+double constant node.  The first operand is a @code{TREE_LIST} of the
+constant nodes and is accessed through @code{TREE_VECTOR_CST_ELTS}.
+
 @item STRING_CST
 These nodes represent string-constants.  The @code{TREE_STRING_LENGTH}
 returns the length of the string, as an @code{int}.  The
index 5b614090b284b2fd2e842f393ac2ffc4b851b15a..6963950301f7e780b6b19adbf6007d9ae198fc14 100644 (file)
@@ -1156,6 +1156,20 @@ bits but small enough to fit within twice that number of bits (GCC
 does not provide a mechanism to represent even larger constants).  In
 the latter case, @var{m} will be @code{VOIDmode}.
 
+@findex const_vector
+@item (const_vector:@var{m} [@var{x0} @var{x1} @dots{}])
+Represents a vector constant.  The square brackets stand for the vector
+containing the constant elements.  @var{x0}, @var{x1} and so on are
+the @code{const_int} or @code{const_double} elements.
+
+The number of units in a @code{const_vector} is obtained with the macro
+@code{CONST_VECTOR_NUNITS} as in @code{CONST_VECTOR_NUNITS (@var{v})}.
+
+Individual elements in a vector constant are accessed with the macro
+@code{CONST_VECTOR_ELT} as in @code{CONST_VECTOR_ELT (@var{v}, @var{n})
+where @var{v} is the vector constant and @var{n} is the element
+desired.
+
 @findex CONST_DOUBLE_MEM
 @findex CONST_DOUBLE_CHAIN
 @var{addr} is used to contain the @code{mem} expression that corresponds
@@ -1185,10 +1199,14 @@ the precise bit pattern used by the target machine, use the macro
 @findex CONST2_RTX
 The macro @code{CONST0_RTX (@var{mode})} refers to an expression with
 value 0 in mode @var{mode}.  If mode @var{mode} is of mode class
-@code{MODE_INT}, it returns @code{const0_rtx}.  Otherwise, it returns a
-@code{CONST_DOUBLE} expression in mode @var{mode}.  Similarly, the macro
+@code{MODE_INT}, it returns @code{const0_rtx}.  If mode @var{mode} is of
+mode class @code{MODE_FLOAT}, it returns a @code{CONST_DOUBLE}
+expression in mode @var{mode}.  Otherwise, it returns a
+@code{CONST_VECTOR} expression in mode @var{mode}.  Similarly, the macro
 @code{CONST1_RTX (@var{mode})} refers to an expression with value 1 in
-mode @var{mode} and similarly for @code{CONST2_RTX}.
+mode @var{mode} and similarly for @code{CONST2_RTX}.  The
+@code{CONST1_RTX} and @code{CONST2_RTX} macros are undefined
+for vector modes.
 
 @findex const_string
 @item (const_string @var{str})
@@ -3331,6 +3349,11 @@ There is only one @code{cc0} expression.
 There is only one @code{const_double} expression with value 0 for
 each floating point mode.  Likewise for values 1 and 2.
 
+@cindex @code{const_vector}, RTL sharing
+@item
+There is only one @code{const_vector} expression with value 0 for
+each vector mode, be it an integer or a double constant vector.
+
 @cindex @code{label_ref}, RTL sharing
 @cindex @code{scratch}, RTL sharing
 @item
index 4ea852b60503080aebac3e94a49470479c9947d3..82dd61a5f64fcaca9d4e63351533a41180de0890 100644 (file)
@@ -196,6 +196,7 @@ static mem_attrs *get_mem_attrs             PARAMS ((HOST_WIDE_INT, tree, rtx,
                                                 rtx, unsigned int,
                                                 enum machine_mode));
 static tree component_ref_for_mem_expr PARAMS ((tree));
+static rtx gen_const_vector_0 PARAMS ((enum mode_class, enum machine_mode));
 
 /* Probability of the conditional branch currently proceeded by try_split.
    Set to -1 otherwise.  */
@@ -2390,6 +2391,7 @@ copy_rtx_if_shared (orig)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -2506,6 +2508,7 @@ reset_used_flags (x)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -4541,6 +4544,7 @@ copy_insn_1 (orig)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -4779,6 +4783,35 @@ mark_emit_status (es)
   ggc_mark_rtx (es->x_first_insn);
 }
 
+/* Generate the constant 0.  The first argument is MODE_VECTOR_INT for
+   integers or MODE_VECTOR_FLOAT for floats.  */
+
+static rtx
+gen_const_vector_0 (type, mode)
+     enum mode_class type;
+     enum machine_mode mode;
+{
+  rtx tem;
+  rtvec v;
+  int units, i;
+  enum machine_mode inner;
+
+  units = GET_MODE_NUNITS (mode);
+  inner = GET_MODE_INNER (mode);
+
+  v = rtvec_alloc (units);
+
+  /* We need to call this function after we to set CONST0_RTX first.  */
+  if (!CONST0_RTX (inner))
+    abort ();
+
+  for (i = 0; i < units; ++i)
+    RTVEC_ELT (v, i) = CONST0_RTX (inner);
+
+  tem = gen_rtx_CONST_VECTOR (mode, v);
+  return tem;
+}
+
 /* Create some permanent unique rtl objects shared between all functions.
    LINE_NUMBERS is nonzero if line numbers are to be generated.  */
 
@@ -4920,6 +4953,18 @@ init_emit_once (line_numbers)
        const_tiny_rtx[i][(int) mode] = GEN_INT (i);
     }
 
+  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
+       mode != VOIDmode;
+       mode = GET_MODE_WIDER_MODE (mode))
+    const_tiny_rtx[0][(int) mode]
+      = gen_const_vector_0 (MODE_VECTOR_INT, mode);
+
+  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
+       mode != VOIDmode;
+       mode = GET_MODE_WIDER_MODE (mode))
+    const_tiny_rtx[0][(int) mode]
+      = gen_const_vector_0 (MODE_VECTOR_FLOAT, mode);
+
   for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)
     if (GET_MODE_CLASS ((enum machine_mode) i) == MODE_CC)
       const_tiny_rtx[0][i] = const0_rtx;
index a26ad0946a9e7f439d26bb41d466a4122d8483a2..ad87865a06317ac032fe11e4f9f82fcf676839d0 100644 (file)
@@ -4038,7 +4038,25 @@ make_tree (type, x)
        }
 
       return t;
-         
+
+    case CONST_VECTOR:
+      {
+       int i, units;
+       rtx elt;
+       tree t = NULL_TREE;
+
+       units = CONST_VECTOR_NUNITS (x);
+
+       /* Build a tree with vector elements.  */
+       for (i = units - 1; i >= 0; --i)
+         {
+           elt = CONST_VECTOR_ELT (x, i);
+           t = tree_cons (NULL_TREE, make_tree (type, elt), t);
+         }
+       
+       return build_vector (type, t);
+      }
+
     case PLUS:
       return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)),
                          make_tree (type, XEXP (x, 1))));
index 73690372e4e70329158c2ab1b16bc07bacecfe59..f56f88640dc58f2df8902d9b783846f36f1fe623 100644 (file)
@@ -2562,8 +2562,7 @@ clear_storage (object, size)
 
   /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
      just move a zero.  Otherwise, do this a piece at a time.  */
-  if ((GET_MODE (object) != BLKmode
-       && !VECTOR_MODE_P (GET_MODE (object)))
+  if (GET_MODE (object) != BLKmode
       && GET_CODE (size) == CONST_INT
       && GET_MODE_SIZE (GET_MODE (object)) == (unsigned int) INTVAL (size))
     emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
@@ -4245,6 +4244,14 @@ is_zeros_p (exp)
     case REAL_CST:
       return REAL_VALUES_IDENTICAL (TREE_REAL_CST (exp), dconst0);
 
+    case VECTOR_CST:
+      for (elt = TREE_VECTOR_CST_ELTS (exp); elt;
+          elt = TREE_CHAIN (elt))
+       if (!is_zeros_p (TREE_VALUE (elt)))
+         return 0;
+
+      return 1;
+
     case CONSTRUCTOR:
       if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
        return CONSTRUCTOR_ELTS (exp) == NULL_TREE;
index 315cb2d7e85851e4da01a3f38ca2ca4953d852c6..6c3cd564d7db1ee42385373e11acf5a21334f902 100644 (file)
@@ -3635,6 +3635,7 @@ mark_used_regs (pbi, x, cond, insn)
     case CONST_INT:
     case CONST:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case PC:
     case ADDR_VEC:
     case ADDR_DIFF_VEC:
index 2f0d4ace1c1f84d3fd7e65e8a9a84c91bfd632c5..7c9a5ec99ee8a9e00c22b2b36ea1a6748b3576f8 100644 (file)
@@ -2427,6 +2427,27 @@ operand_equal_p (arg0, arg1, only_const)
                && REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
                                          TREE_REAL_CST (arg1)));
 
+      case VECTOR_CST:
+       {
+         tree v1, v2;
+
+         if (TREE_CONSTANT_OVERFLOW (arg0)
+             || TREE_CONSTANT_OVERFLOW (arg1))
+           return 0;
+
+         v1 = TREE_VECTOR_CST_ELTS (arg0);
+         v2 = TREE_VECTOR_CST_ELTS (arg1);
+         while (v1 && v2)
+           {
+             if (!operand_equal_p (v1, v2, only_const))
+               return 0;
+             v1 = TREE_CHAIN (v1);
+             v2 = TREE_CHAIN (v2);
+           }
+
+         return 1;
+       }
+
       case COMPLEX_CST:
        return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
                                 only_const)
@@ -5184,6 +5205,7 @@ fold (expr)
     {
     case INTEGER_CST:
     case REAL_CST:
+    case VECTOR_CST:
     case STRING_CST:
     case COMPLEX_CST:
     case CONSTRUCTOR:
@@ -7586,6 +7608,23 @@ rtl_expr_nonnegative_p (r)
        return CONST_DOUBLE_HIGH (r) >= 0;
       return 0;
 
+    case CONST_VECTOR:
+      {
+       int units, i;
+       rtx elt;
+
+       units = CONST_VECTOR_NUNITS (r);
+
+       for (i = 0; i < units; ++i)
+         {
+           elt = CONST_VECTOR_ELT (r, i);
+           if (!rtl_expr_nonnegative_p (elt))
+             return 0;
+         }
+
+       return 1;
+      }
+
     case SYMBOL_REF:
     case LABEL_REF:
       /* These are always nonnegative.  */
index 634e74b4d62c6e006af391e0b6c535e8660fbc04..0c2298c2474487ca6f7e9453f2c072a28d5f122a 100644 (file)
@@ -1994,6 +1994,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
     case SYMBOL_REF:
     case LABEL_REF:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
       return;
 
     case SIGN_EXTRACT:
@@ -3722,6 +3723,7 @@ instantiate_virtual_regs_1 (loc, object, extra_insns)
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case SYMBOL_REF:
     case CODE_LABEL:
index 928b6397624a15dc8cdbe941856afcc266f6e2a2..b7b08f2840a8090a81937dbefa99a219ce06f632 100644 (file)
@@ -1315,6 +1315,7 @@ want_to_gcse_p (x)
     case SUBREG:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CALL:
       return 0;
 
@@ -1400,6 +1401,7 @@ oprs_unchanged_p (x, insn, avail_p)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case ADDR_VEC:
@@ -1635,6 +1637,22 @@ hash_expr_1 (x, mode, do_not_record_p)
                 + (unsigned int) CONST_DOUBLE_HIGH (x));
       return hash;
 
+    case CONST_VECTOR:
+      {
+       int units;
+       rtx elt;
+
+       units = CONST_VECTOR_NUNITS (x);
+
+       for (i = 0; i < units; ++i)
+         {
+           elt = CONST_VECTOR_ELT (x, i);
+           hash += hash_expr_1 (elt, GET_MODE (elt), do_not_record_p);
+         }
+
+       return hash;
+      }
+
       /* Assume there is only one rtx object for any given label.  */
     case LABEL_REF:
       /* We don't hash on the address of the CODE_LABEL to avoid bootstrap
@@ -2756,6 +2774,7 @@ oprs_not_set_p (x, insn)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case ADDR_VEC:
@@ -3089,6 +3108,7 @@ expr_killed_p (x, bb)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case ADDR_VEC:
@@ -3789,6 +3809,7 @@ compute_transp (x, indx, bmap, set_p)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case ADDR_VEC:
@@ -6289,6 +6310,7 @@ store_ops_ok (x, bb)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case ADDR_VEC:
index 1c916b34bf2b8c1c123ba355511c811b44e39cae..a485deef61c5987a26f8b3c1c4a482664b435e71 100644 (file)
@@ -839,6 +839,7 @@ attr_copy_rtx (orig)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -2278,6 +2279,7 @@ encode_units_mask (x)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -4112,6 +4114,7 @@ clear_struct_flag (x)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -4167,6 +4170,7 @@ count_sub_rtxs (x, max)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
index 10d98f2f8a83950a2260ef59d9ff0d539cfbdcfa..ad6b2a1f52aaa64c4cdecb8e95adbaff1a0a1939 100644 (file)
@@ -2120,6 +2120,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
     case PC:
     case CC0:
     case CONST_INT:
+    case CONST_VECTOR:
       return orig;
 
     case SYMBOL_REF:
@@ -2479,6 +2480,7 @@ subst_constants (loc, insn, map, memonly)
     case PC:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CONST:
     case LABEL_REF:
index 1a6e3cf97fbdb1ef0b085246fbf576519ace1d86..c44f3686bb895de426686b8dbb0ed976693a2830 100644 (file)
@@ -539,6 +539,7 @@ equiv_init_varies_p (x)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
       return 0;
@@ -658,6 +659,7 @@ contains_replace_regs (x)
     case LABEL_REF:
     case SYMBOL_REF:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case PC:
     case CC0:
     case HIGH:
@@ -708,6 +710,7 @@ memref_referenced_p (memref, x)
     case LABEL_REF:
     case SYMBOL_REF:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case PC:
     case CC0:
     case HIGH:
index 5ec6a1ea1825ad03665e333518fdf938ae5f9218..16abebb8f3189b99c59eaa47e3db10fa0c72bcaf 100644 (file)
@@ -63,50 +63,54 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    there is none.  Vector modes use this field to point to the next
    vector size, so we can iterate through the different vectors modes.
    The ordering is by increasing byte size, with QI coming before HI,
-   HI before SI, etc.  */
+   HI before SI, etc.
+
+   Eigth arg is the mode of the internal elements in a vector.
+   VOIDmode if not a vector.
+*/
 
 /* VOIDmode is used when no mode needs to be specified,
    as for example on CONST_INT RTL expressions.  */
-DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0, 0, VOIDmode)
+DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
 
-DEF_MACHMODE (BImode, "BI", MODE_INT, 1, 1, 1, QImode)
-DEF_MACHMODE (QImode, "QI", MODE_INT, BITS_PER_UNIT, 1, 1, HImode)
-DEF_MACHMODE (HImode, "HI", MODE_INT, BITS_PER_UNIT*2, 2, 2, SImode)
-DEF_MACHMODE (SImode, "SI", MODE_INT, BITS_PER_UNIT*4, 4, 4, DImode)
-DEF_MACHMODE (DImode, "DI", MODE_INT, BITS_PER_UNIT*8, 8, 8, TImode)
-DEF_MACHMODE (TImode, "TI", MODE_INT, BITS_PER_UNIT*16, 16, 16, OImode)
-DEF_MACHMODE (OImode, "OI", MODE_INT, BITS_PER_UNIT*32, 32, 32, VOIDmode)
+DEF_MACHMODE (BImode, "BI", MODE_INT, 1, 1, 1, QImode, VOIDmode)
+DEF_MACHMODE (QImode, "QI", MODE_INT, BITS_PER_UNIT, 1, 1, HImode, VOIDmode)
+DEF_MACHMODE (HImode, "HI", MODE_INT, BITS_PER_UNIT*2, 2, 2, SImode, VOIDmode)
+DEF_MACHMODE (SImode, "SI", MODE_INT, BITS_PER_UNIT*4, 4, 4, DImode, VOIDmode)
+DEF_MACHMODE (DImode, "DI", MODE_INT, BITS_PER_UNIT*8, 8, 8, TImode, VOIDmode)
+DEF_MACHMODE (TImode, "TI", MODE_INT, BITS_PER_UNIT*16, 16, 16, OImode, VOIDmode)
+DEF_MACHMODE (OImode, "OI", MODE_INT, BITS_PER_UNIT*32, 32, 32, VOIDmode, VOIDmode)
 
 /* Pointers on some machines use these types to distinguish them from
    ints.  Useful if a pointer is 4 bytes but has some bits that are
    not significant, so it is really not quite as wide as an integer.  */
-DEF_MACHMODE (PQImode, "PQI", MODE_PARTIAL_INT, BITS_PER_UNIT, 1, 1, PHImode)
-DEF_MACHMODE (PHImode, "PHI", MODE_PARTIAL_INT, BITS_PER_UNIT*2, 2, 2, PSImode)
-DEF_MACHMODE (PSImode, "PSI", MODE_PARTIAL_INT, BITS_PER_UNIT*4, 4, 4, PDImode)
-DEF_MACHMODE (PDImode, "PDI", MODE_PARTIAL_INT, BITS_PER_UNIT*8, 8, 8, VOIDmode)
-
-DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, BITS_PER_UNIT, 1, 1, HFmode)
-DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, BITS_PER_UNIT*2, 2, 2, TQFmode)
-DEF_MACHMODE (TQFmode, "TQF", MODE_FLOAT, BITS_PER_UNIT*3, 3, 3, SFmode) /* MIL-STD-1750A */
-DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, BITS_PER_UNIT*4, 4, 4, DFmode)
-DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, BITS_PER_UNIT*8, 8, 8, XFmode)
-DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, BITS_PER_UNIT*12, 12, 12, TFmode) /* IEEE extended */
-DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode)
+DEF_MACHMODE (PQImode, "PQI", MODE_PARTIAL_INT, BITS_PER_UNIT, 1, 1, PHImode, VOIDmode)
+DEF_MACHMODE (PHImode, "PHI", MODE_PARTIAL_INT, BITS_PER_UNIT*2, 2, 2, PSImode, VOIDmode)
+DEF_MACHMODE (PSImode, "PSI", MODE_PARTIAL_INT, BITS_PER_UNIT*4, 4, 4, PDImode, VOIDmode)
+DEF_MACHMODE (PDImode, "PDI", MODE_PARTIAL_INT, BITS_PER_UNIT*8, 8, 8, VOIDmode, VOIDmode)
+
+DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, BITS_PER_UNIT, 1, 1, HFmode, VOIDmode)
+DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, BITS_PER_UNIT*2, 2, 2, TQFmode, VOIDmode)
+DEF_MACHMODE (TQFmode, "TQF", MODE_FLOAT, BITS_PER_UNIT*3, 3, 3, SFmode, VOIDmode) /* MIL-STD-1750A */
+DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, BITS_PER_UNIT*4, 4, 4, DFmode, VOIDmode)
+DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, BITS_PER_UNIT*8, 8, 8, XFmode, VOIDmode)
+DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, BITS_PER_UNIT*12, 12, 12, TFmode, VOIDmode) /* IEEE extended */
+DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode, VOIDmode)
 
 /* Complex modes.  */
-DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode)
-DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode)
-DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode)
-DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode)
-DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode)
-DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode)
-
-DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, BITS_PER_UNIT*2, 2, 1, CHImode)
-DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, BITS_PER_UNIT*4, 4, 2, CSImode)
-DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, BITS_PER_UNIT*8, 8, 4, CDImode)
-DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, BITS_PER_UNIT*16, 16, 8, CTImode)
-DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, BITS_PER_UNIT*32, 32, 16, COImode)
-DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode)
+DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode, VOIDmode)
+DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode, VOIDmode)
+DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode, VOIDmode)
+DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode, VOIDmode)
+DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode, VOIDmode)
+DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode, VOIDmode)
+
+DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, BITS_PER_UNIT*2, 2, 1, CHImode, VOIDmode)
+DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, BITS_PER_UNIT*4, 4, 2, CSImode, VOIDmode)
+DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, BITS_PER_UNIT*8, 8, 4, CDImode, VOIDmode)
+DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, BITS_PER_UNIT*16, 16, 8, CTImode, VOIDmode)
+DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, BITS_PER_UNIT*32, 32, 16, COImode, VOIDmode)
+DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode, VOIDmode)
 
 /* Vector modes.  */
 /* There are no V1xx vector modes.  These are equivalent to normal
@@ -114,43 +118,43 @@ DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmo
 /* The wider mode field for vectors follows in order of increasing bit
    size with QI coming before HI, HI before SI, and SI before DI
    within same bit sizes.  */
-DEF_MACHMODE (V2QImode, "V2QI", MODE_VECTOR_INT, BITS_PER_UNIT*2, 2, 1, V4QImode)
-DEF_MACHMODE (V2HImode, "V2HI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 2, V8QImode)
-DEF_MACHMODE (V2SImode, "V2SI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 4, V16QImode)
-DEF_MACHMODE (V2DImode, "V2DI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 8, V8SImode)
+DEF_MACHMODE (V2QImode, "V2QI", MODE_VECTOR_INT, BITS_PER_UNIT*2, 2, 1, V4QImode, QImode)
+DEF_MACHMODE (V2HImode, "V2HI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 2, V8QImode, HImode)
+DEF_MACHMODE (V2SImode, "V2SI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 4, V16QImode, SImode)
+DEF_MACHMODE (V2DImode, "V2DI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 8, V8SImode, DImode)
 
-DEF_MACHMODE (V4QImode, "V4QI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 1, V2HImode)
-DEF_MACHMODE (V4HImode, "V4HI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 2, V2SImode)
-DEF_MACHMODE (V4SImode, "V4SI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 4, V2DImode)
-DEF_MACHMODE (V4DImode, "V4DI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 8, V8DImode)
+DEF_MACHMODE (V4QImode, "V4QI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 1, V2HImode, QImode)
+DEF_MACHMODE (V4HImode, "V4HI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 2, V2SImode, HImode)
+DEF_MACHMODE (V4SImode, "V4SI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 4, V2DImode, SImode)
+DEF_MACHMODE (V4DImode, "V4DI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 8, V8DImode, DImode)
 
-DEF_MACHMODE (V8QImode, "V8QI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 1, V4HImode)
-DEF_MACHMODE (V8HImode, "V8HI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 2, V4SImode)
-DEF_MACHMODE (V8SImode, "V8SI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 4, V4DImode)
-DEF_MACHMODE (V8DImode, "V8DI", MODE_VECTOR_INT, BITS_PER_UNIT*64, 64, 8, VOIDmode)
+DEF_MACHMODE (V8QImode, "V8QI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 1, V4HImode, QImode)
+DEF_MACHMODE (V8HImode, "V8HI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 2, V4SImode, HImode)
+DEF_MACHMODE (V8SImode, "V8SI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 4, V4DImode, SImode)
+DEF_MACHMODE (V8DImode, "V8DI", MODE_VECTOR_INT, BITS_PER_UNIT*64, 64, 8, VOIDmode, DImode)
 
-DEF_MACHMODE (V16QImode, "V16QI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 1, V8HImode)
+DEF_MACHMODE (V16QImode, "V16QI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 1, V8HImode, QImode)
 
-DEF_MACHMODE (V2SFmode, "V2SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*8, 8, 4, V4SFmode)
-DEF_MACHMODE (V2DFmode, "V2DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 8, V8SFmode)
+DEF_MACHMODE (V2SFmode, "V2SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*8, 8, 4, V4SFmode, SFmode)
+DEF_MACHMODE (V2DFmode, "V2DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 8, V8SFmode, DFmode)
 
-DEF_MACHMODE (V4SFmode, "V4SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 4, V2DFmode)
-DEF_MACHMODE (V4DFmode, "V4DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 8, V8DFmode)
+DEF_MACHMODE (V4SFmode, "V4SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 4, V2DFmode, SFmode)
+DEF_MACHMODE (V4DFmode, "V4DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 8, V8DFmode, DFmode)
 
-DEF_MACHMODE (V8SFmode, "V8SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 4,V4DFmode)
-DEF_MACHMODE (V8DFmode, "V8DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*64, 64, 8, VOIDmode)
-DEF_MACHMODE (V16SFmode, "V16SF", MODE_VECTOR_FLOAT, 512, 64, 4, VOIDmode)
+DEF_MACHMODE (V8SFmode, "V8SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 4,V4DFmode, SFmode)
+DEF_MACHMODE (V8DFmode, "V8DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*64, 64, 8, VOIDmode, DFmode)
+DEF_MACHMODE (V16SFmode, "V16SF", MODE_VECTOR_FLOAT, 512, 64, 4, VOIDmode, SFmode)
 
 /* BLKmode is used for structures, arrays, etc.
    that fit no more specific mode.  */
-DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, 0, VOIDmode)
+DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
 
 /* The modes for representing the condition codes come last.  CCmode
    is always defined.  Additional modes for the condition code can be
    specified in the EXTRA_CC_MODES macro.  All MODE_CC modes are the
    same width as SImode and have VOIDmode as their next wider mode.  */
 
-#define CC(E, M)  DEF_MACHMODE (E, M, MODE_CC, BITS_PER_UNIT*4, 4, 4, VOIDmode)
+#define CC(E, M)  DEF_MACHMODE (E, M, MODE_CC, BITS_PER_UNIT*4, 4, 4, VOIDmode, VOIDmode)
 
 CC (CCmode, "CC")
 
@@ -167,7 +171,7 @@ EXTRA_CC_MODES
    lot of redundancy in ports that support both 32-bit and 64-bit targets.  */
 #ifdef GENERATOR_FILE
 #undef Pmode
-DEF_MACHMODE (Pmode, "P", MODE_RANDOM, 0, 0, 0, VOIDmode)
+DEF_MACHMODE (Pmode, "P", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
 #endif
 
 /*
index 0f285e365242f2c029d5b1b793f2c10588105aa7..f581cd041bd7bc74c5ca9e458f9ee00f6b33ee1c 100644 (file)
@@ -24,7 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 /* Make an enum class that gives all the machine modes.  */
 
-#define DEF_MACHMODE(SYM, NAME, TYPE, BITSIZE, SIZE, UNIT, WIDER)  SYM,
+#define DEF_MACHMODE(SYM, NAME, TYPE, BITSIZE, SIZE, UNIT, WIDER, INNER)  SYM,
 
 enum machine_mode {
 #include "machmode.def"
@@ -107,6 +107,12 @@ extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
 
 #define GET_MODE_MASK(MODE) mode_mask_array[(int) (MODE)]
 
+extern const enum machine_mode inner_mode_array[NUM_MACHINE_MODES];
+
+/* Return the mode of the inner elements in a vector.  */
+
+#define GET_MODE_INNER(MODE) inner_mode_array[(int) (MODE)]
+
 #endif /* defined (HOST_WIDE_INT) && ! defined GET_MODE_MASK */
 
 #if ! defined GET_MODE_WIDER_MODE || ! defined GET_MODE_ALIGNMENT \
index 594cf0ba4c2c602e31244ea76ba57a8e6032ec61..adb1881728813c19ef868b6ef49ca4f2954dfe7d 100644 (file)
@@ -707,6 +707,22 @@ print_node (file, prefix, node, indent)
          }
          break;
 
+       case VECTOR_CST:
+         {
+           tree vals = TREE_VECTOR_CST_ELTS (node);
+           char buf[10];
+           tree link;
+           int i;
+
+           i = 0;
+           for (link = vals; link; link = TREE_CHAIN (link), ++i)
+             {
+               sprintf (buf, "elt%d: ", i);
+               print_node (file, buf, TREE_VALUE (link), indent + 4);
+             }
+         }
+         break;
+
        case COMPLEX_CST:
          print_node (file, "real", TREE_REALPART (node), indent + 4);
          print_node (file, "imag", TREE_IMAGPART (node), indent + 4);
index ec0ec882dc72ee2a1d6e16eff6b9aafbffb9104e..6039c4d607a9b430abc7809eca570df88ec7d0b0 100644 (file)
@@ -753,6 +753,7 @@ find_single_use_1 (dest, loc)
     case LABEL_REF:
     case SYMBOL_REF:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CLOBBER:
       return 0;
 
index d064e240b62691b7933d0b3b1ecc032293c09748..93a5edbaf2a20d40634517730fac9b074f1718e1 100644 (file)
@@ -2416,6 +2416,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CC0:
     case PC:
     case SYMBOL_REF:
index 674062e37cda04a5a39d1a8bbba759a63162380c..6277398945d651457e1d63a0df7bc57124c1697b 100644 (file)
@@ -678,6 +678,7 @@ scan_rtx (insn, loc, class, action, type, earlyclobber)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case CC0:
index 97db874acb35dea6894c57cc72f8b47abe85e792..c4231a2ea123d2b38537b689aa29ca9e8f93320a 100644 (file)
@@ -4927,6 +4927,7 @@ subst_reg_equivs (ad, insn)
     case CONST_INT:
     case CONST:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case PC:
index 5211b5fcb367a7efa48a3ec13274abac3b437885..7b420a1ea3d5282b0974c62f59da451a5202dba4 100644 (file)
@@ -2282,6 +2282,7 @@ eliminate_regs (x, mem_mode, insn)
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case SYMBOL_REF:
     case CODE_LABEL:
@@ -2660,6 +2661,7 @@ elimination_effects (x, mem_mode)
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case SYMBOL_REF:
     case CODE_LABEL:
@@ -3749,6 +3751,7 @@ scan_paradoxical_subregs (x)
     case SYMBOL_REF:
     case LABEL_REF:
     case CONST_DOUBLE:
+    case CONST_VECTOR: /* shouldn't happen, but just in case.  */
     case CC0:
     case PC:
     case USE:
index 5b19fe45450ccef6a7dc5bb0f44f438b68dcf184..f306abb304ef467d0430410eedcb7fb3a599f439 100644 (file)
@@ -212,6 +212,7 @@ mark_referenced_resources (x, res, include_delayed_effects)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case PC:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -645,6 +646,7 @@ mark_set_resources (x, res, in_dest, mark_type)
     case USE:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case LABEL_REF:
     case SYMBOL_REF:
     case CONST:
index 7f4a4d5dd7cc0c4848977df1e8b7a8ccdacdce20..6077232d0e7a72e152165071be68e16472c010d8 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -115,7 +115,7 @@ const char * const rtx_name[NUM_RTX_CODE] = {
 /* Indexed by machine mode, gives the name of that machine mode.
    This name does not include the letters "mode".  */
 
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  NAME,
+#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER)  NAME,
 
 const char * const mode_name[NUM_MACHINE_MODES] = {
 #include "machmode.def"
@@ -125,7 +125,7 @@ const char * const mode_name[NUM_MACHINE_MODES] = {
 
 /* Indexed by machine mode, gives the class mode for GET_MODE_CLASS.  */
 
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  CLASS,
+#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER)  CLASS,
 
 const enum mode_class mode_class[NUM_MACHINE_MODES] = {
 #include "machmode.def"
@@ -136,7 +136,7 @@ const enum mode_class mode_class[NUM_MACHINE_MODES] = {
 /* Indexed by machine mode, gives the length of the mode, in bits.
    GET_MODE_BITSIZE uses this.  */
 
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  BITSIZE,
+#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER)  BITSIZE,
 
 const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
 #include "machmode.def"
@@ -147,7 +147,7 @@ const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
 /* Indexed by machine mode, gives the length of the mode, in bytes.
    GET_MODE_SIZE uses this.  */
 
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  SIZE,
+#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER)  SIZE,
 
 const unsigned char mode_size[NUM_MACHINE_MODES] = {
 #include "machmode.def"
@@ -158,7 +158,7 @@ const unsigned char mode_size[NUM_MACHINE_MODES] = {
 /* Indexed by machine mode, gives the length of the mode's subunit.
    GET_MODE_UNIT_SIZE uses this.  */
 
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  UNIT,
+#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER)  UNIT,
 
 const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
 #include "machmode.def"                /* machine modes are documented here */
@@ -170,7 +170,7 @@ const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
    (QI -> HI -> SI -> DI, etc.)  Widening multiply instructions
    use this.  */
 
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  \
+#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER)  \
   (unsigned char) WIDER,
 
 const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
@@ -179,7 +179,7 @@ const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
 
 #undef DEF_MACHMODE
 
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  \
+#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER)  \
   ((BITSIZE) >= HOST_BITS_PER_WIDE_INT) ? ~(unsigned HOST_WIDE_INT) 0 : ((unsigned HOST_WIDE_INT) 1 << (BITSIZE)) - 1,
 
 /* Indexed by machine mode, gives mask of significant bits in mode.  */
@@ -188,6 +188,17 @@ const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES] = {
 #include "machmode.def"
 };
 
+#undef DEF_MACHMODE
+
+#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) INNER,
+
+/* Indexed by machine mode, gives the mode of the inner elements in a
+   vector type.  */
+
+const enum machine_mode inner_mode_array[NUM_MACHINE_MODES] = {
+#include "machmode.def"
+};
+
 /* Indexed by mode class, gives the narrowest mode for each class.
    The Q modes are always of width 1 (2 for complex) - it is impossible
    for any mode to be narrower.
@@ -346,6 +357,7 @@ copy_rtx (orig)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -455,6 +467,7 @@ copy_most_rtx (orig, may_share)
     case QUEUED:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -560,7 +573,13 @@ unsigned int
 get_mode_alignment (mode)
      enum machine_mode mode;
 {
-  unsigned int alignment = GET_MODE_UNIT_SIZE (mode);
+  unsigned int alignment;
+
+  if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
+      || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
+    alignment = GET_MODE_UNIT_SIZE (mode);
+  else
+    alignment = GET_MODE_SIZE (mode);
   
   /* Extract the LSB of the size.  */
   alignment = alignment & -alignment;
@@ -626,6 +645,7 @@ rtx_equal_p (x, y)
     case SCRATCH:
     case CONST_DOUBLE:
     case CONST_INT:
+    case CONST_VECTOR:
       return 0;
 
     default:
index fc12af2665f109e7a9d6d60792dcc1c871c1114b..8fad65018647b1c3324dbb6fb226b96d969dc3ce 100644 (file)
@@ -585,6 +585,9 @@ DEF_RTL_EXPR(CONST_INT, "const_int", "w", 'o')
    there may be from 1 to 4; see rtl.c.  */
 DEF_RTL_EXPR(CONST_DOUBLE, "const_double", CONST_DOUBLE_FORMAT, 'o')
 
+/* Describes a vector constant.  */
+DEF_RTL_EXPR(CONST_VECTOR, "const_vector", "E", 'x')
+
 /* String constant.  Used only for attributes right now.  */
 DEF_RTL_EXPR(CONST_STRING, "const_string", "s", 'o')
 
@@ -972,10 +975,6 @@ DEF_RTL_EXPR(VEC_SELECT, "vec_select", "ee", 'x')
    combined and is the concatenation of the two source vectors.  */
 DEF_RTL_EXPR(VEC_CONCAT, "vec_concat", "ee", 'x')
 
-/* Describes a vector constant.  Each part of the PARALLEL that is operand 0
-   describes a constant for one of the subparts.  */
-DEF_RTL_EXPR(VEC_CONST, "vec_const", "e", 'x')
-
 /* Describes an operation that converts a small vector into a larger one by
    duplicating the input values.  The output vector mode must have the same
    submodes as the input vector mode, and the number of output parts must be
index 99fabfcb3ff9728aeed8ffb0a010dfb1613fd8d4..714faac91c694d50ec31cd099b69cdfe452088dd 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -255,6 +255,7 @@ struct rtvec_def {
   (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF             \
    || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE                \
    || GET_CODE (X) == CONST || GET_CODE (X) == HIGH                    \
+   || GET_CODE (X) == CONST_VECTOR                                     \
    || GET_CODE (X) == CONSTANT_P_RTX)
 
 /* General accessor macros for accessing the fields of an rtx.  */
@@ -823,6 +824,12 @@ extern const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS];
 /* Link for chain of all CONST_DOUBLEs in use in current function.  */
 #define CONST_DOUBLE_CHAIN(r) XCEXP (r, 0, CONST_DOUBLE)
 
+/* For a CONST_VECTOR, return element #n.  */
+#define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR)
+
+/* For a CONST_VECTOR, return the number of elements in a vector.  */
+#define CONST_VECTOR_NUNITS(RTX) XCVECLEN (RTX, 0, CONST_VECTOR)
+
 /* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of.
    SUBREG_BYTE extracts the byte-number.  */
 
index f185c616f5a6f144c1e41d9ca54ffc5a227dba4e..37f1e64910acebee9188b8d25936ea59b7900662 100644 (file)
@@ -64,6 +64,7 @@ rtx_unstable_p (x)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
       return 0;
@@ -139,6 +140,7 @@ rtx_varies_p (x, for_alias)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
       return 0;
@@ -502,6 +504,7 @@ count_occurrences (x, find, count_dest)
     case REG:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CODE_LABEL:
     case PC:
@@ -580,7 +583,8 @@ reg_mentioned_p (reg, in)
 
     case CONST_INT:
       return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
-      
+
+    case CONST_VECTOR:
     case CONST_DOUBLE:
       /* These are kept unique for a given value.  */
       return 0;
@@ -829,6 +833,7 @@ regs_set_between_p (x, start, end)
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -875,6 +880,7 @@ modified_between_p (x, start, end)
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -930,6 +936,7 @@ modified_in_p (x, insn)
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -2021,6 +2028,7 @@ volatile_insn_p (x)
     case CONST_INT:
     case CONST:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CC0:
     case PC:
     case REG:
@@ -2087,6 +2095,7 @@ volatile_refs_p (x)
     case CONST_INT:
     case CONST:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CC0:
     case PC:
     case REG:
@@ -2153,6 +2162,7 @@ side_effects_p (x)
     case CONST_INT:
     case CONST:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CC0:
     case PC:
     case REG:
@@ -2231,6 +2241,7 @@ may_trap_p (x)
       /* Handle these cases quickly.  */
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case LABEL_REF:
     case CONST:
@@ -2339,6 +2350,7 @@ inequality_comparisons_p (x)
     case CC0:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case LABEL_REF:
     case SYMBOL_REF:
@@ -2452,6 +2464,7 @@ replace_regs (x, reg_map, nregs, replace_dest)
     case CC0:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case CONST:
     case SYMBOL_REF:
     case LABEL_REF:
@@ -2542,6 +2555,7 @@ computed_jump_p_1 (x)
     case CONST:
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case REG:
       return 1;
index 9f20aad331b98c2a4d815382dbc8bdad4b8ec2c6..5fb23b76d9b9bc1fd731e573fa260a6cb86e508a 100644 (file)
@@ -723,6 +723,7 @@ sched_analyze_2 (deps, x, insn)
     {
     case CONST_INT:
     case CONST_DOUBLE:
+    case CONST_VECTOR:
     case SYMBOL_REF:
     case CONST:
     case LABEL_REF:
index 02ba7161b46ce198144089bbe642d9afef177571..f8ca55c780f0514b3e7f4992fa4a69818ee3fe91 100644 (file)
@@ -1223,6 +1223,7 @@ walk_tree (tp, func, data, htab_)
     case IDENTIFIER_NODE:
     case INTEGER_CST:
     case REAL_CST:
+    case VECTOR_CST:
     case STRING_CST:
     case REAL_TYPE:
     case COMPLEX_TYPE:
index e2829491ca40eafe911de7b1c0a21e1bbbc42c54..764aa798ed8cb27d8f6371e0c71f5387b652700c 100644 (file)
@@ -558,6 +558,35 @@ build_int_2_wide (low, hi)
   return t;
 }
 
+/* Return a new VECTOR_CST node whose type is TYPE and whose values
+   are in a list pointed by VALS.  */
+
+tree
+build_vector (type, vals)
+     tree type, vals;
+{
+  tree v = make_node (VECTOR_CST);
+  int over1 = 0, over2 = 0;
+  tree link;
+
+  TREE_VECTOR_CST_ELTS (v) = vals;
+  TREE_TYPE (v) = type;
+
+  /* Iterate through elements and check for overflow.  */
+  for (link = vals; link; link = TREE_CHAIN (link))
+    {
+      tree value = TREE_VALUE (link);
+
+      over1 |= TREE_OVERFLOW (value);
+      over2 |= TREE_CONSTANT_OVERFLOW (value);
+    }
+  
+  TREE_OVERFLOW (v) = over1;
+  TREE_CONSTANT_OVERFLOW (v) = over2;
+
+  return v;
+}
+
 /* Return a new REAL_CST node whose type is TYPE and value is D.  */
 
 tree
index 39ea31c033bc1f9913dc51ee8c72df6bafb68961..9cfe139ac5716939776d7c0b9e0b0abc06c217f7 100644 (file)
@@ -269,6 +269,9 @@ DEFTREECODE (REAL_CST, "real_cst", 'c', 3)
    Also there is TREE_CST_RTL.  */
 DEFTREECODE (COMPLEX_CST, "complex_cst", 'c', 3)
 
+/* Contents are in TREE_VECTOR_CST_ELTS field.  */
+DEFTREECODE (VECTOR_CST, "vector_cst", 'c', 3)     
+
 /* Contents are TREE_STRING_LENGTH and TREE_STRING_POINTER fields.
    Also there is TREE_CST_RTL.  */
 DEFTREECODE (STRING_CST, "string_cst", 'c', 3)
index fe4e0335012596751ed0ea97b9d43bc84337d0f3..d4f4c50c636b54ad72742816b3161c2c879072c5 100644 (file)
@@ -175,14 +175,14 @@ struct tree_common
        TREE_VIA_VIRTUAL in
            TREE_LIST or TREE_VEC
        TREE_CONSTANT_OVERFLOW in
-           INTEGER_CST, REAL_CST, COMPLEX_CST
+           INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
        TREE_SYMBOL_REFERENCED in
            IDENTIFIER_NODE
 
    public_flag:
 
        TREE_OVERFLOW in
-           INTEGER_CST, REAL_CST, COMPLEX_CST
+           INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
        TREE_PUBLIC in
            VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE
        TREE_VIA_PUBLIC in
@@ -512,9 +512,10 @@ extern void tree_class_check_failed PARAMS ((const tree, int,
    chain is via a `virtual' declaration.  */
 #define TREE_VIA_VIRTUAL(NODE) ((NODE)->common.static_flag)
 
-/* In an INTEGER_CST, REAL_CST, or COMPLEX_CST, this means there was an
-   overflow in folding.  This is distinct from TREE_OVERFLOW because ANSI C
-   requires a diagnostic when overflows occur in constant expressions.  */
+/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST this means
+   there was an overflow in folding.  This is distinct from
+   TREE_OVERFLOW because ANSI C requires a diagnostic when overflows
+   occur in constant expressions.  */
 #define TREE_CONSTANT_OVERFLOW(NODE) ((NODE)->common.static_flag)
 
 /* In an IDENTIFIER_NODE, this means that assemble_name was called with
@@ -522,9 +523,10 @@ extern void tree_class_check_failed PARAMS ((const tree, int,
 #define TREE_SYMBOL_REFERENCED(NODE) \
   (IDENTIFIER_NODE_CHECK (NODE)->common.static_flag)
 
-/* In an INTEGER_CST, REAL_CST, of COMPLEX_CST, this means there was an
-   overflow in folding, and no warning has been issued for this subexpression.
-   TREE_OVERFLOW implies TREE_CONSTANT_OVERFLOW, but not vice versa.  */
+/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST, this means
+   there was an overflow in folding, and no warning has been issued
+   for this subexpression.  TREE_OVERFLOW implies
+   TREE_CONSTANT_OVERFLOW, but not vice versa.  */
 #define TREE_OVERFLOW(NODE) ((NODE)->common.public_flag)
 
 /* In a VAR_DECL or FUNCTION_DECL,
@@ -707,9 +709,9 @@ struct tree_int_cst
   } int_cst;
 };
 
-/* In REAL_CST, STRING_CST, COMPLEX_CST nodes, and CONSTRUCTOR nodes,
-   and generally in all kinds of constants that could
-   be given labels (rather than being immediate).  */
+/* In REAL_CST, STRING_CST, COMPLEX_CST, VECTOR_CST nodes, and
+   CONSTRUCTOR nodes, and generally in all kinds of constants that
+   could be given labels (rather than being immediate).  */
 
 #define TREE_CST_RTL(NODE) (CST_OR_CONSTRUCTOR_CHECK (NODE)->real_cst.rtl)
 
@@ -752,6 +754,16 @@ struct tree_complex
   tree real;
   tree imag;
 };
+
+/* In a VECTOR_CST node.  */
+#define TREE_VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elements)
+
+struct tree_vector
+{
+  struct tree_common common;
+  rtx rtl;
+  tree elements;
+};
 \f
 #include "hashtable.h"
 
@@ -1843,6 +1855,7 @@ union tree_node
   struct tree_common common;
   struct tree_int_cst int_cst;
   struct tree_real_cst real_cst;
+  struct tree_vector vector;
   struct tree_string string;
   struct tree_complex complex;
   struct tree_identifier identifier;
@@ -2093,6 +2106,7 @@ extern tree build                 PARAMS ((enum tree_code, tree, ...));
 extern tree build_nt                   PARAMS ((enum tree_code, ...));
 
 extern tree build_int_2_wide           PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT));
+extern tree build_vector                PARAMS ((tree, tree));
 extern tree build_real                 PARAMS ((tree, REAL_VALUE_TYPE));
 extern tree build_real_from_int_cst    PARAMS ((tree, tree));
 extern tree build_complex              PARAMS ((tree, tree, tree));
index 0ca2172c32c608a3b820ccf5fdf170a4e1493532..67d64e6263b69dfff00e96fdc88fc41386646797 100644 (file)
@@ -2382,7 +2382,8 @@ decode_addr_const (exp, value)
   value->offset = offset;
 }
 \f
-enum kind { RTX_UNKNOWN, RTX_DOUBLE, RTX_INT, RTX_UNSPEC };
+/* We do RTX_UNSPEC + XINT (blah), so nothing can go after RTX_UNSPEC.  */
+enum kind { RTX_UNKNOWN, RTX_DOUBLE, RTX_INT, RTX_VECTOR, RTX_UNSPEC };
 struct rtx_const
 {
   ENUM_BITFIELD(kind) kind : 16;
@@ -2391,6 +2392,10 @@ struct rtx_const
     union real_extract du;
     struct addr_const addr;
     struct {HOST_WIDE_INT high, low;} di;
+
+    /* The max vector size we have is 8 wide.  This should be enough.  */
+    HOST_WIDE_INT veclo[16];
+    HOST_WIDE_INT vechi[16];
   } un;
 };
 
@@ -3580,6 +3585,34 @@ decode_rtx_const (mode, x, value)
        }
       break;
 
+    case CONST_VECTOR:
+      {
+       int units, i;
+       rtx elt;
+
+       units = CONST_VECTOR_NUNITS (x);
+       value->kind = RTX_VECTOR;
+       value->mode = mode;
+
+       for (i = 0; i < units; ++i)
+         {
+           elt = CONST_VECTOR_ELT (x, i);
+           if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
+             {
+               value->un.veclo[i] = (HOST_WIDE_INT) INTVAL (elt);
+               value->un.vechi[i] = 0;
+             }
+           else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+             {
+               value->un.veclo[i] = (HOST_WIDE_INT) CONST_DOUBLE_LOW (elt);
+               value->un.vechi[i] = (HOST_WIDE_INT) CONST_DOUBLE_HIGH (elt);
+             }
+           else
+             abort ();
+         }
+      }
+      break;
+
     case CONST_INT:
       value->un.addr.offset = INTVAL (x);
       break;
@@ -4007,6 +4040,46 @@ output_constant_pool (fnname, fndecl)
          assemble_integer (x, GET_MODE_SIZE (pool->mode), pool->align, 1);
          break;
 
+       case MODE_VECTOR_FLOAT:
+         {
+           int i, units;
+           rtx elt;
+
+           if (GET_CODE (x) != CONST_VECTOR)
+             abort ();
+
+           units = CONST_VECTOR_NUNITS (x);
+
+           for (i = 0; i < units; i++)
+             {
+               elt = CONST_VECTOR_ELT (x, i);
+               memcpy ((char *) &u,
+                       (char *) &CONST_DOUBLE_LOW (elt),
+                       sizeof u);
+               assemble_real (u.d, GET_MODE_INNER (pool->mode), pool->align);
+             }
+         }
+         break;
+
+        case MODE_VECTOR_INT:
+         {
+           int i, units;
+           rtx elt;
+
+           if (GET_CODE (x) != CONST_VECTOR)
+             abort ();
+
+           units = CONST_VECTOR_NUNITS (x);
+
+           for (i = 0; i < units; i++)
+             {
+               elt = CONST_VECTOR_ELT (x, i);
+               assemble_integer (elt, GET_MODE_UNIT_SIZE (pool->mode),
+                                 pool->align, 1);
+             }
+         }
+         break;
+
        default:
          abort ();
        }
@@ -4255,6 +4328,7 @@ initializer_constant_valid_p (value, endtype)
       return TREE_STATIC (value) ? null_pointer_node : 0;
 
     case INTEGER_CST:
+    case VECTOR_CST:
     case REAL_CST:
     case STRING_CST:
     case COMPLEX_CST: