rpms/mingw32-gcc/devel gcc44-atom.patch, NONE, 1.1 gcc44-memmove-opt.patch, NONE, 1.1 gcc44-power7-2.patch, NONE, 1.1 gcc44-power7.patch, NONE, 1.1 gcc44-pr37959.patch, NONE, 1.1 gcc44-pr38757.patch, NONE, 1.1 gcc44-pr39226.patch, NONE, 1.1 .cvsignore, 1.3, 1.4 gcc44-c++-builtin-redecl.patch, 1.1, 1.2 gcc44-cloog-dl.patch, 1.1, 1.2 gcc44-raw-string.patch, 1.1, 1.2 mingw32-gcc.spec, 1.4, 1.5 sources, 1.3, 1.4 gcc44-diff.patch, 1.1, NONE gcc44-pr39175.patch, 1.1, NONE

Richard W.M. Jones rjones at fedoraproject.org
Mon Mar 23 10:56:43 UTC 2009


Author: rjones

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

Modified Files:
	.cvsignore gcc44-c++-builtin-redecl.patch gcc44-cloog-dl.patch 
	gcc44-raw-string.patch mingw32-gcc.spec sources 
Added Files:
	gcc44-atom.patch gcc44-memmove-opt.patch gcc44-power7-2.patch 
	gcc44-power7.patch gcc44-pr37959.patch gcc44-pr38757.patch 
	gcc44-pr39226.patch 
Removed Files:
	gcc44-diff.patch gcc44-pr39175.patch 
Log Message:
* Mon Mar 23 2009 Richard W.M. Jones <rjones at redhat.com> - 4.4.0-0.7
- New native Fedora version gcc 4.4.0 20090319 svn 144967.
- Enable _smp_mflags.


gcc44-atom.patch:

--- NEW FILE gcc44-atom.patch ---
2009-02-05  Joey Ye  <joey.ye at intel.com>
	    Xuepeng Guo <xuepeng.guo at intel.com>
	    H.J. Lu  <hongjiu.lu at intel.com>

	Atom pipeline model, tuning and insn selection.
	* rtlanal.c (reg_mentioned_by_mem_p_1): New function.
	(reg_mentioned_by_mem_p): New function.
	(reg_dep_by_addr_p): New function.

	* rtl.h (reg_mentioned_by_mem_p): Declare new function.
	(reg_dep_by_addr_p): Likewise.

	* config.gcc (atom): Add atom config options and target.

	* config/i386/i386.h (TARGET_ATOM): New target macro.
	(X86_TUNE_OPT_AGU): New tuning flag.
	(TARGET_OPT_AGU): New target option.
	(TARGET_CPU_DEFAULT_atom): New CPU default.
	(PROCESSOR_ATOM): New processor.

	* config/i386/i386-c.c (ix86_target_macros_internal): New case
	PROCESSOR_ATOM.
	(ix86_target_macros_internal): Likewise.

	* config/i386/i386-protos.h (ix86_lea_for_add_ok): Declare new
	function.
	(ix86_dep_by_shift_count): Likewise.
	(ix86_agi_dependent): Likewise.

	* config/i386/i386.c (atom_cost): New cost.
	(m_ATOM): New macro flag.
	(initial_ix86_tune_fe): Set m_ATOM.
	(x86_accumulate_outgoing_args): Likewise.
	(x86_arch_always_fancy_math_387): Likewise.
	(processor_target): Add Atom cost.
	(cpu_names): Add Atom cpu name.
	(override_options): Set Atom ISA.
	(LEA_SEARCH_THRESHOLD): New macro.
	(distance_non_agu_define): New function.
	(distance_agu_use): Likewise.
	(ix86_lea_for_add_ok): Likewise.
	(ix86_dep_by_shift_count): Likewise.
	(ix86_agi_dependent): Make it global.
	(ix86_issue_rate): New case PROCESSOR_ATOM.
	(ix86_adjust_cost): Likewise.

	* config/i386/i386.md (cpu): Add new value "atom".
	(atom.md): Include atom.md.
	(use_carry, movu): New attr.
	(adddi3_carry_rex64): Set attr "use_carry".
	(addqi3_carry): Likewise.
	(addhi3_carry): Likewise.
	(addsi3_carry): Likewise.
	(*addsi3_carry_zext): Likewise.
	(subdi3_carry_rex64): Likewise.
	(subqi3_carry): Likewise.
	(subhi3_carry): Likewise.
	(subsi3_carry): Likewise.
	(x86_movdicc_0_m1_rex64): Likewise.
	(*x86_movdicc_0_m1_se): Likewise.
	(x86_movsicc_0_m1): Likewise.
	(*x86_movsicc_0_m1_se): Likewise.
	(*adddi_1_rex64): Emit add insn as much as possible.
	(*addsi_1): Likewise.
	(return_internal): Set atom_unit.
	(return_internal_long): Likewise.
	(return_pop_internal): Likewise.
	(*rcpsf2_sse): Set atom_sse_attr attr.
	(*qrt<mode>2_sse): Likewise.
	(*prefetch_sse): Likewise.

	* config/i386/sse.md (cpu): Set attr "atom_sse_attr".
	(*prefetch_sse_rex): Likewise.
	(sse_rcpv4sf2): Likewise.
	(sse_vmrcpv4sf2): Likewise.
	(sse_sqrtv4sf2): Likewise.
	(<sse>_vmsqrt<mode>2): Likewise.
	(sse_ldmxcsr): Likewise.
	(sse_stmxcsr): Likewise.
	(*sse_sfence): Likewise.
	(sse2_clflush): Likewise.
	(*sse2_mfence): Likewise.
	(*sse2_lfence): Likewise.
	(avx_movup<avxmodesuffixf2c><avxmodesuffix>): Set attr "movu".
	(<sse>_movup<ssemodesuffixf2c>): Likewise.
	(avx_movdqu<avxmodesuffix>): Likewise.
	(avx_lddqu<avxmodesuffix>): Likewise.
	(sse2_movntv2di): Change attr "type" to "ssemov".
	(sse2_movntsi): Likewise.
	(rsqrtv8sf2): Change attr "type" to "sseadd".
	(sse3_addsubv2df3): Set attr "atom_unit".
	(sse3_h<plusminus_insn>v4sf3): Likewise.
	(*sse2_pmaddwd): Likewise.
	(*vec_extractv2di_1_rex64): Likewise.
	(*vec_extractv2di_1_avx): Likewise.
	(sse2_psadbw): Likewise.
	(ssse3_phaddwv8hi3): Likewise.
	(ssse3_phaddwv4hi3): Likewise.
	(ssse3_phadddv4si3): Likewise.
	(ssse3_phadddv2si3): Likewise.
	(ssse3_phaddswv8hi3): Likewise.
	(ssse3_phaddswv4hi3): Likewise.
	(ssse3_phsubwv8hi3): Likewise.
	(ssse3_phsubwv4hi3): Likewise.
	(ssse3_phsubdv4si3): Likewise.
	(ssse3_phsubdv2si3): Likewise.
	(ssse3_phsubswv8hi3): Likewise.
	(ssse3_phsubswv4hi3): Likewise.
	(ssse3_pmaddubsw128): Likewise.
	(sse3_pmaddubsw: Likewise.
	(ssse3_palignrti): Likewise.
	(ssse3_palignrdi): Likewise.

	* config/i386/atom.md: New.

2009-02-05  H.J. Lu  <hongjiu.lu at intel.com>

	* config/i386/i386.c (ix86_agi_dependent): Remove the third
	argument.  Swap the first 2 arguments.
	(ix86_adjust_cost): Updated.

2009-01-30  Vladimir Makarov  <vmakarov at redhat.com>

	* genautomata.c: Add a new year to the copyright.  Add a new
	reference.
	(struct insn_reserv_decl): Add comments for member bypass_list.
	(find_bypass): Remove.
	(insert_bypass): New.
	(process_decls): Use insert_bypass.
	(output_internal_insn_latency_func): Output all bypasses with the
	same input insn in one switch case.

	* rtl.def (define_bypass): Describe bypass choice.
	* doc/md.texi (define_bypass): Ditto.

--- gcc/doc/md.texi	(.../trunk)	(revision 144460)
+++ gcc/doc/md.texi	(.../branches/ix86/atom)	(revision 144601)
@@ -7506,6 +7506,11 @@ be ignored for this case.  The additiona
 recognize complicated bypasses, e.g.@: when the consumer is only an address
 of insn @samp{store} (not a stored value).
 
+If there are more one bypass with the same output and input insns, the
+chosen bypass is the first bypass with a guard in description whose
+guard function returns nonzero.  If there is no such bypass, then
+bypass without the guard function is chosen.
+
 @findex exclusion_set
 @findex presence_set
 @findex final_presence_set
--- gcc/rtlanal.c	(.../trunk)	(revision 144460)
+++ gcc/rtlanal.c	(.../branches/ix86/atom)	(revision 144601)
@@ -728,6 +728,129 @@ reg_mentioned_p (const_rtx reg, const_rt
     }
   return 0;
 }
