rpms/gcc/devel .cvsignore, 1.291, 1.292 gcc.spec, 1.69, 1.70 gcc44-pr41175.patch, 1.1, 1.2 sources, 1.295, 1.296 gcc44-pr41175-2.patch, 1.2, NONE

Jakub Jelinek jakub at fedoraproject.org
Wed Sep 16 13:27:07 UTC 2009


Author: jakub

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

Modified Files:
	.cvsignore gcc.spec gcc44-pr41175.patch sources 
Removed Files:
	gcc44-pr41175-2.patch 
Log Message:
4.4.1-14


Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/gcc/devel/.cvsignore,v
retrieving revision 1.291
retrieving revision 1.292
diff -u -p -r1.291 -r1.292
--- .cvsignore	11 Sep 2009 09:52:12 -0000	1.291
+++ .cvsignore	16 Sep 2009 13:27:05 -0000	1.292
@@ -1,2 +1,2 @@
 fastjar-0.97.tar.gz
-gcc-4.4.1-20090911.tar.bz2
+gcc-4.4.1-20090916.tar.bz2


Index: gcc.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gcc/devel/gcc.spec,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -p -r1.69 -r1.70
--- gcc.spec	11 Sep 2009 09:52:12 -0000	1.69
+++ gcc.spec	16 Sep 2009 13:27:05 -0000	1.70
@@ -1,9 +1,9 @@
-%global DATE 20090911
-%global SVNREV 151630
+%global DATE 20090916
+%global SVNREV 151746
 %global gcc_version 4.4.1
 # Note, gcc_release must be integer, if you want to add suffixes to
 # %{release}, append them after %{gcc_release} on Release: line.
-%global gcc_release 13
+%global gcc_release 14
 %global _unpackaged_files_terminate_build 0
 %global multilib_64_archs sparc64 ppc64 s390x x86_64
 %global include_gappletviewer 1
@@ -162,9 +162,8 @@ Patch18: gcc44-libstdc++-docs.patch
 Patch19: gcc44-vta-cfgexpand-ptr-mode-pr41248.patch
 Patch20: gcc44-powerpc-libgcc_s_so.patch
 Patch21: gcc44-pr41175.patch
-Patch22: gcc44-pr41175-2.patch
-Patch23: gcc44-rh518303.patch
-Patch24: gcc44-rh522577.patch
+Patch22: gcc44-rh518303.patch
+Patch23: gcc44-rh522577.patch
 
 Patch1000: fastjar-0.97-segfault.patch
 
@@ -473,9 +472,8 @@ which are required to compile with the G
 %patch19 -p0 -b .vta-cfgexpand-ptr-mode-pr41248~
 %patch20 -p0 -b .powerpc-libgcc_s_so~
 %patch21 -p0 -b .pr41175~
-%patch22 -p0 -b .pr41175-2~
-%patch23 -p0 -b .rh518303~
-%patch24 -p0 -b .rh522577~
+%patch22 -p0 -b .rh518303~
+%patch23 -p0 -b .rh522577~
 
 # This testcase doesn't compile.
 rm libjava/testsuite/libjava.lang/PR35020*
@@ -1831,6 +1829,14 @@ fi
 %doc rpm.doc/changelogs/libmudflap/ChangeLog*
 
 %changelog
