rpms/mingw32-gcc/devel gcc44-libstdc++-docs.patch, NONE, 1.1 gcc44-power7-3.patch, NONE, 1.1 gcc44-rh503816-1.patch, NONE, 1.1 gcc44-rh503816-2.patch, NONE, 1.1 gcc44-unique-object.patch, NONE, 1.1 gcc44-unwind-debug-hook.patch, NONE, 1.1 .cvsignore, 1.4, 1.5 gcc44-hack.patch, 1.1, 1.2 gcc44-power7-2.patch, 1.1, 1.2 gcc44-power7.patch, 1.1, 1.2 gcc44-rh330771.patch, 1.1, 1.2 mingw32-gcc.spec, 1.6, 1.7 sources, 1.4, 1.5 gcc44-atom.patch, 1.1, NONE gcc44-memmove-opt.patch, 1.1, NONE gcc44-pr27898.patch, 1.1, NONE gcc44-pr32139.patch, 1.1, NONE gcc44-pr37959.patch, 1.1, NONE gcc44-pr39226.patch, 1.1, NONE

Kalev Lember kalev at fedoraproject.org
Tue Aug 25 20:26:28 UTC 2009


Author: kalev

Update of /cvs/pkgs/rpms/mingw32-gcc/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv24210

Modified Files:
	.cvsignore gcc44-hack.patch gcc44-power7-2.patch 
	gcc44-power7.patch gcc44-rh330771.patch mingw32-gcc.spec 
	sources 
Added Files:
	gcc44-libstdc++-docs.patch gcc44-power7-3.patch 
	gcc44-rh503816-1.patch gcc44-rh503816-2.patch 
	gcc44-unique-object.patch gcc44-unwind-debug-hook.patch 
Removed Files:
	gcc44-atom.patch gcc44-memmove-opt.patch gcc44-pr27898.patch 
	gcc44-pr32139.patch gcc44-pr37959.patch gcc44-pr39226.patch 
Log Message:
4.4.1-1


gcc44-libstdc++-docs.patch:
 api.html   |   25 +++++--------------------
 index.html |    3 ++-
 2 files changed, 7 insertions(+), 21 deletions(-)

--- NEW FILE gcc44-libstdc++-docs.patch ---
--- libstdc++-v3/doc/html/index.html	2009-01-14 12:06:37.000000000 +0100
+++ libstdc++-v3/doc/html/index.html	2009-05-06 09:17:30.000000000 +0200
@@ -12,7 +12,8 @@
 <div>
 <h1>The GNU C++ Library Documentation</h1>
 
-<p>Copyright 2008 FSF</p>
+<p>Release 4.4.0</p>
+<p>Copyright 2008, 2009 FSF</p>
 
 <p>
   Permission is granted to copy, distribute and/or modify this
--- libstdc++-v3/doc/html/api.html	2009-04-20 21:21:15.000000000 +0200
+++ libstdc++-v3/doc/html/api.html	2009-05-06 09:17:24.000000000 +0200
@@ -17,27 +17,12 @@ useful for examining the signatures of p
 the library classes, finding out what is in a particular include
 file, looking at inheritance diagrams, etc.
 </p><p>
-The source-level documentation for the most recent releases can be
-viewed online:
-</p><div class="itemizedlist"><ul type="disc"><li><p>
-      <a class="ulink" href="libstdc++-html-USERS-3.4/index.html" target="_top">for the 3.4 release
+The source-level documentation can be viewed here:
+</p>
+<div class="itemizedlist"><ul type="disc">
+    <li><p>
+      <a class="ulink" href="api/index.html" target="_top">for the 4.4 release
       </a>
-    </p></li><li><p>
-      <a class="ulink" href="libstdc++-html-USERS-4.1/index.html" target="_top">for the 4.1 release
-      </a>
-    </p></li><li><p>
-      <a class="ulink" href="libstdc++-html-USERS-4.2/index.html" target="_top">for the 4.2 release
-      </a>
-    </p></li><li><p>
-      <a class="ulink" href="libstdc++-html-USERS-4.3/index.html" target="_top">for the 4.3 release
-      </a>
-    </p></li><li><p>
-      <a class="ulink" href="libstdc++-html-USERS-4.4/index.html" target="_top">for the 4.4 release
-      </a>
-    </p></li><li><p>
-      <a class="ulink" href="latest-doxygen/index.html" target="_top">"the latest collection"
-      </a>
-      (For the main development tree; see the date on the first page.)
     </p></li></ul></div><p>
 This generated HTML collection, as above, is also available for download in the libstdc++ snapshots directory at
    <code class="literal">&lt;URL:ftp://gcc.gnu.org/pub/gcc/libstdc++/doxygen/&gt;</code>.

gcc44-power7-3.patch:
 config/rs6000/altivec.md                     |   44 
 config/rs6000/predicates.md                  |    3 
 config/rs6000/rs6000-c.c                     |   79 +
 config/rs6000/rs6000-protos.h                |    2 
 config/rs6000/rs6000.c                       | 1273 +++++++++++++--------------
 config/rs6000/rs6000.h                       |   96 +-
 config/rs6000/rs6000.md                      |   15 
 config/rs6000/rs6000.opt                     |   24 
 config/rs6000/vector.md                      |   56 -
 config/rs6000/vsx.md                         |  406 ++++++--
 doc/extend.texi                              |   17 
 testsuite/gcc.target/powerpc/vsx-builtin-3.c |  212 ++++
 12 files changed, 1363 insertions(+), 864 deletions(-)

--- NEW FILE gcc44-power7-3.patch ---
2009-04-26  Michael Meissner  <meissner at linux.vnet.ibm.com>

	* config/rs6000/vector.md (vector_vsel<mode>): Generate the insns
	directly instead of calling VSX/Altivec expanders.

	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Map VSX
	builtins that are identical to Altivec, to the Altivec vesion.
	(altivec_overloaded_builtins): Add V2DF/V2DI sel, perm support.
	(altivec_resolve_overloaded_builtin): Add V2DF/V2DI support.

	* config/rs6000/rs6000.c (rs6000_expand_vector_init): Rename VSX
	splat functions.
	(expand_vector_set): Merge V2DF/V2DI code.
	(expand_vector_extract): Ditto.
	(bdesc_3arg): Add more VSX builtins.
	(bdesc_2arg): Ditto.
	(bdesc_1arg): Ditto.
	(rs6000_expand_ternop_builtin): Require xxpermdi 3rd argument to
	be 2 bit-constant, and V2DF/V2DI set to be a 1 bit-constant.
	(altivec_expand_builtin): Add support for VSX overloaded builtins.
	(altivec_init_builtins): Ditto.
	(rs6000_common_init_builtins): Ditto.
	(rs6000_init_builtins): Add V2DI types and vector long support.
	(rs6000_handle_altivec_attribute): Ditto.
	(rs6000_mange_type): Ditto.

	* config/rs6000/vsx.md (UNSPEC_*): Add new UNSPEC constants.
	(vsx_vsel<mode>): Add support for all vector types, including
	Altivec types.
	(vsx_ftrunc<mode>2): Emit the correct instruction.
	(vsx_x<VSv>r<VSs>i): New builtin rounding mode insns.
	(vsx_x<VSv>r<VSs>ic): Ditto.
	(vsx_concat_<mode>): Key off of VSX memory instructions being
	generated instead of the vector arithmetic unit to enable V2DI
	mode.
	(vsx_extract_<mode>): Ditto.
	(vsx_set_<mode>): Rewrite as an unspec.
	(vsx_xxpermdi2_<mode>): Rename old vsx_xxpermdi_<mode> here.  Key
	off of VSX memory instructions instead of arithmetic unit.
	(vsx_xxpermdi_<mode>): New insn for __builtin_vsx_xxpermdi.
	(vsx_splat_<mode>): Rename from vsx_splat<mode>.
	(vsx_xxspltw_<mode>): Change from V4SF only to V4SF/V4SI modes.
	Fix up constraints.  Key off of memory instructions instead of
	arithmetic instructions to allow use with V4SI.
	(vsx_xxmrghw_<mode>): Ditto.
	(vsx_xxmrglw_<mode>): Ditto.
	(vsx_xxsldwi_<mode>): Implement vector shift double by word
	immediate.

	* config/rs6000/rs6000.h (VSX_BUILTIN_*): Update for current
	builtins being generated.
	(RS6000_BTI_unsigned_V2DI): Add vector long support.
	(RS6000_BTI_bool_long): Ditto.
	(RS6000_BTI_bool_V2DI): Ditto.
	(unsigned_V2DI_type_node): Ditto.
	(bool_long_type_node): Ditto.
	(bool_V2DI_type_node): Ditto.

	* config/rs6000/altivec.md (altivec_vsel<mode>): Add '*' since we
	don't need the generator function now.  Use VSX instruction if
	-mvsx.
	(altivec_vmrghw): Use VSX instruction if -mvsx.
	(altivec_vmrghsf): Ditto.
	(altivec_vmrglw): Ditto.
	(altivec_vmrglsf): Ditto.

	* doc/extend.texi (PowerPC AltiVec/VSX Built-in Functions):
	Document that under VSX, vector double/long are available.

testsuite/
	* gcc.target/powerpc/vsx-builtin-3.c: New test for VSX builtins.

2009-04-23  Michael Meissner  <meissner at linux.vnet.ibm.com>

	* config/rs6000/vector.md (VEC_E): New iterator to add V2DImode.
	(vec_init<mode>): Use VEC_E instead of VEC_C iterator, to add
	V2DImode support.
	(vec_set<mode>): Ditto.
	(vec_extract<mode>): Ditto.

	* config/rs6000/predicates.md (easy_vector_constant): Add support
	for setting TImode to 0.

	* config/rs6000/rs6000.opt (-mvsx-vector-memory): Delete old debug
	switch that is no longer used.
	(-mvsx-vector-float): Ditto.
	(-mvsx-vector-double): Ditto.
	(-mvsx-v4sf-altivec-regs): Ditto.
	(-mreload-functions): Ditto.
	(-mallow-timode): New debug switch.

	* config/rs6000/rs6000.c (rs6000_ira_cover_classes): New target
	hook for IRA cover classes, to know that under VSX the float and
	altivec registers are part of the same register class, but before
	they weren't.
	(TARGET_IRA_COVER_CLASSES): Set ira cover classes target hookd.
	(rs6000_hard_regno_nregs): Key off of whether VSX/Altivec memory
	instructions are supported, and not whether the vector unit has
	arithmetic support to enable V2DI/TI mode.
	(rs6000_hard_regno_mode_ok): Ditto.
	(rs6000_init_hard_regno_mode_ok): Add V2DImode, TImode support.
	Drop several of the debug switches.
	(rs6000_emit_move): Force TImode constants to memory if we have
	either Altivec or VSX.
	(rs6000_builtin_conversion): Use correct insns for V2DI<->V2DF
	conversions.
	(rs6000_expand_vector_init): Add V2DI support.
	(rs6000_expand_vector_set): Ditto.
	(avoiding_indexed_address_p): Simplify tests to say if the mode
	uses VSX/Altivec memory instructions we can't eliminate reg+reg
	addressing.
	(rs6000_legitimize_address): Move VSX/Altivec REG+REG support
	before the large integer support.
	(rs6000_legitimate_address): Add support for TImode in VSX/Altivec
	registers.
	(rs6000_emit_move): Ditto.
	(def_builtin): Change internal error message to provide more
	information.
	(bdesc_2arg): Add conversion builtins.
	(builtin_hash_function): New function for hashing all of the types
	for builtin functions.
	(builtin_hash_eq): Ditto.
	(builtin_function_type): Ditto.
	(builtin_mode_to_type): New static for builtin argument hashing.
	(builtin_hash_table): Ditto.
	(rs6000_common_init_builtins): Rewrite so that types for builtin
	functions are only created when we need them, and use a hash table
	to store all of the different argument combinations that are
	created.  Add support for VSX conversion builtins.
	(rs6000_preferred_reload_class): Add TImode support.
	(reg_classes_cannot_change_mode_class): Be stricter about VSX and
	Altivec vector types.
	(rs6000_emit_vector_cond_expr): Use VSX_MOVE_MODE, not
	VSX_VECTOR_MOVE_MODE.
	(rs6000_handle_altivec_attribute): Allow __vector long on VSX.

	* config/rs6000/vsx.md (VSX_D): New iterator for vectors with
	64-bit elements.
	(VSX_M): New iterator for 128 bit types for moves, except for
	TImode.
	(VSm, VSs, VSr): Add TImode.
	(VSr4, VSr5): New mode attributes for float<->double conversion.
	(VSX_SPDP): New iterator for float<->double conversion.
	(VS_spdp_*): New mode attributes for float<->double conversion.
	(UNSPEC_VSX_*): Rename unspec constants to remove XV from the
	names.  Change all users.
	(vsx_mov<mode>): Drop TImode support here.
	(vsx_movti): New TImode support, allow GPRs, but favor VSX
	registers.
	(vsx_<VS_spdp_insn>): New support for float<->double conversions.
	(vsx_xvcvdpsp): Delete, move into vsx_<VS_spdp_insn>.
	(vsx_xvcvspdp): Ditto.
	(vsx_xvcvuxdsp): New conversion insn.
	(vsx_xvcvspsxds): Ditto.
	(vsx_xvcvspuxds): Ditto.
	(vsx_concat_<mode>): Generalize V2DF permute/splat operations to
	include V2DI.
	(vsx_set_<mode>): Ditto.
	(vsx_extract_<mode>): Ditto.
	(vsx_xxpermdi_<mode>): Ditto.
	(vsx_splat<mode>): Ditto.

	* config/rs6000/rs6000.h (VSX_VECTOR_MOVE_MODE): Delete.
	(VSX_MOVE_MODE): Add TImode.
	(IRA_COVER_CLASSES): Delete.
	(IRA_COVER_CLASSES_PRE_VSX): New cover classes for machines
	without VSX where float and altivec are different registers.
	(IRA_COVER_CLASS_VSX): New cover classes for machines with VSX
	where float and altivec are part of the same register class.

	* config/rs6000/altivec.md (VM2): New iterator for 128-bit types,
	except TImode.
	(altivec_mov<mode>): Drop movti mode here.
	(altivec_movti): Add movti insn, and allow GPRs, but favor altivec
	registers.

2009-04-16  Michael Meissner  <meissner at linux.vnet.ibm.com>

	* config/rs6000/rs6000-protos.h (rs6000_has_indirect_jump_p): New
	declaration.
	(rs6000_set_indirect_jump): Ditto.

	* config/rs6000/rs6000.c (struct machine_function): Add
	indirect_jump_p field.
	(rs6000_override_options): Wrap warning messages in N_().  If
	-mvsx was implicitly set, don't give a warning for -msoft-float,
	just silently turn off vsx.
	(rs6000_secondary_reload_inner): Don't use strict register
	checking, since pseudos may still be present.
	(register_move_cost): If -mdebug=cost, print out cost information.
	(rs6000_memory_move_cost): Ditto.
	(rs6000_has_indirect_jump_p): New function, return true if
	current function has an indirect jump.
	(rs6000_set_indirect_jump): New function, note that an indirect
	jump has been generated.

	* config/rs6000/rs6000.md (indirect_jump): Note that we've
	generated an indirect jump.
	(tablejump): Ditto.
[...3124 lines suppressed...]
 
   /* VSX overloaded builtins, add the overloaded functions not present in
      Altivec.  */
@@ -3395,7 +3411,13 @@ enum rs6000_builtins
   VSX_BUILTIN_VEC_NMADD,
   VSX_BUITLIN_VEC_NMSUB,
   VSX_BUILTIN_VEC_DIV,
-  VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_DIV,
+  VSX_BUILTIN_VEC_XXMRGHW,
+  VSX_BUILTIN_VEC_XXMRGLW,
+  VSX_BUILTIN_VEC_XXPERMDI,
+  VSX_BUILTIN_VEC_XXSLDWI,
+  VSX_BUILTIN_VEC_XXSPLTD,
+  VSX_BUILTIN_VEC_XXSPLTW,
+  VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_XXSPLTW,
 
   /* Combined VSX/Altivec builtins.  */
   VECTOR_BUILTIN_FLOAT_V4SI_V4SF,
@@ -3425,13 +3447,16 @@ enum rs6000_builtin_type_index
   RS6000_BTI_unsigned_V16QI,
   RS6000_BTI_unsigned_V8HI,
   RS6000_BTI_unsigned_V4SI,
+  RS6000_BTI_unsigned_V2DI,
   RS6000_BTI_bool_char,          /* __bool char */
   RS6000_BTI_bool_short,         /* __bool short */
   RS6000_BTI_bool_int,           /* __bool int */
+  RS6000_BTI_bool_long,		 /* __bool long */
   RS6000_BTI_pixel,              /* __pixel */
   RS6000_BTI_bool_V16QI,         /* __vector __bool char */
   RS6000_BTI_bool_V8HI,          /* __vector __bool short */
   RS6000_BTI_bool_V4SI,          /* __vector __bool int */
+  RS6000_BTI_bool_V2DI,          /* __vector __bool long */
   RS6000_BTI_pixel_V8HI,         /* __vector __pixel */
   RS6000_BTI_long,	         /* long_integer_type_node */
   RS6000_BTI_unsigned_long,      /* long_unsigned_type_node */
@@ -3466,13 +3491,16 @@ enum rs6000_builtin_type_index
 #define unsigned_V16QI_type_node      (rs6000_builtin_types[RS6000_BTI_unsigned_V16QI])
 #define unsigned_V8HI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V8HI])
 #define unsigned_V4SI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V4SI])
+#define unsigned_V2DI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V2DI])
 #define bool_char_type_node           (rs6000_builtin_types[RS6000_BTI_bool_char])
 #define bool_short_type_node          (rs6000_builtin_types[RS6000_BTI_bool_short])
 #define bool_int_type_node            (rs6000_builtin_types[RS6000_BTI_bool_int])
+#define bool_long_type_node           (rs6000_builtin_types[RS6000_BTI_bool_long])
 #define pixel_type_node               (rs6000_builtin_types[RS6000_BTI_pixel])
 #define bool_V16QI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V16QI])
 #define bool_V8HI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V8HI])
 #define bool_V4SI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V4SI])
+#define bool_V2DI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V2DI])
 #define pixel_V8HI_type_node	      (rs6000_builtin_types[RS6000_BTI_pixel_V8HI])
 
 #define long_integer_type_internal_node  (rs6000_builtin_types[RS6000_BTI_long])
--- gcc/config/rs6000/altivec.md	(revision 146119)
+++ gcc/config/rs6000/altivec.md	(revision 146798)
@@ -166,12 +166,15 @@ (define_mode_iterator V [V4SI V8HI V16QI
 ;; otherwise handled by altivec (v2df, v2di, ti)
 (define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI TI])
 
+;; Like VM, except don't do TImode
+(define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI])
+
 (define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
 
 ;; Vector move instructions.
 (define_insn "*altivec_mov<mode>"
-  [(set (match_operand:V 0 "nonimmediate_operand" "=Z,v,v,*o,*r,*r,v,v")
-	(match_operand:V 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
+  [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*o,*r,*r,v,v")
+	(match_operand:VM2 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)
    && (register_operand (operands[0], <MODE>mode) 
        || register_operand (operands[1], <MODE>mode))"
@@ -191,6 +194,31 @@ (define_insn "*altivec_mov<mode>"
 }
   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
 
+;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
+;; is for unions.  However for plain data movement, slightly favor the vector
+;; loads
+(define_insn "*altivec_movti"
+  [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?o,?r,?r,v,v")
+	(match_operand:TI 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
+  "VECTOR_MEM_ALTIVEC_P (TImode)
+   && (register_operand (operands[0], TImode) 
+       || register_operand (operands[1], TImode))"
+{
+  switch (which_alternative)
+    {
+    case 0: return "stvx %1,%y0";
+    case 1: return "lvx %0,%y1";
+    case 2: return "vor %0,%1,%1";
+    case 3: return "#";
+    case 4: return "#";
+    case 5: return "#";
+    case 6: return "vxor %0,%0,%0";
+    case 7: return output_vec_const_move (operands);
+    default: gcc_unreachable ();
+    }
+}
+  [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
+
 (define_split
   [(set (match_operand:VM 0 "altivec_register_operand" "")
 	(match_operand:VM 1 "easy_vector_constant_add_self" ""))]
@@ -434,13 +462,13 @@ (define_insn "*altivec_gev4sf"
   "vcmpgefp %0,%1,%2"
   [(set_attr "type" "veccmp")])
 
-(define_insn "altivec_vsel<mode>"
+(define_insn "*altivec_vsel<mode>"
   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
 	(if_then_else:VM (ne (match_operand:VM 1 "altivec_register_operand" "v")
 			     (const_int 0))
 			 (match_operand:VM 2 "altivec_register_operand" "v")
 			 (match_operand:VM 3 "altivec_register_operand" "v")))]
-  "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
+  "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
   "vsel %0,%3,%2,%1"
   [(set_attr "type" "vecperm")])
 
@@ -780,7 +808,7 @@ (define_insn "altivec_vmrghw"
 						    (const_int 3)
 						    (const_int 1)]))
 		      (const_int 5)))]
-  "TARGET_ALTIVEC"
+  "VECTOR_MEM_ALTIVEC_P (V4SImode)"
   "vmrghw %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -797,7 +825,7 @@ (define_insn "*altivec_vmrghsf"
                                                     (const_int 3)
                                                     (const_int 1)]))
                       (const_int 5)))]
-  "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
+  "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
   "vmrghw %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -881,7 +909,7 @@ (define_insn "altivec_vmrglw"
 				     (const_int 1)
 				     (const_int 3)]))
 	 (const_int 5)))]
-  "TARGET_ALTIVEC"
+  "VECTOR_MEM_ALTIVEC_P (V4SImode)"
   "vmrglw %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -899,7 +927,7 @@ (define_insn "*altivec_vmrglsf"
 				     (const_int 1)
 				     (const_int 3)]))
 	 (const_int 5)))]
-  "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
+  "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
   "vmrglw %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