+
+static int
+reg_mentioned_by_mem_p_1 (const_rtx reg, const_rtx in,
+			  bool *mem_p)
+{
+  const char *fmt;
+  int i;
+  enum rtx_code code;
+
+  if (in == 0)
+    return 0;
+
+  if (reg == in)
+    return 1;
+
+  if (GET_CODE (in) == LABEL_REF)
+    return reg == XEXP (in, 0);
+
+  code = GET_CODE (in);
+
+  switch (code)
+    {
+      /* Compare registers by number.  */
+    case REG:
+      return REG_P (reg) && REGNO (in) == REGNO (reg);
+
+      /* These codes have no constituent expressions
+	 and are unique.  */
+    case SCRATCH:
+    case CC0:
+    case PC:
+      return 0;
+
+    case CONST_INT:
+    case CONST_VECTOR:
+    case CONST_DOUBLE:
+    case CONST_FIXED:
+      /* These are kept unique for a given value.  */
+      return 0;
+
+    default:
+      break;
+    }
+
[...2433 lines suppressed...]
+   USE_INSN.  */
+
+bool
+ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
+{
+  rtx set_pattern = PATTERN (set_insn);
+  rtx set_dest;
+  rtx shift_rtx;
+  rtx use_pattern;
+
+  /* Retrieve destination of set_insn */
+  switch (GET_CODE (set_pattern))
+    {
+    case SET:
+      set_dest = SET_DEST (set_pattern);
+      break;
+    case PARALLEL:
+      set_pattern = XVECEXP (set_pattern, 0, 0);
+      if (GET_CODE (set_pattern ) == SET)
+	{
+	  set_dest = SET_DEST (set_pattern);
+	  break;
+	}
+    default:
+      set_dest = NULL;
+      break;
+    }
+  if (!set_dest || !REG_P (set_dest))
+    return false;
+
+  /* Retrieve shift count of use_insn */
+  use_pattern = PATTERN (use_insn);
+  switch (GET_CODE (use_pattern))
+    {
+    case SET:
+      shift_rtx = XEXP (use_pattern, 1);
+      break;
+    case PARALLEL:
+      set_pattern = XVECEXP (use_pattern, 0, 0);
+      if (GET_CODE (set_pattern) == SET)
+	{
+	  shift_rtx = XEXP (set_pattern, 1);
+	  break;
+	}
+    default:
+      shift_rtx = NULL;
+      break;
+    }
+
+  if (shift_rtx 
+      && (GET_CODE (shift_rtx) == ASHIFT
+	  || GET_CODE (shift_rtx) == LSHIFTRT
+	  || GET_CODE (shift_rtx) == ASHIFTRT
+	  || GET_CODE (shift_rtx) == ROTATE
+	  || GET_CODE (shift_rtx) == ROTATERT))
+    {
+      rtx shift_count = XEXP (shift_rtx, 1);
+      gcc_assert (shift_count);
+
+      /* Return true if shift count is dest of set_insn */
+      if (REG_P (shift_count)
+	  && true_regnum (set_dest) == true_regnum (shift_count))
+	return true;
+    }
+
+  return false;
+}
+
 /* Return TRUE or FALSE depending on whether the unary operator meets the
    appropriate constraints.  */
 
@@ -18985,6 +19333,7 @@ ix86_issue_rate (void)
   switch (ix86_tune)
     {
     case PROCESSOR_PENTIUM:
+    case PROCESSOR_ATOM:
     case PROCESSOR_K6:
       return 2;
 
@@ -19051,41 +19400,21 @@ ix86_flags_dependent (rtx insn, rtx dep_
   return 1;
 }
 
-/* A subroutine of ix86_adjust_cost -- return true iff INSN has a memory
-   address with operands set by DEP_INSN.  */
+/* Return true iff USE_INSN has a memory address with operands set by
+   SET_INSN.  */
 
-static int
-ix86_agi_dependent (rtx insn, rtx dep_insn, enum attr_type insn_type)
+bool
+ix86_agi_dependent (rtx set_insn, rtx use_insn)
 {
-  rtx addr;
-
-  if (insn_type == TYPE_LEA
-      && TARGET_PENTIUM)
-    {
-      addr = PATTERN (insn);
-
-      if (GET_CODE (addr) == PARALLEL)
-	addr = XVECEXP (addr, 0, 0);
-
-      gcc_assert (GET_CODE (addr) == SET);
-
-      addr = SET_SRC (addr);
-    }
-  else
-    {
-      int i;
-      extract_insn_cached (insn);
-      for (i = recog_data.n_operands - 1; i >= 0; --i)
-	if (MEM_P (recog_data.operand[i]))
-	  {
-	    addr = XEXP (recog_data.operand[i], 0);
-	    goto found;
-	  }
-      return 0;
-    found:;
-    }
-
-  return modified_in_p (addr, dep_insn);
+  int i;
+  extract_insn_cached (use_insn);
+  for (i = recog_data.n_operands - 1; i >= 0; --i)
+    if (MEM_P (recog_data.operand[i]))
+      {
+	rtx addr = XEXP (recog_data.operand[i], 0);
+	return modified_in_p (addr, set_insn) != 0;
+      }
+  return false;
 }
 
 static int
@@ -19113,8 +19442,19 @@ ix86_adjust_cost (rtx insn, rtx link, rt
     {
     case PROCESSOR_PENTIUM:
       /* Address Generation Interlock adds a cycle of latency.  */
-      if (ix86_agi_dependent (insn, dep_insn, insn_type))
-	cost += 1;
+      if (insn_type == TYPE_LEA)
+	{
+	  rtx addr = PATTERN (insn);
+
+	  if (GET_CODE (addr) == PARALLEL)
+	    addr = XVECEXP (addr, 0, 0);
+
+	  gcc_assert (GET_CODE (addr) == SET);
+
+	  addr = SET_SRC (addr);
+	  if (modified_in_p (addr, dep_insn))
+	    cost += 1;
+	}
 
       /* ??? Compares pair with jump/setcc.  */
       if (ix86_flags_dependent (insn, dep_insn, insn_type))
@@ -19123,7 +19463,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
       /* Floating point stores require value to be ready one cycle earlier.  */
       if (insn_type == TYPE_FMOV
 	  && get_attr_memory (insn) == MEMORY_STORE
-	  && !ix86_agi_dependent (insn, dep_insn, insn_type))
+	  && !ix86_agi_dependent (dep_insn, insn))
 	cost += 1;
       break;
 
@@ -19146,7 +19486,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
 	 in parallel with previous instruction in case
 	 previous instruction is not needed to compute the address.  */
       if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
-	  && !ix86_agi_dependent (insn, dep_insn, insn_type))
+	  && !ix86_agi_dependent (dep_insn, insn))
 	{
 	  /* Claim moves to take one cycle, as core can issue one load
 	     at time and the next load can start cycle later.  */
@@ -19175,7 +19515,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
 	 in parallel with previous instruction in case
 	 previous instruction is not needed to compute the address.  */
       if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
-	  && !ix86_agi_dependent (insn, dep_insn, insn_type))
+	  && !ix86_agi_dependent (dep_insn, insn))
 	{
 	  /* Claim moves to take one cycle, as core can issue one load
 	     at time and the next load can start cycle later.  */
@@ -19192,6 +19532,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
     case PROCESSOR_ATHLON:
     case PROCESSOR_K8:
     case PROCESSOR_AMDFAM10:
+    case PROCESSOR_ATOM:
     case PROCESSOR_GENERIC32:
     case PROCESSOR_GENERIC64:
       memory = get_attr_memory (insn);
@@ -19200,7 +19541,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
 	 in parallel with previous instruction in case
 	 previous instruction is not needed to compute the address.  */
       if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
-	  && !ix86_agi_dependent (insn, dep_insn, insn_type))
+	  && !ix86_agi_dependent (dep_insn, insn))
 	{
 	  enum attr_unit unit = get_attr_unit (insn);
 	  int loadcost = 3;

gcc44-memmove-opt.patch:

--- NEW FILE gcc44-memmove-opt.patch ---
2009-03-18  Jakub Jelinek  <jakub at redhat.com>

	* builtins.c (fold_builtin_memory_op): Optimize memmove
	into memcpy if we can prove source and destination don't overlap.

	* gcc.dg/memmove-2.c: New test.
	* gcc.dg/memmove-3.c: New test.

--- gcc/builtins.c.jj	2009-03-04 20:06:31.000000000 +0100
+++ gcc/builtins.c	2009-03-18 18:19:28.000000000 +0100
@@ -8882,17 +8882,74 @@ fold_builtin_memory_op (tree dest, tree 
 	     really mandatory?
 
 	     If either SRC is readonly or length is 1, we can use memcpy.  */
-	  if (dest_align && src_align
-	      && (readonly_data_expr (src)
-	          || (host_integerp (len, 1)
-		      && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
-			  tree_low_cst (len, 1)))))
+	  if (!dest_align || !src_align)
+	    return NULL_TREE;
+	  if (readonly_data_expr (src)
+	      || (host_integerp (len, 1)
+		  && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
+		      tree_low_cst (len, 1))))
 	    {
 	      tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
 	      if (!fn)
 		return NULL_TREE;
               return build_call_expr (fn, 3, dest, src, len);
 	    }
