This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

patch: CONST_VECTOR (was clear_storage)


[heads up everyone with SIMD port-- you need to fix your CONSTANT_ALIGNMENT
macros to get vector initializers/constants aligned properly.  see patch]

> Sorry to dump this on you, but how much work would it be forcing
> this all the way through the compiler?  I wouldn't think it would
> be *too* bad, but everything surrounding AldyVec has been harder
> than it should have been...

<preamble>
i think i vaguely remember someone (geoff?) saying "altivec? 2 weeks 
of back end work: tops.  i mean, we already have about a dozen simd
ports.  how hard can it be?"...

i am no longer surprised.  i already assume it's going to be harder :)
</preamble>

first, the vector initializer code will eventually have to be rewritted
to generate vector constants, and not behave like arrays.  however,
this is harder work, and will undoubtedly trigger a myraid of other 
missing features.   (think constant folding, inlining, cse, etc).

i volunteer to write the rest of the vector constant code for 3.2, but
right now, the goal should be to get the vector initializer
code working properly-- actually all this is just so we can call
clear_storage() correctly ;-)

as requested.  here's the patch for CONST_VECTOR.

a few things.

- i changed the name to CONST_VECTOR to be more consistent with CONST_INT
and CONST_DOUBLE.

- the machmode description was wrong.  i changed it to be a vector of
elements, not a parallel containing a vector of elements.

- genrecog.c was choking when recognizing 'w' (HOST_WIDE_INT) in anything
but the first position.  apparently no one has ever put a (const_double x)
node in an .md file before.  fixed.

- i added a new argument to DEF_MACHMODE because now we need to know
the mode of the inner elements in a vector.

- i had to add a VECTOR_CST node (and corresponding magic all throughout)
because (a) we'll need it (b) force_const_mem() needs it to get the
alignment of vector constants correct.

everything else is somewhat obvious, though extensive.  ...with many
interesting surprises along the way.  

and before anyone starts screaming bloody murder, too many changes
this late into the code freeze game... this is the only -correct- way
of fixing vector initializers.  and it'd be a pity to have 99% of
altivec working in 3.1.

there are no gratuitous features in the patch.  everything is needed,
do to an incredibly interesting chain of dependencies.

hey, i wanted the easy route; you're the one wanting it done correctly :)


ok?

2002-02-17  Aldy Hernandez  <aldyh@redhat.com>

	* 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.

	* genrecog.c (add_to_sequence): Do not abort if 'w' and position
	is not 0.

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

	* rtl.c (DEF_MACHMODE): Change all definitions to accept 8th
	argument.
	(inner_mode_array): New.

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

	* emit-rtl.c (init_emit_once): Generate const0_rtx for vectors.
	(gen_rtx): Handle CONST_VECTOR.
	(gen_const_vector_0): New.

	* 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.

	* rs6000.h (CONSTANT_ALIGNMENT): Align vector constants.
	
	* 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.

	* 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.

Index: print-tree.c
===================================================================
RCS file: /cvs/uberbaum/gcc/print-tree.c,v
retrieving revision 1.53
diff -c -p -r1.53 print-tree.c
*** print-tree.c	2002/01/22 14:33:32	1.53
--- print-tree.c	2002/02/17 09:14:25
*************** print_node (file, prefix, node, indent)
*** 707,712 ****
--- 707,728 ----
  	  }
  	  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, "[%2d]: ", 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: tree.h
===================================================================
RCS file: /cvs/uberbaum/gcc/tree.h,v
retrieving revision 1.306
diff -c -p -r1.306 tree.h
*** tree.h	2002/02/09 03:08:05	1.306
--- tree.h	2002/02/17 09:14:27
*************** struct tree_common
*** 175,188 ****
         TREE_VIA_VIRTUAL in
             TREE_LIST or TREE_VEC
         TREE_CONSTANT_OVERFLOW in