--- gcc/config/rs6000/rs6000.md	(revision 146119)
+++ gcc/config/rs6000/rs6000.md	(revision 146798)
@@ -14667,7 +14667,11 @@ (define_insn "return"
   [(set_attr "type" "jmpreg")])
 
 (define_expand "indirect_jump"
-  [(set (pc) (match_operand 0 "register_operand" ""))])
+  [(set (pc) (match_operand 0 "register_operand" ""))]
+  ""
+{
+  rs6000_set_indirect_jump ();
+})
 
 (define_insn "*indirect_jump<mode>"
   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
@@ -14682,14 +14686,14 @@ (define_expand "tablejump"
   [(use (match_operand 0 "" ""))
    (use (label_ref (match_operand 1 "" "")))]
   ""
-  "
 {
+  rs6000_set_indirect_jump ();
   if (TARGET_32BIT)
     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
   else
     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
   DONE;
-}")
+})
 
 (define_expand "tablejumpsi"
   [(set (match_dup 3)
@@ -14749,6 +14753,11 @@ (define_expand "doloop_end"
   /* Only use this on innermost loops.  */
   if (INTVAL (operands[3]) > 1)
     FAIL;
+  /* Do not try to use decrement and count on code that has an indirect
+     jump or a table jump, because the ctr register is preferred over the
+     lr register.  */
+  if (rs6000_has_indirect_jump_p ())
+    FAIL;
   if (TARGET_64BIT)
     {
       if (GET_MODE (operands[0]) != DImode)

gcc44-rh503816-1.patch:
 gcc/var-tracking.c  |  370 +++++++++++++++++++++++++++++++++++++---------------
 libiberty/hashtab.c |    3 
 2 files changed, 271 insertions(+), 102 deletions(-)

--- NEW FILE gcc44-rh503816-1.patch ---
2009-06-21  Jakub Jelinek  <jakub at redhat.com>

	* var-tracking.c (struct shared_hash_def, shared_hash): New types.
	(dataflow_set): Change vars type from htab_t to shared_hash.
	(shared_hash_pool, empty_shared_hash): New variables.
	(vars_clear): Removed.
	(shared_hash_shared, shared_hash_htab, shared_hash_copy,
	shared_hash_find_slot_unshare, shared_hash_find_slot,
	shared_hash_find_slot_noinsert, shared_hash_find): New
	static inlines.
	(shared_hash_unshare, shared_hash_destroy): New functions.
	(unshare_variable): Unshare set->vars if shared, use
	shared_hash_htab.
	(vars_copy): Use htab_traverse_noresize instead of htab_traverse.
	(get_init_value, find_src_set_src, dump_dataflow_set,
	clobber_variable_part, emit_notes_for_differences): Use
	shared_hash_htab.
	(dataflow_set_init): Remove second argument, set vars to
	empty_shared_hash instead of creating a new htab.
	(dataflow_set_clear): Call shared_hash_destroy and set vars
	to empty_shared_hash instead of calling vars_clear.
	(dataflow_set_copy): Don't call vars_copy, instead just share
	the src htab with dst.
	(variable_union): Use shared_hash_*, use initially NO_INSERT
	lookup if set->vars is shared.  Don't keep slot cleared before
	calling unshare_variable.  Unshare set->vars if needed.
	Even ->refcount == 1 vars must be unshared if set->vars is shared
	and var needs to be modified.
	(variable_canonicalize): New function.
	(dataflow_set_union): If dst->vars is empty, just share src->vars
	with dst->vars and traverse with variable_canonicalize to canonicalize
	and unshare what is needed.
	(dataflow_set_different): If old_set and new_set use the same shared
	htab, they aren't different.  If number of htab elements is different,
	htabs are different.  Use shared_hash_*.
	(dataflow_set_destroy): Call shared_hash_destroy instead of
	htab_delete.
	(compute_bb_dataflow, emit_notes_in_bb, vt_emit_notes): Don't pass
	second argument to dataflow_set_init.
	(vt_initialize): Likewise.  Initialize shared_hash_pool and
	empty_shared_hash, move bb in/out initialization afterwards.
	Use variable_htab_free instead of NULL as changed_variables del hook.
	(variable_was_changed): Change type of second argument to pointer to
	dataflow_set.  When inserting var into changed_variables, bump
	refcount.  Unshare set->vars if set is shared htab and slot needs to
	be cleared.
	(set_variable_part): Use shared_hash_*, use initially NO_INSERT
	lookup if set->vars is shared.  Unshare set->vars if needed.
	Even ->refcount == 1 vars must be unshared if set->vars is shared
	and var needs to be modified.  Adjust variable_was_changed caller.
	(delete_variable_part): Use shared_hash_*.  Even ->refcount == 1
	vars must be unshared if set->vars is shared and var needs to be
	modified.  Adjust variable_was_changed caller.
	(emit_note_insn_var_location): Don't pool_free var.
	(emit_notes_for_differences_1): Initialize empty_var->refcount to 0
	instead of 1.
	(vt_finalize): Call htab_delete on empty_shared_hash->htab and
	free_alloc_pool on shared_hash_pool.

	* hashtab.c (htab_traverse): Don't call htab_expand for
	nearly empty hashtabs with sizes 7, 13 or 31.

--- gcc/var-tracking.c	(revision 148758)
+++ gcc/var-tracking.c	(revision 148760)
@@ -182,6 +182,17 @@ typedef struct attrs_def
   HOST_WIDE_INT offset;
 } *attrs;
 
+/* Structure holding a refcounted hash table.  If refcount > 1,
+   it must be first unshared before modified.  */
+typedef struct shared_hash_def
+{
+  /* Reference count.  */
+  int refcount;
+
+  /* Actual hash table.  */
+  htab_t htab;
+} *shared_hash;
+
 /* Structure holding the IN or OUT set for a basic block.  */
 typedef struct dataflow_set_def
 {
@@ -192,7 +203,7 @@ typedef struct dataflow_set_def
   attrs regs[FIRST_PSEUDO_REGISTER];
 
   /* Variable locations.  */
-  htab_t vars;
+  shared_hash vars;
 } dataflow_set;
 
 /* The structure (one for each basic block) containing the information
@@ -280,12 +291,18 @@ static alloc_pool var_pool;
 /* Alloc pool for struct location_chain_def.  */
 static alloc_pool loc_chain_pool;
 
+/* Alloc pool for struct shared_hash_def.  */
+static alloc_pool shared_hash_pool;
+
 /* Changed variables, notes will be emitted for them.  */
 static htab_t changed_variables;
 
 /* Shall notes be emitted?  */
 static bool emit_notes;
 
+/* Empty shared hashtable.  */
+static shared_hash empty_shared_hash;
+
 /* Local function prototypes.  */
 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
 					  HOST_WIDE_INT *);
@@ -305,7 +322,6 @@ static void attrs_list_insert (attrs *, 
 static void attrs_list_copy (attrs *, attrs);
 static void attrs_list_union (attrs *, attrs);
 
-static void vars_clear (htab_t);
 static variable unshare_variable (dataflow_set *set, variable var, 
 				  enum var_init_status);
 static int vars_copy_1 (void **, void *);
@@ -321,11 +337,12 @@ static void var_mem_delete_and_set (data
 				    enum var_init_status, rtx);
 static void var_mem_delete (dataflow_set *, rtx, bool);
 
-static void dataflow_set_init (dataflow_set *, int);
+static void dataflow_set_init (dataflow_set *);
 static void dataflow_set_clear (dataflow_set *);
 static void dataflow_set_copy (dataflow_set *, dataflow_set *);
 static int variable_union_info_cmp_pos (const void *, const void *);
 static int variable_union (void **, void *);
+static int variable_canonicalize (void **, void *);
 static void dataflow_set_union (dataflow_set *, dataflow_set *);
 static bool variable_part_different_p (variable_part *, variable_part *);
 static bool variable_different_p (variable, variable, bool);
@@ -352,7 +369,7 @@ static void dump_vars (htab_t);
 static void dump_dataflow_set (dataflow_set *);
 static void dump_dataflow_sets (void);
 
-static void variable_was_changed (variable, htab_t);
+static void variable_was_changed (variable, dataflow_set *);
 static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT, 
 			       enum var_init_status, rtx);
 static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT, 
@@ -742,12 +759,107 @@ attrs_list_union (attrs *dstp, attrs src
     }
 }
 
-/* Delete all variables from hash table VARS.  */
+/* Shared hashtable support.  */
+
+/* Return true if VARS is shared.  */
+
+static inline bool
+shared_hash_shared (shared_hash vars)
+{
+  return vars->refcount > 1;
+}
+
+/* Return the hash table for VARS.  */
+
+static inline htab_t
+shared_hash_htab (shared_hash vars)
+{
+  return vars->htab;
+}
+
+/* Copy variables into a new hash table.  */
+
+static shared_hash
+shared_hash_unshare (shared_hash vars)
+{
+  shared_hash new_vars = (shared_hash) pool_alloc (shared_hash_pool);
+  gcc_assert (vars->refcount > 1);
+  new_vars->refcount = 1;
+  new_vars->htab
+    = htab_create (htab_elements (vars->htab) + 3, variable_htab_hash,
+		   variable_htab_eq, variable_htab_free);
+  vars_copy (new_vars->htab, vars->htab);
+  vars->refcount--;
+  return new_vars;
+}
+
+/* Increment reference counter on VARS and return it.  */
+
+static inline shared_hash
+shared_hash_copy (shared_hash vars)
+{
+  vars->refcount++;
+  return vars;
+}
+
+/* Decrement reference counter and destroy hash table if not shared
+   anymore.  */
 
 static void
-vars_clear (htab_t vars)
+shared_hash_destroy (shared_hash vars)
 {
-  htab_empty (vars);
+  gcc_assert (vars->refcount > 0);
+  if (--vars->refcount == 0)
+    {
+      htab_delete (vars->htab);
+      pool_free (shared_hash_pool, vars);
+    }
+}
+
+/* Unshare *PVARS if shared and return slot for DECL.  If INS is
+   INSERT, insert it if not already present.  */
+
+static inline void **
+shared_hash_find_slot_unshare (shared_hash *pvars, tree decl,
+			       enum insert_option ins)
+{
+  if (shared_hash_shared (*pvars))
+    *pvars = shared_hash_unshare (*pvars);
+  return htab_find_slot_with_hash (shared_hash_htab (*pvars), decl,
+				   VARIABLE_HASH_VAL (decl), ins);
+}
+
+/* Return slot for DECL, if it is already present in the hash table.
+   If it is not present, insert it only VARS is not shared, otherwise
+   return NULL.  */
+
+static inline void **
+shared_hash_find_slot (shared_hash vars, tree decl)
+{
+  return htab_find_slot_with_hash (shared_hash_htab (vars), decl,
+				   VARIABLE_HASH_VAL (decl),
+				   shared_hash_shared (vars)
+				   ? NO_INSERT : INSERT);
+}
+
+/* Return slot for DECL only if it is already present in the hash table.  */
+
+static inline void **
+shared_hash_find_slot_noinsert (shared_hash vars, tree decl)
+{
+  return htab_find_slot_with_hash (shared_hash_htab (vars), decl,
+				   VARIABLE_HASH_VAL (decl), NO_INSERT);
+}
+
+/* Return variable for DECL or NULL if not already present in the hash
+   table.  */
+
+static inline variable
+shared_hash_find (shared_hash vars, tree decl)
+{
+  return (variable)
+	 htab_find_with_hash (shared_hash_htab (vars), decl,
+			      VARIABLE_HASH_VAL (decl));
 }
 
 /* Return a copy of a variable VAR and insert it to dataflow set SET.  */
@@ -801,9 +913,7 @@ unshare_variable (dataflow_set *set, var
 	new_var->var_part[i].cur_loc = NULL;
     }
 
-  slot = htab_find_slot_with_hash (set->vars, new_var->decl,
-				   VARIABLE_HASH_VAL (new_var->decl),
-				   INSERT);
+  slot = shared_hash_find_slot_unshare (&set->vars, new_var->decl, INSERT);
   *slot = new_var;
   return new_var;
 }
@@ -834,8 +944,7 @@ vars_copy_1 (void **slot, void *data)
 static void
 vars_copy (htab_t dst, htab_t src)
 {
-  vars_clear (dst);
-  htab_traverse (src, vars_copy_1, dst);
+  htab_traverse_noresize (src, vars_copy_1, dst);
 }
 
 /* Map a decl to its main debug decl.  */
@@ -874,7 +983,6 @@ var_reg_set (dataflow_set *set, rtx loc,
 static int
 get_init_value (dataflow_set *set, rtx loc, tree decl)
 {
-  void **slot;
   variable var;
   int i;
   int ret_val = VAR_INIT_STATUS_UNKNOWN;
@@ -882,11 +990,9 @@ get_init_value (dataflow_set *set, rtx l
   if (! flag_var_tracking_uninit)
     return VAR_INIT_STATUS_INITIALIZED;
 
-  slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
-				   NO_INSERT);
-  if (slot)
+  var = shared_hash_find (set->vars, decl);
+  if (var)
     {
-      var = * (variable *) slot;
       for (i = 0; i < var->n_var_parts && ret_val == VAR_INIT_STATUS_UNKNOWN; i++)
 	{
 	  location_chain nextp;
@@ -1050,11 +1156,10 @@ var_mem_delete (dataflow_set *set, rtx l
    VARS_SIZE is the initial size of hash table VARS.  */
 
 static void
-dataflow_set_init (dataflow_set *set, int vars_size)
+dataflow_set_init (dataflow_set *set)
 {
   init_attrs_list_set (set->regs);
-  set->vars = htab_create (vars_size, variable_htab_hash, variable_htab_eq,
-			   variable_htab_free);
+  set->vars = shared_hash_copy (empty_shared_hash);
   set->stack_adjust = 0;
 }
 
@@ -1068,7 +1173,8 @@ dataflow_set_clear (dataflow_set *set)
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     attrs_list_clear (&set->regs[i]);
 
-  vars_clear (set->vars);
+  shared_hash_destroy (set->vars);
+  set->vars = shared_hash_copy (empty_shared_hash);
 }
 
 /* Copy the contents of dataflow set SRC to DST.  */
@@ -1081,7 +1187,8 @@ dataflow_set_copy (dataflow_set *dst, da
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     attrs_list_copy (&dst->regs[i], src->regs[i]);
 
-  vars_copy (dst->vars, src->vars);
+  shared_hash_destroy (dst->vars);
+  dst->vars = shared_hash_copy (src->vars);
   dst->stack_adjust = src->stack_adjust;
 }
 
@@ -1129,15 +1236,14 @@ variable_union_info_cmp_pos (const void 
 static int
 variable_union (void **slot, void *data)
 {
-  variable src, dst, *dstp;
+  variable src, dst;
+  void **dstp;
   dataflow_set *set = (dataflow_set *) data;
   int i, j, k;
 
   src = *(variable *) slot;
-  dstp = (variable *) htab_find_slot_with_hash (set->vars, src->decl,
-						VARIABLE_HASH_VAL (src->decl),
-						INSERT);
-  if (!*dstp)
+  dstp = shared_hash_find_slot (set->vars, src->decl);
+  if (!dstp || !*dstp)
     {
       src->refcount++;
 
@@ -1162,16 +1268,23 @@ variable_union (void **slot, void *data)
 	  if (! flag_var_tracking_uninit)
 	    status = VAR_INIT_STATUS_INITIALIZED;
 
+	  if (dstp)
+	    *dstp = (void *) src;
 	  unshare_variable (set, src, status);
 	}
       else
-	*dstp = src;
+	{
+	  if (!dstp)
+	    dstp = shared_hash_find_slot_unshare (&set->vars, src->decl,
+						  INSERT);
+	  *dstp = (void *) src;
+	}
 
       /* Continue traversing the hash table.  */
       return 1;
     }
   else
-    dst = *dstp;
+    dst = (variable) *dstp;
 
   gcc_assert (src->n_var_parts);
 
@@ -1196,7 +1309,8 @@ variable_union (void **slot, void *data)
      thus there are at most MAX_VAR_PARTS different offsets.  */
   gcc_assert (k <= MAX_VAR_PARTS);
 
-  if (dst->refcount > 1 && dst->n_var_parts != k)
+  if ((dst->refcount > 1 || shared_hash_shared (set->vars))
+      && dst->n_var_parts != k)
     {
       enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
       
@@ -1226,7 +1340,7 @@ variable_union (void **slot, void *data)
 	  /* If DST is shared compare the location chains.
 	     If they are different we will modify the chain in DST with
 	     high probability so make a copy of DST.  */
-	  if (dst->refcount > 1)
+	  if (dst->refcount > 1 || shared_hash_shared (set->vars))
 	    {
 	      for (node = src->var_part[i].loc_chain,
 		   node2 = dst->var_part[j].loc_chain; node && node2;
@@ -1379,6 +1493,46 @@ variable_union (void **slot, void *data)
   return 1;
 }
 
+/* Like variable_union, but only used when doing dataflow_set_union
+   into an empty hashtab.  To allow sharing, dst is initially shared
+   with src (so all variables are "copied" from src to dst hashtab),
+   so only unshare_variable for variables that need canonicalization
+   are needed.  */
+
+static int
+variable_canonicalize (void **slot, void *data)
+{
+  variable src;
+  dataflow_set *set = (dataflow_set *) data;
+  int k;
+
+  src = *(variable *) slot;
+
+  /* If CUR_LOC of some variable part is not the first element of
+     the location chain we are going to change it so we have to make
+     a copy of the variable.  */
+  for (k = 0; k < src->n_var_parts; k++)
+    {
+      gcc_assert (!src->var_part[k].loc_chain == !src->var_part[k].cur_loc);
+      if (src->var_part[k].loc_chain)
+	{
+	  gcc_assert (src->var_part[k].cur_loc);
+	  if (src->var_part[k].cur_loc != src->var_part[k].loc_chain->loc)
+	    break;
+	}
+    }
+  if (k < src->n_var_parts)
+    {
+      enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
+
+      if (! flag_var_tracking_uninit)
+	status = VAR_INIT_STATUS_INITIALIZED;
+
+      unshare_variable (set, src, status);
+    }
+  return 1;
+}
+
 /* Compute union of dataflow sets SRC and DST and store it to DST.  */
 
 static void
@@ -1389,7 +1543,14 @@ dataflow_set_union (dataflow_set *dst, d
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     attrs_list_union (&dst->regs[i], src->regs[i]);
 
-  htab_traverse (src->vars, variable_union, dst);
+  if (dst->vars == empty_shared_hash)
+    {
+      shared_hash_destroy (dst->vars);
+      dst->vars = shared_hash_copy (src->vars);
+      htab_traverse (shared_hash_htab (src->vars), variable_canonicalize, dst);
+    }
+  else
+    htab_traverse (shared_hash_htab (src->vars), variable_union, dst);
 }
 
 /* Flag whether two dataflow sets being compared contain different data.  */
@@ -1522,15 +1683,24 @@ dataflow_set_different_2 (void **slot, v
 static bool
 dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
 {
+  if (old_set->vars == new_set->vars)
+    return false;
+
+  if (htab_elements (shared_hash_htab (old_set->vars))
+      != htab_elements (shared_hash_htab (new_set->vars)))
+    return true;
+
   dataflow_set_different_value = false;
 
-  htab_traverse (old_set->vars, dataflow_set_different_1, new_set->vars);
+  htab_traverse (shared_hash_htab (old_set->vars), dataflow_set_different_1,
+		 shared_hash_htab (new_set->vars));
   if (!dataflow_set_different_value)
     {
       /* We have compared the variables which are in both hash tables
 	 so now only check whether there are some variables in NEW_SET->VARS
 	 which are not in OLD_SET->VARS.  */
-      htab_traverse (new_set->vars, dataflow_set_different_2, old_set->vars);
+      htab_traverse (shared_hash_htab (new_set->vars), dataflow_set_different_2,
+		     shared_hash_htab (old_set->vars));
     }
   return dataflow_set_different_value;
 }
@@ -1545,7 +1715,7 @@ dataflow_set_destroy (dataflow_set *set)
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     attrs_list_clear (&set->regs[i]);
 
-  htab_delete (set->vars);
+  shared_hash_destroy (set->vars);
   set->vars = NULL;
 }
 
@@ -1985,7 +2155,6 @@ find_src_set_src (dataflow_set *set, rtx
 {
   tree decl = NULL_TREE;   /* The variable being copied around.          */
   rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
-  void **slot;
   variable var;
   location_chain nextp;
   int i;
@@ -1998,12 +2167,9 @@ find_src_set_src (dataflow_set *set, rtx
 
   if (src && decl)
     {
-      slot = htab_find_slot_with_hash (set->vars, decl, 
-				       VARIABLE_HASH_VAL (decl), NO_INSERT);
-
-      if (slot)
+      var = shared_hash_find (set->vars, decl);
+      if (var)
 	{
-	  var = *(variable *) slot;
 	  found = false;
 	  for (i = 0; i < var->n_var_parts && !found; i++)
 	    for (nextp = var->var_part[i].loc_chain; nextp && !found; 
@@ -2031,7 +2197,7 @@ compute_bb_dataflow (basic_block bb)
   dataflow_set *in = &VTI (bb)->in;
   dataflow_set *out = &VTI (bb)->out;
 
-  dataflow_set_init (&old_out, htab_elements (VTI (bb)->out.vars) + 3);
+  dataflow_set_init (&old_out);
   dataflow_set_copy (&old_out, out);
   dataflow_set_copy (out, in);
 
@@ -2323,7 +2489,7 @@ dump_dataflow_set (dataflow_set *set)
 	  dump_attrs_list (set->regs[i]);
 	}
     }
-  dump_vars (set->vars);
+  dump_vars (shared_hash_htab (set->vars));
   fprintf (dump_file, "\n");
 }
 
@@ -2345,10 +2511,10 @@ dump_dataflow_sets (void)
 }
 
 /* Add variable VAR to the hash table of changed variables and
-   if it has no locations delete it from hash table HTAB.  */
+   if it has no locations delete it from SET's hash table.  */
 
 static void
-variable_was_changed (variable var, htab_t htab)
+variable_was_changed (variable var, dataflow_set *set)
 {
   hashval_t hash = VARIABLE_HASH_VAL (var->decl);
 
@@ -2359,36 +2525,39 @@ variable_was_changed (variable var, htab
       slot = (variable *) htab_find_slot_with_hash (changed_variables,
 						    var->decl, hash, INSERT);
 
-      if (htab && var->n_var_parts == 0)
+      if (set && var->n_var_parts == 0)
 	{
 	  variable empty_var;
-	  void **old;
 
 	  empty_var = (variable) pool_alloc (var_pool);
 	  empty_var->decl = var->decl;
 	  empty_var->refcount = 1;
 	  empty_var->n_var_parts = 0;
 	  *slot = empty_var;
-
-	  old = htab_find_slot_with_hash (htab, var->decl, hash,
-					  NO_INSERT);
-	  if (old)
-	    htab_clear_slot (htab, old);
+	  goto drop_var;
 	}
       else
 	{
+	  var->refcount++;
 	  *slot = var;
 	}
     }
   else
     {
-      gcc_assert (htab);
+      gcc_assert (set);
       if (var->n_var_parts == 0)
 	{
-	  void **slot = htab_find_slot_with_hash (htab, var->decl, hash,
-						  NO_INSERT);
+	  void **slot;
+
+	drop_var:
+	  slot = shared_hash_find_slot_noinsert (set->vars, var->decl);
 	  if (slot)
-	    htab_clear_slot (htab, slot);
+	    {
+	      if (shared_hash_shared (set->vars))
+		slot = shared_hash_find_slot_unshare (&set->vars, var->decl,
+						      NO_INSERT);
+	      htab_clear_slot (shared_hash_htab (set->vars), slot);
+	    }
 	}
     }
 }
@@ -2438,12 +2607,12 @@ set_variable_part (dataflow_set *set, rt
   location_chain node, next;
   location_chain *nextp;
   variable var;
-  void **slot;
-  
-  slot = htab_find_slot_with_hash (set->vars, decl,
-				   VARIABLE_HASH_VAL (decl), INSERT);
-  if (!*slot)
+  void **slot = shared_hash_find_slot (set->vars, decl);
+
+  if (!slot || !*slot)
     {
+      if (!slot)
+	slot = shared_hash_find_slot_unshare (&set->vars, decl, INSERT);
       /* Create new variable information.  */
       var = (variable) pool_alloc (var_pool);
       var->decl = decl;
@@ -2479,13 +2648,12 @@ set_variable_part (dataflow_set *set, rt
 	      if (set_src != NULL)
 		node->set_src = set_src;
 
-	      *slot = var;
 	      return;
 	    }
 	  else
 	    {
 	      /* We have to make a copy of a shared variable.  */
-	      if (var->refcount > 1)
+	      if (var->refcount > 1 || shared_hash_shared (set->vars))
 		var = unshare_variable (set, var, initialized);
 	    }
 	}
@@ -2494,7 +2662,7 @@ set_variable_part (dataflow_set *set, rt
 	  /* We have not found the location part, new one will be created.  */
 
 	  /* We have to make a copy of the shared variable.  */
-	  if (var->refcount > 1)
+	  if (var->refcount > 1 || shared_hash_shared (set->vars))
 	    var = unshare_variable (set, var, initialized);
 
 	  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
@@ -2548,7 +2716,7 @@ set_variable_part (dataflow_set *set, rt
   if (var->var_part[pos].cur_loc == NULL)
     {
       var->var_part[pos].cur_loc = loc;
-      variable_was_changed (var, set->vars);
+      variable_was_changed (var, set);
     }
 }
 
@@ -2561,16 +2729,14 @@ static void
 clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
 		       HOST_WIDE_INT offset, rtx set_src)
 {
-  void **slot;
+  variable var;
 
   if (! decl || ! DECL_P (decl))
     return;
 
-  slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
-				   NO_INSERT);
-  if (slot)
+  var = shared_hash_find (set->vars, decl);
+  if (var)
     {
-      variable var = (variable) *slot;
       int pos = find_variable_location_part (var, offset, NULL);
 
       if (pos >= 0)
@@ -2627,13 +2793,9 @@ static void
 delete_variable_part (dataflow_set *set, rtx loc, tree decl,
 		      HOST_WIDE_INT offset)
 {
-  void **slot;
-    
-  slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
-				   NO_INSERT);
-  if (slot)
+  variable var = shared_hash_find (set->vars, decl);;
+  if (var)
     {
-      variable var = (variable) *slot;
       int pos = find_variable_location_part (var, offset, NULL);
 
       if (pos >= 0)
@@ -2642,7 +2804,7 @@ delete_variable_part (dataflow_set *set,
 	  location_chain *nextp;
 	  bool changed;
 
-	  if (var->refcount > 1)
+	  if (var->refcount > 1 || shared_hash_shared (set->vars))
 	    {
 	      /* If the variable contains the location part we have to
 		 make a copy of the variable.  */
@@ -2705,7 +2867,7 @@ delete_variable_part (dataflow_set *set,
 		}
 	    }
 	  if (changed)
-	    variable_was_changed (var, set->vars);
+	    variable_was_changed (var, set);
 	}
     }
 }
@@ -2864,14 +3026,6 @@ emit_note_insn_var_location (void **varp
 
   htab_clear_slot (changed_variables, varp);
 
-  /* When there are no location parts the variable has been already
-     removed from hash table and a new empty variable was created.
-     Free the empty variable.  */
-  if (var->n_var_parts == 0)
-    {
-      pool_free (var_pool, var);
-    }
-
   /* Continue traversing the hash table.  */
   return 1;
 }
@@ -2910,7 +3064,7 @@ emit_notes_for_differences_1 (void **slo
 
       empty_var = (variable) pool_alloc (var_pool);
       empty_var->decl = old_var->decl;
-      empty_var->refcount = 1;
+      empty_var->refcount = 0;
       empty_var->n_var_parts = 0;
       variable_was_changed (empty_var, NULL);
     }
@@ -2952,8 +3106,12 @@ static void
 emit_notes_for_differences (rtx insn, dataflow_set *old_set,
 			    dataflow_set *new_set)
 {
-  htab_traverse (old_set->vars, emit_notes_for_differences_1, new_set->vars);
-  htab_traverse (new_set->vars, emit_notes_for_differences_2, old_set->vars);
+  htab_traverse (shared_hash_htab (old_set->vars),
+		 emit_notes_for_differences_1,
+		 shared_hash_htab (new_set->vars));
+  htab_traverse (shared_hash_htab (new_set->vars),
+		 emit_notes_for_differences_2,
+		 shared_hash_htab (old_set->vars));
   emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
 }
 
@@ -2965,7 +3123,7 @@ emit_notes_in_bb (basic_block bb)
   int i;
   dataflow_set set;
 
-  dataflow_set_init (&set, htab_elements (VTI (bb)->in.vars) + 3);
+  dataflow_set_init (&set);
   dataflow_set_copy (&set, &VTI (bb)->in);
 
   for (i = 0; i < VTI (bb)->n_mos; i++)
@@ -3098,7 +3256,7 @@ vt_emit_notes (void)
      delete_variable_part).  */
   emit_notes = true;
 
-  dataflow_set_init (&empty, 7);
+  dataflow_set_init (&empty);
   last_out = &empty;
 
   FOR_EACH_BB (bb)
@@ -3343,14 +3501,6 @@ vt_initialize (void)
 	}
     }
 
-  /* Init the IN and OUT sets.  */
-  FOR_ALL_BB (bb)
-    {
-      VTI (bb)->visited = false;
-      dataflow_set_init (&VTI (bb)->in, 7);
-      dataflow_set_init (&VTI (bb)->out, 7);
-    }
-
   attrs_pool = create_alloc_pool ("attrs_def pool",
 				  sizeof (struct attrs_def), 1024);
   var_pool = create_alloc_pool ("variable_def pool",
@@ -3358,8 +3508,24 @@ vt_initialize (void)
   loc_chain_pool = create_alloc_pool ("location_chain_def pool",
 				      sizeof (struct location_chain_def),
 				      1024);
+  shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
+					sizeof (struct shared_hash_def), 256);
+  empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
+  empty_shared_hash->refcount = 1;
+  empty_shared_hash->htab
+    = htab_create (1, variable_htab_hash, variable_htab_eq,
+		   variable_htab_free);
   changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
-				   NULL);
+				   variable_htab_free);
+
+  /* Init the IN and OUT sets.  */
+  FOR_ALL_BB (bb)
+    {
+      VTI (bb)->visited = false;
+      dataflow_set_init (&VTI (bb)->in);
+      dataflow_set_init (&VTI (bb)->out);
+    }
+
   vt_add_function_parameters ();
 }
 
@@ -3381,10 +3547,12 @@ vt_finalize (void)
       dataflow_set_destroy (&VTI (bb)->out);
     }
   free_aux_for_blocks ();
+  htab_delete (empty_shared_hash->htab);
+  htab_delete (changed_variables);
   free_alloc_pool (attrs_pool);
   free_alloc_pool (var_pool);
   free_alloc_pool (loc_chain_pool);
-  htab_delete (changed_variables);
+  free_alloc_pool (shared_hash_pool);
 }
 
 /* The entry point to variable tracking pass.  */
--- libiberty/hashtab.c	(revision 148758)
+++ libiberty/hashtab.c	(revision 148760)
@@ -759,7 +759,8 @@ htab_traverse_noresize (htab_t htab, hta
 void
 htab_traverse (htab_t htab, htab_trav callback, PTR info)
 {
-  if (htab_elements (htab) * 8 < htab_size (htab))
+  size_t size = htab_size (htab);
+  if (htab_elements (htab) * 8 < size && size > 32)
     htab_expand (htab);
 
   htab_traverse_noresize (htab, callback, info);

gcc44-rh503816-2.patch:
 var-tracking.c |  318 +++++++++++++++++++++++++++++++--------------------------
 1 file changed, 176 insertions(+), 142 deletions(-)

--- NEW FILE gcc44-rh503816-2.patch ---
2009-06-23  Jakub Jelinek  <jakub at redhat.com>

	* var-tracking.c (unshare_variable): Force initialized to
	be VAR_INIT_STATUS_INITIALIZED unless flag_var_tracking_uninit.
	(set_variable_part): Likewise.
	(struct variable_union_info): Remove pos_src field.
	(vui_vec, vui_allocated): New variables.
	(variable_union): Pass VAR_INIT_STATUS_UNKNOWN to unshare_variable
	unconditionally.  Avoid XCVECNEW/free for every sorting, for dst_l
	== 1 use a simpler sorting algorithm.  Compute pos field right
	away, don't fill in pos_src.  For dst_l == 2 avoid qsort.
	Avoid quadratic comparison if !flag_var_tracking_uninit.
	(variable_canonicalize): Pass VAR_INIT_STATUS_UNKNOWN to
	unshare_variable unconditionally.   
	(dataflow_set_different_2): Removed.
	(dataflow_set_different): Don't traverse second hash table.
	(compute_bb_dataflow): Pass VAR_INIT_STATUS_UNINITIALIZED
	unconditionally to var_reg_set or var_mem_set.
	(emit_notes_in_bb): Likewise.
	(delete_variable_part): Pass VAR_INIT_STATUS_UNKNOWN to
	unshare_variable.
	(emit_note_insn_var_location): Don't set initialized to
	VAR_INIT_STATUS_INITIALIZED early.
	(vt_finalize): Free vui_vec if needed, clear vui_vec and
	vui_allocated.

--- gcc/var-tracking.c	(revision 148851)
+++ gcc/var-tracking.c	(revision 148852)
@@ -347,7 +347,6 @@ static void dataflow_set_union (dataflow
 static bool variable_part_different_p (variable_part *, variable_part *);
 static bool variable_different_p (variable, variable, bool);
 static int dataflow_set_different_1 (void **, void *);
-static int dataflow_set_different_2 (void **, void *);
 static bool dataflow_set_different (dataflow_set *, dataflow_set *);
 static void dataflow_set_destroy (dataflow_set *);
 
@@ -878,6 +877,9 @@ unshare_variable (dataflow_set *set, var
   var->refcount--;
   new_var->n_var_parts = var->n_var_parts;
 
+  if (! flag_var_tracking_uninit)
+    initialized = VAR_INIT_STATUS_INITIALIZED;
+
   for (i = 0; i < var->n_var_parts; i++)
     {
       location_chain node;
@@ -1202,11 +1204,14 @@ struct variable_union_info
   /* The sum of positions in the input chains.  */
   int pos;
 
-  /* The position in the chains of SRC and DST dataflow sets.  */
-  int pos_src;
+  /* The position in the chain of DST dataflow set.  */
   int pos_dst;
 };
 
+/* Buffer for location list sorting and its allocated size.  */
+static struct variable_union_info *vui_vec;
+static int vui_allocated;
+
 /* Compare function for qsort, order the structures by POS element.  */
 
 static int
@@ -1263,14 +1268,9 @@ variable_union (void **slot, void *data)
 	}
       if (k < src->n_var_parts)
 	{
-	  enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
-	  
-	  if (! flag_var_tracking_uninit)
-	    status = VAR_INIT_STATUS_INITIALIZED;
-
 	  if (dstp)
 	    *dstp = (void *) src;
-	  unshare_variable (set, src, status);
+	  unshare_variable (set, src, VAR_INIT_STATUS_UNKNOWN);
 	}
       else
 	{
@@ -1311,13 +1311,7 @@ variable_union (void **slot, void *data)
 
   if ((dst->refcount > 1 || shared_hash_shared (set->vars))
       && dst->n_var_parts != k)
-    {
-      enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
-      
-      if (! flag_var_tracking_uninit)
-	status = VAR_INIT_STATUS_INITIALIZED;
-      dst = unshare_variable (set, dst, status);
-    }
+    dst = unshare_variable (set, dst, VAR_INIT_STATUS_UNKNOWN);
 
   i = src->n_var_parts - 1;
   j = dst->n_var_parts - 1;
@@ -1366,70 +1360,152 @@ variable_union (void **slot, void *data)
 	  dst_l = 0;
 	  for (node = dst->var_part[j].loc_chain; node; node = node->next)
 	    dst_l++;
-	  vui = XCNEWVEC (struct variable_union_info, src_l + dst_l);
 
-	  /* Fill in the locations from DST.  */
-	  for (node = dst->var_part[j].loc_chain, jj = 0; node;
-	       node = node->next, jj++)
+	  if (dst_l == 1)
 	    {
-	      vui[jj].lc = node;
-	      vui[jj].pos_dst = jj;
+	      /* The most common case, much simpler, no qsort is needed.  */
+	      location_chain dstnode = dst->var_part[j].loc_chain;
+	      dst->var_part[k].loc_chain = dstnode;
+	      dst->var_part[k].offset = dst->var_part[j].offset;
+	      node2 = dstnode;
+	      for (node = src->var_part[i].loc_chain; node; node = node->next)
+		if (!((REG_P (dstnode->loc)
+		       && REG_P (node->loc)
+		       && REGNO (dstnode->loc) == REGNO (node->loc))
+		      || rtx_equal_p (dstnode->loc, node->loc)))
+		  {
+		    location_chain new_node;
 
-	      /* Value larger than a sum of 2 valid positions.  */
-	      vui[jj].pos_src = src_l + dst_l;
+		    /* Copy the location from SRC.  */
+		    new_node = (location_chain) pool_alloc (loc_chain_pool);
+		    new_node->loc = node->loc;
+		    new_node->init = node->init;
+		    if (!node->set_src || MEM_P (node->set_src))
+		      new_node->set_src = NULL;
+		    else
+		      new_node->set_src = node->set_src;
+		    node2->next = new_node;
+		    node2 = new_node;
+		  }
+	      node2->next = NULL;
 	    }
-
-	  /* Fill in the locations from SRC.  */
-	  n = dst_l;
-	  for (node = src->var_part[i].loc_chain, ii = 0; node;
-	       node = node->next, ii++)
+	  else
 	    {
-	      /* Find location from NODE.  */
-	      for (jj = 0; jj < dst_l; jj++)
+	      if (src_l + dst_l > vui_allocated)
 		{
-		  if ((REG_P (vui[jj].lc->loc)
-		       && REG_P (node->loc)
-		       && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
-		      || rtx_equal_p (vui[jj].lc->loc, node->loc))
-		    {
-		      vui[jj].pos_src = ii;
-		      break;
-		    }
+		  vui_allocated = MAX (vui_allocated * 2, src_l + dst_l);
+		  vui_vec = XRESIZEVEC (struct variable_union_info, vui_vec,
+					vui_allocated);
 		}
-	      if (jj >= dst_l)	/* The location has not been found.  */
+	      vui = vui_vec;
+
+	      /* Fill in the locations from DST.  */
+	      for (node = dst->var_part[j].loc_chain, jj = 0; node;
+		   node = node->next, jj++)
 		{
-		  location_chain new_node;
+		  vui[jj].lc = node;
+		  vui[jj].pos_dst = jj;
 
-		  /* Copy the location from SRC.  */
-		  new_node = (location_chain) pool_alloc (loc_chain_pool);
-		  new_node->loc = node->loc;
-		  new_node->init = node->init;
-		  if (!node->set_src || MEM_P (node->set_src))
-		    new_node->set_src = NULL;
-		  else
-		    new_node->set_src = node->set_src;
-		  vui[n].lc = new_node;
-		  vui[n].pos_src = ii;
-		  vui[n].pos_dst = src_l + dst_l;
-		  n++;
+		  /* Pos plus value larger than a sum of 2 valid positions.  */
+		  vui[jj].pos = jj + src_l + dst_l;
 		}
-	    }
 
-	  for (ii = 0; ii < src_l + dst_l; ii++)
-	    vui[ii].pos = vui[ii].pos_src + vui[ii].pos_dst;
+	      /* Fill in the locations from SRC.  */
+	      n = dst_l;
+	      for (node = src->var_part[i].loc_chain, ii = 0; node;
+		   node = node->next, ii++)
+		{
+		  /* Find location from NODE.  */
+		  for (jj = 0; jj < dst_l; jj++)
+		    {
+		      if ((REG_P (vui[jj].lc->loc)
+			   && REG_P (node->loc)
+			   && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
+			  || rtx_equal_p (vui[jj].lc->loc, node->loc))
+			{
+			  vui[jj].pos = jj + ii;
+			  break;
+			}
+		    }
+		  if (jj >= dst_l)	/* The location has not been found.  */
+		    {
+		      location_chain new_node;
 
-	  qsort (vui, n, sizeof (struct variable_union_info),
-		 variable_union_info_cmp_pos);
+		      /* Copy the location from SRC.  */
+		      new_node = (location_chain) pool_alloc (loc_chain_pool);
+		      new_node->loc = node->loc;
+		      new_node->init = node->init;
+		      if (!node->set_src || MEM_P (node->set_src))
+			new_node->set_src = NULL;
+		      else
+			new_node->set_src = node->set_src;
+		      vui[n].lc = new_node;
+		      vui[n].pos_dst = src_l + dst_l;
+		      vui[n].pos = ii + src_l + dst_l;
+		      n++;
+		    }
+		}
 
-	  /* Reconnect the nodes in sorted order.  */
-	  for (ii = 1; ii < n; ii++)
-	    vui[ii - 1].lc->next = vui[ii].lc;
-	  vui[n - 1].lc->next = NULL;
+	      if (dst_l == 2)
+		{
+		  /* Special case still very common case.  For dst_l == 2
+		     all entries dst_l ... n-1 are sorted, with for i >= dst_l
+		     vui[i].pos == i + src_l + dst_l.  */
+		  if (vui[0].pos > vui[1].pos)
+		    {
+		      /* Order should be 1, 0, 2... */
+		      dst->var_part[k].loc_chain = vui[1].lc;
+		      vui[1].lc->next = vui[0].lc;
+		      if (n >= 3)
+			{
+			  vui[0].lc->next = vui[2].lc;
+			  vui[n - 1].lc->next = NULL;
+			}
+		      else
+			vui[0].lc->next = NULL;
+		      ii = 3;
+		    }
+		  else
+		    {
+		      dst->var_part[k].loc_chain = vui[0].lc;
+		      if (n >= 3 && vui[2].pos < vui[1].pos)
+			{
+			  /* Order should be 0, 2, 1, 3... */
+			  vui[0].lc->next = vui[2].lc;
+			  vui[2].lc->next = vui[1].lc;
+			  if (n >= 4)
+			    {
+			      vui[1].lc->next = vui[3].lc;
+			      vui[n - 1].lc->next = NULL;
+			    }
+			  else
+			    vui[1].lc->next = NULL;
+			  ii = 4;
+			}
+		      else
+			{
+			  /* Order should be 0, 1, 2... */
+			  ii = 1;
+			  vui[n - 1].lc->next = NULL;
+			}
+		    }
+		  for (; ii < n; ii++)
+		    vui[ii - 1].lc->next = vui[ii].lc;
+		}
+	      else
+		{
+		  qsort (vui, n, sizeof (struct variable_union_info),
+			 variable_union_info_cmp_pos);
 
-	  dst->var_part[k].loc_chain = vui[0].lc;
-	  dst->var_part[k].offset = dst->var_part[j].offset;
+		  /* Reconnect the nodes in sorted order.  */
+		  for (ii = 1; ii < n; ii++)
+		    vui[ii - 1].lc->next = vui[ii].lc;
+		  vui[n - 1].lc->next = NULL;
+		  dst->var_part[k].loc_chain = vui[0].lc;
+		}
 
-	  free (vui);
+	      dst->var_part[k].offset = dst->var_part[j].offset;
+	    }
 	  i--;
 	  j--;
 	}
@@ -1477,17 +1553,18 @@ variable_union (void **slot, void *data)
 	dst->var_part[k].cur_loc = NULL;
     }
 
-  for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
-    {
-      location_chain node, node2;
-      for (node = src->var_part[i].loc_chain; node; node = node->next)
-	for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
-	  if (rtx_equal_p (node->loc, node2->loc))
-	    {
-	      if (node->init > node2->init)
-		node2->init = node->init;
-	    }
-    }
+  if (flag_var_tracking_uninit)
+    for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
+      {
+	location_chain node, node2;
+	for (node = src->var_part[i].loc_chain; node; node = node->next)
+	  for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
+	    if (rtx_equal_p (node->loc, node2->loc))
+	      {
+		if (node->init > node2->init)
+		  node2->init = node->init;
+	      }
+      }
 
   /* Continue traversing the hash table.  */
   return 1;
@@ -1522,14 +1599,7 @@ variable_canonicalize (void **slot, void
 	}
     }
   if (k < src->n_var_parts)
-    {
-      enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
-
-      if (! flag_var_tracking_uninit)
-	status = VAR_INIT_STATUS_INITIALIZED;
-
-      unshare_variable (set, src, status);
-    }
+    unshare_variable (set, src, VAR_INIT_STATUS_UNKNOWN);
   return 1;
 }
 
@@ -1650,34 +1720,6 @@ dataflow_set_different_1 (void **slot, v
   return 1;
 }
 
-/* Compare variable *SLOT with the same variable in hash table DATA
-   and set DATAFLOW_SET_DIFFERENT_VALUE if they are different.  */
-
-static int
-dataflow_set_different_2 (void **slot, void *data)
-{
-  htab_t htab = (htab_t) data;
-  variable var1, var2;
-
-  var1 = *(variable *) slot;
-  var2 = (variable) htab_find_with_hash (htab, var1->decl,
-			      VARIABLE_HASH_VAL (var1->decl));
-  if (!var2)
-    {
-      dataflow_set_different_value = true;
-
-      /* Stop traversing the hash table.  */
-      return 0;
-    }
-
-  /* If both variables are defined they have been already checked for
-     equivalence.  */
-  gcc_assert (!variable_different_p (var1, var2, false));
-
-  /* Continue traversing the hash table.  */
-  return 1;
-}
-
 /* Return true if dataflow sets OLD_SET and NEW_SET differ.  */
 
 static bool
@@ -1694,14 +1736,9 @@ dataflow_set_different (dataflow_set *ol
 
   htab_traverse (shared_hash_htab (old_set->vars), dataflow_set_different_1,
 		 shared_hash_htab (new_set->vars));
-  if (!dataflow_set_different_value)
-    {
-      /* We have compared the variables which are in both hash tables
-	 so now only check whether there are some variables in NEW_SET->VARS
-	 which are not in OLD_SET->VARS.  */
-      htab_traverse (shared_hash_htab (new_set->vars), dataflow_set_different_2,
-		     shared_hash_htab (old_set->vars));
-    }
+  /* No need to traverse the second hashtab, if both have the same number
+     of elements and the second one had all entries found in the first one,
+     then it can't have any extra entries.  */
   return dataflow_set_different_value;
 }
 
@@ -2215,15 +2252,11 @@ compute_bb_dataflow (basic_block bb)
 	  case MO_USE:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
-	      enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
-
-	      if (! flag_var_tracking_uninit)
-		status = VAR_INIT_STATUS_INITIALIZED;
 
 	      if (GET_CODE (loc) == REG)
-		var_reg_set (out, loc, status, NULL);
+		var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
 	      else if (GET_CODE (loc) == MEM)
-		var_mem_set (out, loc, status, NULL);
+		var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
 	    }
 	    break;
 
@@ -2262,10 +2295,12 @@ compute_bb_dataflow (basic_block bb)
 	      if (! flag_var_tracking_uninit)
 		src_status = VAR_INIT_STATUS_INITIALIZED;
 	      else
-		src_status = find_src_status (in, set_src);
+		{
+		  src_status = find_src_status (in, set_src);
 
-	      if (src_status == VAR_INIT_STATUS_UNKNOWN)
-		src_status = find_src_status (out, set_src);
+		  if (src_status == VAR_INIT_STATUS_UNKNOWN)
+		    src_status = find_src_status (out, set_src);
+		}
 
 	      set_src = find_src_set_src (in, set_src);
 
@@ -2609,6 +2644,9 @@ set_variable_part (dataflow_set *set, rt
   variable var;
   void **slot = shared_hash_find_slot (set->vars, decl);
 
+  if (! flag_var_tracking_uninit)
+    initialized = VAR_INIT_STATUS_INITIALIZED;
+
   if (!slot || !*slot)
     {
       if (!slot)
@@ -2815,10 +2853,8 @@ delete_variable_part (dataflow_set *set,
 		       && REGNO (node->loc) == REGNO (loc))
 		      || rtx_equal_p (node->loc, loc))
 		    {
-		      enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
-		      if (! flag_var_tracking_uninit)
-			status = VAR_INIT_STATUS_INITIALIZED;
-		      var = unshare_variable (set, var, status);
+		      var = unshare_variable (set, var,
+					      VAR_INIT_STATUS_UNKNOWN);
 		      break;
 		    }
 		}
@@ -2893,9 +2929,6 @@ emit_note_insn_var_location (void **varp
 
   gcc_assert (var->decl);
 
-  if (! flag_var_tracking_uninit)
-    initialized = VAR_INIT_STATUS_INITIALIZED;
-
   complete = true;
   last_limit = 0;
   n_var_parts = 0;
@@ -3148,14 +3181,11 @@ emit_notes_in_bb (basic_block bb)
 	  case MO_USE:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
-      
-	      enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
-	      if (! flag_var_tracking_uninit)
-		status = VAR_INIT_STATUS_INITIALIZED;
+
 	      if (GET_CODE (loc) == REG)
-		var_reg_set (&set, loc, status, NULL);
+		var_reg_set (&set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
 	      else
-		var_mem_set (&set, loc, status, NULL);
+		var_mem_set (&set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
 
 	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
 	    }
@@ -3553,6 +3583,10 @@ vt_finalize (void)
   free_alloc_pool (var_pool);
   free_alloc_pool (loc_chain_pool);
   free_alloc_pool (shared_hash_pool);
+  if (vui_vec)
+    free (vui_vec);
+  vui_vec = NULL;
+  vui_allocated = 0;
 }
 
 /* The entry point to variable tracking pass.  */

gcc44-unique-object.patch:
 config.in      |    6 ++++++
 config/elfos.h |   49 +++++++++++++++++++++++++++++++------------------
 configure      |   38 ++++++++++++++++++++++++++++++++++++++
 configure.ac   |    6 ++++++
 4 files changed, 81 insertions(+), 18 deletions(-)

--- NEW FILE gcc44-unique-object.patch ---
2009-07-22  Jason Merrill  <jason at redhat.com>

	* config/elfos.h (ASM_DECLARE_OBJECT_NAME): Use gnu_unique_object
	type if available.
	* configure.ac: Test for it.
	* configure, config.in: Regenerate.

--- gcc/config/elfos.h.jj	2009-04-14 15:51:24.000000000 +0200
+++ gcc/config/elfos.h	2009-07-23 09:25:46.000000000 +0200
@@ -289,24 +289,37 @@ see the files COPYING3 and COPYING.RUNTI
 
 /* Write the extra assembler code needed to declare an object properly.  */
 
-#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)		\
-  do								\
-    {								\
-      HOST_WIDE_INT size;					\
-								\
-      ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");		\
-								\
-      size_directive_output = 0;				\
-      if (!flag_inhibit_size_directive				\
-	  && (DECL) && DECL_SIZE (DECL))			\
-	{							\
-	  size_directive_output = 1;				\
-	  size = int_size_in_bytes (TREE_TYPE (DECL));		\
-	  ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size);		\
-	}							\
-								\
-      ASM_OUTPUT_LABEL (FILE, NAME);				\
-    }								\
+#ifdef HAVE_GAS_GNU_UNIQUE_OBJECT
+#define USE_GNU_UNIQUE_OBJECT 1
+#else
+#define USE_GNU_UNIQUE_OBJECT 0
+#endif
+
+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)			\
+  do									\
+    {									\
+      HOST_WIDE_INT size;						\
+									\
+      /* For template static data member instantiations or		\
+	 inline fn local statics, use gnu_unique_object so that		\
+	 they will be combined even under RTLD_LOCAL.  */		\
+      if (USE_GNU_UNIQUE_OBJECT						\
+	  && !DECL_ARTIFICIAL (DECL) && DECL_ONE_ONLY (DECL))		\
+	ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "gnu_unique_object");	\
+      else								\
+	ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");		\
+									\
+      size_directive_output = 0;					\
+      if (!flag_inhibit_size_directive					\
+	  && (DECL) && DECL_SIZE (DECL))				\
+	{								\
+	  size_directive_output = 1;					\
+	  size = int_size_in_bytes (TREE_TYPE (DECL));			\
+	  ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size);			\
+	}								\
+									\
+      ASM_OUTPUT_LABEL (FILE, NAME);					\
+    }									\
   while (0)
 
 /* Output the size directive for a decl in rest_of_decl_compilation
--- gcc/configure.ac.jj	2009-03-28 09:53:59.000000000 +0100
+++ gcc/configure.ac	2009-07-23 09:25:46.000000000 +0200
@@ -3299,6 +3299,12 @@ gcc_GAS_CHECK_FEATURE([.lcomm with align
 [AC_DEFINE(HAVE_GAS_LCOMM_WITH_ALIGNMENT, 1,
   [Define if your assembler supports .lcomm with an alignment field.])])
 
+gcc_GAS_CHECK_FEATURE([gnu_unique_object], gcc_cv_as_gnu_unique_object,
+ [elf,2,19,52],,
+[.type foo, @gnu_unique_object],,
+[AC_DEFINE(HAVE_GAS_GNU_UNIQUE_OBJECT, 1,
+  [Define if your assembler supports @gnu_unique_object.])])
+
 AC_CACHE_CHECK([assembler for tolerance to line number 0],
  [gcc_cv_as_line_zero],
  [gcc_cv_as_line_zero=no
--- gcc/configure.jj	2009-03-28 09:53:37.000000000 +0100
+++ gcc/configure	2009-07-23 09:26:52.000000000 +0200
@@ -24288,6 +24288,44 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking assembler for gnu_unique_object" >&5
+echo $ECHO_N "checking assembler for gnu_unique_object... $ECHO_C" >&6
+if test "${gcc_cv_as_gnu_unique_object+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  gcc_cv_as_gnu_unique_object=no
+    if test $in_tree_gas = yes; then
+    if test $in_tree_gas_is_elf = yes \
+  && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 52`
+  then gcc_cv_as_gnu_unique_object=yes
+fi
+  elif test x$gcc_cv_as != x; then
+    echo '.type foo, @gnu_unique_object' > conftest.s
+    if { ac_try='$gcc_cv_as  -o conftest.o conftest.s >&5'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }
+    then
+	gcc_cv_as_gnu_unique_object=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_gnu_unique_object" >&5
+echo "${ECHO_T}$gcc_cv_as_gnu_unique_object" >&6
+if test $gcc_cv_as_gnu_unique_object = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GAS_GNU_UNIQUE_OBJECT 1
+_ACEOF
+
+fi
+
 echo "$as_me:$LINENO: checking assembler for tolerance to line number 0" >&5
 echo $ECHO_N "checking assembler for tolerance to line number 0... $ECHO_C" >&6
 if test "${gcc_cv_as_line_zero+set}" = set; then
--- gcc/config.in.jj	2009-02-16 22:48:20.000000000 +0100
+++ gcc/config.in	2009-07-23 09:26:56.000000000 +0200
@@ -845,6 +845,12 @@
 #endif
 
 
+/* Define if your assembler supports @gnu_unique_object. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_GAS_GNU_UNIQUE_OBJECT
+#endif
+
+
 /* Define if your assembler and linker support .hidden. */
 #undef HAVE_GAS_HIDDEN
 

gcc44-unwind-debug-hook.patch:
 unwind-dw2.c |   27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

--- NEW FILE gcc44-unwind-debug-hook.patch ---
2009-05-27  Tom Tromey  <tromey at redhat.com>

	* unwind-dw2.c (_Unwind_DebugHook): New function.
	(uw_install_context): Call _Unwind_DebugHook.

--- gcc/unwind-dw2.c	(revision 147933)
+++ gcc/unwind-dw2.c	(revision 147934)
@@ -1473,18 +1473,31 @@ uw_init_context_1 (struct _Unwind_Contex
   context->ra = __builtin_extract_return_addr (outer_ra);
 }
 
+static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__));
+
+/* This function is called during unwinding.  It is intended as a hook
+   for a debugger to intercept exceptions.  CFA is the CFA of the
+   target frame.  HANDLER is the PC to which control will be
+   transferred.  */
+static void
+_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
+		   void *handler __attribute__ ((__unused__)))
+{
+  asm ("");
+}
 
 /* Install TARGET into CURRENT so that we can return to it.  This is a
    macro because __builtin_eh_return must be invoked in the context of
    our caller.  */
 
-#define uw_install_context(CURRENT, TARGET)				 \
-  do									 \
-    {									 \
-      long offset = uw_install_context_1 ((CURRENT), (TARGET));		 \
-      void *handler = __builtin_frob_return_addr ((TARGET)->ra);	 \
-      __builtin_eh_return (offset, handler);				 \
-    }									 \
+#define uw_install_context(CURRENT, TARGET)				\
+  do									\
+    {									\
+      long offset = uw_install_context_1 ((CURRENT), (TARGET));		\
+      void *handler = __builtin_frob_return_addr ((TARGET)->ra);	\
+      _Unwind_DebugHook ((TARGET)->cfa, handler);			\
+      __builtin_eh_return (offset, handler);				\
+    }									\
   while (0)
 
 static long


Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/.cvsignore,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -p -r1.4 -r1.5
--- .cvsignore	23 Mar 2009 10:56:41 -0000	1.4
+++ .cvsignore	25 Aug 2009 20:26:27 -0000	1.5
@@ -1 +1 @@
-gcc-4.4.0-20090319.tar.bz2
+gcc-4.4.1-20090818.tar.bz2

gcc44-hack.patch:
 gcc/ada/make.adb   |    1 +
 libada/Makefile.in |   30 ++++++++++++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

Index: gcc44-hack.patch
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/gcc44-hack.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- gcc44-hack.patch	20 Feb 2009 19:59:34 -0000	1.1
+++ gcc44-hack.patch	25 Aug 2009 20:26:27 -0000	1.2
@@ -1,8 +1,8 @@
 --- libada/Makefile.in.jj	2009-01-14 12:07:35.000000000 +0100
 +++ libada/Makefile.in	2009-01-15 14:25:33.000000000 +0100
-@@ -66,17 +66,39 @@ target_noncanonical:=@target_noncanonica
- version := $(shell cat $(srcdir)/../gcc/BASE-VER)
+@@ -67,17 +67,39 @@ version := $(shell cat $(srcdir)/../gcc/
  libsubdir := $(libdir)/gcc/$(target_noncanonical)/$(version)$(MULTISUBDIR)
+ ADA_RTS_DIR=$(GCC_DIR)/ada/rts$(subst /,_,$(MULTISUBDIR))
  
 +DEFAULTMULTIFLAGS :=
 +ifeq ($(MULTISUBDIR),)
@@ -43,7 +43,7 @@
          "TARGET_LIBGCC2_CFLAGS=$(TARGET_LIBGCC2_CFLAGS)" \
          "THREAD_KIND=$(THREAD_KIND)" \
          "TRACE=$(TRACE)" \
-@@ -87,7 +109,7 @@ LIBADA_FLAGS_TO_PASS = \
+@@ -88,7 +110,7 @@ LIBADA_FLAGS_TO_PASS = \
          "exeext=.exeext.should.not.be.used " \
  	'CC=the.host.compiler.should.not.be.needed' \
  	"GCC_FOR_TARGET=$(CC)" \

gcc44-power7-2.patch:
 rs6000.c  |  162 +++++++++++++++++++++++++++++++++++++++++++++++---------------
 vector.md |   22 +++++++-
 2 files changed, 144 insertions(+), 40 deletions(-)

Index: gcc44-power7-2.patch
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/gcc44-power7-2.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- gcc44-power7-2.patch	23 Mar 2009 10:56:41 -0000	1.1
+++ gcc44-power7-2.patch	25 Aug 2009 20:26:28 -0000	1.2
@@ -1,1369 +1,267 @@
-2009-03-13  Michael Meissner  <meissner at linux.vnet.ibm.com>
+2009-04-14  Michael Meissner  <meissner at linux.vnet.ibm.com>
 
-	PR target/39457
-	* config/rs6000/rs6000.opt (-mdisallow-float-in-lr-ctr): Add
-	temporary debug switch.
+	* config/rs6000/rs6000.c (rs6000_secondary_reload_inner): Handle
+	more possible combinations of addresses.
 
-	* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Revert
-	behavior of disallowing 
-
-2009-03-13  Michael Meissner  <meissner at linux.vnet.ibm.com>
-
-	* config/rs6000/vector.md (vec_extract_evenv2df): Delete, insn
-	causes problems in building spec 2006.
-	(vec_extract_oddv2df): Ditto.
-	(vec_pack_trunc_v2df): New expanders for VSX vectorized
-	conversions.
-	(vec_pack_sfix_trunc_v2df): Ditto.
-	(vec_pack_ufix_trunc_v2df): Ditto.
-	(vec_unpacks_hi_v4sf): Ditto.
-	(vec_unpacks_lo_v4sf): Ditto.
-	(vec_unpacks_float_hi_v4si): Ditto.
-	(vec_unpacks_float_lo_v4si): Ditto.
-	(vec_unpacku_float_hi_v4si): Ditto.
-	(vec_unpacku_float_lo_v4si): Ditto.
-
-	* config/rs6000/rs6000-protos.h (rs6000_vector_secondary_reload):
-	Declaration for new target hook.
-
-	* config/rs6000/rs6000.c (TARGET_SECONDARY_RELOAD): Add new target
-	hook for eventually fixing up the memory references for Altivec
-	and VSX reloads to be reg+reg instead of reg+offset.  Right now,
-	this is a stub function that prints debug information if
-	-mdebug=addr and then calls default_secondary_reload.
-	(rs6000_secondary_reload): Ditto.
-	(rs6000_vector_secondary_reload): Ditto.
-	(rs6000_builtin_conversion): Add support for V2DI/V2DF
-	conversions.
-	(rs6000_legitimate_offset_address_p): Test for the vector unit
-	doing the memory references.
-	(rs6000_legimize_reload_address): Ditto.
-	(rs6000_legitimize_address): Print extra \n if -mdebug=addr.
-	(rs6000_legitimize_reload_address): Ditto.
-	(rs6000_legitimate_address): Ditto.
-	(rs6000_mode_dependent_address): Ditto.
-	(bdesc_2arg): Add VSX builtins.
-	(bdesc_abs): Ditto.
-	(bdesc_1arg): Ditto.
-	(altivec_init_builtins): Ditto.
-	(rs6000_secondary_memory_needed_rtx): Add debug support if
-	-mdebug=addr.
-	(rs6000_preferred_reload_class): Ditto.
-	(rs6000_secondary_memory_needed): Ditto.
-	(rs6000_secondary_reload_class): Ditto.
-	(rs6000_cannot_change_mode_class): Ditto.
-
-	* config/rs6000/vsx.md (UNSPEC_VSX_*): Add unspecs for VSX
-	conversions.
-	(vsx_nabs<mode>): Add generator function.
-	(vsx_float<VSi><mode>2): Ditto.
-	(vsx_floatuns<VSi><mode>2): Ditto.
-	(vsx_xxmrghw): Ditto.
-	(vsx_xxmrglw): Ditto.
-	(vsx_xvcvdpsp): New VSX vector conversion insn.
-	(vsx_xvcvdpsxws): Ditto.
-	(vsx_xvcvdpuxws): Ditto.
-	(vsx_xvcvspdp): Ditto.
-	(vsx_xvcvsxwdp): Ditto.
-	(vsx_xvcvuxwdp): Ditto.
-	(vsx_reload_*): New insns for reload support.
-
-	* config/rs6000/rs6000.h: Fix a comment.
-
-	* config/rs6000/altivec.md (altivec_reload_*): New insns for
-	reload support.
-
-	* config/rs6000/rs6000.md (ptrsize): New mode attribute for the
-	pointer size.
-
-2009-03-10  Michael Meissner  <meissner at linux.vnet.ibm.com>
-
-	* config/rs6000/vsx.md (vsx_concat_v2df): Add explicit 'f'
-	register class for scalar data, correct uses of the xxpermdi
-	instruction.
-	(vsx_set_v2df): Ditto.
-	(vsx_extract_v2df): Ditto.
-	(vsx_xxpermdi): Ditto.
-	(vsx_splatv2df): Ditto.
-	(vsx_xxmrghw): Use wf instead of v constraints.
-	(vsx_xxmrglw): Ditto.
-testsuite/
-2009-03-13  Michael Meissner  <meissner at linux.vnet.ibm.com>
-
-	PR target/39457
-	* gcc.target/powerpc/pr39457.c: New test for PR39457.
-
-2009-03-13  Michael Meissner  <meissner at linux.vnet.ibm.com>
-
-	* gcc.target/powerpc/vsx-builtin-1.c: New test for builtins.
-	* gcc.target/powerpc/vsx-builtin-2.c: Ditto.
-
---- gcc/config/rs6000/vector.md	(revision 144758)
-+++ gcc/config/rs6000/vector.md	(revision 144843)
-@@ -496,23 +496,122 @@ (define_expand "vec_interleave_lowv2df"
-   "VECTOR_UNIT_VSX_P (V2DFmode)"
-   "")
- 
--;; For 2 element vectors, even/odd is the same as high/low
--(define_expand "vec_extract_evenv2df"
--  [(set (match_operand:V2DF 0 "vfloat_operand" "")
--	(vec_concat:V2DF
--	 (vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "")
--			(parallel [(const_int 0)]))
--	 (vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "")
--			(parallel [(const_int 0)]))))]
--  "VECTOR_UNIT_VSX_P (V2DFmode)"
--  "")
-+
-+;; Convert double word types to single word types
-+(define_expand "vec_pack_trunc_v2df"
-+  [(match_operand:V4SF 0 "vsx_register_operand" "")
-+   (match_operand:V2DF 1 "vsx_register_operand" "")
-+   (match_operand:V2DF 2 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
-+{
-+  rtx r1 = gen_reg_rtx (V4SFmode);
-+  rtx r2 = gen_reg_rtx (V4SFmode);
- 
--(define_expand "vec_extract_oddv2df"
--  [(set (match_operand:V2DF 0 "vfloat_operand" "")
--	(vec_concat:V2DF
--	 (vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "")
--			(parallel [(const_int 1)]))
--	 (vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "")
--			(parallel [(const_int 1)]))))]
--  "VECTOR_UNIT_VSX_P (V2DFmode)"
--  "")
-+  emit_insn (gen_vsx_xvcvdpsp (r1, operands[1]));
-+  emit_insn (gen_vsx_xvcvdpsp (r2, operands[2]));
-+  emit_insn (gen_vec_extract_evenv4sf (operands[0], r1, r2));
-+  DONE;
-+})
-+
-+(define_expand "vec_pack_sfix_trunc_v2df"
-+  [(match_operand:V4SI 0 "vsx_register_operand" "")
-+   (match_operand:V2DF 1 "vsx_register_operand" "")
-+   (match_operand:V2DF 2 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
-+{
-+  rtx r1 = gen_reg_rtx (V4SImode);
-+  rtx r2 = gen_reg_rtx (V4SImode);
-+
-+  emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1]));
-+  emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2]));
-+  emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2));
-+  DONE;
-+})
-+
-+(define_expand "vec_pack_ufix_trunc_v2df"
-+  [(match_operand:V4SI 0 "vsx_register_operand" "")
-+   (match_operand:V2DF 1 "vsx_register_operand" "")
-+   (match_operand:V2DF 2 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
-+{
-+  rtx r1 = gen_reg_rtx (V4SImode);
-+  rtx r2 = gen_reg_rtx (V4SImode);
-+
-+  emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1]));
-+  emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2]));
-+  emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2));
-+  DONE;
-+})
-+
-+;; Convert single word types to double word
-+(define_expand "vec_unpacks_hi_v4sf"
-+  [(match_operand:V2DF 0 "vsx_register_operand" "")
-+   (match_operand:V4SF 1 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
-+{
-+  rtx reg = gen_reg_rtx (V4SFmode);
-+
-+  emit_insn (gen_vec_interleave_highv4sf (reg, operands[1], operands[1]));
-+  emit_insn (gen_vsx_xvcvspdp (operands[0], reg));
-+  DONE;
-+})
-+
-+(define_expand "vec_unpacks_lo_v4sf"
-+  [(match_operand:V2DF 0 "vsx_register_operand" "")
-+   (match_operand:V4SF 1 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
-+{
-+  rtx reg = gen_reg_rtx (V4SFmode);
-+
-+  emit_insn (gen_vec_interleave_lowv4sf (reg, operands[1], operands[1]));
-+  emit_insn (gen_vsx_xvcvspdp (operands[0], reg));
-+  DONE;
-+})
-+
-+(define_expand "vec_unpacks_float_hi_v4si"
-+  [(match_operand:V2DF 0 "vsx_register_operand" "")
-+   (match_operand:V4SI 1 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
-+{
-+  rtx reg = gen_reg_rtx (V4SImode);
-+
-+  emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1]));
-+  emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg));
-+  DONE;
-+})
-+
-+(define_expand "vec_unpacks_float_lo_v4si"
-+  [(match_operand:V2DF 0 "vsx_register_operand" "")
-+   (match_operand:V4SI 1 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
-+{
-+  rtx reg = gen_reg_rtx (V4SImode);
-+
-+  emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1]));
-+  emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg));
-+  DONE;
-+})
-+
-+(define_expand "vec_unpacku_float_hi_v4si"
-+  [(match_operand:V2DF 0 "vsx_register_operand" "")
-+   (match_operand:V4SI 1 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
-+{
-+  rtx reg = gen_reg_rtx (V4SImode);
-+
-+  emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1]));
-+  emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg));
-+  DONE;
-+})
-+
-+(define_expand "vec_unpacku_float_lo_v4si"
-+  [(match_operand:V2DF 0 "vsx_register_operand" "")
-+   (match_operand:V4SI 1 "vsx_register_operand" "")]
-+  "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
-+{
-+  rtx reg = gen_reg_rtx (V4SImode);
-+
-+  emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1]));
-+  emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg));
-+  DONE;
-+})
---- gcc/config/rs6000/rs6000-protos.h	(revision 144758)
-+++ gcc/config/rs6000/rs6000-protos.h	(revision 144843)
-@@ -72,6 +72,7 @@ extern bool rs6000_secondary_memory_need
- extern bool rs6000_cannot_change_mode_class (enum machine_mode,
- 					     enum machine_mode,
- 					     enum reg_class);
-+extern void rs6000_vector_secondary_reload (rtx, rtx, rtx, bool);
- extern int paired_emit_vector_cond_expr (rtx, rtx, rtx,
-                                          rtx, rtx, rtx);
- extern void paired_expand_vector_move (rtx operands[]);
---- gcc/config/rs6000/rs6000.opt	(revision 144845)
-+++ gcc/config/rs6000/rs6000.opt	(revision 144857)
-@@ -139,6 +139,9 @@ mvsx-scalar-memory
- Target Report Var(TARGET_VSX_SCALAR_MEMORY)
- If -mvsx, use VSX scalar memory reference instructions for scalar double (off by default)
- 
-+mdisallow-float-in-lr-ctr
-+Target Undocumented Var(TARGET_DISALLOW_FLOAT_IN_LR_CTR) Init(-1)
-+
- mupdate
- Target Report Var(TARGET_UPDATE) Init(1)
- Generate load/store with update instructions
---- gcc/config/rs6000/rs6000.c	(revision 144758)
-+++ gcc/config/rs6000/rs6000.c	(revision 144843)
-@@ -1004,6 +1004,10 @@ static rtx rs6000_emit_vector_compare (e
- 				       enum machine_mode);
- static tree rs6000_stack_protect_fail (void);
- 
-+static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
-+					       enum machine_mode,
-+					       struct secondary_reload_info *);
-+
- const int INSN_NOT_AVAILABLE = -1;
- static enum machine_mode rs6000_eh_return_filter_mode (void);
- 
-@@ -1333,6 +1337,9 @@ static const char alt_reg_names[][8] =
- #undef TARGET_INSTANTIATE_DECLS
- #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
- 
-+#undef TARGET_SECONDARY_RELOAD
-+#define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
-+
- struct gcc_target targetm = TARGET_INITIALIZER;
+	* config/rs6000/vector.md (vec_reload_and_plus_<mptrsize>): Allow
+	register+small constant in addition to register+register, and
+	restrict the insn to only match during reload and afterwards.
+	(vec_reload_and_reg_<mptrsize>): Allow for and of register
+	indirect to not generate insn not found message.
+
+--- gcc/config/rs6000/vector.md	(revision 146069)
++++ gcc/config/rs6000/vector.md	(revision 146118)
+@@ -129,14 +129,15 @@ (define_expand "reload_<VEC_R:mode>_<P:m
+ })
+ 
+ ;; Reload sometimes tries to move the address to a GPR, and can generate
+-;; invalid RTL for addresses involving AND -16.
++;; invalid RTL for addresses involving AND -16.  Allow addresses involving
++;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
+ 
+ (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
+   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
+ 	(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
+-		       (match_operand:P 2 "gpc_reg_operand" "r"))
++		       (match_operand:P 2 "reg_or_cint_operand" "rI"))
+ 	       (const_int -16)))]
+-  "TARGET_ALTIVEC || TARGET_VSX"
++  "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
+   "#"
+   "&& reload_completed"
+   [(set (match_dup 0)
+@@ -146,6 +147,21 @@ (define_insn_and_split "*vec_reload_and_
+ 		   (and:P (match_dup 0)
+ 			  (const_int -16)))
+ 	      (clobber:CC (scratch:CC))])])
++
++;; The normal ANDSI3/ANDDI3 won't match if reload decides to move an AND -16
++;; address to a register because there is no clobber of a (scratch), so we add
++;; it here.
++(define_insn_and_split "*vec_reload_and_reg_<mptrsize>"
++  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
++	(and:P (match_operand:P 1 "gpc_reg_operand" "r")
++	       (const_int -16)))]
++  "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
++  "#"
++  "&& reload_completed"
++  [(parallel [(set (match_dup 0)
++		   (and:P (match_dup 1)
++			  (const_int -16)))
++	      (clobber:CC (scratch:CC))])])
  