+
+	  /* If *src and *dest can't overlap, optimize into memcpy as well.  */
+	  srcvar = build_fold_indirect_ref (src);
+	  destvar = build_fold_indirect_ref (dest);
+	  if (srcvar && !TREE_THIS_VOLATILE (srcvar)
+	      && destvar && !TREE_THIS_VOLATILE (destvar))
+	    {
+	      tree src_base, dest_base, fn;
+	      HOST_WIDE_INT src_offset = 0, dest_offset = 0;
+	      HOST_WIDE_INT size = -1;
+	      HOST_WIDE_INT maxsize = -1;
+
+	      src_base = srcvar;
+	      if (handled_component_p (src_base))
+		src_base = get_ref_base_and_extent (src_base, &src_offset,
+						    &size, &maxsize);
+	      dest_base = destvar;
+	      if (handled_component_p (dest_base))
+		dest_base = get_ref_base_and_extent (dest_base, &dest_offset,
+						     &size, &maxsize);
+	      if (host_integerp (len, 1))
+		{
+		  maxsize = tree_low_cst (len, 1);
+		  if (maxsize
+		      > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT)
+		    maxsize = -1;
+		  else
+		    maxsize *= BITS_PER_UNIT;
+		}
+	      else
+		maxsize = -1;
+	      if (SSA_VAR_P (src_base)
+		  && SSA_VAR_P (dest_base))
+		{
+		  if (operand_equal_p (src_base, dest_base, 0)
+		      && ranges_overlap_p (src_offset, maxsize,
+					   dest_offset, maxsize))
+		    return NULL_TREE;
+		}
+	      else if (TREE_CODE (src_base) == INDIRECT_REF
+		       && TREE_CODE (dest_base) == INDIRECT_REF)
+		{
+		  if (! operand_equal_p (TREE_OPERAND (src_base, 0),
+					 TREE_OPERAND (dest_base, 0), 0)
+		      || ranges_overlap_p (src_offset, maxsize,
+					   dest_offset, maxsize))
+		    return NULL_TREE;
+		}
+	      else
+		return NULL_TREE;
+
+	      fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+	      if (!fn)
+		return NULL_TREE;
+	      return build_call_expr (fn, 3, dest, src, len);
+	    }
 	  return NULL_TREE;
 	}
 
--- gcc/testsuite/gcc.dg/memmove-2.c.jj	2009-03-18 18:30:17.000000000 +0100
+++ gcc/testsuite/gcc.dg/memmove-2.c	2009-03-18 18:30:49.000000000 +0100
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "memmove" 0 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
+char a[40];
+extern void bar (char *);
+
+void
+foo (void)
+{
+  char b[10];
+  __builtin_memmove (&a[0], &a[20], 20);
+  __builtin_memmove (&b[1], &a[25], 9);
+  bar (b);
+}
--- gcc/testsuite/gcc.dg/memmove-3.c.jj	2009-03-18 18:30:19.000000000 +0100
+++ gcc/testsuite/gcc.dg/memmove-3.c	2009-03-18 18:31:01.000000000 +0100
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "memmove" 3 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
+char a[40];
+struct A { char a[30]; };
+
+void
+foo (struct A *p, char *q, char *r)
+{
+  char b[10];
+  __builtin_memmove (&a[1], &a[19], 20);
+  __builtin_memmove (&p->a[1], &p->a[9], 10);
+  __builtin_memmove (q, r, 9);
+}

gcc44-power7-2.patch:

