aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.3.3/debian
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.3.3/debian')
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.3.3/debian/arm-unbreak-eabi-armv4t.dpatch36
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.3.3/debian/gcc-ice-hack.dpatch331
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.3.3/debian/libstdc++-pic.dpatch71
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.3.3/debian/pr30961.dpatch179
4 files changed, 617 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.3.3/debian/arm-unbreak-eabi-armv4t.dpatch b/meta/recipes-devtools/gcc/gcc-4.3.3/debian/arm-unbreak-eabi-armv4t.dpatch
new file mode 100644
index 0000000000..7bb8887068
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.3.3/debian/arm-unbreak-eabi-armv4t.dpatch
@@ -0,0 +1,36 @@
+#! /bin/sh -e
+
+# DP: Fix armv4t build on ARM
+
+dir=
+if [ $# -eq 3 -a "$2" = '-d' ]; then
+ pdir="-d $3"
+ dir="$3/"
+elif [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+case "$1" in
+ -patch)
+ patch $pdir -f --no-backup-if-mismatch -p1 < $0
+ ;;
+ -unpatch)
+ patch $pdir -f --no-backup-if-mismatch -R -p1 < $0
+ ;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+esac
+exit 0
+
+--- src/gcc/config/arm/linux-eabi.h.orig 2007-11-24 12:37:38.000000000 +0000
++++ src/gcc/config/arm/linux-eabi.h 2007-11-24 12:39:41.000000000 +0000
+@@ -44,7 +44,7 @@
+ The ARM10TDMI core is the default for armv5t, so set
+ SUBTARGET_CPU_DEFAULT to achieve this. */
+ #undef SUBTARGET_CPU_DEFAULT
+-#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm10tdmi
++#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm9tdmi
+
+ /* TARGET_BIG_ENDIAN_DEFAULT is set in
+ config.gcc for big endian configurations. */
diff --git a/meta/recipes-devtools/gcc/gcc-4.3.3/debian/gcc-ice-hack.dpatch b/meta/recipes-devtools/gcc/gcc-4.3.3/debian/gcc-ice-hack.dpatch
new file mode 100644
index 0000000000..84c5ef2ebd
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.3.3/debian/gcc-ice-hack.dpatch
@@ -0,0 +1,331 @@
+#! /bin/sh -e
+
+# DP: Retry the build on an ice, save the calling options and preprocessed
+# DP: source when the ice is reproducible.
+
+dir=
+if [ $# -eq 3 -a "$2" = '-d' ]; then
+ pdir="-d $3"
+ dir="$3/"
+elif [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+case "$1" in
+ -patch)
+ patch $pdir -f --no-backup-if-mismatch -p0 < $0
+ ;;
+ -unpatch)
+ patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
+ ;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+esac
+exit 0
+
+2004-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ * system.h (ICE_EXIT_CODE): Define.
+ * gcc.c (execute): Don't free first string early, but at the end
+ of the function. Call retry_ice if compiler exited with
+ ICE_EXIT_CODE.
+ (retry_ice): New function.
+ * diagnostic.c (diagnostic_count_diagnostic,
+ diagnostic_action_after_output, error_recursion): Exit with
+ ICE_EXIT_CODE instead of FATAL_EXIT_CODE.
+
+--- gcc/diagnostic.c.orig 2007-09-30 10:48:13.000000000 +0000
++++ gcc/diagnostic.c 2007-09-30 10:49:57.000000000 +0000
+@@ -244,7 +244,7 @@
+ fnotice (stderr, "Please submit a full bug report,\n"
+ "with preprocessed source if appropriate.\n"
+ "See %s for instructions.\n", bug_report_url);
+- exit (ICE_EXIT_CODE);
++ exit (FATAL_EXIT_CODE);
+
+ case DK_FATAL:
+ if (context->abort_on_error)
+--- gcc/gcc.c.orig 2007-09-30 10:48:13.000000000 +0000
++++ gcc/gcc.c 2007-09-30 10:48:39.000000000 +0000
+@@ -357,6 +357,9 @@
+ #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
+ static const char *convert_filename (const char *, int, int);
+ #endif
++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
++static void retry_ice (const char *prog, const char **argv);
++#endif
+
+ static const char *getenv_spec_function (int, const char **);
+ static const char *if_exists_spec_function (int, const char **);
+@@ -2999,7 +3002,7 @@
+ }
+ }
+
+- if (string != commands[i].prog)
++ if (i && string != commands[i].prog)
+ free (CONST_CAST (char *, string));
+ }
+
+@@ -3056,6 +3059,16 @@
+ else if (WIFEXITED (status)
+ && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
+ {
++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
++ /* For ICEs in cc1, cc1obj, cc1plus see if it is
++ reproducible or not. */
++ char *p;
++ if (WEXITSTATUS (status) == ICE_EXIT_CODE
++ && i == 0
++ && (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
++ && ! strncmp (p + 1, "cc1", 3))
++ retry_ice (commands[0].prog, commands[0].argv);
++#endif
+ if (WEXITSTATUS (status) > greatest_status)
+ greatest_status = WEXITSTATUS (status);
+ ret_code = -1;
+@@ -3076,6 +3089,9 @@
+ }
+ }
+
++ if (commands[0].argv[0] != commands[0].prog)
++ free ((PTR) commands[0].argv[0]);
++
+ return ret_code;
+ }
+ }
+@@ -6016,6 +6032,224 @@
+ switches[switchnum].validated = 1;
+ }
+
++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
++#define RETRY_ICE_ATTEMPTS 2
++
++static void
++retry_ice (const char *prog, const char **argv)
++{
++ int nargs, out_arg = -1, quiet = 0, attempt;
++ int pid, retries, sleep_interval;
++ const char **new_argv;
++ char *temp_filenames[RETRY_ICE_ATTEMPTS * 2 + 2];
++
++ if (input_filename == NULL || ! strcmp (input_filename, "-"))
++ return;
++
++ for (nargs = 0; argv[nargs] != NULL; ++nargs)
++ /* Only retry compiler ICEs, not preprocessor ones. */
++ if (! strcmp (argv[nargs], "-E"))
++ return;
++ else if (argv[nargs][0] == '-' && argv[nargs][1] == 'o')
++ {
++ if (out_arg == -1)
++ out_arg = nargs;
++ else
++ return;
++ }
++ /* If the compiler is going to output any time information,
++ it might vary between invocations. */
++ else if (! strcmp (argv[nargs], "-quiet"))
++ quiet = 1;
++ else if (! strcmp (argv[nargs], "-ftime-report"))
++ return;
++
++ if (out_arg == -1 || !quiet)
++ return;
++
++ memset (temp_filenames, '\0', sizeof (temp_filenames));
++ new_argv = alloca ((nargs + 3) * sizeof (const char *));
++ memcpy (new_argv, argv, (nargs + 1) * sizeof (const char *));
++ new_argv[nargs++] = "-frandom-seed=0";
++ new_argv[nargs] = NULL;
++ if (new_argv[out_arg][2] == '\0')
++ new_argv[out_arg + 1] = "-";
++ else
++ new_argv[out_arg] = "-o-";
++
++ for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS + 1; ++attempt)
++ {
++ int fd = -1;
++ int status;
++
++ temp_filenames[attempt * 2] = make_temp_file (".out");
++ temp_filenames[attempt * 2 + 1] = make_temp_file (".err");
++
++ if (attempt == RETRY_ICE_ATTEMPTS)
++ {
++ int i;
++ int fd1, fd2;
++ struct stat st1, st2;
++ size_t n, len;
++ char *buf;
++
++ buf = xmalloc (8192);
++
++ for (i = 0; i < 2; ++i)
++ {
++ fd1 = open (temp_filenames[i], O_RDONLY);
++ fd2 = open (temp_filenames[2 + i], O_RDONLY);
++
++ if (fd1 < 0 || fd2 < 0)
++ {
++ i = -1;
++ close (fd1);
++ close (fd2);
++ break;
++ }
++
++ if (fstat (fd1, &st1) < 0 || fstat (fd2, &st2) < 0)
++ {
++ i = -1;
++ close (fd1);
++ close (fd2);
++ break;
++ }
++
++ if (st1.st_size != st2.st_size)
++ {
++ close (fd1);
++ close (fd2);
++ break;
++ }
++
++ len = 0;
++ for (n = st1.st_size; n; n -= len)
++ {
++ len = n;
++ if (len > 4096)
++ len = 4096;
++
++ if (read (fd1, buf, len) != (int) len
++ || read (fd2, buf + 4096, len) != (int) len)
++ {
++ i = -1;
++ break;
++ }
++
++ if (memcmp (buf, buf + 4096, len) != 0)
++ break;
++ }
++
++ close (fd1);
++ close (fd2);
++
++ if (n)
++ break;
++ }
++
++ free (buf);
++ if (i == -1)
++ break;
++
++ if (i != 2)
++ {
++ notice ("The bug is not reproducible, so it is likely a hardware or OS problem.\n");
++ break;
++ }
++
++ fd = open (temp_filenames[attempt * 2], O_RDWR);
++ if (fd < 0)
++ break;
++ write (fd, "//", 2);
++ for (i = 0; i < nargs; i++)
++ {
++ write (fd, " ", 1);
++ write (fd, new_argv[i], strlen (new_argv[i]));
++ }
++ write (fd, "\n", 1);
++ new_argv[nargs] = "-E";
++ new_argv[nargs + 1] = NULL;
++ }
++
++ /* Fork a subprocess; wait and retry if it fails. */
++ sleep_interval = 1;
++ pid = -1;
++ for (retries = 0; retries < 4; retries++)
++ {
++ pid = fork ();
++ if (pid >= 0)
++ break;
++ sleep (sleep_interval);
++ sleep_interval *= 2;
++ }
++
++ if (pid < 0)
++ break;
++ else if (pid == 0)
++ {
++ if (attempt != RETRY_ICE_ATTEMPTS)
++ fd = open (temp_filenames[attempt * 2], O_RDWR);
++ if (fd < 0)
++ exit (-1);
++ if (fd != 1)
++ {
++ close (1);
++ dup (fd);
++ close (fd);
++ }
++
++ fd = open (temp_filenames[attempt * 2 + 1], O_RDWR);
++ if (fd < 0)
++ exit (-1);
++ if (fd != 2)
++ {
++ close (2);
++ dup (fd);
++ close (fd);
++ }
++
++ if (prog == new_argv[0])
++ execvp (prog, (char *const *) new_argv);
++ else
++ execv (new_argv[0], (char *const *) new_argv);
++ exit (-1);
++ }
++
++ if (waitpid (pid, &status, 0) < 0)
++ break;
++
++ if (attempt < RETRY_ICE_ATTEMPTS
++ && (! WIFEXITED (status) || WEXITSTATUS (status) != ICE_EXIT_CODE))
++ {
++ notice ("The bug is not reproducible, so it is likely a hardware or OS problem.\n");
++ break;
++ }
++ else if (attempt == RETRY_ICE_ATTEMPTS)
++ {
++ close (fd);
++ if (WIFEXITED (status)
++ && WEXITSTATUS (status) == SUCCESS_EXIT_CODE)
++ {
++ notice ("Preprocessed source stored into %s file, please attach this to your bugreport.\n",
++ temp_filenames[attempt * 2]);
++ /* Make sure it is not deleted. */
++ free (temp_filenames[attempt * 2]);
++ temp_filenames[attempt * 2] = NULL;
++ break;
++ }
++ }
++ }
++
++ for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS * 2 + 2; attempt++)
++ if (temp_filenames[attempt])
++ {
++ unlink (temp_filenames[attempt]);
++ free (temp_filenames[attempt]);
++ }
++}
++#endif
++
+ /* Search for a file named NAME trying various prefixes including the
+ user's -B prefix and some standard ones.
+ Return the absolute file name found. If nothing is found, return NAME. */
+--- gcc/Makefile.in.orig 2007-09-30 10:48:13.000000000 +0000
++++ gcc/Makefile.in 2007-09-30 10:48:39.000000000 +0000
+@@ -192,6 +192,7 @@
+ build/gengtype-lex.o-warn = -Wno-error
+ # SYSCALLS.c misses prototypes
+ SYSCALLS.c.X-warn = -Wno-strict-prototypes -Wno-error
++build/gcc.o-warn = -Wno-error
+
+ # All warnings have to be shut off in stage1 if the compiler used then
+ # isn't gcc; configure determines that. WARN_CFLAGS will be either
diff --git a/meta/recipes-devtools/gcc/gcc-4.3.3/debian/libstdc++-pic.dpatch b/meta/recipes-devtools/gcc/gcc-4.3.3/debian/libstdc++-pic.dpatch
new file mode 100644
index 0000000000..70c9e81542
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.3.3/debian/libstdc++-pic.dpatch
@@ -0,0 +1,71 @@
+#! /bin/sh -e
+
+# DP: Build and install libstdc++_pic.a library.
+
+dir=
+if [ $# -eq 3 -a "$2" = '-d' ]; then
+ pdir="-d $3"
+ dir="$3/"
+elif [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+case "$1" in
+ -patch)
+ patch $pdir -f --no-backup-if-mismatch -p0 < $0
+ ;;
+ -unpatch)
+ patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
+ ;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+esac
+exit 0
+
+diff -ur libstdc++-v3/src/Makefile.am libstdc++-v3/src/Makefile.am
+--- libstdc++-v3/src/Makefile.am~ 2004-04-16 21:04:05.000000000 +0200
++++ libstdc++-v3/src/Makefile.am 2004-07-03 20:22:43.000000000 +0200
+@@ -210,6 +210,10 @@
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LDFLAGS) -o $@
+
+
++install-exec-local:
++ $(AR) cru libstdc++_pic.a .libs/*.o $(top_builddir)/libsupc++/*.o || touch libstdc++_pic.a
++ $(INSTALL_DATA) libstdc++_pic.a $(DESTDIR)$(toolexeclibdir)
++
+ # Added bits to build debug library.
+ if GLIBCXX_BUILD_DEBUG
+ all-local: build_debug
+diff -ur libstdc++-v3/src/Makefile.in libstdc++-v3/src/Makefile.in
+--- libstdc++-v3/src/Makefile.in 2004-07-03 06:41:13.000000000 +0200
++++ libstdc++-v3/src/Makefile.in 2004-07-03 20:25:05.000000000 +0200
+@@ -611,7 +611,7 @@
+
+ install-data-am: install-data-local
+
+-install-exec-am: install-toolexeclibLTLIBRARIES
++install-exec-am: install-toolexeclibLTLIBRARIES install-exec-local
+
+ install-info: install-info-am
+
+@@ -644,6 +644,7 @@
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-local install-exec \
++ install-exec-local \
+ install-exec-am install-info install-info-am install-man \
+ install-strip install-toolexeclibLTLIBRARIES installcheck \
+ installcheck-am installdirs maintainer-clean \
+@@ -729,6 +730,11 @@
+ install_debug:
+ (cd ${debugdir} && $(MAKE) \
+ toolexeclibdir=$(glibcxx_toolexeclibdir)/debug install)
++
++install-exec-local:
++ $(AR) cru libstdc++_pic.a .libs/*.o $(top_builddir)/libsupc++/*.o || touch libstdc++_pic.a
++ $(INSTALL_DATA) libstdc++_pic.a $(DESTDIR)$(toolexeclibdir)
++
+ # Tell versions [3.59,3.63) of GNU make to not export all variables.
+ # Otherwise a system limit (for SysV at least) may be exceeded.
+ .NOEXPORT:
diff --git a/meta/recipes-devtools/gcc/gcc-4.3.3/debian/pr30961.dpatch b/meta/recipes-devtools/gcc/gcc-4.3.3/debian/pr30961.dpatch
new file mode 100644
index 0000000000..b20fdf5bf5
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.3.3/debian/pr30961.dpatch
@@ -0,0 +1,179 @@
+#! /bin/sh -e
+
+# DP: <your description>
+
+dir=
+if [ $# -eq 3 -a "$2" = '-d' ]; then
+ pdir="-d $3"
+ dir="$3/"
+elif [ $# -ne 1 ]; then
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+fi
+case "$1" in
+ -patch)
+ patch $pdir -f --no-backup-if-mismatch -p0 < $0
+ ;;
+ -unpatch)
+ patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
+ ;;
+ *)
+ echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
+ exit 1
+esac
+exit 0
+
+From: "H.J. Lu" <hjl@lucon.org>
+Sender: gcc-patches-owner@gcc.gnu.org
+To: gcc-patches@gcc.gnu.org
+Subject: PATCH: PR target/30961: [4.1/4.2/4.3 regression] redundant reg/mem stores/moves
+Date: Mon, 27 Aug 2007 11:34:12 -0700
+
+We start with
+
+(note:HI 3 4 22 2 NOTE_INSN_FUNCTION_BEG)
+
+(insn:HI 6 3 10 2 c.c:3 (set (reg:DF 58 [ <result> ])
+ (subreg:DF (reg/v:DI 59 [ in ]) 0)) 102 {*movdf_integer_rex64} (expr_list:REG_DEAD (reg/v:DI 59 [ in ])
+ (nil)))
+
+(insn:HI 10 6 16 2 c.c:7 (set (reg/i:DF 21 xmm0 [ <result> ])
+ (reg:DF 58 [ <result> ])) 102 {*movdf_integer_rex64} (expr_list:REG_DEAD (reg:DF 58 [ <result> ])
+ (nil)))
+
+(insn:HI 16 10 0 2 c.c:7 (use (reg/i:DF 21 xmm0 [ <result> ])) -1 (nil))
+
+we are trying to allocate registers for insn 6 and we allocate
+xmm0 for the return value. Reload doesn't check if xmm0 can be used for
+DF 59, it allocates xmm1 for DF 59 and generates:
+
+Reloads for insn # 6
+Reload 0: reload_in (DF) = (reg:DF 5 di)
+ SSE_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine
+ reload_in_reg: (subreg:DF (reg/v:DI 5 di [orig:59 in ] [59]) 0)
+ reload_reg_rtx: (reg:DF 22 xmm1)
+...
+
+(note:HI 4 1 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+
+(note:HI 3 4 22 2 NOTE_INSN_FUNCTION_BEG)
+
+(insn 22 3 23 2 c.c:3 (set (mem/c:DF (plus:DI (reg/f:DI 7 sp)
+ (const_int -8 [0xfffffffffffffff8])) [0 S8 A8])
+ (reg:DF 5 di)) 102 {*movdf_integer_rex64} (nil))
+
+(insn 23 22 6 2 c.c:3 (set (reg:DF 22 xmm1)
+ (mem/c:DF (plus:DI (reg/f:DI 7 sp)
+ (const_int -8 [0xfffffffffffffff8])) [0 S8 A8])) 102 {*movdf_integer_rex64} (nil))
+
+(insn:HI 6 23 16 2 c.c:3 (set (reg:DF 21 xmm0 [orig:58 <result> ] [58])
+ (reg:DF 22 xmm1)) 102 {*movdf_integer_rex64} (nil))
+
+(insn 16 6 21 2 c.c:7 (use (reg/i:DF 21 xmm0 [ <result> ])) -1 (nil))
+
+This patch tries to use the destination register when reloading for input. It
+generates
+
+Reloads for insn # 6
+Reload 0: reload_in (DF) = (reg:DF 5 di)
+ SSE_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine
+ reload_in_reg: (subreg:DF (reg/v:DI 5 di [orig:59 in ] [59]) 0)
+ reload_reg_rtx: (reg:DF 21 xmm0)
+...
+(note:HI 4 1 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+
+(note:HI 3 4 22 2 NOTE_INSN_FUNCTION_BEG)
+
+(insn 22 3 23 2 c.c:3 (set (mem/c:DF (plus:DI (reg/f:DI 7 sp)
+ (const_int -8 [0xfffffffffffffff8])) [0 S8 A8])
+ (reg:DF 5 di)) 102 {*movdf_integer_rex64} (nil))
+
+(insn 23 22 6 2 c.c:3 (set (reg:DF 21 xmm0)
+ (mem/c:DF (plus:DI (reg/f:DI 7 sp)
+ (const_int -8 [0xfffffffffffffff8])) [0 S8 A8])) 102 {*movdf_integer_rex64} (nil))
+
+(insn:HI 6 23 10 2 c.c:3 (set (reg:DF 22 xmm1 [orig:58 <result> ] [58])
+ (reg:DF 21 xmm0)) 102 {*movdf_integer_rex64} (nil))
+
+(insn:HI 10 6 16 2 c.c:7 (set (reg/i:DF 21 xmm0 [ <result> ])
+ (reg:DF 22 xmm1 [orig:58 <result> ] [58])) 102 {*movdf_integer_rex64} (nil))
+
+(insn 16 10 21 2 c.c:7 (use (reg/i:DF 21 xmm0 [ <result> ])) -1 (nil))
+
+
+H.J.
+----
+gcc/
+
+2007-08-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/30961
+ * reload1.c (find_reg): Favor the hard register in destination
+ if it is usable and a memory location is needed for reload
+ input.
+
+gcc/testsuite/
+
+2007-08-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/30961
+ * gcc.target/i386/pr30961-1.c: New.
+
+--- gcc/reload1.c.second 2007-08-27 09:35:08.000000000 -0700
++++ gcc/reload1.c 2007-08-27 09:36:33.000000000 -0700
+@@ -1781,6 +1781,20 @@ find_reg (struct insn_chain *chain, int
+ HARD_REG_SET not_usable;
+ HARD_REG_SET used_by_other_reload;
+ reg_set_iterator rsi;
++#ifdef SECONDARY_MEMORY_NEEDED
++ rtx body = PATTERN (chain->insn);
++ unsigned int dest_reg = FIRST_PSEUDO_REGISTER;
++
++ if (GET_CODE (body) == SET)
++ {
++ rtx dest = SET_DEST (body);
++
++ if ((REG_P (dest)
++ || (GET_CODE (dest) == SUBREG
++ && REG_P (SUBREG_REG (dest)))))
++ dest_reg = reg_or_subregno (dest);
++ }
++#endif
+
+ COPY_HARD_REG_SET (not_usable, bad_spill_regs);
+ IOR_HARD_REG_SET (not_usable, bad_spill_regs_global);
+@@ -1821,6 +1835,18 @@ find_reg (struct insn_chain *chain, int
+ this_cost--;
+ if (rl->out && REG_P (rl->out) && REGNO (rl->out) == regno)
+ this_cost--;
++#ifdef SECONDARY_MEMORY_NEEDED
++ /* If a memory location is needed for rl->in and dest_reg
++ is usable, we will favor it. */
++ else if (dest_reg == regno
++ && rl->in
++ && REG_P (rl->in)
++ && REGNO (rl->in) < FIRST_PSEUDO_REGISTER
++ && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (rl->in)),
++ rl->class,
++ rl->mode))
++ this_cost = 0;
++#endif
+ if (this_cost < best_cost
+ /* Among registers with equal cost, prefer caller-saved ones, or
+ use REG_ALLOC_ORDER if it is defined. */
+--- gcc/testsuite/gcc.target/i386/pr30961-1.c.second 2007-08-27 11:01:59.000000000 -0700
++++ gcc/testsuite/gcc.target/i386/pr30961-1.c 2007-08-27 11:02:51.000000000 -0700
+@@ -0,0 +1,13 @@
++/* { dg-do compile } */
++/* { dg-require-effective-target lp64 } */
++/* { dg-options "-O2" } */
++
++double
++convert (long long in)
++{
++ double f;
++ __builtin_memcpy( &f, &in, sizeof( in ) );
++ return f;
++}
++
++/* { dg-final { scan-assembler-not "movapd" } } */