- /* Return number of consecutive hard regs needed starting at reg REGNO
-@@ -1448,10 +1448,16 @@ rs6000_hard_regno_mode_ok (int regno, en
-   if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
-     return 1;
+ ;; Generic floating point vector arithmetic support
+ (define_expand "add<mode>3"
+--- gcc/config/rs6000/rs6000.c	(revision 146069)
++++ gcc/config/rs6000/rs6000.c	(revision 146118)
+@@ -12574,6 +12574,11 @@ rs6000_secondary_reload_inner (rtx reg, 
+   enum reg_class rclass;
+   rtx addr;
+   rtx and_op2 = NULL_RTX;
++  rtx addr_op1;
++  rtx addr_op2;
++  rtx scratch_or_premodify = scratch;
++  rtx and_rtx;
++  rtx cc_clobber;
  
--  /* Don't allow anything but word sized integers (aka pointers) in CTR/LR.  You
--     really don't want to spill your floating point values to those
--     registers.  Also do it for the old MQ register in the power.  */
--  if (regno == CTR_REGNO || regno == LR_REGNO || regno == MQ_REGNO)
-+  /* Don't allow anything but word sized integers (aka pointers) in CTR/LR.
-+     You really don't want to spill your floating point values to those
-+     registers.  Also do it for the old MQ register in the power.
-+
-+     While this is desirable in theory, disabling float to go in LR/CTR does
-+     cause some regressions, so until they are taken care of, revert to the old
-+     behavior by default for most power systems, but enable it for power7.  */
-+  if ((TARGET_DISALLOW_FLOAT_IN_LR_CTR > 0
-+       || (TARGET_DISALLOW_FLOAT_IN_LR_CTR < 0 && TARGET_VSX))
-+      && (regno == CTR_REGNO || regno == LR_REGNO || regno == MQ_REGNO))
-     return (GET_MODE_CLASS (mode) == MODE_INT
- 	    && GET_MODE_SIZE (mode) <= UNITS_PER_WORD);
+   if (TARGET_DEBUG_ADDR)
+     {
+@@ -12595,7 +12600,8 @@ rs6000_secondary_reload_inner (rtx reg, 
  
-@@ -2447,6 +2454,14 @@ rs6000_builtin_conversion (enum tree_cod
-     case FIX_TRUNC_EXPR:
-       switch (TYPE_MODE (type))
- 	{
-+	case V2DImode:
-+	  if (!VECTOR_UNIT_VSX_P (V2DFmode))
-+	    return NULL_TREE;
+   switch (rclass)
+     {
+-      /* Move reg+reg addresses into a scratch register for GPRs.  */
++      /* GPRs can handle reg + small constant, all other addresses need to use
++	 the scratch register.  */
+     case GENERAL_REGS:
+     case BASE_REGS:
+       if (GET_CODE (addr) == AND)
+@@ -12603,70 +12609,152 @@ rs6000_secondary_reload_inner (rtx reg, 
+ 	  and_op2 = XEXP (addr, 1);
+ 	  addr = XEXP (addr, 0);
+ 	}
 +
-+	  return TYPE_UNSIGNED (type)
-+	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS]
-+	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
++      if (GET_CODE (addr) == PRE_MODIFY)
++	{
++	  scratch_or_premodify = XEXP (addr, 0);
++	  gcc_assert (REG_P (scratch_or_premodify));
++	  gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
++	  addr = XEXP (addr, 1);
++	}
 +
- 	case V4SImode:
- 	  if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
- 	    return NULL_TREE;
-@@ -2462,6 +2477,14 @@ rs6000_builtin_conversion (enum tree_cod
-     case FLOAT_EXPR:
-       switch (TYPE_MODE (type))
+       if (GET_CODE (addr) == PLUS
+ 	  && (!rs6000_legitimate_offset_address_p (TImode, addr, true)
+ 	      || and_op2 != NULL_RTX))
  	{
-+	case V2DImode:
-+	  if (!VECTOR_UNIT_VSX_P (V2DFmode))
-+	    return NULL_TREE;
-+
-+	  return TYPE_UNSIGNED (type)
-+	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDSP]
-+	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDSP];
+-	  if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
+-	      || GET_CODE (addr) == CONST_INT)
+-	    rs6000_emit_move (scratch, addr, GET_MODE (addr));
+-	  else
+-	    emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
+-	  addr = scratch;
++	  addr_op1 = XEXP (addr, 0);
++	  addr_op2 = XEXP (addr, 1);
++	  gcc_assert (legitimate_indirect_address_p (addr_op1, true));
++
++	  if (!REG_P (addr_op2)
++	      && (GET_CODE (addr_op2) != CONST_INT
++		  || !satisfies_constraint_I (addr_op2)))
++	    {
++	      rs6000_emit_move (scratch, addr_op2, Pmode);
++	      addr_op2 = scratch;
++	    }
 +
- 	case V4SImode:
- 	  if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
- 	    return NULL_TREE;
-@@ -2469,6 +2492,7 @@ rs6000_builtin_conversion (enum tree_cod
- 	  return TYPE_UNSIGNED (type)
- 	    ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
- 	    : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
++	  emit_insn (gen_rtx_SET (VOIDmode,
++				  scratch_or_premodify,
++				  gen_rtx_PLUS (Pmode,
++						addr_op1,
++						addr_op2)));
 +
- 	default:
- 	  return NULL_TREE;
++	  addr = scratch_or_premodify;
++	  scratch_or_premodify = scratch;
  	}
-@@ -4101,7 +4125,7 @@ rs6000_legitimate_offset_address_p (enum
-     case V2DImode:
-       /* AltiVec/VSX vector modes.  Only reg+reg addressing is valid and
- 	 constant offset zero should not occur due to canonicalization.  */
--      if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
-+      if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
- 	return false;
-       break;
- 
-@@ -4441,6 +4465,7 @@ rs6000_legitimize_address (rtx x, rtx ol
+-      else if (GET_CODE (addr) == PRE_MODIFY
+-	       && REG_P (XEXP (addr, 0))
+-	       && GET_CODE (XEXP (addr, 1)) == PLUS)
++      else if (!legitimate_indirect_address_p (addr, true)
++	       && !rs6000_legitimate_offset_address_p (TImode, addr, true))
+ 	{
+-	  emit_insn (gen_rtx_SET (VOIDmode, XEXP (addr, 0), XEXP (addr, 1)));
+-	  addr = XEXP (addr, 0);
++	  rs6000_emit_move (scratch_or_premodify, addr, Pmode);
++	  addr = scratch_or_premodify;
++	  scratch_or_premodify = scratch;
  	}
-       else
- 	fprintf (stderr, "NULL returned\n");
-+      fprintf (stderr, "\n");
-     }
+       break;
  
-   return ret;
-@@ -4776,8 +4801,7 @@ rs6000_legitimize_reload_address (rtx x,
- 	   && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
- 	   && GET_CODE (XEXP (x, 1)) == CONST_INT
- 	   && (INTVAL (XEXP (x, 1)) & 3) != 0
--	   && !ALTIVEC_VECTOR_MODE (mode)
--	   && !VSX_VECTOR_MODE (mode)
-+	   && VECTOR_MEM_NONE_P (mode)
- 	   && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
- 	   && TARGET_POWERPC64)
-     {
-@@ -4798,8 +4822,7 @@ rs6000_legitimize_reload_address (rtx x,
- 	   && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
- 				       || mode == DDmode || mode == TDmode
- 				       || mode == DImode))
--	   && !ALTIVEC_VECTOR_MODE (mode)
--	   && !VSX_VECTOR_MODE (mode))
-+	   && VECTOR_MEM_NONE_P (mode))
-     {
-       HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
-@@ -4843,6 +4866,7 @@ rs6000_legitimize_reload_address (rtx x,
- 	   /* Don't do this for TFmode or TDmode, since the result isn't
- 	      offsettable.  The same goes for DImode without 64-bit gprs and
- 	      DFmode and DDmode without fprs.  */
-+	   && VECTOR_MEM_NONE_P (mode)
- 	   && mode != TFmode
- 	   && mode != TDmode
- 	   && (mode != DImode || TARGET_POWERPC64)
-@@ -4918,6 +4942,8 @@ rs6000_legitimize_reload_address (rtx x,
- 	  fprintf (stderr, "New address:\n");
- 	  debug_rtx (ret);
++      /* Float/Altivec registers can only handle reg+reg addressing.  Move
++	 other addresses into a scratch register.  */
++    case FLOAT_REGS:
++    case VSX_REGS:
++    case ALTIVEC_REGS:
++
+       /* With float regs, we need to handle the AND ourselves, since we can't
+ 	 use the Altivec instruction with an implicit AND -16.  Allow scalar
+ 	 loads to float registers to use reg+offset even if VSX.  */
+-    case FLOAT_REGS:
+-    case VSX_REGS:
+-      if (GET_CODE (addr) == AND)
++      if (GET_CODE (addr) == AND
++	  && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16))
+ 	{
+ 	  and_op2 = XEXP (addr, 1);
+ 	  addr = XEXP (addr, 0);
  	}
-+
-+      fprintf (stderr, "\n");
-     }
- 
-   return ret;
-@@ -5035,6 +5061,7 @@ rs6000_legitimate_address (enum machine_
- 	       GET_MODE_NAME (mode),
- 	       reg_ok_strict);
-       debug_rtx (orig_x);
-+      fprintf (stderr, "\n");
-     }
- 
-   return ret;
-@@ -5082,9 +5109,10 @@ rs6000_mode_dependent_address (rtx addr)
-   if (TARGET_DEBUG_ADDR)
-     {
-       fprintf (stderr,
--	       "\nrs6000_mode_dependent_address: ret = %d\n",
--	       (int)ret);
-+	       "\nrs6000_mode_dependent_address: ret = %s\n",
-+	       ret ? "true" : "false");
-       debug_rtx (addr);
-+      fprintf (stderr, "\n");
-     }
+-      /* fall through */
  
-   return ret;
-@@ -7917,6 +7945,20 @@ static struct builtin_description bdesc_
-   { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
-   { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
- 
-+  { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
-+  { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
-+  { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
-+  { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
-+  { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
-+  { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
-+
-+  { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
-+  { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
-+  { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
-+  { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
-+  { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
-+  { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
-+
-   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
-   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
-   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
-@@ -8288,7 +8330,11 @@ static const struct builtin_description 
-   { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
-   { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
-   { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
--  { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
-+  { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
-+  { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
-+  { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
-+  { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
-+  { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
- };
- 
- /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
-@@ -8314,6 +8360,11 @@ static struct builtin_description bdesc_
-   { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
-   { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
- 
-+  { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
-+  { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
-+  { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
-+  { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
+-      /* Move reg+offset addresses into a scratch register.  */
+-    case ALTIVEC_REGS:
+-      if (!legitimate_indirect_address_p (addr, true)
+-	  && !legitimate_indexed_address_p (addr, true)
+-	  && (GET_CODE (addr) != PRE_MODIFY
+-	      || !legitimate_indexed_address_p (XEXP (addr, 1), true))
+-	  && (rclass != FLOAT_REGS
+-	      || GET_MODE_SIZE (mode) != 8
++      /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
++	 as the address later.  */
++      if (GET_CODE (addr) == PRE_MODIFY
++	  && (!VECTOR_MEM_VSX_P (mode)
+ 	      || and_op2 != NULL_RTX
+-	      || !rs6000_legitimate_offset_address_p (mode, addr, true)))
++	      || !legitimate_indexed_address_p (XEXP (addr, 1), true)))
+ 	{
+-	  if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
+-	      || GET_CODE (addr) == CONST_INT)
+-	    rs6000_emit_move (scratch, addr, GET_MODE (addr));
+-	  else
+-	    emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
+-	  addr = scratch;
++	  scratch_or_premodify = XEXP (addr, 0);
++	  gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
++						     true));
++	  gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
++	  addr = XEXP (addr, 1);
++	}
 +
-   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
-   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
-   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
-@@ -8339,6 +8390,15 @@ static struct builtin_description bdesc_
-   { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
-   { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
- 
-+  { MASK_VSX, CODE_FOR_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
-+  { MASK_VSX, CODE_FOR_unsigned_floatv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
-+  { MASK_VSX, CODE_FOR_fix_truncv2dfv2di2, "__builtin_vsx_xvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
-+  { MASK_VSX, CODE_FOR_fixuns_truncv2dfv2di2, "__builtin_vsx_xvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
-+  { MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXDSP },
-+  { MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
-+  { MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vsx_xvspsxws", VSX_BUILTIN_XVCVSPSXWS },
-+  { MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vsx_xvspuxws", VSX_BUILTIN_XVCVSPUXWS },
++      if (legitimate_indirect_address_p (addr, true)	/* reg */
++	  || legitimate_indexed_address_p (addr, true)	/* reg+reg */
++	  || GET_CODE (addr) == PRE_MODIFY		/* VSX pre-modify */
++	  || GET_CODE (addr) == AND			/* Altivec memory */
++	  || (rclass == FLOAT_REGS			/* legacy float mem */
++	      && GET_MODE_SIZE (mode) == 8
++	      && and_op2 == NULL_RTX
++	      && scratch_or_premodify == scratch
++	      && rs6000_legitimate_offset_address_p (mode, addr, true)))
++	;
 +
-   /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
-      end with SPE_BUILTIN_EVSUBFUSIAAW.  */
-   { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
-@@ -10484,6 +10544,8 @@ altivec_init_builtins (void)
-     = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
-   tree v4sf_ftype_v4sf
-     = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
-+  tree v2df_ftype_v2df
-+    = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
-   tree void_ftype_pcvoid_int_int
-     = build_function_type_list (void_type_node,
- 				pcvoid_type_node, integer_type_node,
-@@ -10641,6 +10703,9 @@ altivec_init_builtins (void)
- 	case V4SFmode:
- 	  type = v4sf_ftype_v4sf;
- 	  break;
-+	case V2DFmode:
-+	  type = v2df_ftype_v2df;
-+	  break;
- 	default:
- 	  gcc_unreachable ();
++      else if (GET_CODE (addr) == PLUS)
++	{
++	  addr_op1 = XEXP (addr, 0);
++	  addr_op2 = XEXP (addr, 1);
++	  gcc_assert (REG_P (addr_op1));
++
++	  rs6000_emit_move (scratch, addr_op2, Pmode);
++	  emit_insn (gen_rtx_SET (VOIDmode,
++				  scratch_or_premodify,
++				  gen_rtx_PLUS (Pmode,
++						addr_op1,
++						scratch)));
++	  addr = scratch_or_premodify;
++	  scratch_or_premodify = scratch;
  	}
-@@ -10960,6 +11025,18 @@ rs6000_common_init_builtins (void)
-   tree int_ftype_v8hi_v8hi
-     = build_function_type_list (integer_type_node,
- 				V8HI_type_node, V8HI_type_node, NULL_TREE);
-+  tree v2di_ftype_v2df
-+    = build_function_type_list (V2DI_type_node,
-+				V2DF_type_node, NULL_TREE);
-+  tree v2df_ftype_v2df
-+    = build_function_type_list (V2DF_type_node,
-+				V2DF_type_node, NULL_TREE);
-+  tree v2df_ftype_v2di
-+    = build_function_type_list (V2DF_type_node,
-+				V2DI_type_node, NULL_TREE);
-+  tree v2df_ftype_v2df_v2df
-+    = build_function_type_list (V2DF_type_node,
-+				V2DF_type_node, V2DF_type_node, NULL_TREE);
-   tree v2df_ftype_v2df_v2df_v2df
-     = build_function_type_list (V2DF_type_node,
- 				V2DF_type_node, V2DF_type_node,
-@@ -11136,6 +11213,9 @@ rs6000_common_init_builtins (void)
- 	    case VOIDmode:
- 	      type = opaque_ftype_opaque_opaque;
- 	      break;
-+	    case V2DFmode:
-+	      type = v2df_ftype_v2df_v2df;
-+	      break;
- 	    case V4SFmode:
- 	      type = v4sf_ftype_v4sf_v4sf;
- 	      break;
-@@ -11285,6 +11365,8 @@ rs6000_common_init_builtins (void)
- 	type = v16qi_ftype_int;
-       else if (mode0 == VOIDmode && mode1 == VOIDmode)
- 	type = opaque_ftype_opaque;
-+      else if (mode0 == V2DFmode && mode1 == V2DFmode)
-+	type = v2df_ftype_v2df;
-       else if (mode0 == V4SFmode && mode1 == V4SFmode)
- 	type = v4sf_ftype_v4sf;
-       else if (mode0 == V8HImode && mode1 == V16QImode)
-@@ -11310,6 +11392,10 @@ rs6000_common_init_builtins (void)
- 	type = v4si_ftype_v4sf;
-       else if (mode0 == V4SFmode && mode1 == V4SImode)
- 	type = v4sf_ftype_v4si;
-+      else if (mode0 == V2DImode && mode1 == V2DFmode)
-+	type = v2di_ftype_v2df;
-+      else if (mode0 == V2DFmode && mode1 == V2DImode)
-+	type = v2df_ftype_v2di;
-       else
- 	gcc_unreachable ();
- 
-@@ -12092,8 +12178,10 @@ rtx
- rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
- {
-   static bool eliminated = false;
-+  rtx ret;
 +
-   if (mode != SDmode)
--    return assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
-+    ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
-   else
-     {
-       rtx mem = cfun->machine->sdmode_stack_slot;
-@@ -12105,8 +12193,21 @@ rs6000_secondary_memory_needed_rtx (enum
- 	  cfun->machine->sdmode_stack_slot = mem;
- 	  eliminated = true;
- 	}
--      return mem;
-+      ret = mem;
-+    }
++      else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
++	       || GET_CODE (addr) == CONST_INT)
++	{
++	  rs6000_emit_move (scratch_or_premodify, addr, Pmode);
++	  addr = scratch_or_premodify;
++	  scratch_or_premodify = scratch;
++	}
 +
-+  if (TARGET_DEBUG_ADDR)
-+    {
-+      fprintf (stderr, "rs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
-+	       GET_MODE_NAME (mode));
-+      if (!ret)
-+	fprintf (stderr, "\tNULL_RTX\n");
 +      else
-+	debug_rtx (ret);
-+      fprintf (stderr, "\n");
-     }
++	gcc_unreachable ();
 +
-+  return ret;
- }
+       break;
  
- static tree
-@@ -12140,6 +12241,54 @@ rs6000_check_sdmode (tree *tp, int *walk
-   return NULL_TREE;
- }
+     default:
+       gcc_unreachable ();
+     }
  
-+/* Inform reload about cases where moving X with a mode MODE to a register in
-+   RCLASS requires an extra scratch or immediate register.  Return the class
-+   needed for the immediate register.  */
-+
-+static enum reg_class
-+rs6000_secondary_reload (bool in_p,
-+			 rtx x,
-+			 enum reg_class rclass,
-+			 enum machine_mode mode,
-+			 secondary_reload_info *sri)
-+{
-+  if (TARGET_DEBUG_ADDR)
-+    {
-+      fprintf (stderr,
-+	       "rs6000_secondary_reload, in_p = %s, rclass = %s, mode = %s\n",
-+	       in_p ? "true" : "false", reg_class_names[rclass],
-+	       GET_MODE_NAME (mode));
-+      debug_rtx (x);
-+      fprintf (stderr, "\n");
-+    }
-+
-+  return default_secondary_reload (in_p, x, rclass, mode, sri);
-+}
-+
-+/* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
-+   to SP+reg addressing.  */
-+
-+void
-+rs6000_vector_secondary_reload (rtx op0, rtx op1, rtx op2, bool to_mem_p)
-+{
-+  rtx memref = to_mem_p ? op0 : op1;
-+  gcc_assert (MEM_P (memref));
-+
-+  if (TARGET_DEBUG_ADDR)
+-  /* If the original address involved an AND -16 that is part of the Altivec
+-     addresses, recreate the and now.  */
++  /* If the original address involved a pre-modify that we couldn't use the VSX
++     memory instruction with update, and we haven't taken care of already,
++     store the address in the pre-modify register and use that as the
++     address.  */
++  if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
 +    {
-+      fprintf (stderr, "rs6000_vector_secondary_reload, to_mem_p = %s\n",
-+	       to_mem_p ? "true" : "false");
-+      fprintf (stderr, "op0:\n");
-+      debug_rtx (op0);
-+      fprintf (stderr, "op1:\n");
-+      debug_rtx (op1);
-+      fprintf (stderr, "op2:\n");
-+      debug_rtx (op2);
-+      fprintf (stderr, "\n");
-+    }
-+
-+  gcc_unreachable ();
-+}
- 
- /* Allocate a 64-bit stack slot to be used for copying SDmode
-    values through if this function has any SDmode references.  */
-@@ -12212,32 +12361,44 @@ enum reg_class
- rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
- {
-   enum machine_mode mode = GET_MODE (x);
-+  enum reg_class ret;
- 
-   if (TARGET_VSX && VSX_VECTOR_MODE (mode) && x == CONST0_RTX (mode)
-       && VSX_REG_CLASS_P (rclass))
--    return rclass;
-+    ret = rclass;
- 
--  if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode) && rclass == ALTIVEC_REGS
--      && easy_vector_constant (x, mode))
--    return rclass;
-+  else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode)
-+	   && rclass == ALTIVEC_REGS && easy_vector_constant (x, mode))
-+    ret = rclass;
- 
--  if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
--    return NO_REGS;
-+  else if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
-+    ret = NO_REGS;
- 
--  if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
--    return GENERAL_REGS;
-+  else if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
-+    ret = GENERAL_REGS;
- 
-   /* For VSX, prefer the traditional registers.  */
--  if (rclass == VSX_REGS)
-+  else if (rclass == VSX_REGS)
-     {
-       if (mode == DFmode)
--	return FLOAT_REGS;
-+	ret = FLOAT_REGS;
- 
-       if (ALTIVEC_VECTOR_MODE (mode))
--	return ALTIVEC_REGS;
-+	ret = ALTIVEC_REGS;
++      emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
++      addr = scratch_or_premodify;
 +    }
-+  else
-+    ret = rclass;
-+
-+  if (TARGET_DEBUG_ADDR)
-+    {
-+      fprintf (stderr,
-+	       "rs6000_preferred_reload_class, return %s, rclass = %s, x:\n",
-+	       reg_class_names[ret], reg_class_names[rclass]);
-+      debug_rtx (x);
-+      fprintf (stderr, "\n");
-     }
- 
--  return rclass;
-+  return ret;
- }
- 
- /* If we are copying between FP or AltiVec registers and anything else, we need
-@@ -12251,31 +12412,46 @@ rs6000_secondary_memory_needed (enum reg
- 				enum reg_class class2,
- 				enum machine_mode mode)
- {
-+  bool ret;
-+  bool vsx1;
-+  bool vsx2;
-+
-   if (class1 == class2)
--    return false;
-+    ret = false;
- 
--  if (TARGET_VSX && VSX_MOVE_MODE (mode) && VSX_REG_CLASS_P (class1)
--      && VSX_REG_CLASS_P (class2))
--    return false;
-+  else if (TARGET_VSX && VECTOR_MEM_VSX_P (mode)
-+	   && ((vsx1 = VSX_REG_CLASS_P (class1))
-+	       || (vsx2 = VSX_REG_CLASS_P (class2))))
-+    ret = (vsx1 != vsx2);
-+
-+  else if (class1 == FLOAT_REGS
-+	   && (!TARGET_MFPGPR || !TARGET_POWERPC64
-+	       || ((mode != DFmode)
-+		   && (mode != DDmode)
-+		   && (mode != DImode))))
-+    ret = true;
 +
-+  else if (class2 == FLOAT_REGS
-+	   && (!TARGET_MFPGPR || !TARGET_POWERPC64
-+	       || ((mode != DFmode)
-+		   && (mode != DDmode)
-+		   && (mode != DImode))))
-+    ret = true;
- 
--  if (class1 == FLOAT_REGS
--       && (!TARGET_MFPGPR || !TARGET_POWERPC64
--	   || ((mode != DFmode)
--	       && (mode != DDmode)
--	       && (mode != DImode))))
--    return true;
-+  else if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
-+    ret = true;
- 
--  if (class2 == FLOAT_REGS
--      && (!TARGET_MFPGPR || !TARGET_POWERPC64
--	  || ((mode != DFmode)
--	      && (mode != DDmode)
--	      && (mode != DImode))))
--    return true;
-+  else
-+    ret = false;
- 
--  if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
--    return true;
-+  if (TARGET_DEBUG_ADDR)
-+    fprintf (stderr,
-+	     "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
-+	     "class2 = %s, mode = %s\n",
-+	     ret ? "true" : "false", reg_class_names[class1],
-+	     reg_class_names[class2], GET_MODE_NAME (mode));
- 
--  return false;
-+  return ret;
- }
- 
- /* Return the register class of a scratch register needed to copy IN into
-@@ -12287,6 +12463,7 @@ rs6000_secondary_reload_class (enum reg_
- 			       enum machine_mode mode,
- 			       rtx in)
- {
-+  enum reg_class ret = NO_REGS;
-   int regno;
- 
-   if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
-@@ -12307,58 +12484,75 @@ rs6000_secondary_reload_class (enum reg_
- 	      || GET_CODE (in) == HIGH
- 	      || GET_CODE (in) == LABEL_REF
- 	      || GET_CODE (in) == CONST))
--	return BASE_REGS;
-+	ret = BASE_REGS;
-     }
- 
--  if (GET_CODE (in) == REG)
-+  if (ret == NO_REGS)
++  /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
++     memory instruction, recreate the AND now, including the clobber which is
++     generated by the general ANDSI3/ANDDI3 patterns for the
++     andi. instruction.  */
+   if (and_op2 != NULL_RTX)
      {
--      regno = REGNO (in);
--      if (regno >= FIRST_PSEUDO_REGISTER)
-+      if (GET_CODE (in) == REG)
+-      rtx and_rtx = gen_rtx_SET (VOIDmode,
+-				 scratch,
+-				 gen_rtx_AND (Pmode, addr, and_op2));
+-      rtx cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
++      if (! legitimate_indirect_address_p (addr, true))
 +	{
-+	  regno = REGNO (in);
-+	  if (regno >= FIRST_PSEUDO_REGISTER)
-+	    {
-+	      regno = true_regnum (in);
-+	      if (regno >= FIRST_PSEUDO_REGISTER)
-+		regno = -1;
-+	    }
++	  emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
++	  addr = scratch;
 +	}
-+      else if (GET_CODE (in) == SUBREG)
- 	{
- 	  regno = true_regnum (in);
- 	  if (regno >= FIRST_PSEUDO_REGISTER)
- 	    regno = -1;
- 	}
--    }
--  else if (GET_CODE (in) == SUBREG)
--    {
--      regno = true_regnum (in);
--      if (regno >= FIRST_PSEUDO_REGISTER)
-+      else
- 	regno = -1;
--    }
--  else
--    regno = -1;
- 
--  /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
--     into anything.  */
--  if (rclass == GENERAL_REGS || rclass == BASE_REGS
--      || (regno >= 0 && INT_REGNO_P (regno)))
--    return NO_REGS;
--
--  /* Constants, memory, and FP registers can go into FP registers.  */
--  if ((regno == -1 || FP_REGNO_P (regno))
--      && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
--    return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
--
--  /* Memory, and FP/altivec registers can go into fp/altivec registers under
--     VSX.  */
--  if (TARGET_VSX
--      && (regno == -1 || VSX_REGNO_P (regno))
--      && VSX_REG_CLASS_P (rclass))
--    return NO_REGS;
-+      /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
-+	 into anything.  */
-+      if (rclass == GENERAL_REGS || rclass == BASE_REGS
-+	  || (regno >= 0 && INT_REGNO_P (regno)))
-+	ret = NO_REGS;
-+
-+      /* Constants, memory, and FP registers can go into FP registers.  */
-+      else if ((regno == -1 || FP_REGNO_P (regno))
-+	       && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
-+	ret = (mode != SDmode) ? NO_REGS : GENERAL_REGS;
-+
-+      /* Memory, and FP/altivec registers can go into fp/altivec registers under
-+	 VSX.  */
-+      else if (TARGET_VSX
-+	       && (regno == -1 || VSX_REGNO_P (regno))
-+	       && VSX_REG_CLASS_P (rclass))
-+	ret = NO_REGS;
-+
-+      /* Memory, and AltiVec registers can go into AltiVec registers.  */
-+      else if ((regno == -1 || ALTIVEC_REGNO_P (regno))
-+	       && rclass == ALTIVEC_REGS)
-+	ret = NO_REGS;
-+
-+      /* We can copy among the CR registers.  */
-+      else if ((rclass == CR_REGS || rclass == CR0_REGS)
-+	       && regno >= 0 && CR_REGNO_P (regno))
-+	ret = NO_REGS;
-+
-+      /* Otherwise, we need GENERAL_REGS.  */
-+      else
-+	ret = GENERAL_REGS;
-+    }
- 
--  /* Memory, and AltiVec registers can go into AltiVec registers.  */
--  if ((regno == -1 || ALTIVEC_REGNO_P (regno))
--      && rclass == ALTIVEC_REGS)
--    return NO_REGS;
--
--  /* We can copy among the CR registers.  */
--  if ((rclass == CR_REGS || rclass == CR0_REGS)
--      && regno >= 0 && CR_REGNO_P (regno))
--    return NO_REGS;
-+  if (TARGET_DEBUG_ADDR)
-+    {
-+      fprintf (stderr,
-+	       "rs6000_secondary_reload_class, return %s, rclass = %s, "
-+	       "mode = %s, input rtx:\n",
-+	       reg_class_names[ret], reg_class_names[rclass],
-+	       GET_MODE_NAME (mode));
-+      debug_rtx (in);
-+      fprintf (stderr, "\n");
-+    }
- 
--  /* Otherwise, we need GENERAL_REGS.  */
--  return GENERAL_REGS;
-+  return ret;
- }
- 
- /* Return nonzero if for CLASS a mode change from FROM to TO is invalid.  */
-@@ -12368,19 +12562,29 @@ rs6000_cannot_change_mode_class (enum ma
- 				 enum machine_mode to,
- 				 enum reg_class rclass)
- {
--  return (GET_MODE_SIZE (from) != GET_MODE_SIZE (to)
--	  ? ((GET_MODE_SIZE (from) < 8 || GET_MODE_SIZE (to) < 8
--	      || TARGET_IEEEQUAD)
--	     && reg_classes_intersect_p (FLOAT_REGS, rclass))
--	  : (((TARGET_E500_DOUBLE
--	       && ((((to) == DFmode) + ((from) == DFmode)) == 1
--		   || (((to) == TFmode) + ((from) == TFmode)) == 1
--		   || (((to) == DDmode) + ((from) == DDmode)) == 1
--		   || (((to) == TDmode) + ((from) == TDmode)) == 1
--		   || (((to) == DImode) + ((from) == DImode)) == 1))
--	      || (TARGET_SPE
--		  && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1))
--	     && reg_classes_intersect_p (GENERAL_REGS, rclass)));
-+  bool ret = (GET_MODE_SIZE (from) != GET_MODE_SIZE (to)
-+	      ? ((GET_MODE_SIZE (from) < 8 || GET_MODE_SIZE (to) < 8
-+		  || TARGET_IEEEQUAD)
-+		 && reg_classes_intersect_p (FLOAT_REGS, rclass))
-+	      : (((TARGET_E500_DOUBLE
-+		   && ((((to) == DFmode) + ((from) == DFmode)) == 1
-+		       || (((to) == TFmode) + ((from) == TFmode)) == 1
-+		       || (((to) == DDmode) + ((from) == DDmode)) == 1
-+		       || (((to) == TDmode) + ((from) == TDmode)) == 1
-+		       || (((to) == DImode) + ((from) == DImode)) == 1))
-+		  || (TARGET_SPE
-+		      && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1))
-+		 && reg_classes_intersect_p (GENERAL_REGS, rclass)));
-+
-+  if (TARGET_DEBUG_ADDR)
-+    fprintf (stderr,
-+	     "rs6000_cannot_change_mode_class, return %s, from = %s, "
-+	     "to = %s, rclass = %s\n",
-+	     ret ? "true" : "false",
-+	     GET_MODE_NAME (from), GET_MODE_NAME (to),
-+	     reg_class_names[rclass]);
-+
-+  return ret;
- }
- 
- /* Given a comparison operation, return the bit number in CCR to test.  We
---- gcc/config/rs6000/vsx.md	(revision 144758)
-+++ gcc/config/rs6000/vsx.md	(revision 144843)
-@@ -68,7 +68,13 @@ (define_mode_attr VSbit [(SI "32")
- 			 (DI "64")])
- 
- (define_constants
--  [(UNSPEC_VSX_CONCAT_V2DF	500)])
-+  [(UNSPEC_VSX_CONCAT_V2DF	500)
-+   (UNSPEC_VSX_XVCVDPSP		501)
-+   (UNSPEC_VSX_XVCVDPSXWS	502)
-+   (UNSPEC_VSX_XVCVDPUXWS	503)
-+   (UNSPEC_VSX_XVCVSPDP		504)
-+   (UNSPEC_VSX_XVCVSXWDP	505)
-+   (UNSPEC_VSX_XVCVUXWDP	506)])
- 
- ;; VSX moves
- (define_insn "*vsx_mov<mode>"
-@@ -245,7 +251,7 @@ (define_insn "*vsx_abs<mode>2"
-   "xvabs<VSs> %x0,%x1"
-   [(set_attr "type" "vecfloat")])
- 
--(define_insn "*vsx_nabs<mode>2"
-+(define_insn "vsx_nabs<mode>2"
-   [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>")
-         (neg:VSX_F
- 	 (abs:VSX_F
-@@ -417,14 +423,14 @@ (define_insn "*vsx_ftrunc<mode>2"
-   "xvr<VSs>piz %x0,%x1"
-   [(set_attr "type" "vecperm")])
- 
--(define_insn "*vsx_float<VSi><mode>2"
-+(define_insn "vsx_float<VSi><mode>2"
-   [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>")
- 	(float:VSX_F (match_operand:<VSI> 1 "vsx_register_operand" "<VSr>")))]
-   "VECTOR_UNIT_VSX_P (<MODE>mode)"
-   "xvcvsx<VSc><VSs> %x0,%x1"
-   [(set_attr "type" "vecfloat")])
- 
--(define_insn "*vsx_floatuns<VSi><mode>2"
-+(define_insn "vsx_floatuns<VSi><mode>2"
-   [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>")
- 	(unsigned_float:VSX_F (match_operand:<VSI> 1 "vsx_register_operand" "<VSr>")))]
-   "VECTOR_UNIT_VSX_P (<MODE>mode)"
-@@ -446,6 +452,62 @@ (define_insn "*vsx_fixuns_trunc<mode><VS
-   [(set_attr "type" "vecfloat")])
- 
- 
-+;; VSX convert to/from double vector
-+
-+;; Convert from 64-bit to 32-bit types
-+;; Note, favor the Altivec registers since the usual use of these instructions
-+;; is in vector converts and we need to use the Altivec vperm instruction.
-+
-+(define_insn "vsx_xvcvdpsp"
-+  [(set (match_operand:V4SF 0 "vsx_register_operand" "=v,?wa")
-+	(unspec:V4SF [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
-+		     UNSPEC_VSX_XVCVDPSP))]
-+  "VECTOR_UNIT_VSX_P (V2DFmode)"
-+  "xvcvdpsp %x0,%x1"
-+  [(set_attr "type" "vecfloat")])
-+
-+(define_insn "vsx_xvcvdpsxws"
-+  [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
-+	(unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
-+		     UNSPEC_VSX_XVCVDPSXWS))]
-+  "VECTOR_UNIT_VSX_P (V2DFmode)"
-+  "xvcvdpsxws %x0,%x1"
-+  [(set_attr "type" "vecfloat")])
-+
-+(define_insn "vsx_xvcvdpuxws"
-+  [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
-+	(unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
-+		     UNSPEC_VSX_XVCVDPUXWS))]
-+  "VECTOR_UNIT_VSX_P (V2DFmode)"
-+  "xvcvdpuxws %x0,%x1"
-+  [(set_attr "type" "vecfloat")])
-+
-+;; Convert from 32-bit to 64-bit types
-+(define_insn "vsx_xvcvspdp"
-+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
-+	(unspec:V2DF [(match_operand:V4SF 1 "vsx_register_operand" "wf,wa")]
-+		     UNSPEC_VSX_XVCVSPDP))]
-+  "VECTOR_UNIT_VSX_P (V2DFmode)"
-+  "xvcvspdp %x0,%x1"
-+  [(set_attr "type" "vecfloat")])
-+
-+(define_insn "vsx_xvcvsxwdp"
-+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
-+	(unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
-+		     UNSPEC_VSX_XVCVSXWDP))]
-+  "VECTOR_UNIT_VSX_P (V2DFmode)"
-+  "xvcvsxwdp %x0,%x1"
-+  [(set_attr "type" "vecfloat")])
-+
-+(define_insn "vsx_xvcvuxwdp"
-+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
-+	(unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
-+		     UNSPEC_VSX_XVCVUXWDP))]
-+  "VECTOR_UNIT_VSX_P (V2DFmode)"
-+  "xvcvuxwdp %x0,%x1"
-+  [(set_attr "type" "vecfloat")])
-+
-+
- ;; VSX scalar double precision floating point operations
- (define_insn"*vsx_adddf3"
-   [(set (match_operand:DF 0 "vsx_register_operand" "=ws")
-@@ -753,8 +815,8 @@ (define_insn "*vsx_andc<mode>3"
- (define_insn "vsx_concat_v2df"
-   [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
- 	(unspec:V2DF
--	 [(match_operand:DF 1 "vsx_register_operand" "f,wa")
--	  (match_operand:DF 2 "vsx_register_operand" "f,wa")]
-+	 [(match_operand:DF 1 "vsx_register_operand" "ws,wa")
-+	  (match_operand:DF 2 "vsx_register_operand" "ws,wa")]
- 	 UNSPEC_VSX_CONCAT_V2DF))]
-   "VECTOR_UNIT_VSX_P (V2DFmode)"
-   "xxpermdi %x0,%x1,%x2,0"
-@@ -762,32 +824,37 @@ (define_insn "vsx_concat_v2df"
- 
- ;; Set a double into one element
- (define_insn "vsx_set_v2df"
--  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd")
-+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
- 	(vec_merge:V2DF
--	 (match_operand:V2DF 1 "vsx_register_operand" "wd")
--	 (vec_duplicate:V2DF (match_operand:DF 2 "vsx_register_operand" "ws"))
--	 (match_operand:QI 3 "u5bit_cint_operand" "i")))]
-+	 (match_operand:V2DF 1 "vsx_register_operand" "wd,wa")
-+	 (vec_duplicate:V2DF (match_operand:DF 2 "vsx_register_operand" "ws,f"))
-+	 (match_operand:QI 3 "u5bit_cint_operand" "i,i")))]
-   "VECTOR_UNIT_VSX_P (V2DFmode)"
- {
--  operands[3] = GEN_INT (INTVAL (operands[3]) & 1);
--  return \"xxpermdi %x0,%x1,%x2,%3\";
-+  if (INTVAL (operands[3]) == 0)
-+    return \"xxpermdi %x0,%x1,%x2,1\";
-+  else if (INTVAL (operands[3]) == 1)
-+    return \"xxpermdi %x0,%x2,%x1,0\";
-+  else
-+    gcc_unreachable ();
- }
-   [(set_attr "type" "vecperm")])
- 
- ;; Extract a DF element from V2DF
- (define_insn "vsx_extract_v2df"
--  [(set (match_operand:DF 0 "vsx_register_operand" "=ws")
--	(vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd")
-+  [(set (match_operand:DF 0 "vsx_register_operand" "=ws,f,?wa")
-+	(vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd,wd,wa")
- 		       (parallel
--			[(match_operand:QI 2 "u5bit_cint_operand" "i")])))]
-+			[(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))]
-   "VECTOR_UNIT_VSX_P (V2DFmode)"
- {
--  operands[3] = GEN_INT (INTVAL (operands[2]) & 1);
-+  gcc_assert (UINTVAL (operands[2]) <= 1);
-+  operands[3] = GEN_INT (INTVAL (operands[2]) << 1);
-   return \"xxpermdi %x0,%x1,%x1,%3\";
- }
-   [(set_attr "type" "vecperm")])
- 
--;; General V2DF permute
-+;; General V2DF permute, extract_{high,low,even,odd}
- (define_insn "vsx_xxpermdi"
-   [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd")
- 	(vec_concat:V2DF
-@@ -799,6 +866,7 @@ (define_insn "vsx_xxpermdi"
- 			 [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))]
-   "VECTOR_UNIT_VSX_P (V2DFmode)"
- {
-+  gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1));
-   operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1)
- 			 | (INTVAL (operands[4]) & 1));
-   return \"xxpermdi %x0,%x1,%x3,%5\";
-@@ -807,14 +875,15 @@ (define_insn "vsx_xxpermdi"
- 
- ;; V2DF splat
- (define_insn "vsx_splatv2df"
--  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd")
-+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd,wd")
- 	(vec_duplicate:V2DF
--	 (match_operand:DF 1 "input_operand" "ws,Z")))]
-+	 (match_operand:DF 1 "input_operand" "ws,f,Z")))]
-   "VECTOR_UNIT_VSX_P (V2DFmode)"
-   "@
-    xxpermdi %x0,%x1,%x1,0
-+   xxpermdi %x0,%x1,%x1,0
-    lxvdsx %x0,%y1"
--  [(set_attr "type" "vecperm,vecload")])
-+  [(set_attr "type" "vecperm,vecperm,vecload")])
- 
- ;; V4SF splat
- (define_insn "*vsx_xxspltw"
-@@ -828,14 +897,14 @@ (define_insn "*vsx_xxspltw"
-   [(set_attr "type" "vecperm")])
- 
- ;; V4SF interleave
--(define_insn "*vsx_xxmrghw"
--  [(set (match_operand:V4SF 0 "register_operand" "=v")
--        (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
-+(define_insn "vsx_xxmrghw"
-+  [(set (match_operand:V4SF 0 "register_operand" "=wf")
-+        (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "wf")
-                                          (parallel [(const_int 0)
-                                                     (const_int 2)
-                                                     (const_int 1)
-                                                     (const_int 3)]))
--                        (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
-+                        (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "wf")
-                                          (parallel [(const_int 2)
-                                                     (const_int 0)
-                                                     (const_int 3)
-@@ -845,15 +914,15 @@ (define_insn "*vsx_xxmrghw"
-   "xxmrghw %x0,%x1,%x2"
-   [(set_attr "type" "vecperm")])
- 
--(define_insn "*vsx_xxmrglw"
--  [(set (match_operand:V4SF 0 "register_operand" "=v")
-+(define_insn "vsx_xxmrglw"
-+  [(set (match_operand:V4SF 0 "register_operand" "=wf")
-         (vec_merge:V4SF
--	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
-+	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "wf")
- 			  (parallel [(const_int 2)
- 				     (const_int 0)
- 				     (const_int 3)
- 				     (const_int 1)]))
--	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
-+	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "wf")
- 			  (parallel [(const_int 0)
- 				     (const_int 2)
- 				     (const_int 1)
-@@ -862,3 +931,26 @@ (define_insn "*vsx_xxmrglw"
-   "VECTOR_UNIT_VSX_P (V4SFmode)"
-   "xxmrglw %x0,%x1,%x2"
-   [(set_attr "type" "vecperm")])
-+
-+
-+;; Reload patterns for VSX loads/stores.  We need a scratch register to convert
-+;; the stack temporary address from reg+offset to reg+reg addressing.
-+(define_expand "vsx_reload_<VSX_L:mode>_<P:ptrsize>_to_mem"
-+  [(parallel [(match_operand:VSX_L 0 "memory_operand" "")
-+              (match_operand:VSX_L 1 "register_operand" "=wa")
-+              (match_operand:P 2 "register_operand" "=&b")])]
-+  "VECTOR_MEM_VSX_P (<MODE>mode)"
-+{
-+  rs6000_vector_secondary_reload (operands[0], operands[1], operands[2], true);
-+  DONE;
-+})
-+
-+(define_expand "vsx_reload_<VSX_L:mode>_<P:ptrsize>_to_reg"
-+  [(parallel [(match_operand:VSX_L 0 "register_operand" "=wa")
-+              (match_operand:VSX_L 1 "memory_operand" "")
-+              (match_operand:P 2 "register_operand" "=&b")])]
-+  "VECTOR_MEM_VSX_P (<MODE>mode)"
-+{
-+  rs6000_vector_secondary_reload (operands[0], operands[1], operands[2], false);
-+  DONE;
-+})
---- gcc/config/rs6000/rs6000.h	(revision 144758)
-+++ gcc/config/rs6000/rs6000.h	(revision 144843)
-@@ -3388,7 +3388,7 @@ enum rs6000_builtins
-   VSX_BUILTIN_XXSPLTW,
-   VSX_BUILTIN_XXSWAPD,
- 
--  /* Combine VSX/Altivec builtins.  */
-+  /* Combined VSX/Altivec builtins.  */
-   VECTOR_BUILTIN_FLOAT_V4SI_V4SF,
-   VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF,
-   VECTOR_BUILTIN_FIX_V4SF_V4SI,
---- gcc/config/rs6000/altivec.md	(revision 144758)
-+++ gcc/config/rs6000/altivec.md	(revision 144843)
-@@ -2685,3 +2685,27 @@ (define_expand "vec_unpacku_float_lo_v8h
-   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
-   DONE;
- }")
-+
-+
-+;; Reload patterns for Altivec loads/stores.  We need a scratch register to
-+;; convert the stack temporary address from reg+offset to reg+reg addressing.
-+
-+(define_expand "altivec_reload_<V:mode>_<P:ptrsize>_to_mem"
-+  [(parallel [(match_operand:V 0 "memory_operand" "")
-+              (match_operand:V 1 "register_operand" "=v")
-+              (match_operand:P 2 "register_operand" "=&b")])]
-+  "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
-+{
-+  rs6000_vector_secondary_reload (operands[0], operands[1], operands[2], true);
-+  DONE;
-+})
-+
-+(define_expand "altivec_reload_<V:mode>_<P:ptrsize>_to_reg"
-+  [(parallel [(match_operand:V 0 "register_operand" "=v")
-+              (match_operand:V 1 "memory_operand" "")
-+              (match_operand:P 2 "register_operand" "=&b")])]
-+  "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
-+{
-+  rs6000_vector_secondary_reload (operands[0], operands[1], operands[2], false);
-+  DONE;
-+})
---- gcc/config/rs6000/rs6000.md	(revision 144758)
-+++ gcc/config/rs6000/rs6000.md	(revision 144843)
-@@ -222,6 +222,10 @@ (define_mode_attr dbits [(QI "56") (HI "
- ;; ISEL/ISEL64 target selection
- (define_mode_attr sel [(SI "") (DI "64")])
- 
-+;; Suffix for reload patterns
-+(define_mode_attr ptrsize [(SI "32bit")
-+			   (DI "64bit")])
-+
- 
- ;; Start with fixed-point load and store insns.  Here we put only the more
- ;; complex forms.  Basic data transfer is done later.
---- gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c	(revision 0)
-+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c	(revision 144843)
-@@ -0,0 +1,29 @@
-+/* { dg-do compile { target { powerpc*-*-* } } } */
-+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
-+/* { dg-require-effective-target powerpc_vsx_ok } */
-+/* { dg-options "-O2 -mcpu=power7" } */
-+/* { dg-final { scan-assembler "xvaddsp" } } */
-+/* { dg-final { scan-assembler "xvsubsp" } } */
-+/* { dg-final { scan-assembler "xvmulsp" } } */
-+/* { dg-final { scan-assembler "xvdivsp" } } */
-+/* { dg-final { scan-assembler "xvmaxsp" } } */
-+/* { dg-final { scan-assembler "xvminsp" } } */
-+/* { dg-final { scan-assembler "xvsqrtsp" } } */
-+/* { dg-final { scan-assembler "xvabssp" } } */
-+/* { dg-final { scan-assembler "xvnabssp" } } */
-+
-+void use_builtins (__vector float *p, __vector float *q, __vector float *r)
-+{
-+  __vector float tmp1 = *q;
-+  __vector float tmp2 = *r;
-+
-+  *p++ = __builtin_vsx_xvaddsp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvsubsp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvmulsp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvdivsp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvmaxsp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvminsp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvabssp (tmp1);
-+  *p++ = __builtin_vsx_xvnabssp (tmp1);
-+  *p   = __builtin_vsx_xvsqrtsp (tmp1);
-+}
---- gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c	(revision 0)
-+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c	(revision 144843)
-@@ -0,0 +1,29 @@
-+/* { dg-do compile { target { powerpc*-*-* } } } */
-+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
-+/* { dg-require-effective-target powerpc_vsx_ok } */
-+/* { dg-options "-O2 -mcpu=power7" } */
-+/* { dg-final { scan-assembler "xvadddp" } } */
-+/* { dg-final { scan-assembler "xvsubdp" } } */
-+/* { dg-final { scan-assembler "xvmuldp" } } */
-+/* { dg-final { scan-assembler "xvdivdp" } } */
-+/* { dg-final { scan-assembler "xvmaxdp" } } */
-+/* { dg-final { scan-assembler "xvmindp" } } */
-+/* { dg-final { scan-assembler "xvsqrtdp" } } */
-+/* { dg-final { scan-assembler "xvabsdp" } } */
-+/* { dg-final { scan-assembler "xvnabsdp" } } */
-+
-+void use_builtins (__vector double *p, __vector double *q, __vector double *r)
-+{
-+  __vector double tmp1 = *q;
-+  __vector double tmp2 = *r;
-+
-+  *p++ = __builtin_vsx_xvadddp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvsubdp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvmuldp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvdivdp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvmaxdp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvmindp (tmp1, tmp2);
-+  *p++ = __builtin_vsx_xvabsdp (tmp1);
-+  *p++ = __builtin_vsx_xvnabsdp (tmp1);
-+  *p   = __builtin_vsx_xvsqrtdp (tmp1);
-+}
---- gcc/testsuite/gcc.target/powerpc/pr39457.c	(revision 0)
-+++ gcc/testsuite/gcc.target/powerpc/pr39457.c	(revision 144857)
-@@ -0,0 +1,56 @@
-+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
-+/* { dg-options "-m64 -O2 -mminimal-toc" } */
-+
-+/* PR 39457 -- fix breakage because the compiler ran out of registers and
-+   wanted to stash a floating point value to the LR/CTR register.  */
-+
-+/* -O2 -m64 -mminimal-toc */
-+typedef struct { void *s; } S;
-+typedef void (*T1) (void);
-+typedef void (*T2) (void *, void *, int, void *);
-+char *fn1 (const char *, ...);
-+void *fn2 (void);
-+int fn3 (char *, int);
-+int fn4 (const void *);
-+int fn5 (const void *);
-+long fn6 (void) __attribute__ ((__const__));
-+int fn7 (void *, void *, void *);
-+void *fn8 (void *, long);
-+void *fn9 (void *, long, const char *, ...);
-+void *fn10 (void *);
-+long fn11 (void) __attribute__ ((__const__));
-+long fn12 (void *, const char *, T1, T2, void *);
-+void *fn13 (void *);
-+long fn14 (void) __attribute__ ((__const__));
-+extern void *v1;
-+extern char *v2;
-+extern int v3;
 +
-+void
-+foo (void *x, char *z)
-+{
-+  void *i1, *i2;
-+  int y;
-+  if (v1)
-+    return;
-+  v1 = fn9 (fn10 (fn2 ()), fn6 (), "x", 0., "y", 0., 0);
-+  y = 520 - (520 - fn4 (x)) / 2;
-+  fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", fn8 (v1, fn14 ()), "x", 18.0,
-+       "y", 16.0, "wid", 80.0, "hi", 500.0, 0);
-+  fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 80.0, "y2",
-+       500.0, "f", fn3 ("fff", 0x0D0DFA00), 0);
-+  fn13 (((S *) fn8 (v1, fn6 ()))->s);
-+  fn12 (fn8 (v1, fn11 ()), "ev", (T1) fn7, 0, fn8 (v1, fn6 ()));
-+  fn9 (fn8 (v1, fn6 ()), fn6 (), "wig",
-+       fn8 (v1, fn14 ()), "x", 111.0, "y", 14.0, "wid", 774.0, "hi",
-+       500.0, 0);
-+  v1 = fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 774.0, "y2",
-+            500.0, "f", fn3 ("gc", 0x0D0DFA00), 0);
-+  fn1 (z, 0);
-+  i1 = fn9 (fn8 (v1, fn6 ()), fn6 (), "pixbuf", x, "x",
-+            800 - fn5 (x) / 2, "y", y - fn4 (x), 0);
-+  fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, "/ok/");
-+  fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, 0);
-+  i2 = fn9 (fn8 (v1, fn6 ()), fn6 (), "txt", "OK", "fnt", v2, "x",
-+            800, "y", y - fn4 (x) + 15, "ar", 0, "f", v3, 0);
-+}
++      and_rtx = gen_rtx_SET (VOIDmode,
++			     scratch,
++			     gen_rtx_AND (Pmode,
++					  addr,
++					  and_op2));
++
++      cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
+       emit_insn (gen_rtx_PARALLEL (VOIDmode,
+ 				   gen_rtvec (2, and_rtx, cc_clobber)));
+       addr = scratch;

gcc44-power7.patch:
 config.in                                    |    8 
 config/rs6000/aix53.h                        |    8 
 config/rs6000/aix61.h                        |    8 
 config/rs6000/altivec.md                     |  708 +------
 config/rs6000/constraints.md                 |   28 
 config/rs6000/driver-rs6000.c                |  141 +
 config/rs6000/e500.h                         |    2 
 config/rs6000/linux64.h                      |    2 
 config/rs6000/linux64.opt                    |    2 
 config/rs6000/power7.md                      |  318 +++
 config/rs6000/ppc-asm.h                      |  139 +
 config/rs6000/predicates.md                  |   75 
 config/rs6000/rs6000-c.c                     |  103 -
 config/rs6000/rs6000-protos.h                |   11 
 config/rs6000/rs6000.c                       | 2644 ++++++++++++++++++++-------
 config/rs6000/rs6000.h                       |  464 +++-
 config/rs6000/rs6000.md                      |  421 +++-
 config/rs6000/rs6000.opt                     |   56 
 config/rs6000/spe.md                         |    2 
 config/rs6000/sysv4.h                        |    4 
 config/rs6000/sysv4.opt                      |    6 
 config/rs6000/t-rs6000                       |   30 
 config/rs6000/vector.md                      |  664 ++++++
 config/rs6000/vsx.md                         | 1004 ++++++++++
 configure                                    |   54 
 configure.ac                                 |   23 
 doc/invoke.texi                              |   24 
 doc/md.texi                                  |   17 
 reload.c                                     |   10 
 testsuite/gcc.dg/vmx/vmx.exp                 |    2 
 testsuite/gcc.target/powerpc/popcount-2.c    |    9 
 testsuite/gcc.target/powerpc/popcount-3.c    |    9 
 testsuite/gcc.target/powerpc/pr39457.c       |   56 
 testsuite/gcc.target/powerpc/vsx-builtin-1.c |   42 
 testsuite/gcc.target/powerpc/vsx-builtin-2.c |   42 
 testsuite/gcc.target/powerpc/vsx-vector-1.c  |   74 
 testsuite/gcc.target/powerpc/vsx-vector-2.c  |   74 
 testsuite/gcc.target/powerpc/vsx-vector-3.c  |   48 
 testsuite/gcc.target/powerpc/vsx-vector-4.c  |   48 
 testsuite/lib/target-supports.exp            |   60 
 40 files changed, 5999 insertions(+), 1441 deletions(-)

View full diff with command:
/usr/bin/cvs -n -f diff -kk -u -p -N -r 1.1 -r 1.2 gcc44-power7.patchIndex: gcc44-power7.patch
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/gcc44-power7.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- gcc44-power7.patch	23 Mar 2009 10:56:41 -0000	1.1
+++ gcc44-power7.patch	25 Aug 2009 20:26:28 -0000	1.2
@@ -1,3 +1,247 @@
+2009-04-08  Michael Meissner  <meissner at linux.vnet.ibm.com>
+
+	* doc/invoke.texi (-mvsx-vector-memory): Make debug switches
+	undoucmented.
+	(-mvsx-vector-float): Ditto.
+	(-mvsx-vector-double): Ditto.
+	(-mvsx-scalar-double): Ditto.
+	(-mvsx-scalar-memory): Ditto.
+
+	* config/rs6000/vector.md (VEC_R): New iterator for reload
+	patterns.
+	(mov<mode>): Don't call rs6000_emit_move.
+	(reload_<VEC_R:mode>_<P:mptrsize>_*): New insns for
+	secondary_reload support.
+	(vec_reload_and_plus_<mptrsize>): New insns in case reload needs
+	to move a VSX/Altivec (and (plus reg reg) -16) type address to a
+	base register.
+
+	* config/rs6000/rs6000-protos.h (rs6000_secondary_reload_inner):
+	Rename from rs6000_vector_secondary_reload.
+
+	* config/rs6000/rs6000.opt (-mvsx-vector-memory): Make debug
+	switches undoucmented.
+	(-mvsx-vector-float): Ditto.
+	(-mvsx-vector-double): Ditto.
+	(-mvsx-scalar-double): Ditto.
+	(-mvsx-scalar-memory): Ditto.
+	(-mvsx-v4sf-altivec-regs): New undocumented debug switch to
+	control whether V4SF types prefer the Altivec registers or all of
+	the VSX registers.
+	(-mreload-functions): New undocumented debug switch to
+	enable/disable the secondary reload support.
+
+	* config/rs6000/rs6000.c (rs6000_regno_regclass): New global to
+	map register number to regclass.
+	(rs6000_vector_reload): New array to hold the secondary reload
+	insn codes for the vector types.
+	(rs6000_init_hard_regno_mode_ok): Fill in rs6000_regno_regclass
+	and rs6000_vector_reload.
+	(rs6000_mode_dependent_address): Using AND in addresses is mode
+	dependent.
+	(rs6000_emit_move): Add debug information if -mdebug=addr.
+	(rs6000_reload_register_type): Classify register classes for
+	secondary reload.
+	(rs6000_secondary_reload): For the vector types, add reload
+	support to support reg+reg addressing for gprs, and reg+offset
+	addressing for vector registers.
+	(rs6000_secondary_reload_inner): Rename from
+	rs6000_vector_secondary_reload.  Fixup gpr addressing to just reg
+	or reg+offset, and vector addressing to just reg or reg+reg.
+	(rs6000_preferred_reload_class): Make sure all cases set the
+	return value.  If VSX/Altivec address with AND -16, prefer using
+	an Altivec register.
+	(rs6000_secondary_memory_needed): Handle things like SFmode that
+	can go in floating registers, but not altivec registers under
+	-mvsx.
+
+	* config/rs6000/vsx.md (VSX_U): New iterator for load/store with
+	update.
+	(VSi, VSI): Reorder fields.
+	(VSd): Add support for load/store with update rewrite.
+	(VSv): Ditto.
+	(VStype_load_update): New mode attribute for load/store with
+	update.
+	(VStype_store_update): Ditto.
+	(vsx_mov<type>): Use * instead of store/load attributes for
+	multi-instruction gpr loads/stores.
+	(vsx_reload**): Delete unused reload patterns.
+
+	* config/rs6000/rs6000.h (REGNO_REG_CLASS): Change from a bunch of
+	if statements to using a lookup table.
+	(rs6000_regno_regclass): Lookup table for REGNO_REG_CLASS.
+
+	* config/rs6000/altivec.md (altivec_reload*): Delete unused reload
+	patterns.
+
+	* config/rs6000/rs6000.md (tptrsize, mptrsize): New mode
+	attributes for -m32/-m64 support.
+
+2009-03-27  Jakub Jelinek  <jakub at redhat.com>
+
+	PR target/39558
+	* macro.c (cpp_get_token): If macro_to_expand returns NULL
+	and used some tokens, add CPP_PADDING before next token.
+
+	* gcc.target/powerpc/altivec-29.c: New test.
+
+2009-03-27  Michael Meissner  <meissner at linux.vnet.ibm.com>
+
+	* config/rs6000/constraints.md ("wZ" constraint): New constraint
+	for using Altivec loads/stores under VSX for vector realignment.
+
+	* config/rs6000/predicates.md
+	(altivec_indexed_or_indirect_operand): New predicate to recognize
+	Altivec load/stores with an explicit AND -16.
+
+	* config/rs6000/power7.md: Whitespace change.
+
+	* config/rs6000/rs6000.opt (-mpower7-adjust-cost): New debug
+	switch.
+
+	* config/rs6000/rs6000-c.c (altivec_categorize_keyword): If -mvsx
+	and -mno-altivec, recognize the 'vector' keyword, but do not
+	recognize 'bool' or 'pixel'.  Recognize vector double under VSX.
+	(init_vector_keywords): Ditto.
+	(rs6000_macro_to_expand): Ditto.
+	(altivec_overloaded_builtins): Add VSX overloaded builtins.
+	(altivec_resolve_overloaded_builtin): Ditto.
+
+	* config/rs6000/rs6000.c (rs6000_debug_cost): New global for
+	-mdebug=cost.
+	(rs6000_debug_address_cost): New function for printing costs if
+	-mdebug=cost.
+	(rs6000_debug_rtx_costs): Ditto.
+	(rs6000_debug_adjust_cost): Ditto.
+	(rs6000_override_options): Add -mdebug=cost support.
+	(rs6000_legitimize_reload_address): Allow Altivec loads and stores
+	with an explicit AND -16, in VSX for vector realignment.
+	(rs6000_legitimize_reload_address): Ditto.
+	(rs6000_legitimate_address): Ditto.
+	(print_operand): Ditto.
+	(bdesc_3arg): Add VSX builtins.
+	(bdesc_2arg): Ditto.
+	(bdesc_1arg): Ditto.
+	(bdesc_abs): Ditto.
+	(vsx_expand_builtin): Stub function for expanding VSX builtins.
+	(rs6000_expand_builtin): Call vsx_expand_builtin.
+
+	* config/rs6000/vsx.md (most DF insns): Merge DF insns in with
+	V2DF and V4SF insns, rather than duplicating much of the code.
+	(all insns): Go through all insns, and alternatives to address the
+	full VSX register set, as a non-preferred option.
+	(vsx_mod<mode>): Add support for using Altivec load/store with
+	explicit AND -16.  Use xxlor to copy registers, not copy sign.
+	(multiply/add insns): Add an expander and unspec so the insn can
+	be used directly even if -mno-fused-madd.
+	(vsx_tdiv<mode>3): New insn for use as a builtin function.
+	(vsx_tsqrt<mode>2): Ditto.
+	(vsx_rsqrte<mode>2): Ditto.
+
+	* config/rs6000/rs6000.h (rs6000_debug_cost): New for
+	-mdebug=cost.
+	(TARGET_DEBUG_COST): Ditto.
+	(VSX_BUILTIN_*): Merge the two forms of multiply/add instructions
+	into a single insn.  Start to add overloaded VSX builtins.
+
+	* config/rs6000/altivec.md (build_vector_mask_for_load): Delete
+	VSX code.
+
+	* config/rs6000/rs6000.md (btruncsf2): Delete extra space.
+	(movdf_hardfloat32): Use xxlor instead of xscpsgndp to copy data.
+	(movdf_hardfloat64_mfpgpr): Ditto.
+	(movdf_hardfloat64): Ditto.
+
+2009-03-13  Michael Meissner  <meissner at linux.vnet.ibm.com>
+
+	PR target/39457
+	* config/rs6000/rs6000.opt (-mdisallow-float-in-lr-ctr): Add
+	temporary debug switch.
+
+	* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Revert
+	behavior of disallowing 
+
+2009-03-13  Michael Meissner  <meissner at linux.vnet.ibm.com>
+
+	* config/rs6000/vector.md (vec_extract_evenv2df): Delete, insn
+	causes problems in building spec 2006.
+	(vec_extract_oddv2df): Ditto.
+	(vec_pack_trunc_v2df): New expanders for VSX vectorized
+	conversions.
+	(vec_pack_sfix_trunc_v2df): Ditto.
+	(vec_pack_ufix_trunc_v2df): Ditto.
+	(vec_unpacks_hi_v4sf): Ditto.
+	(vec_unpacks_lo_v4sf): Ditto.
+	(vec_unpacks_float_hi_v4si): Ditto.
+	(vec_unpacks_float_lo_v4si): Ditto.
+	(vec_unpacku_float_hi_v4si): Ditto.
+	(vec_unpacku_float_lo_v4si): Ditto.
+
+	* config/rs6000/rs6000-protos.h (rs6000_vector_secondary_reload):
+	Declaration for new target hook.
+
+	* config/rs6000/rs6000.c (TARGET_SECONDARY_RELOAD): Add new target
+	hook for eventually fixing up the memory references for Altivec
+	and VSX reloads to be reg+reg instead of reg+offset.  Right now,
+	this is a stub function that prints debug information if
+	-mdebug=addr and then calls default_secondary_reload.
+	(rs6000_secondary_reload): Ditto.
+	(rs6000_vector_secondary_reload): Ditto.
+	(rs6000_builtin_conversion): Add support for V2DI/V2DF
+	conversions.
[...6181 lines suppressed...]
@@ -9023,7 +10958,7 @@ testsuite/
     (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
  
  (define_split
-@@ -7718,7 +7828,9 @@ (define_insn "*anddi3_internal3_mc"
+@@ -7718,7 +7838,9 @@
     #
     #
     #"
@@ -9034,7 +10969,7 @@ testsuite/
     (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
  
  (define_split
-@@ -7858,7 +7970,7 @@ (define_insn "*booldi3_internal2"
+@@ -7858,7 +7980,7 @@
    "@
     %q4. %3,%1,%2
     #"
@@ -9043,7 +10978,7 @@ testsuite/
     (set_attr "length" "4,8")])
  
  (define_split
-@@ -7887,7 +7999,7 @@ (define_insn "*booldi3_internal3"
+@@ -7887,7 +8009,7 @@
    "@
     %q4. %0,%1,%2
     #"
@@ -9052,7 +10987,7 @@ testsuite/
     (set_attr "length" "4,8")])
  
  (define_split
-@@ -7958,7 +8070,7 @@ (define_insn "*boolcdi3_internal2"
+@@ -7958,7 +8080,7 @@
    "@
     %q4. %3,%2,%1
     #"
@@ -9061,7 +10996,7 @@ testsuite/
     (set_attr "length" "4,8")])
  
  (define_split
-@@ -7987,7 +8099,7 @@ (define_insn "*boolcdi3_internal3"
+@@ -7987,7 +8109,7 @@
    "@
     %q4. %0,%2,%1
     #"
@@ -9070,7 +11005,7 @@ testsuite/
     (set_attr "length" "4,8")])
  
  (define_split
-@@ -8024,7 +8136,7 @@ (define_insn "*boolccdi3_internal2"
+@@ -8024,7 +8146,7 @@
    "@
     %q4. %3,%1,%2
     #"
@@ -9079,7 +11014,7 @@ testsuite/
     (set_attr "length" "4,8")])
  
  (define_split
-@@ -8053,7 +8165,7 @@ (define_insn "*boolccdi3_internal3"
+@@ -8053,7 +8175,7 @@
    "@
     %q4. %0,%1,%2
     #"
@@ -9088,7 +11023,7 @@ testsuite/
     (set_attr "length" "4,8")])
  
  (define_split
-@@ -8070,6 +8182,51 @@ (define_split
+@@ -8070,6 +8192,51 @@
  	(compare:CC (match_dup 0)
  		    (const_int 0)))]
    "")
@@ -9140,7 +11075,7 @@ testsuite/
  
  ;; Now define ways of moving data around.
  
-@@ -8473,8 +8630,8 @@ (define_split
+@@ -8473,8 +8640,8 @@
  ;; The "??" is a kludge until we can figure out a more reasonable way
  ;; of handling these non-offsettable values.
  (define_insn "*movdf_hardfloat32"
@@ -9151,14 +11086,14 @@ testsuite/
    "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
     && (gpc_reg_operand (operands[0], DFmode)
         || gpc_reg_operand (operands[1], DFmode))"
-@@ -8553,19 +8710,30 @@ (define_insn "*movdf_hardfloat32"
+@@ -8553,19 +8720,30 @@
  	  return \"\";
  	}
      case 3:
 -      return \"fmr %0,%1\";
      case 4:
 -      return \"lfd%U1%X1 %0,%1\";
-+      return \"xscpsgndp %x0,%x1,%x1\";
++      return \"xxlor %x0,%x1,%x1\";
      case 5:
 -      return \"stfd%U0%X0 %1,%0\";
      case 6:
@@ -9187,7 +11122,7 @@ testsuite/
  
  (define_insn "*movdf_softfloat32"
    [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
-@@ -8613,19 +8781,26 @@ (define_insn "*movdf_softfloat32"
+@@ -8613,19 +8791,26 @@
  ; ld/std require word-aligned displacements -> 'Y' constraint.
  ; List Y->r and r->Y before r->r for reload.
  (define_insn "*movdf_hardfloat64_mfpgpr"
@@ -9204,8 +11139,8 @@ testsuite/
     std%U0%X0 %1,%0
     ld%U1%X1 %0,%1
     mr %0,%1
-+   xscpsgndp %x0,%x1,%x1
-+   xscpsgndp %x0,%x1,%x1
++   xxlor %x0,%x1,%x1
++   xxlor %x0,%x1,%x1
 +   lxsd%U1x %x0,%y1
 +   lxsd%U1x %x0,%y1
 +   stxsd%U0x %x1,%y0
@@ -9217,7 +11152,7 @@ testsuite/
     mt%0 %1
     mf%1 %0
     {cror 0,0,0|nop}
-@@ -8634,33 +8809,40 @@ (define_insn "*movdf_hardfloat64_mfpgpr"
+@@ -8634,33 +8819,40 @@
     #
     mftgpr %0,%1
     mffgpr %0,%1"
@@ -9242,8 +11177,8 @@ testsuite/
     std%U0%X0 %1,%0
     ld%U1%X1 %0,%1
     mr %0,%1
-+   xscpsgndp %x0,%x1,%x1
-+   xscpsgndp %x0,%x1,%x1
++   xxlor %x0,%x1,%x1
++   xxlor %x0,%x1,%x1
 +   lxsd%U1x %x0,%y1
 +   lxsd%U1x %x0,%y1
 +   stxsd%U0x %x1,%y0
@@ -9265,7 +11200,7 @@ testsuite/
  
  (define_insn "*movdf_softfloat64"
    [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
-@@ -9237,15 +9419,16 @@ (define_insn "*movti_string"
+@@ -9237,15 +9429,16 @@
  (define_insn "*movti_ppc64"
    [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r")
  	(match_operand:TI 1 "input_operand" "r,r,m"))]
@@ -9285,7 +11220,7 @@ testsuite/
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
    "
-@@ -9271,7 +9454,7 @@ (define_split
+@@ -9271,7 +9464,7 @@
  (define_split
    [(set (match_operand:TI 0 "nonimmediate_operand" "")
          (match_operand:TI 1 "input_operand" ""))]
@@ -9294,7 +11229,7 @@ testsuite/
     && gpr_or_gpr_p (operands[0], operands[1])"
    [(pc)]
  { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
-@@ -14891,6 +15074,8 @@ (define_insn "prefetch"
+@@ -14891,6 +15084,8 @@
  
  
  (include "sync.md")
@@ -9303,8 +11238,8 @@ testsuite/
  (include "altivec.md")
  (include "spe.md")
  (include "dfp.md")
---- gcc/config/rs6000/e500.h	(.../trunk)	(revision 144557)
-+++ gcc/config/rs6000/e500.h	(.../branches/ibm/power7-meissner)	(revision 144730)
+--- gcc/config/rs6000/e500.h	(.../trunk)	(revision 145777)
++++ gcc/config/rs6000/e500.h	(.../branches/ibm/power7-meissner)	(revision 146027)
 @@ -37,6 +37,8 @@
        {									\
  	if (TARGET_ALTIVEC)						\
@@ -9314,8 +11249,8 @@ testsuite/
  	if (TARGET_64BIT)						\
  	  error ("64-bit E500 not supported");				\
  	if (TARGET_HARD_FLOAT && TARGET_FPRS)				\
---- gcc/config/rs6000/driver-rs6000.c	(.../trunk)	(revision 144557)
-+++ gcc/config/rs6000/driver-rs6000.c	(.../branches/ibm/power7-meissner)	(revision 144730)
+--- gcc/config/rs6000/driver-rs6000.c	(.../trunk)	(revision 145777)
++++ gcc/config/rs6000/driver-rs6000.c	(.../branches/ibm/power7-meissner)	(revision 146027)
 @@ -343,11 +343,115 @@ detect_processor_aix (void)
  #endif /* _AIX */
  
@@ -9496,9 +11431,9 @@ testsuite/
    return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
  }
  
---- gcc/config/rs6000/sysv4.h	(.../trunk)	(revision 144557)
-+++ gcc/config/rs6000/sysv4.h	(.../branches/ibm/power7-meissner)	(revision 144730)
-@@ -119,9 +119,9 @@ do {									\
+--- gcc/config/rs6000/sysv4.h	(.../trunk)	(revision 145777)
++++ gcc/config/rs6000/sysv4.h	(.../branches/ibm/power7-meissner)	(revision 146027)
+@@ -120,9 +120,9 @@ do {									\
    else if (!strcmp (rs6000_abi_name, "i960-old"))			\
      {									\
        rs6000_current_abi = ABI_V4;					\

gcc44-rh330771.patch:
 Makefile.am |    2 ++
 Makefile.in |    2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

Index: gcc44-rh330771.patch
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/gcc44-rh330771.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- gcc44-rh330771.patch	20 Feb 2009 19:59:34 -0000	1.1
+++ gcc44-rh330771.patch	25 Aug 2009 20:26:28 -0000	1.2
@@ -3,20 +3,20 @@
 	* Makefile.am (libgcj_tools_la_LIBADD): Add.
 	* Makefile.in: Regenerated.
 
---- libjava/Makefile.am.jj	2007-03-17 09:20:30.000000000 +0100
-+++ libjava/Makefile.am	2007-10-16 15:45:14.000000000 +0200
-@@ -277,6 +277,8 @@ EXTRA_libgcj_la_SOURCES = java/lang/Obje
- 
- libgcj_tools_la_SOURCES = classpath/tools/tools.zip
- libgcj_tools_la_GCJFLAGS = $(AM_GCJFLAGS) -findirect-dispatch -fno-indirect-classes  -fsource-filename=$(here)/classpath/tools/all-classes.lst
+--- libjava/Makefile.am.jj	2009-05-06 08:14:50.000000000 +0200
++++ libjava/Makefile.am	2009-05-06 10:26:43.000000000 +0200
+@@ -314,6 +314,8 @@ libgcj_tools_la_SOURCES = classpath/tool
+ libgcj_tools_la_GCJFLAGS = $(AM_GCJFLAGS) -findirect-dispatch \
+  -fno-bootstrap-classes -fno-indirect-classes \
+  -fsource-filename=$(here)/classpath/tools/all-classes.lst
 +## See jv_convert_LDADD.
 +libgcj_tools_la_LIBADD = -L$(here)/.libs libgcj.la
  libgcj_tools_la_LDFLAGS = -rpath $(toolexeclibdir) \
   -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
   $(LIBGCJ_LD_SYMBOLIC_FUNCTIONS)
---- libjava/Makefile.in.jj	2007-07-04 21:11:11.000000000 +0200
-+++ libjava/Makefile.in	2007-10-16 15:56:07.000000000 +0200
-@@ -153,7 +153,6 @@ am__objects_1 = gnu/gcj/xlib/lib_gnu_awt
+--- libjava/Makefile.in.jj	2009-05-06 08:14:49.000000000 +0200
++++ libjava/Makefile.in	2009-05-06 10:27:18.000000000 +0200
+@@ -160,7 +160,6 @@ am__objects_1 = gnu/gcj/xlib/lib_gnu_awt
  am_lib_gnu_awt_xlib_la_OBJECTS = $(am__objects_1)
  lib_gnu_awt_xlib_la_OBJECTS = $(am_lib_gnu_awt_xlib_la_OBJECTS)
  @XLIB_AWT_TRUE at am_lib_gnu_awt_xlib_la_rpath = -rpath $(toolexeclibdir)
@@ -24,10 +24,10 @@
  am_libgcj_tools_la_OBJECTS = classpath/tools/libgcj_tools_la-tools.lo
  libgcj_tools_la_OBJECTS = $(am_libgcj_tools_la_OBJECTS)
  @INTERPRETER_TRUE at am__DEPENDENCIES_1 = gnu/classpath/jdwp.lo \
-@@ -941,6 +940,7 @@ libgcj_la_LINK = $(LIBLINK)
- EXTRA_libgcj_la_SOURCES = java/lang/Object.java
- libgcj_tools_la_SOURCES = classpath/tools/tools.zip
- libgcj_tools_la_GCJFLAGS = $(AM_GCJFLAGS) -findirect-dispatch -fno-indirect-classes  -fsource-filename=$(here)/classpath/tools/all-classes.lst
+@@ -1041,6 +1040,7 @@ libgcj_tools_la_GCJFLAGS = $(AM_GCJFLAGS
+  -fno-bootstrap-classes -fno-indirect-classes \
+  -fsource-filename=$(here)/classpath/tools/all-classes.lst
+ 
 +libgcj_tools_la_LIBADD = -L$(here)/.libs libgcj.la
  libgcj_tools_la_LDFLAGS = -rpath $(toolexeclibdir) \
   -version-info `grep -v '^\#' $(srcdir)/libtool-version` \


Index: mingw32-gcc.spec
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/mingw32-gcc.spec,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -p -r1.6 -r1.7
--- mingw32-gcc.spec	25 Jul 2009 12:17:32 -0000	1.6
+++ mingw32-gcc.spec	25 Aug 2009 20:26:28 -0000	1.7
@@ -1,14 +1,14 @@
-%define __os_install_post /usr/lib/rpm/brp-compress %{nil}
+%global __os_install_post /usr/lib/rpm/brp-compress %{nil}
 
-%define DATE 20090319
-%define SVNREV 144967
+%global DATE 20090818
+%global SVNREV 150873
 
 Name:           mingw32-gcc
-Version:        4.4.0
-Release:        0.8%{?dist}
+Version:        4.4.1
+Release:        1%{?dist}
 Summary:        MinGW Windows cross-compiler (GCC) for C
 
-License:        GPLv3+ and GPLv2+ with exceptions
+License:        GPLv3+, GPLv3+ with exceptions and GPLv2+ with exceptions
 Group:          Development/Languages
 
 # We use the same source as Fedora's native gcc.
@@ -25,8 +25,6 @@ Patch2:         gcc44-c++-builtin-redecl
 Patch3:         gcc44-ia64-libunwind.patch
 Patch4:         gcc44-java-nomulti.patch
 Patch5:         gcc44-ppc32-retaddr.patch
-Patch7:         gcc44-pr27898.patch
-Patch8:         gcc44-pr32139.patch
 Patch9:         gcc44-pr33763.patch
 Patch10:        gcc44-rh330771.patch
 Patch11:        gcc44-rh341221.patch
@@ -37,13 +35,15 @@ Patch16:        gcc44-libgomp-omp_h-mult
 Patch20:        gcc44-libtool-no-rpath.patch
 Patch21:        gcc44-cloog-dl.patch
 Patch22:        gcc44-raw-string.patch
-Patch24:        gcc44-atom.patch
-Patch25:        gcc44-pr39226.patch
-Patch26:        gcc44-power7.patch
-Patch27:        gcc44-power7-2.patch
+Patch24:        gcc44-unwind-debug-hook.patch
+Patch25:        gcc44-power7.patch
+Patch26:        gcc44-power7-2.patch
+Patch27:        gcc44-power7-3.patch
 Patch28:        gcc44-pr38757.patch
-Patch29:        gcc44-pr37959.patch
-Patch30:        gcc44-memmove-opt.patch
+#Patch29:        gcc44-libstdc++-docs.patch
+Patch30:        gcc44-rh503816-1.patch
+Patch31:        gcc44-rh503816-2.patch
+Patch32:        gcc44-unique-object.patch
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
@@ -128,8 +128,6 @@ MinGW Windows cross-compiler for FORTRAN
 %patch3 -p0 -b .ia64-libunwind~
 %patch4 -p0 -b .java-nomulti~
 %patch5 -p0 -b .ppc32-retaddr~
-%patch7 -p0 -b .pr27898~
-%patch8 -p0 -b .pr32139~
 %patch9 -p0 -b .pr33763~
 %patch10 -p0 -b .rh330771~
 %patch11 -p0 -b .rh341221~
@@ -140,13 +138,17 @@ MinGW Windows cross-compiler for FORTRAN
 %patch20 -p0 -b .libtool-no-rpath~
 %patch21 -p0 -b .cloog-dl~
 %patch22 -p0 -b .raw-string~
-%patch24 -p0 -b .atom~
-%patch25 -p0 -b .pr39226~
-%patch26 -p0 -b .power7~
-%patch27 -p0 -b .power7-2~
+%patch24 -p0 -b .unwind-debug-hook~
+%patch25 -p0 -b .power7~
+%patch26 -p0 -b .power7-2~
+%patch27 -p0 -b .power7-3~
 %patch28 -p0 -b .pr38757~
-%patch29 -p0 -b .pr37959~
-%patch30 -p0 -b .memmove-opt~
+%patch30 -p0 -b .rh503816-1~
+%patch31 -p0 -b .rh503816-2~
+%patch32 -p0 -b .unique-object~
+
+sed -i -e 's/4\.4\.2/%{version}/' gcc/BASE-VER
+echo 'Fedora MinGW %{version}-%{release}' > gcc/DEV-PHASE
 
 
 %build
@@ -216,7 +218,7 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %files
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_bindir}/i686-pc-mingw32-gcc
 %{_bindir}/i686-pc-mingw32-gcc-%{version}
 %{_bindir}/i686-pc-mingw32-gccbug
@@ -253,7 +255,7 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %files -n mingw32-cpp
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 /lib/i686-pc-mingw32-cpp
 %{_bindir}/i686-pc-mingw32-cpp
 %{_mandir}/man1/i686-pc-mingw32-cpp.1*
@@ -263,7 +265,7 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %files c++
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_bindir}/i686-pc-mingw32-g++
 %{_bindir}/i686-pc-mingw32-c++
 %{_mandir}/man1/i686-pc-mingw32-g++.1*
@@ -275,19 +277,19 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %files objc
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_libdir}/gcc/i686-pc-mingw32/%{version}/include/objc/
 %{_libdir}/gcc/i686-pc-mingw32/%{version}/libobjc.a
 %{_libexecdir}/gcc/i686-pc-mingw32/%{version}/cc1obj
 
 
 %files objc++
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_libexecdir}/gcc/i686-pc-mingw32/%{version}/cc1objplus
 
 
 %files gfortran
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_bindir}/i686-pc-mingw32-gfortran
 %{_mandir}/man1/i686-pc-mingw32-gfortran.1*
 %{_libdir}/gcc/i686-pc-mingw32/%{version}/libgfortran.a
@@ -296,6 +298,12 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Sun Aug 23 2009 Kalev Lember <kalev at smartlink.ee> - 4.4.1-1
+- Update to gcc 4.4.1 20090818 svn 150873.
+- Patches taken from native Fedora gcc-4.4.1-6.
+- Replaced %%define with %%global and updated %%defattr.
+- Changed license to match native Fedora gcc package.
+
 * Sat Jul 25 2009 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 4.4.0-0.8
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
 


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/sources,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -p -r1.4 -r1.5
--- sources	23 Mar 2009 10:56:41 -0000	1.4
+++ sources	25 Aug 2009 20:26:28 -0000	1.5
@@ -1 +1 @@
-2992035eaf092d72eb98ad16b173f737  gcc-4.4.0-20090319.tar.bz2
+a280c87e7d0a44a99a6bc84bbe3eb86d  gcc-4.4.1-20090818.tar.bz2


--- gcc44-atom.patch DELETED ---


--- gcc44-memmove-opt.patch DELETED ---


--- gcc44-pr27898.patch DELETED ---


--- gcc44-pr32139.patch DELETED ---


--- gcc44-pr37959.patch DELETED ---


--- gcc44-pr39226.patch DELETED ---




More information about the scm-commits mailing list