--- NEW FILE gcc44-power7-2.patch ---
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.
	(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;
 
 /* 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;
 
-  /* 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);
 
@@ -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;
+
+	  return TYPE_UNSIGNED (type)
+	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS]
+	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
+
 	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))
 	{
+	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];
+
 	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];
+
 	default:
 	  return NULL_TREE;
 	}
@@ -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
 	fprintf (stderr, "NULL returned\n");
+      fprintf (stderr, "\n");
     }
 
   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);
 	}
+
+      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");
     }
 
   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 },
+
   { 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 },
+
   /* 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 ();
 	}
@@ -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;
+    }
+
+  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");
     }
+
+  return ret;
 }
 
 static tree
@@ -12140,6 +12241,54 @@ rs6000_check_sdmode (tree *tp, int *walk
   return NULL_TREE;
 }
 
+/* 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)
+    {
+      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;
+    }
+  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)
     {
-      regno = REGNO (in);
-      if (regno >= FIRST_PSEUDO_REGISTER)
+      if (GET_CODE (in) == REG)
+	{
+	  regno = REGNO (in);
+	  if (regno >= FIRST_PSEUDO_REGISTER)
+	    {
+	      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)
 	    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);
+}

gcc44-power7.patch:

--- NEW FILE gcc44-power7.patch ---
2009-03-09  Michael Meissner  <meissner at linux.vnet.ibm.com>

	* config/rs6000/vsx.md (vsx_store<mode>_update64): Use correct
	registers for store with update.
	(vsx_store<mode>_update32): Ditto.
	(vsx_storedf_update<VSbit>): Ditto.

2009-03-06  Michael Meissner  <meissner at linux.vnet.ibm.com>

	* doc/invoke.texi (-mvsx-scalar-memory): New switch, to switch to
	use VSX reg+reg addressing for all scalar double precision
	floating point.
	* config/rs6000/rs6000.opt (-vsx-scalar-memory): Ditto.
	
	* configure.ac (gcc_cv_as_powerpc_mfpgpr): Set binutils version to
	2.19.2.
	(gcc_cv_as_powerpc_cmpb): Ditto.
	(gcc_cv_as_powerpc_dfp): Ditto.
	(gcc_cv_as_powerpc_vsx): Ditto.
	(gcc_cv_as_powerpc_popcntd): Ditto.
	* configure: Regenerate.

	* config/rs6000/vector.md (VEC_int): New mode attribute for vector
	conversions.
	(VEC_INT): Ditto.
	(ftrunc<mode>2): Make this a define_expand.
	(float<VEC_int><mode>2): New vector conversion support to add VSX
	32 bit int/32 bit floating point convert and 64 bit int/64 bit
	floating point vector instructions.
	(unsigned_float<VEC_int><mode>2): Ditto.
	(fix_trunc<mode><VEC_int>2): Ditto.
	(fixuns_trunc<mode><VEC_int>2): Ditto.

	* config/rs6000/predicates.md (easy_fp_constant): 0.0 is an easy
	constant under VSX.
	(indexed_or_indirect_operand): Add VSX load/store with update
	support.

	* config/rs6000/rs6000.c (rs6000_debug_addr): New global for
	-mdebug=addr.
	(rs6000_init_hard_regno_mode_ok): Add -mvsx-scalar-memory
	support.
	(rs6000_override_options): Add -mdebug=addr support.
	(rs6000_builtin_conversion): Add VSX same size conversions.
	(rs6000_legitimize_address): Add -mdebug=addr support.  Add
	support for VSX load/store with update instructions.
	(rs6000_legitimize_reload_address): Ditto.
	(rs6000_legitimate_address): Ditto.
	(rs6000_mode_dependent_address): Ditto.
	(print_operand): Ditto.
	(bdesc_1arg): Add builtins for conversion that calls either the
	VSX or Altivec insn pattern.
	(rs6000_common_init_builtins): Ditto.

	* config/rs6000/vsx.md (VSX_I): Delete, no longer used.
	(VSi): New mode attribute for conversions.
	(VSI): Ditto.
	(VSc): Ditto.
	(vsx_mov<mode>): Add load/store with update support.
	(vsx_load<mode>_update*): New insns for load/store with update
	support.
	(vsx_store<mode>_update*): Ditto.
	(vsx_fmadd<mode>4): Generate correct code for V4SF.
	(vsx_fmsub<mode>4): Ditto.
	(vsx_fnmadd<mode>4_*): Ditto.
	(vsx_fnmsub<mode>4_*): Ditto.
	(vsx_float<VSi><mode>2): New insn for vector conversion.
	(vsx_floatuns<VSi><mode>2): Ditto.
	(vsx_fix_trunc<mode><VSi>2): Ditto.
	(vsx_fixuns_trunc<mode><VSi>2): Ditto.
	(vsx_xxmrghw): New insn for V4SF interleave.
	(vsx_xxmrglw): Ditto.

	* config/rs6000/rs6000.h (rs6000_debug_addr): -mdebug=addr
	support.
	(TARGET_DEBUG_ADDR): Ditto.
	(rs6000_builtins): Add VSX instructions for eventual VSX
	builtins.

	* config/rs6000/altivec.md (altivec_vmrghsf): Don't do the altivec
	instruction if VSX.
	(altivec_vmrglsf): Ditto.

	* config/rs6000/rs6000.md (movdf_hardfloat32): Add support for
	using xxlxor to zero a floating register if VSX.
	(movdf_hardfloat64_mfpgpr): Ditto.
	(movdf_hardfloat64): Ditto.

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

	* config/rs6000/vsx.md (vsx_xxmrglw): Delete for now, use Altivec.
	(vsx_xxmrghw): Ditto.

	* config/rs6000/altivec.md (altivec_vmrghsf): Use this insn even
	on VSX systems.
	(altivec_vmrglsf): Ditto.

	* config/rs6000/rs6000.h (ASM_CPU_NATIVE_SPEC): Use %(asm_default)
	if we are running as a cross compiler.

	* config/rs6000/vector.md (vec_interleave_highv4sf): Use correct
	constants for the extraction.
	(vec_interleave_lowv4sf): Ditto.

	* config/rs6000/rs6000.md (floordf2): Fix typo, make this a
	define_expand, not define_insn.

	* config/rs6000/aix53.h (ASM_CPU_SPEC): If -mcpu=native, call
	%:local_cpu_detect(asm) to get the appropriate assembler flags for
	the machine.
	* config/rs6000/aix61.h (ASM_CPU_SPEC): Ditto.
	* config/rs6000/rs6000.h (ASM_CPU_SPEC): Ditto.
	(ASM_CPU_NATIVE_SPEC): New spec to get asm options if
	-mcpu=native.
	(EXTRA_SPECS): Add ASM_CPU_NATIVE_SPEC.

	* config/rs6000/driver-rs6000.c (asm_names): New static array to
	give the appropriate asm switches if -mcpu=native.
	(host_detect_local_cpu): Add support for "asm".

	* config/rs6000/rs6000.c (processor_target_table): Don't turn on
	-misel by default for power7.

2009-03-02  Michael Meissner  <meissner at linux.vnet.ibm.com>

	* config/rs6000/rs6000.c (rs6000_emit_swdivdf): Revert last
	change, since we reverted the floating multiply/add changes.

	* doc/md.texi (Machine Constraints): Update rs6000 constraints.

	* config/rs6000/vector.md (neg<mode>2): Fix typo to enable
	vectorized negation.
	(ftrunc<mode>2): Move ftrunc expander here from altivec.md, and
	add V2DF case.
	(vec_interleave_highv4sf): Correct type to be V4SF, not V4SI.
	(vec_extract_evenv2df): Add expander.
	(vec_extract_oddv2df): Ditto.

	* config/rs6000/vsx.md (vsx_ftrunc<mode>2): New VSX pattern for
	truncate.
	(vsx_ftruncdf2): Ditto.
	(vsx_xxspltw): New instruction for word splat.
	(vsx_xxmrglw): Whitespace changes.  Fix typo from V4SI to v4SF.
	(vsx_xxmrghw): Ditto.

	* config/rs6000/altivec.md (altivec_vmrghsf): Whitespace changes.
	(altivec_vmrglsf): Ditto.
	(altivec_vspltsf): Disable if we have VSX.
	(altivec_ftruncv4sf2): Move expander to vector.md, rename insn.

	* config/rs6000/rs6000.md (ftruncdf2): Add expander for VSX.

	* config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok):
	Reenable vectorizing V4SF under altivec.
	(rs6000_hard_regno_mode_ok): Don't allow floating values in LR,
	CTR, MQ.  Also, VRSAVE/VSCR are both 32-bits.
	(rs6000_init_hard_regno_mode_ok): Print some of the special
	registers if -mdebug=reg.

	* config/rs6000/rs6000.md (floating multiply/add insns): Go back
	to the original semantics for multiply add/subtract, particularly
	with -ffast-math.

	* config/rs6000/vsx.md (floating multiply/add insns): Mirror the
	rs6000 floating point multiply/add insns in VSX.

2009-03-01  Michael Meissner  <meissner at linux.vnet.ibm.com>

	* config/rs6000/vector.md (VEC_L): At TImode.
	(VEC_M): Like VEC_L, except no TImode.
	(VEC_base): Add TImode support.
	(mov<mode>): Use VEC_M, not VEC_L.  If there is no extra
	optimization for the move, just generate the standard move.
	(vector_store_<mode>): Ditto.
	(vector_load_<mode>): Ditto.
	(vec_init<mode>): Use vec_init_operand predicate.

	* config/rs6000/predicates.md (vec_init_operand): New predicate.

	* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Allow mode
	in a VSX register if there is a move operation.
	(rs6000_vector_reg_class): Add internal register number to the
	debug output.
	(rs6000_init_hard_regno_mode_ok): Reorganize so all of the code
	for a given type is located together.  If not -mvsx, make "ws"
	constraint become NO_REGS, not FLOAT_REGS.  Change -mdebug=reg
	output.
	(rs6000_expand_vector_init): Before calling gen_vsx_concat_v2df,
	make sure the two float arguments are copied into registers.
	(rs6000_legitimate_offset_address_p): If no vsx or altivec, don't
	disallow offset addressing.  Add V2DImode.  If TImode is handled
	by the vector unit, allow indexed addressing.  Change default case
	to be a fatal_insn instead of gcc_unreachable.
	(rs6000_handle_altivec_attribute): Add support for vector double
	if -mvsx.
	(rs6000_register_move_cost): Add support for VSX_REGS.  Know that
	under VSX, you can move between float and altivec registers
	cheaply.
	(rs6000_emit_swdivdf): Change the pattern of the negate multiply
[...9114 lines suppressed...]
 	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)
@@ -343,11 +343,115 @@ detect_processor_aix (void)
 #endif /* _AIX */
 
 
+/*
+ * Array to map -mcpu=native names to the switches passed to the assembler.
+ * This list mirrors the specs in ASM_CPU_SPEC, and any changes made here
+ * should be made there as well.
+ */
+
+struct asm_name {
+  const char *cpu;
+  const char *asm_sw;
+};
+
+static const
+struct asm_name asm_names[] = {
+#if defined (_AIX)
+  { "power3",	"-m620" },
+  { "power4",	"-mpwr4" },
+  { "power5",	"-mpwr5" },
+  { "power5+",	"-mpwr5x" },
+  { "power6",	"-mpwr6" },
+  { "power6x",	"-mpwr6" },
+  { "power7",	"-mpwr7" },
+  { "powerpc",	"-mppc" },
+  { "rs64a",	"-mppc" },
+  { "603",	"-m603" },
+  { "603e",	"-m603" },
+  { "604",	"-m604" },
+  { "604e",	"-m604" },
+  { "620",	"-m620" },
+  { "630",	"-m620" },
+  { "970",	"-m970" },
+  { "G5",	"-m970" },
+  { NULL,	"\
+%{!maix64: \
+%{mpowerpc64: -mppc64} \
+%{maltivec: -m970} \
+%{!maltivec: %{!mpower64: %(asm_default)}}}" },
+
+#else
+  { "common",	"-mcom" },
+  { "cell",	"-mcell" },
+  { "power",	"-mpwr" },
+  { "power2",	"-mpwrx" },
+  { "power3",	"-mppc64" },
+  { "power4",	"-mpower4" },
+  { "power5",	"%(asm_cpu_power5)" },
+  { "power5+",	"%(asm_cpu_power5)" },
+  { "power6",	"%(asm_cpu_power6) -maltivec" },
+  { "power6x",	"%(asm_cpu_power6) -maltivec" },
+  { "power7",	"%(asm_cpu_power7)" },
+  { "powerpc",	"-mppc" },
+  { "rios",	"-mpwr" },
+  { "rios1",	"-mpwr" },
+  { "rios2",	"-mpwrx" },
+  { "rsc",	"-mpwr" },
+  { "rsc1",	"-mpwr" },
+  { "rs64a",	"-mppc64" },
+  { "401",	"-mppc" },
+  { "403",	"-m403" },
+  { "405",	"-m405" },
+  { "405fp",	"-m405" },
+  { "440",	"-m440" },
+  { "440fp",	"-m440" },
+  { "464",	"-m440" },
+  { "464fp",	"-m440" },
+  { "505",	"-mppc" },
+  { "601",	"-m601" },
+  { "602",	"-mppc" },
+  { "603",	"-mppc" },
+  { "603e",	"-mppc" },
+  { "ec603e",	"-mppc" },
+  { "604",	"-mppc" },
+  { "604e",	"-mppc" },
+  { "620",	"-mppc64" },
+  { "630",	"-mppc64" },
+  { "740",	"-mppc" },
+  { "750",	"-mppc" },
+  { "G3",	"-mppc" },
+  { "7400",	"-mppc -maltivec" },
+  { "7450",	"-mppc -maltivec" },
+  { "G4",	"-mppc -maltivec" },
+  { "801",	"-mppc" },
+  { "821",	"-mppc" },
+  { "823",	"-mppc" },
+  { "860",	"-mppc" },
+  { "970",	"-mpower4 -maltivec" },
+  { "G5",	"-mpower4 -maltivec" },
+  { "8540",	"-me500" },
+  { "8548",	"-me500" },
+  { "e300c2",	"-me300" },
+  { "e300c3",	"-me300" },
+  { "e500mc",	"-me500mc" },
+  { NULL,	"\
+%{mpower: %{!mpower2: -mpwr}} \
+%{mpower2: -mpwrx} \
+%{mpowerpc64*: -mppc64} \
+%{!mpowerpc64*: %{mpowerpc*: -mppc}} \
+%{mno-power: %{!mpowerpc*: -mcom}} \
+%{!mno-power: %{!mpower*: %(asm_default)}}" },
+#endif
+};
+
 /* This will be called by the spec parser in gcc.c when it sees
    a %:local_cpu_detect(args) construct.  Currently it will be called
    with either "arch" or "tune" as argument depending on if -march=native
    or -mtune=native is to be substituted.
 
+   Additionally it will be called with "asm" to select the appropriate flags
+   for the assembler.
+
    It returns a string containing new command line parameters to be
    put at the place of the above two options, depending on what CPU
    this is executed.
@@ -361,29 +465,35 @@ const char
   const char *cache = "";
   const char *options = "";
   bool arch;
+  bool assembler;
+  size_t i;
 
   if (argc < 1)
     return NULL;
 
   arch = strcmp (argv[0], "cpu") == 0;
-  if (!arch && strcmp (argv[0], "tune"))
+  assembler = (!arch && strcmp (argv[0], "asm") == 0);
+  if (!arch && !assembler && strcmp (argv[0], "tune"))
     return NULL;
 
+  if (! assembler)
+    {
 #if defined (_AIX)
-  cache = detect_caches_aix ();
+      cache = detect_caches_aix ();
 #elif defined (__APPLE__)
-  cache = detect_caches_darwin ();
+      cache = detect_caches_darwin ();
 #elif defined (__FreeBSD__)
-  cache = detect_caches_freebsd ();
-  /* FreeBSD PPC does not provide any cache information yet.  */
-  cache = "";
+      cache = detect_caches_freebsd ();
+      /* FreeBSD PPC does not provide any cache information yet.  */
+      cache = "";
 #elif defined (__linux__)
-  cache = detect_caches_linux ();
-  /* PPC Linux does not provide any cache information yet.  */
-  cache = "";
+      cache = detect_caches_linux ();
+      /* PPC Linux does not provide any cache information yet.  */
+      cache = "";
 #else
-  cache = "";
+      cache = "";
 #endif
+    }
 
 #if defined (_AIX)
   cpu = detect_processor_aix ();