!            INTEGER_CST, REAL_CST, COMPLEX_CST
         TREE_SYMBOL_REFERENCED in
             IDENTIFIER_NODE
  
     public_flag:
  
         TREE_OVERFLOW in
!            INTEGER_CST, REAL_CST, COMPLEX_CST
         TREE_PUBLIC in
             VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE
         TREE_VIA_PUBLIC in
--- 175,188 ----
         TREE_VIA_VIRTUAL in
             TREE_LIST or TREE_VEC
         TREE_CONSTANT_OVERFLOW in
!            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, VECTOR_CST
         TREE_PUBLIC in
             VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE
         TREE_VIA_PUBLIC in
*************** extern void tree_class_check_failed PARA
*** 512,520 ****
     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.  */
  #define TREE_CONSTANT_OVERFLOW(NODE) ((NODE)->common.static_flag)
  
  /* In an IDENTIFIER_NODE, this means that assemble_name was called with
--- 512,521 ----
     chain is via a `virtual' declaration.  */
  #define TREE_VIA_VIRTUAL(NODE) ((NODE)->common.static_flag)
  
! /* 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
*************** extern void tree_class_check_failed PARA
*** 522,530 ****
  #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.  */
  #define TREE_OVERFLOW(NODE) ((NODE)->common.public_flag)
  
  /* In a VAR_DECL or FUNCTION_DECL,
--- 523,532 ----
  #define TREE_SYMBOL_REFERENCED(NODE) \
    (IDENTIFIER_NODE_CHECK (NODE)->common.static_flag)
  
! /* 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,
*************** struct tree_int_cst
*** 707,715 ****
    } 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).  */
  
  #define TREE_CST_RTL(NODE) (CST_OR_CONSTRUCTOR_CHECK (NODE)->real_cst.rtl)
  
--- 709,717 ----
    } int_cst;
  };
  
! /* 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)
  
*************** struct tree_complex
*** 752,757 ****
--- 754,769 ----
    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;
+ };
  
  #include "hashtable.h"
  
*************** union tree_node
*** 1843,1848 ****
--- 1855,1861 ----
    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;
*************** extern tree build			PARAMS ((enum tree_c
*** 2093,2098 ****
--- 2106,2112 ----
  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: tree.def
===================================================================
RCS file: /cvs/uberbaum/gcc/tree.def,v
retrieving revision 1.49
diff -c -p -r1.49 tree.def
*** tree.def	2001/11/21 23:32:03	1.49
--- tree.def	2002/02/17 09:14:28
*************** DEFTREECODE (REAL_CST, "real_cst", 'c', 
*** 269,274 ****
--- 269,277 ----
     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: tree.c
===================================================================
RCS file: /cvs/uberbaum/gcc/tree.c,v
retrieving revision 1.238
diff -c -p -r1.238 tree.c
*** tree.c	2002/02/09 03:08:05	1.238
--- tree.c	2002/02/17 09:14:29
*************** build_int_2_wide (low, hi)
*** 558,563 ****
--- 558,592 ----
    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, over2;
+   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: expmed.c
===================================================================
RCS file: /cvs/uberbaum/gcc/expmed.c,v
retrieving revision 1.104
diff -c -p -r1.104 expmed.c
*** expmed.c	2002/02/01 23:43:14	1.104
--- expmed.c	2002/02/17 09:14:31
*************** make_tree (type, x)
*** 4038,4044 ****
  	}
  
        return t;
! 	  
      case PLUS:
        return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)),
  			  make_tree (type, XEXP (x, 1))));
--- 4038,4062 ----
  	}
  
        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: rtl.h
===================================================================
RCS file: /cvs/uberbaum/gcc/rtl.h,v
retrieving revision 1.328
diff -c -p -r1.328 rtl.h
*** rtl.h	2002/01/31 06:21:19	1.328
--- rtl.h	2002/02/17 09:14:32
*************** struct rtvec_def {
*** 255,260 ****
--- 255,261 ----
    (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.  */