+* Wed Sep 16 2009 Jakub Jelinek <jakub at redhat.com> 4.4.1-14
+- update from gcc-4_4-branch
+  - PRs fortran/39876, tree-optimization/41101
+- asm goto support
+- VTA delayed branch scheduling fix (PR bootstrap/41349)
+- power7 VSX fix (PR target/41210)
+- ppc bswap fixes (PR target/41331)
+
 * Fri Sep 11 2009 Jakub Jelinek <jakub at redhat.com> 4.4.1-13
 - fix ICE in debuginfo output with BLOCK_NONLOCALIZED_VARS (#518303)
 - wrap_constant when propagating for subst in debug in the combiner (#522577)

gcc44-pr41175.patch:
 config/rs6000/linux64.h                |    4 
 config/rs6000/rs6000.c                 |  330 +++++++++++++++++------
 config/rs6000/rs6000.md                |   13 
 config/rs6000/spe.md                   |   18 -
 config/rs6000/sysv4.h                  |   12 
 testsuite/gcc.target/powerpc/pr41175.c |  461 +++++++++++++++++++++++++++++++++
 6 files changed, 735 insertions(+), 103 deletions(-)

Index: gcc44-pr41175.patch
===================================================================
RCS file: /cvs/pkgs/rpms/gcc/devel/gcc44-pr41175.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- gcc44-pr41175.patch	10 Sep 2009 14:24:09 -0000	1.1
+++ gcc44-pr41175.patch	16 Sep 2009 13:27:05 -0000	1.2
@@ -1,29 +1,520 @@
-2009-09-10  Nathan Froyd  <froydnj at codesourcery.com>
+2009-09-15  Nathan Froyd  <froydnj at codesourcery.com>
+	    Jakub Jelinek  <jakub at redhat.com>
 
-	PR target/40677
 	PR target/41175
+	PR target/40677
 	* config/rs6000/rs6000.c (no_global_regs_above): Fix precedence
 	problem.
+	(SAVRES_NOINLINE_GPRS_SAVES_LR, SAVRES_NOINLINE_FPRS_SAVES_LR,
+	SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR): New strategy bits.
+	(rs6000_savres_strategy): Always save FP registers inline if the
+	target doesn't support hardware double-precision.  Set the above
+	bits in return value when needed.
 	(rs6000_savres_routine_sym): Fix computation for cache selector.
-	Mark the generated symbol as a function.
-	(rs6000_emit_prologue): Correct use of call_used_regs.
+	Mark the generated symbol as a function.  Rename exitp argument to
+	lr.  Move code for determining the name of the symbol...
+	(rs6000_savres_routine_name): ...here.  New function.  Add cases for
+	getting the names right on AIX and 64-bit Linux.
+	(savres_routine_name): New variable.
+	(rs6000_make_savres_rtx): Rename exitp argument to lr.  Don't assert
+	lr isn't set when savep.  Use r12 resp. r1 instead of r11 depending
+	on what the target routine uses as a base register.  If savep && lr
+	describe saving of r0 into memory slot.
+	(rs6000_emit_prologue): Correct use of call_used_regs.  Fix out of
+	line calls for AIX ABI.
+	(rs6000_output_function_prologue): Use rs6000_savres_routine_name to
+	determine FP save/restore functions.
+	(rs6000_emit_stack_reset): Handle savres if sp_offset != 0 and
+	frame_reg_rtx != sp_reg_rtx.  Use gen_add3_insn instead of
+	gen_addsi3.
 	(rs6000_emit_epilogue): Adjust computation of restore_lr.
 	Duplicate restoration of LR and execute the appropriate one
-	depending on whether GPRs are being restored inline.
-	* config/rs6000/rs6000.md (*save_gpregs_<mode>): Use explicit
-	match for register 11.
-	(*save_fpregs_<mode>): Likewise.
-	(*restore_gpregs_<mode>): Likewise.
-	(*return_and_restore_gpregs_<mode>): Likewise.
-	(*return_and_restore_fpregs_<mode>): Likewise.
+	depending on whether GPRs are being restored inline.  Set r11 from
+	offsetted frame_reg_rtx instead of sp_reg_rtx; if frame_reg_rtx is
+	r11, adjust sp_offset.  Use gen_add3_insn instead of gen_addsi3.
+	Fix out of line calls for AIX ABI.
+	* config/rs6000/rs6000.md (*return_and_restore_fpregs_aix_<mode>):
+	New insn.
 	* config/rs6000/spe.md (*save_gpregs_spe): Use explicit match for
 	register 11.
 	(*restore_gpregs_spe): Likewise.
 	(*return_and_restore_gpregs_spe): Likewise.
+	* config/rs6000/linux64.h (SAVE_FP_SUFFIX, RESTORE_FP_SUFFIX):
+	Define to empty string unconditionally.
+	* config/rs6000/sysv4.h (SAVE_FP_SUFFIX, RESTORE_FP_SUFFIX):
+	Define to empty string unconditionally.
+	(GP_SAVE_INLINE, FP_SAVE_INLINE): Handle TARGET_64BIT the same as
+	!TARGET_64BIT.
+
+	* gcc.target/powerpc/pr41175.c: New test.
 
---- gcc/config/rs6000/spe.md.jj	2009-08-31 23:30:14.352526952 +0200
-+++ gcc/config/rs6000/spe.md	2009-09-09 20:46:08.391404851 +0200
-@@ -3156,9 +3156,9 @@
+--- gcc/testsuite/gcc.target/powerpc/pr41175.c	(revision 0)
++++ gcc/testsuite/gcc.target/powerpc/pr41175.c	(revision 151729)
+@@ -0,0 +1,461 @@
++/* PR target/41175 */
++/* { dg-do run } */
++/* { dg-options "-Os" } */
++
++#define X2(n) X1(n##0) X1(n##1)
++#define X4(n) X2(n##0) X2(n##1)
++#define X8(n) X4(n##0) X4(n##1)
++
++#ifndef __SPE__
++#define FLOAT_REG_CONSTRAINT "f"
++#else
++#define FLOAT_REG_CONSTRAINT "r"
++#endif
++
++volatile int ll;
++
++__attribute__((noinline)) void
++foo (void)
++{
++  asm volatile ("" : : : "memory");
++}
++
++__attribute__((noinline)) void
++bar (char *p)
++{
++  asm volatile ("" : : "r" (p) : "memory");
++}
++
++__attribute__((noinline)) void
++f1 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++  foo ();
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f2 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++  char *pp = __builtin_alloca (ll);
++  bar (pp);
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f3 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++}
++
++#ifndef __NO_FPRS__
++__attribute__((noinline)) void
++f4 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X4(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X4(d) "=m" (mem) : : "memory");
++  foo ();
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X4(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f5 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X4(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X4(d) "=m" (mem) : : "memory");
++  char *pp = __builtin_alloca (ll);
++  bar (pp);
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X4(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f6 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X4(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X4(d) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X4(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f7 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X2(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X2(d) "=m" (mem) : : "memory");
++  foo ();
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X2(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f8 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X2(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X2(d) "=m" (mem) : : "memory");
++  char *pp = __builtin_alloca (ll);
++  bar (pp);
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X2(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f9 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X8(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X2(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X2(d) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X8(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X2(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f10 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X4(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X1(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X4(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X1(d) "=m" (mem) : : "memory");
++  foo ();
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X4(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X1(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f11 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X4(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X1(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X4(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X1(d) "=m" (mem) : : "memory");
++  char *pp = __builtin_alloca (ll);
++  bar (pp);
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X4(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X1(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f12 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X4(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X1(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X4(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X1(d) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X4(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X1(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f13 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X2(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X8(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X2(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X8(d) "=m" (mem) : : "memory");
++  foo ();
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X2(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X8(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f14 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X2(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X8(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X2(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X8(d) "=m" (mem) : : "memory");
++  char *pp = __builtin_alloca (ll);
++  bar (pp);
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X2(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X8(d) "m" (mem) : "memory");
++}
++
++__attribute__((noinline)) void
++f15 (void)
++{
++  int mem;
++#undef X1
++#define X1(n) int gpr##n = 0;
++  X8(a) X8(b) X2(c)
++#undef X1
++#define X1(n) double fpr##n = 0.0;
++  X8(d)
++#undef X1
++#define X1(n) "+r" (gpr##n),
++  asm volatile ("" : X8(a) "=m" (mem) : : "memory");
++  asm volatile ("" : X8(b) "=m" (mem) : : "memory");
++  asm volatile ("" : X2(c) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "+" FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : X8(d) "=m" (mem) : : "memory");
++#undef X1
++#define X1(n) "r" (gpr##n),
++  asm volatile ("" : : X8(a) "m" (mem) : "memory");
++  asm volatile ("" : : X8(b) "m" (mem) : "memory");
++  asm volatile ("" : : X2(c) "m" (mem) : "memory");
++#undef X1
++#define X1(n) FLOAT_REG_CONSTRAINT (fpr##n),
++  asm volatile ("" : : X8(d) "m" (mem) : "memory");
++}
++#endif
++
++int
++main ()
++{
++  ll = 60;
++  f1 ();
++  f2 ();
++  f3 ();
++#ifndef __NO_FPRS__
++  f4 ();
++  f5 ();
++  f6 ();
++  f7 ();
++  f8 ();
++  f9 ();
++  f10 ();
++  f11 ();
++  f12 ();
++  f13 ();
++  f14 ();
++  f15 ();
++#endif
++  return 0;
++}
+--- gcc/config/rs6000/spe.md	(revision 151728)
++++ gcc/config/rs6000/spe.md	(revision 151729)
+@@ -3156,9 +3156,9 @@ (define_insn "*save_gpregs_spe"
    [(match_parallel 0 "any_parallel_operand"
  		   [(clobber (reg:P 65))
  		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
@@ -36,7 +527,7 @@
    "TARGET_SPE_ABI"
    "bl %z1"
    [(set_attr "type" "branch")
-@@ -3168,9 +3168,9 @@
+@@ -3168,9 +3168,9 @@ (define_insn "*restore_gpregs_spe"
   [(match_parallel 0 "any_parallel_operand"
  		  [(clobber (reg:P 65))
  		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
@@ -49,7 +540,7 @@
   "TARGET_SPE_ABI"
   "bl %z1"
   [(set_attr "type" "branch")
-@@ -3181,9 +3181,9 @@
+@@ -3181,9 +3181,9 @@ (define_insn "*return_and_restore_gpregs
  		  [(return)
  		   (clobber (reg:P 65))
  		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
@@ -62,9 +553,25 @@
   "TARGET_SPE_ABI"
   "b %z1"
   [(set_attr "type" "branch")
---- gcc/config/rs6000/rs6000.c.jj	2009-09-09 20:45:10.794535794 +0200
-+++ gcc/config/rs6000/rs6000.c	2009-09-09 20:46:57.195401830 +0200
-@@ -18011,7 +18011,8 @@ static bool
+--- gcc/config/rs6000/linux64.h	(revision 151728)
++++ gcc/config/rs6000/linux64.h	(revision 151729)
+@@ -437,11 +437,11 @@ extern int dot_symbols;
+ #undef  SAVE_FP_PREFIX
+ #define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
+ #undef  SAVE_FP_SUFFIX
+-#define SAVE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
++#define SAVE_FP_SUFFIX ""
+ #undef  RESTORE_FP_PREFIX
+ #define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
+ #undef  RESTORE_FP_SUFFIX
+-#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
++#define RESTORE_FP_SUFFIX ""
+ 
+ /* Dwarf2 debugging.  */
+ #undef  PREFERRED_DEBUGGING_TYPE
+--- gcc/config/rs6000/rs6000.c	(revision 151728)
++++ gcc/config/rs6000/rs6000.c	(revision 151729)
+@@ -18033,7 +18033,8 @@ static bool
  no_global_regs_above (int first, bool gpr)
  {
    int i;
@@ -74,22 +581,166 @@
      if (global_regs[i])
        return false;
    return true;
-@@ -18037,11 +18038,11 @@ rs6000_savres_routine_sym (rs6000_stack_
+@@ -18050,54 +18051,136 @@ no_global_regs_above (int first, bool gp
+ 
+ static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
+ 
+-/* Return the symbol for an out-of-line register save/restore routine.
++/* Temporary holding space for an out-of-line register save/restore
++   routine name.  */
++static char savres_routine_name[30];
++
++/* Return the name for an out-of-line register save/restore routine.
++   We are saving/restoring GPRs if GPR is true.  */
++
++static char *
++rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
++			    bool savep, bool gpr, bool lr)
++{
++  const char *prefix = "";
++  const char *suffix = "";
++
++  /* Different targets are supposed to define
++     {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
++     routine name could be defined with:
++
++     sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
++
++     This is a nice idea in practice, but in reality, things are
++     complicated in several ways:
++
++     - ELF targets have save/restore routines for GPRs.
++
++     - SPE targets use different prefixes for 32/64-bit registers, and
++       neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
++
++     - PPC64 ELF targets have routines for save/restore of GPRs that
++       differ in what they do with the link register, so having a set
++       prefix doesn't work.  (We only use one of the save routines at
++       the moment, though.)
++
++     - PPC32 elf targets have "exit" versions of the restore routines
++       that restore the link register and can save some extra space.
++       These require an extra suffix.  (There are also "tail" versions
++       of the restore routines and "GOT" versions of the save routines,
++       but we don't generate those at present.  Same problems apply,
++       though.)
++
++     We deal with all this by synthesizing our own prefix/suffix and
++     using that for the simple sprintf call shown above.  */
++  if (TARGET_SPE)
++    {
++      /* No floating point saves on the SPE.  */
++      gcc_assert (gpr);
++
++      if (savep)
++	prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
++      else
++	prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
++
++      if (lr)
++	suffix = "_x";
++    }
++  else if (DEFAULT_ABI == ABI_V4)
++    {
++      if (TARGET_64BIT)
++	goto aix_names;
++
++      if (gpr)
++	prefix = savep ? "_savegpr_" : "_restgpr_";
++      else
++	prefix = savep ? "_savefpr_" : "_restfpr_";
++
++      if (lr)
++	suffix = "_x";
++    }
++  else if (DEFAULT_ABI == ABI_AIX)
++    {
++#ifndef POWERPC_LINUX
++      /* No out-of-line save/restore routines for GPRs on AIX.  */
++      gcc_assert (!TARGET_AIX || !gpr);
++#endif
++
++    aix_names:
++      if (gpr)
++	prefix = (savep
++		  ? (lr ? "_savegpr0_" : "_savegpr1_")
++		  : (lr ? "_restgpr0_" : "_restgpr1_"));
++#ifdef POWERPC_LINUX
++      else if (lr)
++	prefix = (savep ? "_savefpr_" : "_restfpr_");
++#endif
++      else
++	{
++	  prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
++	  suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
++	}
++    }
++  else if (DEFAULT_ABI == ABI_DARWIN)
++    sorry ("Out-of-line save/restore routines not supported on Darwin");
++
++  sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
++
++  return savres_routine_name;
++}
++
++/* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
+    We are saving/restoring GPRs if GPR is true.  */
+ 
+ static rtx
+-rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exitp)
++rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
++			   bool gpr, bool lr)
+ {
    int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
    rtx sym;
    int select = ((savep ? 1 : 0) << 2
 -		| (gpr
-+		| (TARGET_SPE_ABI
- 		   /* On the SPE, we never have any FPRs, but we do have
- 		      32/64-bit versions of the routines.  */
+-		   /* On the SPE, we never have any FPRs, but we do have
+-		      32/64-bit versions of the routines.  */
 -		   ? (TARGET_SPE_ABI && info->spe_64bit_regs_used ? 1 : 0)
 -		   : 0) << 1
-+		   ? (info->spe_64bit_regs_used ? 1 : 0)
-+		   : (gpr ? 1 : 0)) << 1
- 		| (exitp ? 1: 0));
+-		| (exitp ? 1: 0));
++		| ((TARGET_SPE_ABI
++		    /* On the SPE, we never have any FPRs, but we do have
++		       32/64-bit versions of the routines.  */
++		    ? (info->spe_64bit_regs_used ? 1 : 0)
++		    : (gpr ? 1 : 0)) << 1)
++		| (lr ? 1: 0));
  
    /* Don't generate bogus routine names.  */
-@@ -18076,6 +18077,7 @@ rs6000_savres_routine_sym (rs6000_stack_
+-  gcc_assert (FIRST_SAVRES_REGISTER <= regno && regno <= LAST_SAVRES_REGISTER);
++  gcc_assert (FIRST_SAVRES_REGISTER <= regno
++	      && regno <= LAST_SAVRES_REGISTER);
+ 
+   sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
+ 
+   if (sym == NULL)
+     {
+-      char name[30];
+-      const char *action;
+-      const char *regkind;
+-      const char *exit_suffix;
+-
+-      action = savep ? "save" : "rest";
+-
+-      /* SPE has slightly different names for its routines depending on
+-	 whether we are saving 32-bit or 64-bit registers.  */
+-      if (TARGET_SPE_ABI)
+-	{
+-	  /* No floating point saves on the SPE.  */
+-	  gcc_assert (gpr);
+-
+-	  regkind = info->spe_64bit_regs_used ? "64gpr" : "32gpr";
+-	}
+-      else
+-	regkind = gpr ? "gpr" : "fpr";
+-
+-      exit_suffix = exitp ? "_x" : "";
++      char *name;
+ 
+-      sprintf (name, "_%s%s_%d%s", action, regkind, regno, exit_suffix);
++      name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
  
        sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
  	= gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
@@ -97,28 +748,278 @@
      }
  
    return sym;
-@@ -18289,7 +18291,7 @@ rs6000_emit_prologue (void)
+@@ -18124,8 +18207,11 @@ rs6000_emit_stack_reset (rs6000_stack_t 
+   if (frame_reg_rtx != sp_reg_rtx)
+     {
+       if (sp_offset != 0)
+-	return emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
+-				      GEN_INT (sp_offset)));
++	{
++	  rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
++	  return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
++					   GEN_INT (sp_offset)));
++	}
+       else if (!savres)
+ 	return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
+     }
+@@ -18154,7 +18240,7 @@ static rtx
+ rs6000_make_savres_rtx (rs6000_stack_t *info,
+ 			rtx frame_reg_rtx, int save_area_offset,
+ 			enum machine_mode reg_mode,
+-			bool savep, bool gpr, bool exitp)
++			bool savep, bool gpr, bool lr)
+ {
+   int i;
+   int offset, start_reg, end_reg, n_regs;
+@@ -18168,20 +18254,21 @@ rs6000_make_savres_rtx (rs6000_stack_t *
+ 	       : info->first_fp_reg_save);
+   end_reg = gpr ? 32 : 64;
+   n_regs = end_reg - start_reg;
+-  p = rtvec_alloc ((exitp ? 4 : 3) + n_regs);
++  p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
+ 
+-  /* If we're saving registers, then we should never say we're exiting.	 */
+-  gcc_assert ((savep && !exitp) || !savep);
+-
+-  if (exitp)
++  if (!savep && lr)
+     RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
+ 
+   RTVEC_ELT (p, offset++)
+     = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
+ 
+-  sym = rs6000_savres_routine_sym (info, savep, gpr, exitp);
++  sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
+   RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
+-  RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 11));
++  RTVEC_ELT (p, offset++)
++    = gen_rtx_USE (VOIDmode,
++		   gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
++				       : gpr && !lr ? 12
++				       : 1));
+ 
+   for (i = 0; i < end_reg - start_reg; i++)
+     {
+@@ -18196,6 +18283,16 @@ rs6000_make_savres_rtx (rs6000_stack_t *
+ 					       savep ? reg : mem);
+     }
+ 
++  if (savep && lr)
++    {
++      rtx addr, reg, mem;
++      reg = gen_rtx_REG (Pmode, 0);
++      addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
++			   GEN_INT (info->lr_save_offset));
++      mem = gen_frame_mem (Pmode, addr);
++      RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
++    }
++
+   return gen_rtx_PARALLEL (VOIDmode, p);
+ }
+ 
+@@ -18216,7 +18313,10 @@ rs6000_reg_live_or_pic_offset_p (int reg
+ enum {
+   SAVRES_MULTIPLE = 0x1,
+   SAVRES_INLINE_FPRS = 0x2,
+-  SAVRES_INLINE_GPRS = 0x4
++  SAVRES_INLINE_GPRS = 0x4,
++  SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
++  SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
++  SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
+ };
+ 
+ /* Determine the strategy for savings/restoring registers.  */
+@@ -18231,6 +18331,7 @@ rs6000_savres_strategy (rs6000_stack_t *
+   bool savres_gprs_inline;
+   bool noclobber_global_gprs
+     = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
++  int strategy;
+ 
+   using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
+ 		      && (!TARGET_SPE_ABI
+@@ -18250,6 +18351,10 @@ rs6000_savres_strategy (rs6000_stack_t *
+ 			|| info->first_fp_reg_save == 64
+ 			|| !no_global_regs_above (info->first_fp_reg_save,
+ 						  /*gpr=*/false)
++			/* The out-of-line FP routines use
++			   double-precision stores; we can't use those
++			   routines if we don't have such stores.  */
++			|| (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
+ 			|| FP_SAVE_INLINE (info->first_fp_reg_save));
+   savres_gprs_inline = (common
+ 			/* Saving CR interferes with the exit routines
+@@ -18287,9 +18392,22 @@ rs6000_savres_strategy (rs6000_stack_t *
+ 	savres_gprs_inline = savres_gprs_inline || using_multiple_p;
+     }
+ 
+-  return (using_multiple_p
+-	  | (savres_fprs_inline << 1)
+-	  | (savres_gprs_inline << 2));
++  strategy = (using_multiple_p
++	      | (savres_fprs_inline << 1)
++	      | (savres_gprs_inline << 2));
++#ifdef POWERPC_LINUX
++  if (TARGET_64BIT)
++    {
++      if (!savres_fprs_inline)
++	strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
++      else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
++	strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
++    }
++#else
++  if (TARGET_AIX && !savres_fprs_inline)
++    strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
++#endif
++  return strategy;
+ }
+ 
+ /* Emit function prologue as insns.  */
+@@ -18311,7 +18429,7 @@ rs6000_emit_prologue (void)
    int using_store_multiple;
    int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
                                && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
 -                              && !call_used_regs[STATIC_CHAIN_REGNUM]);
-+                              && call_used_regs[STATIC_CHAIN_REGNUM]);
++			      && call_used_regs[STATIC_CHAIN_REGNUM]);
    HOST_WIDE_INT sp_offset = 0;
  
    if (TARGET_FIX_AND_CONTINUE)
-@@ -19095,8 +19097,9 @@ rs6000_emit_epilogue (int sibcall)
+@@ -18496,24 +18614,30 @@ rs6000_emit_prologue (void)
+ 			     gen_rtx_REG (Pmode, LR_REGNO));
+       RTX_FRAME_RELATED_P (insn) = 1;
+ 
+-      addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
++      if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
++			| SAVRES_NOINLINE_FPRS_SAVES_LR)))
++	{
++	  addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ 			       GEN_INT (info->lr_save_offset + sp_offset));
+-      reg = gen_rtx_REG (Pmode, 0);
+-      mem = gen_rtx_MEM (Pmode, addr);
+-      /* This should not be of rs6000_sr_alias_set, because of
+-	 __builtin_return_address.  */
++	  reg = gen_rtx_REG (Pmode, 0);
++	  mem = gen_rtx_MEM (Pmode, addr);
++	  /* This should not be of rs6000_sr_alias_set, because of
++	     __builtin_return_address.  */
+ 
+-      insn = emit_move_insn (mem, reg);
+-      rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+-			    NULL_RTX, NULL_RTX);
++	  insn = emit_move_insn (mem, reg);
++	  rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
++				NULL_RTX, NULL_RTX);
++	}
+     }
+ 
+-  /* If we need to save CR, put it into r12.  */
++  /* If we need to save CR, put it into r12 or r11.  */
+   if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
+     {
+       rtx set;
+ 
+-      cr_save_rtx = gen_rtx_REG (SImode, 12);
++      cr_save_rtx
++	= gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
++		       ? 11 : 12);
+       insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
+       RTX_FRAME_RELATED_P (insn) = 1;
+       /* Now, there's no way that dwarf2out_frame_debug_expr is going
+@@ -18550,7 +18674,9 @@ rs6000_emit_prologue (void)
+ 				    info->fp_save_offset + sp_offset,
+ 				    DFmode,
+ 				    /*savep=*/true, /*gpr=*/false,
+-				    /*exitp=*/false);
++				    /*lr=*/(strategy
++					    & SAVRES_NOINLINE_FPRS_SAVES_LR)
++					   != 0);
+       insn = emit_insn (par);
+       rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ 			    NULL_RTX, NULL_RTX);
+@@ -18646,7 +18772,7 @@ rs6000_emit_prologue (void)
+ 	  par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
+ 					0, reg_mode,
+ 					/*savep=*/true, /*gpr=*/true,
+-					/*exitp=*/false);
++					/*lr=*/false);
+ 	  insn = emit_insn (par);
+ 	  rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ 				NULL_RTX, NULL_RTX);
+@@ -18661,23 +18787,23 @@ rs6000_emit_prologue (void)
+     {
+       rtx par;
+ 
+-      /* Need to adjust r11 if we saved any FPRs.  */
++      /* Need to adjust r11 (r12) if we saved any FPRs.  */
+       if (info->first_fp_reg_save != 64)
+         {
+-          rtx r11 = gen_rtx_REG (reg_mode, 11);
+-          rtx offset = GEN_INT (info->total_size
++	  rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
++				      ? 12 : 11);
++	  rtx offset = GEN_INT (sp_offset
+                                 + (-8 * (64-info->first_fp_reg_save)));
+-          rtx ptr_reg = (sp_reg_rtx == frame_reg_rtx
+-                         ? sp_reg_rtx : r11);
+-
+-	  emit_insn (gen_add3_insn (r11, ptr_reg, offset));
++	  emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
+         }
+ 
+       par = rs6000_make_savres_rtx (info, frame_reg_rtx,
+ 				    info->gp_save_offset + sp_offset,
+ 				    reg_mode,
+ 				    /*savep=*/true, /*gpr=*/true,
+-				    /*exitp=*/false);
++				    /*lr=*/(strategy
++					    & SAVRES_NOINLINE_GPRS_SAVES_LR)
++					   != 0);
+       insn = emit_insn (par);
+       rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ 			    NULL_RTX, NULL_RTX);
+@@ -18954,9 +19080,18 @@ rs6000_output_function_prologue (FILE *f
+      fp values.  */
+   if (info->first_fp_reg_save < 64
+       && !FP_SAVE_INLINE (info->first_fp_reg_save))
+-    fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
+-	     SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
+-	     RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
++    {
++      char *name;
++      int regno = info->first_fp_reg_save - 32;
++
++      name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
++					 /*gpr=*/false, /*lr=*/false);
++      fprintf (file, "\t.extern %s\n", name);
++
++      name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
++					 /*gpr=*/false, /*lr=*/true);
++      fprintf (file, "\t.extern %s\n", name);
++    }
+ 
+   /* Write .extern for AIX common mode routines, if needed.  */
+   if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
+@@ -19082,6 +19217,7 @@ rs6000_emit_epilogue (int sibcall)
+   rtx frame_reg_rtx = sp_reg_rtx;
+   rtx cfa_restores = NULL_RTX;
+   rtx insn;
++  rtx cr_save_reg = NULL_RTX;
+   enum machine_mode reg_mode = Pmode;
+   int reg_size = TARGET_32BIT ? 4 : 8;
+   int i;
+@@ -19115,8 +19251,10 @@ rs6000_emit_epilogue (int sibcall)
  				 || (cfun->calls_alloca
  				     && !frame_pointer_needed));
    restore_lr = (info->lr_save_p
 -		&& restoring_GPRs_inline
 -		&& restoring_FPRs_inline);
++		&& (restoring_FPRs_inline
++		    || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
 +		&& (restoring_GPRs_inline
-+		    || (restoring_FPRs_inline
-+			&& info->first_fp_reg_save < 64)));
++		    || info->first_fp_reg_save < 64));
  
    if (WORLD_SAVE_P (info))
      {
-@@ -19383,7 +19386,7 @@ rs6000_emit_epilogue (int sibcall)
+@@ -19403,7 +19541,7 @@ rs6000_emit_epilogue (int sibcall)
  
    /* Get the old lr if we saved it.  If we are restoring registers
       out-of-line, then the out-of-line routines can do this for us.  */
@@ -127,7 +1028,18 @@
      {
        rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
  				      info->lr_save_offset + sp_offset);
-@@ -19403,7 +19406,7 @@ rs6000_emit_epilogue (int sibcall)
+@@ -19418,12 +19556,17 @@ rs6000_emit_epilogue (int sibcall)
+ 			       GEN_INT (info->cr_save_offset + sp_offset));
+       rtx mem = gen_frame_mem (SImode, addr);
+ 
+-      emit_move_insn (gen_rtx_REG (SImode, 12), mem);
++      cr_save_reg = gen_rtx_REG (SImode,
++				 DEFAULT_ABI == ABI_AIX
++				 && !restoring_GPRs_inline
++				 && info->first_fp_reg_save < 64
++				 ? 11 : 12);
++      emit_move_insn (cr_save_reg, mem);
+     }
  
    /* Set LR here to try to overlap restores below.  LR is always saved
       above incoming stack, so it never needs REG_CFA_RESTORE.  */
@@ -136,101 +1048,158 @@
      emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
  		    gen_rtx_REG (Pmode, 0));
  
-@@ -19639,6 +19642,18 @@ rs6000_emit_epilogue (int sibcall)
+@@ -19540,7 +19683,7 @@ rs6000_emit_epilogue (int sibcall)
+ 	  par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
+ 					0, reg_mode,
+ 					/*savep=*/false, /*gpr=*/true,
+-					/*exitp=*/true);
++					/*lr=*/true);
+ 	  emit_jump_insn (par);
+ 	  /* We don't want anybody else emitting things after we jumped
+ 	     back.  */
+@@ -19558,21 +19701,25 @@ rs6000_emit_epilogue (int sibcall)
+ 	rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
+ 				 sp_offset, can_use_exit);
+       else
+-	emit_insn (gen_addsi3 (gen_rtx_REG (Pmode, 11),
+-			       sp_reg_rtx,
+-			       GEN_INT (sp_offset - info->fp_size)));
++	{
++	  emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
++							? 12 : 11),
++				    frame_reg_rtx,
++				    GEN_INT (sp_offset - info->fp_size)));
++	  if (REGNO (frame_reg_rtx) == 11)
++	    sp_offset += info->fp_size;
++	}
+ 
+       par = rs6000_make_savres_rtx (info, frame_reg_rtx,
+ 				    info->gp_save_offset, reg_mode,
+ 				    /*savep=*/false, /*gpr=*/true,
+-				    /*exitp=*/can_use_exit);
++				    /*lr=*/can_use_exit);
+ 
+       if (can_use_exit)
+ 	{
+ 	  if (info->cr_save_p)
+ 	    {
+-	      rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
+-				       using_mtcr_multiple);
++	      rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
+ 	      if (DEFAULT_ABI == ABI_V4)
+ 		cfa_restores
+ 		  = alloc_reg_note (REG_CFA_RESTORE,
+@@ -19659,6 +19806,16 @@ rs6000_emit_epilogue (int sibcall)
            }
      }
  
 +  if (restore_lr && !restoring_GPRs_inline)
 +    {
 +      rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
-+				      info->lr_save_offset + sp_offset);
++				     info->lr_save_offset + sp_offset);
 +
 +      emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
++      emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
++		      gen_rtx_REG (Pmode, 0));
 +    }
 +
-+  if (restore_lr && !restoring_GPRs_inline)
-+    emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
-+		    gen_rtx_REG (Pmode, 0));
-+
    /* Restore fpr's if we need to do it without calling a function.  */
    if (restoring_FPRs_inline)
      for (i = 0; i < 64 - info->first_fp_reg_save; i++)
---- gcc/config/rs6000/rs6000.md.jj	2009-08-31 23:30:14.383526862 +0200
-+++ gcc/config/rs6000/rs6000.md	2009-09-09 21:03:19.667779689 +0200
-@@ -15289,9 +15289,9 @@
-   [(match_parallel 0 "any_parallel_operand"
- 		   [(clobber (reg:P 65))
- 		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
--                    (use (match_operand:P 2 "gpc_reg_operand" "r"))
--		    (set (match_operand:P 3 "memory_operand" "=m")
--			 (match_operand:P 4 "gpc_reg_operand" "r"))])]
-+		    (use (reg:P 11))
-+		    (set (match_operand:P 2 "memory_operand" "=m")
-+			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
-   ""
-   "bl %z1"
-   [(set_attr "type" "branch")
-@@ -15301,9 +15301,9 @@
-   [(match_parallel 0 "any_parallel_operand"
- 		   [(clobber (reg:P 65))
- 		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
--                    (use (match_operand:P 2 "gpc_reg_operand" "r"))
--		    (set (match_operand:DF 3 "memory_operand" "=m")
--			 (match_operand:DF 4 "gpc_reg_operand" "f"))])]
-+		    (use (reg:P 11))
-+		    (set (match_operand:DF 2 "memory_operand" "=m")
-+			 (match_operand:DF 3 "gpc_reg_operand" "f"))])]
-   ""
-   "bl %z1"
-   [(set_attr "type" "branch")
-@@ -15394,11 +15394,11 @@
+@@ -19685,7 +19842,7 @@ rs6000_emit_epilogue (int sibcall)
+   /* If we saved cr, restore it here.  Just those that were used.  */
+   if (info->cr_save_p)
+     {
+-      rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
++      rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
+       if (DEFAULT_ABI == ABI_V4)
+ 	cfa_restores
+ 	  = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
+@@ -19716,13 +19873,14 @@ rs6000_emit_epilogue (int sibcall)
+   if (!sibcall)
+     {
+       rtvec p;
++      bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
+       if (! restoring_FPRs_inline)
+ 	p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
+       else
+ 	p = rtvec_alloc (2);
  
- (define_insn "*restore_gpregs_<mode>"
-  [(match_parallel 0 "any_parallel_operand"
--                  [(clobber (match_operand:P 1 "register_operand" "=l"))
--                   (use (match_operand:P 2 "symbol_ref_operand" "s"))
--                   (use (match_operand:P 3 "gpc_reg_operand" "r"))
--		   (set (match_operand:P 4 "gpc_reg_operand" "=r")
--			(match_operand:P 5 "memory_operand" "m"))])]
-+		  [(clobber (match_operand:P 1 "register_operand" "=l"))
-+		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
-+		   (use (reg:P 11))
-+		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
-+			(match_operand:P 4 "memory_operand" "m"))])]
-  ""
-  "bl %z2"
+       RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
+-      RTVEC_ELT (p, 1) = (restoring_FPRs_inline
++      RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
+ 			  ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
+ 			  : gen_rtx_CLOBBER (VOIDmode,
+ 					     gen_rtx_REG (Pmode, 65)));
+@@ -19737,10 +19895,12 @@ rs6000_emit_epilogue (int sibcall)
+ 	  sym = rs6000_savres_routine_sym (info,
+ 					   /*savep=*/false,
+ 					   /*gpr=*/false,
+-					   /*exitp=*/true);
++					   /*lr=*/lr);
+ 	  RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
+ 	  RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
+-					  gen_rtx_REG (Pmode, 11));
++					  gen_rtx_REG (Pmode,
++						       DEFAULT_ABI == ABI_AIX
++						       ? 1 : 11));
+ 	  for (i = 0; i < 64 - info->first_fp_reg_save; i++)
+ 	    {
+ 	      rtx addr, mem;
+--- gcc/config/rs6000/rs6000.md	(revision 151728)
++++ gcc/config/rs6000/rs6000.md	(revision 151729)
+@@ -15436,6 +15436,19 @@ (define_insn "*return_and_restore_fpregs
   [(set_attr "type" "branch")
-@@ -15406,12 +15406,12 @@
+   (set_attr "length" "4")])
  
- (define_insn "*return_and_restore_gpregs_<mode>"
-  [(match_parallel 0 "any_parallel_operand"
--                  [(return)
++(define_insn "*return_and_restore_fpregs_aix_<mode>"
++ [(match_parallel 0 "any_parallel_operand"
 +		  [(return)
- 		   (clobber (match_operand:P 1 "register_operand" "=l"))
- 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
--                   (use (match_operand:P 3 "gpc_reg_operand" "r"))
--		   (set (match_operand:P 4 "gpc_reg_operand" "=r")
--			(match_operand:P 5 "memory_operand" "m"))])]
-+		   (use (reg:P 11))
-+		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
-+			(match_operand:P 4 "memory_operand" "m"))])]
-  ""
-  "b %z2"
-  [(set_attr "type" "branch")
-@@ -15419,12 +15419,12 @@
++		   (use (match_operand:P 1 "register_operand" "l"))
++		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
++		   (use (match_operand:P 3 "gpc_reg_operand" "r"))
++		   (set (match_operand:DF 4 "gpc_reg_operand" "=d")
++			(match_operand:DF 5 "memory_operand" "m"))])]
++ ""
++ "b %z2"
++ [(set_attr "type" "branch")
++  (set_attr "length" "4")])
++
+ ; This is used in compiling the unwind routines.
+ (define_expand "eh_return"
+   [(use (match_operand 0 "general_operand" ""))]
+--- gcc/config/rs6000/sysv4.h	(revision 151728)
++++ gcc/config/rs6000/sysv4.h	(revision 151729)
+@@ -272,27 +272,25 @@ do {									\
+ #endif
  
- (define_insn "*return_and_restore_fpregs_<mode>"
-  [(match_parallel 0 "any_parallel_operand"
--                  [(return)
-+		  [(return)
- 		   (clobber (match_operand:P 1 "register_operand" "=l"))
- 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
--                   (use (match_operand:P 3 "gpc_reg_operand" "r"))
--		   (set (match_operand:DF 4 "gpc_reg_operand" "=f")
--			(match_operand:DF 5 "memory_operand" "m"))])]
-+		   (use (reg:P 11))
-+		   (set (match_operand:DF 3 "gpc_reg_operand" "=f")
-+			(match_operand:DF 4 "memory_operand" "m"))])]
-  ""
-  "b %z2"
-  [(set_attr "type" "branch")
+ /* Define cutoff for using external functions to save floating point.
+-   Currently on 64-bit V.4, always use inline stores.  When optimizing
+-   for size on 32-bit targets, use external functions when
+-   profitable.  */
+-#define FP_SAVE_INLINE(FIRST_REG) (optimize_size && !TARGET_64BIT	\
++   When optimizing for size, use external functions when profitable.  */
++#define FP_SAVE_INLINE(FIRST_REG) (optimize_size			\
+ 				   ? ((FIRST_REG) == 62			\
+ 				      || (FIRST_REG) == 63)		\
+ 				   : (FIRST_REG) < 64)
+ /* And similarly for general purpose registers.  */
+ #define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32	\
+-				   && (TARGET_64BIT || !optimize_size))
++				   && !optimize_size)
+ 
+ /* Put jump tables in read-only memory, rather than in .text.  */
+ #define JUMP_TABLES_IN_TEXT_SECTION 0
+ 
+ /* Prefix and suffix to use to saving floating point.  */
+ #define	SAVE_FP_PREFIX "_savefpr_"
+-#define SAVE_FP_SUFFIX (TARGET_64BIT ? "_l" : "")
++#define SAVE_FP_SUFFIX ""
+ 
+ /* Prefix and suffix to use to restoring floating point.  */
+ #define	RESTORE_FP_PREFIX "_restfpr_"
+-#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "_l" : "")
++#define RESTORE_FP_SUFFIX ""
+ 
+ /* Type used for ptrdiff_t, as a string used in a declaration.  */
+ #define PTRDIFF_TYPE "int"


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/gcc/devel/sources,v
retrieving revision 1.295
retrieving revision 1.296
diff -u -p -r1.295 -r1.296
--- sources	11 Sep 2009 09:52:13 -0000	1.295
+++ sources	16 Sep 2009 13:27:06 -0000	1.296
@@ -1,2 +1,2 @@
 2659f09c2e43ef8b7d4406321753f1b2  fastjar-0.97.tar.gz
-36739b78d9654be37ccf6019e72db459  gcc-4.4.1-20090911.tar.bz2
+921813722475a64597078d02577eda9c  gcc-4.4.1-20090916.tar.bz2


--- gcc44-pr41175-2.patch DELETED ---




More information about the scm-commits mailing list