@@ -397,6 +507,17 @@ const char
   cpu = "powerpc";
 #endif
 
+  if (assembler)
+    {
+      for (i = 0; i < sizeof (asm_names) / sizeof (asm_names[0]); i++)
+	{
+	  if (!asm_names[i].cpu || !strcmp (asm_names[i].cpu, cpu))
+	    return asm_names[i].asm_sw;
+	}
+
+      return NULL;
+    }
+
   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 {									\
   else if (!strcmp (rs6000_abi_name, "i960-old"))			\
     {									\
       rs6000_current_abi = ABI_V4;					\
-      target_flags |= (MASK_LITTLE_ENDIAN | MASK_EABI			\
-		       | MASK_NO_BITFIELD_WORD);			\
+      target_flags |= (MASK_LITTLE_ENDIAN | MASK_EABI);			\
       target_flags &= ~MASK_STRICT_ALIGN;				\
+      TARGET_NO_BITFIELD_WORD = 1;					\
     }									\
   else									\
     {									\


gcc44-pr37959.patch:

--- NEW FILE gcc44-pr37959.patch ---
2009-03-18  Dodji Seketeli  <dodji at redhat.com>
	    Jakub Jelinek  <jakub at redhat.com>

	PR debug/37959
	* dwarf2out.c (dwarf_attr_name): Handle DW_AT_explicit attribute.
	(gen_subprogram_die): When a function is explicit, generate the DW_AT_explicit
	attribute.
	* langhooks.h (struct lang_hooks_for_decls): Add function_decl_explicit_p
	langhook.
	* langhooks-def.h (LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P): Define.
	(LANG_HOOKS_DECLS): Add LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P.

	* cp-objcp-common.h (LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P): Define.
	(cp_function_decl_explicit_p): New prototype.
	* cp-objcp-common.c (cp_function_decl_explicit_p): New function.

	* g++.dg/debug/dwarf2/explicit-constructor.C: New test.

--- gcc/cp/cp-objcp-common.c.jj	2009-03-05 22:32:17.000000000 +0100
+++ gcc/cp/cp-objcp-common.c	2009-03-18 14:31:17.000000000 +0100
@@ -1,5 +1,5 @@
 /* Some code common to C++ and ObjC++ front ends.
-   Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by Ziemowit Laski  <zlaski at apple.com>
 
 This file is part of GCC.
@@ -203,6 +203,16 @@ cxx_staticp (tree arg)
   return NULL_TREE;
 }
 
+/* Return true if DECL is explicit member function.  */
+
+bool
+cp_function_decl_explicit_p (tree decl)
+{
+  return (decl
+	  && FUNCTION_FIRST_USER_PARMTYPE (decl) != void_list_node
+	  && DECL_NONCONVERTING_P (decl));
+}
+
 /* Stubs to keep c-opts.c happy.  */
 void
 push_file_scope (void)
--- gcc/cp/cp-objcp-common.h.jj	2009-03-02 16:21:33.000000000 +0100
+++ gcc/cp/cp-objcp-common.h	2009-03-18 14:33:51.000000000 +0100
@@ -1,5 +1,5 @@
 /* Language hooks common to C++ and ObjC++ front ends.
-   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by Ziemowit Laski  <zlaski at apple.com>
 
 This file is part of GCC.
@@ -26,6 +26,8 @@ along with GCC; see the file COPYING3.  
 extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
 					 tree, bool);
 
+extern bool cp_function_decl_explicit_p (tree decl);
+
 /* Lang hooks that are shared between C++ and ObjC++ are defined here.  Hooks
    specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c,
    respectively.  */
@@ -131,6 +133,8 @@ extern tree objcp_tsubst_copy_and_build 
 #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
 #undef LANG_HOOKS_GIMPLIFY_EXPR
 #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr
+#undef LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P
+#define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P cp_function_decl_explicit_p
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
 #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
--- gcc/langhooks-def.h.jj	2009-03-18 14:24:43.000000000 +0100
+++ gcc/langhooks-def.h	2009-03-18 14:32:37.000000000 +0100
@@ -190,6 +190,7 @@ extern tree lhd_make_node (enum tree_cod
 #define LANG_HOOKS_GLOBAL_BINDINGS_P global_bindings_p
 #define LANG_HOOKS_PUSHDECL	pushdecl
 #define LANG_HOOKS_GETDECLS	getdecls
+#define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P hook_bool_tree_false
 #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
 #define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
 #define LANG_HOOKS_DECL_OK_FOR_SIBCALL	lhd_decl_ok_for_sibcall
@@ -209,6 +210,7 @@ extern tree lhd_make_node (enum tree_cod
   LANG_HOOKS_GLOBAL_BINDINGS_P, \
   LANG_HOOKS_PUSHDECL, \
   LANG_HOOKS_GETDECLS, \
+  LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
   LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
   LANG_HOOKS_WRITE_GLOBALS, \
   LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
--- gcc/langhooks.h.jj	2009-03-18 14:24:43.000000000 +0100
+++ gcc/langhooks.h	2009-03-18 14:32:06.000000000 +0100
@@ -159,6 +159,9 @@ struct lang_hooks_for_decls
   /* Returns the chain of decls so far in the current scope level.  */
   tree (*getdecls) (void);
 
+  /* Returns true if DECL is explicit member function.  */
+  bool (*function_decl_explicit_p) (tree);
+
   /* Returns true when we should warn for an unused global DECL.
      We will already have checked that it has static binding.  */
   bool (*warn_unused_global) (const_tree);
--- gcc/dwarf2out.c.jj	2009-03-18 14:24:43.000000000 +0100
+++ gcc/dwarf2out.c	2009-03-18 14:33:04.000000000 +0100
@@ -5599,6 +5599,8 @@ dwarf_attr_name (unsigned int attr)
       return "DW_AT_encoding";
     case DW_AT_external:
       return "DW_AT_external";
+    case DW_AT_explicit:
+      return "DW_AT_explicit";
     case DW_AT_frame_base:
       return "DW_AT_frame_base";
     case DW_AT_friend:
@@ -13620,6 +13622,11 @@ gen_subprogram_die (tree decl, dw_die_re
 	{
 	  add_AT_flag (subr_die, DW_AT_declaration, 1);
 
+	  /* If this is an explicit function declaration then generate
+	     a DW_AT_explicit attribute.  */
+          if (lang_hooks.decls.function_decl_explicit_p (decl))
+	    add_AT_flag (subr_die, DW_AT_explicit, 1);
+
 	  /* The first time we see a member function, it is in the context of
 	     the class to which it belongs.  We make sure of this by emitting
 	     the class first.  The next time is the definition, which is
--- gcc/testsuite/g++.dg/debug/dwarf2/explicit-constructor.C.jj	2009-03-18 14:24:55.000000000 +0100
+++ gcc/testsuite/g++.dg/debug/dwarf2/explicit-constructor.C	2009-03-18 14:24:55.000000000 +0100
@@ -0,0 +1,19 @@
+// Contributed by Dodji Seketeli <dodji at redhat.com>
+// Origin: PR c++
+// { dg-do compile }
+// { dg-options "-O -g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_explicit" 2 } }
+
+struct Foo
+{
+  Foo () {}
+  explicit Foo (int) {}
+  Foo (char) {}
+  ~Foo () {};
+};
+
+void
+bar ()
+{
+  Foo foo;
+}

gcc44-pr38757.patch:

--- NEW FILE gcc44-pr38757.patch ---
2009-03-18  Jakub Jelinek  <jakub at redhat.com>

	PR debug/38757
	* langhooks.h (struct lang_hooks): Add source_language langhook.
	* langhooks-def.h (LANG_HOOKS_SOURCE_LANGUAGE): Define to NULL.
	(LANG_HOOKS_INITIALIZER): Add LANG_HOOKS_SOURCE_LANGUAGE.
	* c-lang.c (c_source_language): New function.
	(LANG_HOOKS_SOURCE_LANGUAGE): Define.
	* dwarf2out.c (add_prototyped_attribute): Add DW_AT_prototype
	also for DW_LANG_{C,C99,ObjC}.
	(gen_compile_unit_die): Use lang_hooks.source_language () to
	determine if DW_LANG_C99 or DW_LANG_C89 should be returned.

--- gcc/langhooks.h.jj	2009-03-02 09:45:47.000000000 +0100
+++ gcc/langhooks.h	2009-03-18 12:53:24.000000000 +0100
@@ -1,5 +1,5 @@
 /* The lang_hooks data structure.
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -414,6 +414,10 @@ struct lang_hooks
      if in the process TREE_CONSTANT or TREE_SIDE_EFFECTS need updating.  */
   tree (*expr_to_decl) (tree expr, bool *tc, bool *se);
 
+  /* Return year of the source language standard version if the FE supports
+     multiple versions of the standard.  */
+  int (*source_language) (void);
+
   /* Whenever you add entries here, make sure you adjust langhooks-def.h
      and langhooks.c accordingly.  */
 };
--- gcc/langhooks-def.h.jj	2009-03-02 09:45:47.000000000 +0100
+++ gcc/langhooks-def.h	2009-03-18 12:53:45.000000000 +0100
@@ -1,5 +1,5 @@
 /* Default macros to initialize the lang_hooks data structure.
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Alexandre Oliva  <aoliva at redhat.com>
 
@@ -113,6 +113,7 @@ extern void lhd_omp_firstprivatize_type_
 #define LANG_HOOKS_EXPR_TO_DECL		lhd_expr_to_decl
 #define LANG_HOOKS_TO_TARGET_CHARSET	lhd_to_target_charset
 #define LANG_HOOKS_INIT_TS		lhd_do_nothing
+#define LANG_HOOKS_SOURCE_LANGUAGE	NULL
 
 /* Attribute hooks.  */
 #define LANG_HOOKS_ATTRIBUTE_TABLE		NULL
@@ -270,6 +271,7 @@ extern tree lhd_make_node (enum tree_cod
   LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
   LANG_HOOKS_INIT_TS,          \
   LANG_HOOKS_EXPR_TO_DECL, \
+  LANG_HOOKS_SOURCE_LANGUAGE, \
 }
 
 #endif /* GCC_LANG_HOOKS_DEF_H */
--- gcc/c-lang.c.jj	2009-02-20 15:06:14.000000000 +0100
+++ gcc/c-lang.c	2009-03-18 13:33:41.000000000 +0100
@@ -1,6 +1,6 @@
 /* Language-specific hook definitions for C front end.
    Copyright (C) 1991, 1995, 1997, 1998,
-   1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008
+   1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -37,6 +37,12 @@ along with GCC; see the file COPYING3.  
 
 enum c_language_kind c_language = clk_c;
 
+static int
+c_source_language (void)
+{
+  return flag_isoc99 ? 1999 : 1989;
+}
+
 /* Lang hooks common to C and ObjC are declared in c-objc-common.h;
    consequently, there should be very few hooks below.  */
 
@@ -44,6 +50,8 @@ enum c_language_kind c_language = clk_c;
 #define LANG_HOOKS_NAME "GNU C"
 #undef LANG_HOOKS_INIT
 #define LANG_HOOKS_INIT c_objc_common_init
+#undef LANG_HOOKS_SOURCE_LANGUAGE
+#define LANG_HOOKS_SOURCE_LANGUAGE c_source_language
 
 /* Each front end provides its own lang hook initializer.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
--- gcc/dwarf2out.c.jj	2009-03-17 13:06:29.000000000 +0100
+++ gcc/dwarf2out.c	2009-03-18 12:55:36.000000000 +0100
@@ -12470,9 +12470,18 @@ add_bit_size_attribute (dw_die_ref die, 
 static inline void
 add_prototyped_attribute (dw_die_ref die, tree func_type)
 {
-  if (get_AT_unsigned (comp_unit_die, DW_AT_language) == DW_LANG_C89
-      && TYPE_ARG_TYPES (func_type) != NULL)
-    add_AT_flag (die, DW_AT_prototyped, 1);
+  switch (get_AT_unsigned (comp_unit_die, DW_AT_language))
+    {
+    case DW_LANG_C:
+    case DW_LANG_C89:
+    case DW_LANG_C99:
+    case DW_LANG_ObjC:
+      if (TYPE_ARG_TYPES (func_type) != NULL)
+	add_AT_flag (die, DW_AT_prototyped, 1);
+      break;
+    default:
+      break;
+    }
 }
 
 /* Add an 'abstract_origin' attribute below a given DIE.  The DIE is found
@@ -14419,7 +14428,13 @@ gen_compile_unit_die (const char *filena
   else if (strcmp (language_string, "GNU Objective-C++") == 0)
     language = DW_LANG_ObjC_plus_plus;
   else
-    language = DW_LANG_C89;
+    {
+      if (lang_hooks.source_language
+	  && lang_hooks.source_language () >= 1999)
+	language = DW_LANG_C99;
+      else
+	language = DW_LANG_C89;
+    }
 
   add_AT_unsigned (die, DW_AT_language, language);
   return die;

gcc44-pr39226.patch:

--- NEW FILE gcc44-pr39226.patch ---
2009-03-03  Jakub Jelinek  <jakub at redhat.com>

	PR target/39226
	* config/rs6000/rs6000.md (andsi3_internal5_nomc,
	anddi3_internal2_nomc, anddi3_internal3_nomc): Removed.
	(booldi3_internal3): Use boolean_or_operator instead of
	boolean_operator.

	* gcc.dg/pr39226.c: New test.

--- gcc/config/rs6000/rs6000.md.jj	2009-03-02 18:09:02.000000000 +0100
+++ gcc/config/rs6000/rs6000.md	2009-03-03 10:02:37.771461086 +0100
@@ -2999,20 +2999,6 @@
   [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
    (set_attr "length" "8,4,4,4,8,8,8,8")])
 
-(define_insn "*andsi3_internal5_nomc"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,??y,??y,?y")
-        (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
-                            (match_operand:SI 2 "and_operand" "r,r,K,L,T"))
-                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
-        (and:SI (match_dup 1)
-                (match_dup 2)))
-   (clobber (match_scratch:CC 4 "=X,X,x,x,X"))]
-  "TARGET_64BIT && !rs6000_gen_cell_microcode"
-  "#"
-  [(set_attr "type" "compare")
-   (set_attr "length" "8,8,8,8,8")])
-
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
@@ -7684,18 +7670,6 @@
   [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
-(define_insn "*anddi3_internal2_nomc"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y,?y,??y,??y,?y")
-	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
-			    (match_operand:DI 2 "and64_2_operand" "t,r,S,K,J,t"))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r,r,r,r,r"))
-   (clobber (match_scratch:CC 4 "=X,X,X,x,x,X"))]
-  "TARGET_64BIT && !rs6000_gen_cell_microcode"
-  "#"
-  [(set_attr "type" "delayed_compare,compare,compare,compare,compare,compare")
-   (set_attr "length" "8,8,8,8,8,12")])
-
 (define_split
   [(set (match_operand:CC 0 "cc_reg_operand" "")
         (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -7747,18 +7721,6 @@
   [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
    (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
 
-(define_insn "*anddi3_internal3_nomc"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?y,??y,??y,?y")
-	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
-			    (match_operand:DI 2 "and64_2_operand" "t,r,S,K,J,t"))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
-	(and:DI (match_dup 1) (match_dup 2)))
-   (clobber (match_scratch:CC 4 "=X,X,X,x,x,X"))]
-  "TARGET_64BIT  && !rs6000_gen_cell_microcode"
-  "#"
-  [(set_attr "type" "delayed_compare,compare,compare,compare,compare,compare")
-   (set_attr "length" "8,8,8,8,8,12")])
 (define_split
   [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
 	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
@@ -7915,7 +7877,7 @@
 
 (define_insn "*booldi3_internal3"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (match_operator:DI 4 "boolean_operator"
+	(compare:CC (match_operator:DI 4 "boolean_or_operator"
 	 [(match_operand:DI 1 "gpc_reg_operand" "%r,r")
 	  (match_operand:DI 2 "gpc_reg_operand" "r,r")])
 	 (const_int 0)))
--- gcc/testsuite/gcc.dg/pr39226.c.jj	2009-03-02 23:27:03.398459808 +0100
+++ gcc/testsuite/gcc.dg/pr39226.c	2009-03-02 23:26:19.696462209 +0100
@@ -0,0 +1,25 @@
+/* PR target/39226 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mtune=cell -mminimal-toc" { target { powerpc*-*-* && lp64 } } } */
+
+struct A
+{
+  char *a;
+  unsigned int b : 1;
+  unsigned int c : 31;
+};
+
+struct B
+{
+  struct A *d;
+};
+
+void
+foo (struct B *x, unsigned long y)
+{
+  if (x->d[y].c)
+    return;
+  if (x->d[y].b)
+    x->d[y].a = 0;
+}


Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/.cvsignore,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- .cvsignore	20 Feb 2009 19:59:34 -0000	1.3
+++ .cvsignore	23 Mar 2009 10:56:41 -0000	1.4
@@ -1,3 +1 @@
-fastjar-0.97.tar.gz
-gcc-4.4.0-20090216.tar.bz2
-cloog-ppl-0.15.tar.gz
+gcc-4.4.0-20090319.tar.bz2

gcc44-c++-builtin-redecl.patch:

Index: gcc44-c++-builtin-redecl.patch
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/gcc44-c++-builtin-redecl.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- gcc44-c++-builtin-redecl.patch	20 Feb 2009 19:59:34 -0000	1.1
+++ gcc44-c++-builtin-redecl.patch	23 Mar 2009 10:56:41 -0000	1.2
@@ -9,7 +9,7 @@
 
 --- gcc/cp/decl.c.jj	2007-10-01 22:11:09.000000000 +0200
 +++ gcc/cp/decl.c	2007-10-02 11:39:46.000000000 +0200
-@@ -1988,23 +1988,21 @@ duplicate_decls (tree newdecl, tree oldd
+@@ -2001,23 +2001,21 @@ duplicate_decls (tree newdecl, tree oldd
  	  DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
  	  DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
  	}
@@ -40,8 +40,8 @@
 -	    }
 -
  	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
- 	  /* Don't clear out the arguments if we're redefining a function.  */
- 	  if (DECL_ARGUMENTS (olddecl))
+ 	  /* Don't clear out the arguments if we're just redeclaring a
+ 	     function.  */
 --- gcc/testsuite/gcc.dg/builtins-65.c.jj	2007-10-02 11:23:51.000000000 +0200
 +++ gcc/testsuite/gcc.dg/builtins-65.c	2007-10-02 11:24:12.000000000 +0200
 @@ -0,0 +1,25 @@

gcc44-cloog-dl.patch:

Index: gcc44-cloog-dl.patch
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/gcc44-cloog-dl.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- gcc44-cloog-dl.patch	20 Feb 2009 19:59:34 -0000	1.1
+++ gcc44-cloog-dl.patch	23 Mar 2009 10:56:41 -0000	1.2
@@ -1,6 +1,5 @@
 2009-01-27  Jakub Jelinek  <jakub at redhat.com>
 
-	* toplev.c (save_argv): No longer static.
 	* Makefile.in (BACKENDLIBS): Link against -ldl instead of -lcloog -lppl.
 	(graphite.o): Force -O, remove -fkeep-inline-functions.
 	* graphite.c: Include <dlfcn.h>.  Reference libcloog and libppl symbols
@@ -9,17 +8,6 @@
 	(gcc_type_for_iv_of_clast_loop): Rename stmt_for argument to stmt_fora.
 	(graphite_transform_loops): Call init_cloog_pointers.
 
---- gcc/toplev.c.jj	2008-12-09 23:59:10.000000000 +0100
-+++ gcc/toplev.c	2009-01-27 14:33:52.000000000 +0100
-@@ -128,7 +128,7 @@ static bool no_backend;
- const char *progname;
- 
- /* Copy of argument vector to toplev_main.  */
--static const char **save_argv;
-+const char **save_argv;
- 
- /* Name of top-level original source file (what was input to cpp).
-    This comes from the #-command at the beginning of the actual input.
 --- gcc/Makefile.in.jj	2009-01-26 20:50:38.000000000 +0100
 +++ gcc/Makefile.in	2009-01-27 14:18:10.000000000 +0100
 @@ -915,7 +915,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
@@ -43,7 +31,7 @@
  	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tfile.o version.o $(LIBS)
 --- gcc/graphite.c.jj	2009-01-24 19:59:02.000000000 +0100
 +++ gcc/graphite.c	2009-01-27 14:52:08.000000000 +0100
-@@ -59,6 +59,138 @@ along with GCC; see the file COPYING3.  
+@@ -59,6 +59,110 @@ along with GCC; see the file COPYING3.  
  #include "cloog/cloog.h"
  #include "graphite.h"
  
@@ -128,39 +116,11 @@
 +static bool
 +init_cloog_pointers (void)
 +{
-+  void *h = NULL;
-+  extern const char **save_argv;
-+  char *buf, *p;
-+  size_t len;
++  void *h;
 +
 +  if (cloog_pointers.inited)
 +    return cloog_pointers.h != NULL;
-+  len = progname - save_argv[0];
-+  buf = XALLOCAVAR (char, len + sizeof "libcloog.so.0");
-+  memcpy (buf, save_argv[0], len);
-+  strcpy (buf + len, "libcloog.so.0");
-+  len += sizeof "libcloog.so.0";
-+  p = strstr (buf, "/libexec/");
-+  if (p != NULL)
-+    {
-+      while (1)
-+	{
-+	  char *q = strstr (p + 8, "/libexec/");
-+	  if (q == NULL)
-+	    break;
-+	  p = q;
-+	}
-+      memmove (p + 4, p + 8, len - (p + 8 - buf));
-+      h = dlopen (buf, RTLD_LAZY);
-+      if (h == NULL)
-+	{
-+	  len = progname - save_argv[0];
-+	  memcpy (buf, save_argv[0], len);
-+	  strcpy (buf + len, "libcloog.so.0");
-+	}
-+    }
-+  if (h == NULL)
-+    h = dlopen (buf, RTLD_LAZY);
++  h = dlopen ("libcloog.so.0", RTLD_LAZY);
 +  cloog_pointers.h = h;
 +  if (h == NULL)
 +    return false;

gcc44-raw-string.patch:

Index: gcc44-raw-string.patch
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/gcc44-raw-string.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- gcc44-raw-string.patch	20 Feb 2009 19:59:34 -0000	1.1
+++ gcc44-raw-string.patch	23 Mar 2009 10:56:41 -0000	1.2
@@ -177,7 +177,7 @@
  
 --- libcpp/lex.c.jj	2008-09-05 12:59:49.000000000 +0200
 +++ libcpp/lex.c	2008-09-12 13:54:01.000000000 +0200
-@@ -609,10 +609,185 @@ create_literal (cpp_reader *pfile, cpp_t
+@@ -610,12 +610,186 @@ create_literal (cpp_reader *pfile, cpp_t
    token->val.str.text = dest;
  }
  
@@ -358,14 +358,17 @@
  /* Lexes a string, character constant, or angle-bracketed header file
     name.  The stored string contains the spelling, including opening
 -   quote and leading any leading 'L', 'u' or 'U'.  It returns the type
--   of the literal, or CPP_OTHER if it was not properly terminated.
+-   of the literal, or CPP_OTHER if it was not properly terminated, or
+-   CPP_LESS for an unterminated header name which must be relexed as
+-   normal tokens.
 +   quote and any leading 'L', 'u', 'U' or 'u8' and optional
 +   'R' modifier.  It returns the type of the literal, or CPP_OTHER
-+   if it was not properly terminated.
++   if it was not properly terminated, or CPP_LESS for an unterminated
++   header name which must be relexed as normal tokens.
  
     The spelling is NUL-terminated, but it is not guaranteed that this
     is the first NUL since embedded NULs are preserved.  */
-@@ -626,12 +801,24 @@ lex_string (cpp_reader *pfile, cpp_token
+@@ -629,12 +803,24 @@ lex_string (cpp_reader *pfile, cpp_token
  
    cur = base;
    terminator = *cur++;
@@ -393,7 +396,7 @@
    else if (terminator == '\'')
      type = (*base == 'L' ? CPP_WCHAR :
  	    *base == 'U' ? CPP_CHAR32 :
-@@ -1035,10 +1222,20 @@ _cpp_lex_direct (cpp_reader *pfile)
+@@ -1094,10 +1280,20 @@ _cpp_lex_direct (cpp_reader *pfile)
      case 'L':
      case 'u':
      case 'U':
@@ -415,7 +418,7 @@
  	    {
  	      lex_string (pfile, result, buffer->cur - 1);
  	      break;
-@@ -1054,7 +1251,7 @@ _cpp_lex_direct (cpp_reader *pfile)
+@@ -1113,7 +1309,7 @@ _cpp_lex_direct (cpp_reader *pfile)
      case 'y': case 'z':
      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
      case 'G': case 'H': case 'I': case 'J': case 'K':


Index: mingw32-gcc.spec
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/mingw32-gcc.spec,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- mingw32-gcc.spec	4 Mar 2009 10:54:24 -0000	1.4
+++ mingw32-gcc.spec	23 Mar 2009 10:56:41 -0000	1.5
@@ -1,11 +1,11 @@
 %define __os_install_post /usr/lib/rpm/brp-compress %{nil}
 
-%define DATE 20090216
-%define SVNREV 144214
+%define DATE 20090319
+%define SVNREV 144967
 
 Name:           mingw32-gcc
 Version:        4.4.0
-Release:        0.6%{?dist}
+Release:        0.7%{?dist}
 Summary:        MinGW Windows cross-compiler (GCC) for C
 
 License:        GPLv3+ and GPLv2+ with exceptions
@@ -17,7 +17,6 @@
 Source1:        libgcc_post_upgrade.c
 Source2:        README.libgcjwebplugin.so
 Source3:        protoize.1
-Source5:        ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-ppl-0.15.tar.gz
 
 # Patches from Fedora's native gcc.
 Patch0:         gcc44-hack.patch
@@ -38,8 +37,13 @@
 Patch20:        gcc44-libtool-no-rpath.patch
 Patch21:        gcc44-cloog-dl.patch
 Patch22:        gcc44-raw-string.patch
-Patch23:        gcc44-pr39175.patch
-Patch24:        gcc44-diff.patch
+Patch24:        gcc44-atom.patch
+Patch25:        gcc44-pr39226.patch
+Patch26:        gcc44-power7.patch
+Patch27:        gcc44-power7-2.patch
+Patch28:        gcc44-pr38757.patch
+Patch29:        gcc44-pr37959.patch
+Patch30:        gcc44-memmove-opt.patch
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
@@ -136,8 +140,13 @@
 %patch20 -p0 -b .libtool-no-rpath~
 %patch21 -p0 -b .cloog-dl~
 %patch22 -p0 -b .raw-string~
-%patch23 -p0 -b .pr39175~
-%patch24 -p0 -b .diff~
+%patch24 -p0 -b .atom~
+%patch25 -p0 -b .pr39226~
+%patch26 -p0 -b .power7~
+%patch27 -p0 -b .power7-2~
+%patch28 -p0 -b .pr38757~
+%patch29 -p0 -b .pr37959~
+%patch30 -p0 -b .memmove-opt~
 
 
 %build
@@ -170,7 +179,7 @@
   --enable-languages="$languages" \
   --with-bugurl=http://bugzilla.redhat.com/bugzilla
 
-make all
+make %{?_smp_mflags} all
 
 popd
 
@@ -287,6 +296,10 @@
 
 
 %changelog
+* Mon Mar 23 2009 Richard W.M. Jones <rjones at redhat.com> - 4.4.0-0.7
+- New native Fedora version gcc 4.4.0 20090319 svn 144967.
+- Enable _smp_mflags.
+
 * Wed Mar  4 2009 Richard W.M. Jones <rjones at redhat.com> - 4.4.0-0.6
 - Fix libobjc and consequently Objective C and Objective C++ compilers.
 


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/mingw32-gcc/devel/sources,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- sources	20 Feb 2009 19:59:34 -0000	1.3
+++ sources	23 Mar 2009 10:56:41 -0000	1.4
@@ -1,3 +1 @@
-2659f09c2e43ef8b7d4406321753f1b2  fastjar-0.97.tar.gz
-0f5cb535b5450a8d61b14f690700a54c  gcc-4.4.0-20090216.tar.bz2
-716b7a0823f96c9d02c1703a9c47d387  cloog-ppl-0.15.tar.gz
+2992035eaf092d72eb98ad16b173f737  gcc-4.4.0-20090319.tar.bz2


--- gcc44-diff.patch DELETED ---


--- gcc44-pr39175.patch DELETED ---




More information about the mingw mailing list