*************** extern const char * const note_insn_name
*** 822,827 ****
--- 823,834 ----
  
  /* 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(x,n) RTVEC_ELT (XVEC(x, 0), n)
+ 
+ /* For a CONST_VECTOR, return the number of elements in a vector.  */
+ #define CONST_VECTOR_NUNITS(x) GET_MODE_NUNITS (GET_MODE (x))
  
  /* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of.
     SUBREG_BYTE extracts the byte-number.  */
Index: genrecog.c
===================================================================
RCS file: /cvs/uberbaum/gcc/genrecog.c,v
retrieving revision 1.116
diff -c -p -r1.116 genrecog.c
*** genrecog.c	2002/01/05 22:11:20	1.116
--- genrecog.c	2002/02/17 09:14:33
*************** add_to_sequence (pattern, last, position
*** 980,987 ****
--- 980,991 ----
  	    = ((int) XWINT (pattern, i) == XWINT (pattern, i))
  	      ? DT_elt_zero_wide_safe : DT_elt_zero_wide;
  
+ 	  /* HOST_WIDE_INTs can be in places other than [0],
+ 	     otherwise we can't recognize CONST_DOUBLEs.
+ 
  	  if (i != 0)
  	    abort ();
+ 	  */
  
  	  test = new_decision_test (type, &place);
  	  test->u.intval = XWINT (pattern, i);
Index: machmode.h
===================================================================
RCS file: /cvs/uberbaum/gcc/machmode.h,v
retrieving revision 1.28
diff -c -p -r1.28 machmode.h
*** machmode.h	2001/12/23 04:59:05	1.28
--- machmode.h	2002/02/17 09:14:33
*************** Software Foundation, 59 Temple Place - S
*** 24,30 ****
  
  /* Make an enum class that gives all the machine modes.  */
  
! #define DEF_MACHMODE(SYM, NAME, TYPE, BITSIZE, SIZE, UNIT, WIDER)  SYM,
  
  enum machine_mode {
  #include "machmode.def"
--- 24,30 ----
  
  /* Make an enum class that gives all the machine modes.  */
  
! #define DEF_MACHMODE(SYM, NAME, TYPE, BITSIZE, SIZE, UNIT, WIDER, INNER)  SYM,
  
  enum machine_mode {
  #include "machmode.def"
*************** extern const unsigned short mode_bitsize
*** 106,111 ****
--- 106,117 ----
  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 */
  
Index: rtl.c
===================================================================
RCS file: /cvs/uberbaum/gcc/rtl.c,v
retrieving revision 1.107
diff -c -p -r1.107 rtl.c
*** rtl.c	2002/01/31 06:21:19	1.107
--- rtl.c	2002/02/17 09:14:34
*************** const char * const rtx_name[NUM_RTX_CODE
*** 115,121 ****
  /* 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,
  
  const char * const mode_name[NUM_MACHINE_MODES] = {
  #include "machmode.def"
--- 115,121 ----
  /* 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, INNER)  NAME,
  
  const char * const mode_name[NUM_MACHINE_MODES] = {
  #include "machmode.def"
*************** const char * const mode_name[NUM_MACHINE
*** 125,131 ****
  
  /* Indexed by machine mode, gives the class mode for GET_MODE_CLASS.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  CLASS,
  
  const enum mode_class mode_class[NUM_MACHINE_MODES] = {
  #include "machmode.def"
--- 125,131 ----
  
  /* Indexed by machine mode, gives the class mode for GET_MODE_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"
*************** const enum mode_class mode_class[NUM_MAC
*** 136,142 ****
  /* 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,
  
  const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
  #include "machmode.def"
--- 136,142 ----
  /* 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, INNER)  BITSIZE,
  
  const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
  #include "machmode.def"
*************** const unsigned short mode_bitsize[NUM_MA
*** 147,153 ****
  /* 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,
  
  const unsigned char mode_size[NUM_MACHINE_MODES] = {
  #include "machmode.def"
--- 147,153 ----
  /* 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, INNER)  SIZE,
  
  const unsigned char mode_size[NUM_MACHINE_MODES] = {
  #include "machmode.def"
*************** const unsigned char mode_size[NUM_MACHIN
*** 158,164 ****
  /* 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,
  
  const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
  #include "machmode.def"		/* machine modes are documented here */
--- 158,164 ----
  /* 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, INNER)  UNIT,
  
  const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
  #include "machmode.def"		/* machine modes are documented here */
*************** const unsigned char mode_unit_size[NUM_M
*** 170,176 ****
     (QI -> HI -> SI -> DI, etc.)  Widening multiply instructions
     use this.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  \
    (unsigned char) WIDER,
  
  const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
--- 170,176 ----
     (QI -> HI -> SI -> DI, etc.)  Widening multiply instructions
     use this.  */
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER)  \
    (unsigned char) WIDER,
  
  const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
*************** const unsigned char mode_wider_mode[NUM_
*** 179,190 ****
  
  #undef DEF_MACHMODE
  
! #define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER)  \
    ((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.  */
  
  const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES] = {
  #include "machmode.def"
  };
  
--- 179,201 ----
  
  #undef DEF_MACHMODE
  
! #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.  */
  
  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 elemnts in a
+    vector type.  */
+ 
+ const enum machine_mode inner_mode_array[NUM_MACHINE_MODES] = {
  #include "machmode.def"
  };
  
Index: machmode.def
===================================================================
RCS file: /cvs/uberbaum/gcc/machmode.def,v
retrieving revision 1.16
diff -c -p -r1.16 machmode.def
*** machmode.def	2002/02/09 03:08:05	1.16
--- machmode.def	2002/02/17 09:14:34
*************** Software Foundation, 59 Temple Place - S
*** 63,112 ****
     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.  */
  
  /* 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 (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)
  
  /* 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)
  
  /* 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)
  
  /* Vector modes.  */
  /* There are no V1xx vector modes.  These are equivalent to normal
--- 63,116 ----
     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.
  
+    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, 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, 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, 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
*************** DEF_MACHMODE (COImode, "COI", MODE_COMPL
*** 114,156 ****
  /* 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 (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 (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 (V16QImode, "V16QI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 1, V8HImode)
! 
! 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 (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 (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)
  
  /* BLKmode is used for structures, arrays, etc.
     that fit no more specific mode.  */
! DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, 0, 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)
  
  CC (CCmode, "CC")
  
--- 118,160 ----
  /* 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, 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, 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, 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, QImode)
! 
! 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, 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, 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, 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, VOIDmode)
  
  CC (CCmode, "CC")
  
*************** EXTRA_CC_MODES
*** 167,173 ****
     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)
  #endif
  
  /*
--- 171,177 ----
     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, VOIDmode)
  #endif
  
  /*
Index: emit-rtl.c
===================================================================
RCS file: /cvs/uberbaum/gcc/emit-rtl.c,v
retrieving revision 1.247
diff -c -p -r1.247 emit-rtl.c
*** emit-rtl.c	2002/01/31 06:21:19	1.247
--- emit-rtl.c	2002/02/17 09:14:36
*************** static mem_attrs *get_mem_attrs		PARAMS 
*** 196,201 ****
--- 196,202 ----
  						 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.  */
*************** mark_emit_status (es)
*** 4779,4784 ****
--- 4780,4822 ----
    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);
+ 
+   if (type == MODE_VECTOR_INT)
+     {
+       for (i = 0; i < units; ++i)
+ 	RTVEC_ELT (v, i) 
+ 	  = gen_rtx_CONST_INT (VOIDmode, 0);
+     }
+   else if (type == MODE_VECTOR_FLOAT)
+     {
+       for (i = 0; i < units; ++i)
+ 	RTVEC_ELT (v, i)
+ 	  = gen_rtx_CONST_DOUBLE (inner, 0, 0);
+     }
+   else
+     abort ();
+ 
+   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.  */
  
*************** init_emit_once (line_numbers)
*** 4919,4924 ****
--- 4957,4974 ----
  	   mode = GET_MODE_WIDER_MODE (mode))
  	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)
Index: rtl.def
===================================================================
RCS file: /cvs/uberbaum/gcc/rtl.def,v
retrieving revision 1.53
diff -c -p -r1.53 rtl.def
*** rtl.def	2001/12/20 14:37:30	1.53
--- rtl.def	2002/02/17 09:14:36
*************** DEF_RTL_EXPR(CONST_INT, "const_int", "w"
*** 585,590 ****
--- 585,594 ----
     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.  Each part of the PARALLEL that is operand 0
+    describes a constant for one of the subparts.  */
+ 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')
  
*************** DEF_RTL_EXPR(VEC_SELECT, "vec_select", "
*** 971,980 ****
     vectors, the result is a vector that is as long as operands 0 and 1
     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
--- 975,980 ----
Index: expr.c
===================================================================
RCS file: /cvs/uberbaum/gcc/expr.c,v
retrieving revision 1.417
diff -c -p -r1.417 expr.c
*** expr.c	2002/02/12 22:26:11	1.417
--- expr.c	2002/02/17 09:14:41
*************** clear_storage (object, size)
*** 2562,2569 ****
  
    /* 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)))
        && GET_CODE (size) == CONST_INT
        && GET_MODE_SIZE (GET_MODE (object)) == (unsigned int) INTVAL (size))
      emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
--- 2562,2568 ----
  
    /* 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
        && GET_CODE (size) == CONST_INT
        && GET_MODE_SIZE (GET_MODE (object)) == (unsigned int) INTVAL (size))
      emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
*************** is_zeros_p (exp)
*** 4244,4249 ****
--- 4243,4256 ----
  
      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)
Index: varasm.c
===================================================================
RCS file: /cvs/uberbaum/gcc/varasm.c,v
retrieving revision 1.248
diff -c -p -r1.248 varasm.c
*** varasm.c	2002/02/12 22:26:11	1.248
--- varasm.c	2002/02/17 09:14:43
*************** output_constant_pool (fnname, fndecl)
*** 4007,4012 ****
--- 4007,4052 ----
  	  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 ();
  	}
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.285
diff -c -p -r1.285 rs6000.c
*** rs6000.c	2002/02/14 03:37:37	1.285
--- rs6000.c	2002/02/17 09:14:47
*************** static void is_altivec_return_reg PARAMS
*** 174,179 ****
--- 174,180 ----
  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));
  
  /* Default register names.  */
  char rs6000_reg_names[][8] =
*************** easy_fp_constant (op, mode)
*** 1194,1199 ****
--- 1195,1238 ----
      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 0.0.  */
  int
  zero_fp_constant (op, mode)
*************** rs6000_legitimize_reload_address (x, mod
*** 1892,1897 ****
--- 1931,1937 ----
  #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.  */
*************** rs6000_emit_move (dest, source, mode)
*** 2187,2194 ****
    /* 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)
      {
        emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
        return;
--- 2227,2235 ----
    /* Handle the case where reload calls us with an invalid address;
       and the case of CONSTANT_P_RTX.  */
    if (! general_operand (operands[1], mode)
!       || (!VECTOR_MODE_P (mode)
! 	  && (! nonimmediate_operand (operands[0], mode)
! 	      || GET_CODE (operands[1]) == CONSTANT_P_RTX)))
      {
        emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
        return;
*************** rs6000_emit_move (dest, source, mode)
*** 2218,2225 ****
      case V8HImode:
      case V4SFmode:
      case V4SImode:
!       /* fixme: aldyh -- allow vector constants when they are implemented.  */
!       if (CONSTANT_P (operands[1]))
  	operands[1] = force_const_mem (mode, operands[1]);
        break;
        
--- 2259,2266 ----
      case V8HImode:
      case V4SFmode:
      case V4SImode:
!       if (CONSTANT_P (operands[1])
! 	  && !easy_vector_constant (operands[1]))
  	operands[1] = force_const_mem (mode, operands[1]);
        break;
        
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.180
diff -c -p -r1.180 rs6000.h
*** rs6000.h	2002/02/13 04:00:26	1.180
--- rs6000.h	2002/02/17 09:14:49
*************** extern int rs6000_altivec_abi;
*** 638,647 ****
  /* 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 arrays of chars word-aligned for the same reasons.
     Align vectors to 128 bits.  */
--- 638,651 ----
  /* 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.
!    Make vector constants quadword aligned.  */
! #define CONSTANT_ALIGNMENT(EXP, ALIGN)          \
!   (TREE_CODE (EXP) == STRING_CST	        \
!    && (ALIGN) < BITS_PER_WORD                   \
!    ? BITS_PER_WORD                              \
!    : (TREE_CODE (EXP) == VECTOR_CST) ? 128      \
!    : (ALIGN))
  
  /* Make arrays of chars word-aligned for the same reasons.
     Align vectors to 128 bits.  */
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.167
diff -c -p -r1.167 rs6000.md
*** rs6000.md	2002/02/14 03:37:37	1.167
--- rs6000.md	2002/02/17 09:14:55
***************
*** 14017,14022 ****
--- 14017,14080 ----
    "mtvrsave %1"
    [(set_attr "type" "altivec")])
  
+ ;; Vector clears
+ (define_insn "*movv4si_const0"
+   [(set (match_operand:V4SI 0 "altivec_register_operand" "=v")
+ 	(const_vector:V4SI [(const_int 0)
+ 			    (const_int 0)
+ 			    (const_int 0)
+ 			    (const_int 0)]))]
+   "TARGET_ALTIVEC"
+   "vxor %0,%0,%0"
+   [(set_attr "type" "vecsimple")])
+ 
+ (define_insn "*movv4sf_const0"
+   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
+ 	(const_vector:V4SF [(const_double:SF 0 0 0 0 0)
+ 			    (const_double:SF 0 0 0 0 0)
+ 			    (const_double:SF 0 0 0 0 0)
+ 			    (const_double:SF 0 0 0 0 0)]))]
+ 					 
+   "TARGET_ALTIVEC"
+   "vxor %0,%0,%0"
+   [(set_attr "type" "vecsimple")])
+ 
+ (define_insn "*movv8hi_const0"
+   [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
+ 	(const_vector:V8HI [(const_int 0)
+ 			    (const_int 0)
+ 			    (const_int 0)
+ 			    (const_int 0)
+ 			    (const_int 0)
+ 			    (const_int 0)
+ 			    (const_int 0)
+ 			    (const_int 0)]))]
+   "TARGET_ALTIVEC"
+   "vxor %0,%0,%0"
+   [(set_attr "type" "vecsimple")])
+ 
+ (define_insn "*movv16qi_const0"
+   [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
+ 	(const_vector:V16QI [(const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)
+ 			     (const_int 0)]))]
+   "TARGET_ALTIVEC"
+   "vxor %0,%0,%0"
+   [(set_attr "type" "vecsimple")])
+ 
  ;; Simple binary operations.
  
  (define_insn "addv16qi3"
***************
*** 15481,15528 ****
    "lvsr %0,%1,%2"
    [(set_attr "type" "vecload")])
  
  (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))]
    "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))]
    "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))]
    "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))]
    "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))]
    "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
--- 15539,15598 ----
    "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"
!   [(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"
!   [(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"
!   [(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"
!   [(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")
! 	(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")])
  
  (define_insn "altivec_stvx"
    [(parallel


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]