This looks to be against meta-oe instead of oe-core, but I guess you&#39;re testing patchwork?<br><br><div class="gmail_quote">2011/2/17 Khem Raj <span dir="ltr">&lt;<a href="mailto:raj.khem@gmail.com">raj.khem@gmail.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">Signed-off-by: Khem Raj &lt;<a href="mailto:raj.khem@gmail.com">raj.khem@gmail.com</a>&gt;<br>

---<br>
 recipes/gcc/gcc-4.5.inc                            |   13 +-<br>
 recipes/gcc/gcc-4.5/arm-bswapsi2.patch             |   13 -<br>
 .../gcc-4.5/gcc-arm-volatile-bitfield-fix.patch    |    6 +-<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch |  147 -<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch | 3163 ---------------<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99457.patch | 4236 --------------------<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99464.patch |  157 +<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99465.patch |   94 +<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99466.patch |   38 +<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99468.patch |  811 ++++<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99473.patch |  409 ++<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99474.patch | 3346 ++++++++++++++++<br>
 .../gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99475.patch | 4217 +++++++++++++++++++<br>
 13 files changed, 9083 insertions(+), 7567 deletions(-)<br>
 delete mode 100644 recipes/gcc/gcc-4.5/arm-bswapsi2.patch<br>
 delete mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch<br>
 delete mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch<br>
 delete mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99457.patch<br>
 create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99464.patch<br>
 create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99465.patch<br>
 create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99466.patch<br>
 create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99468.patch<br>
 create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99473.patch<br>
 create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99474.patch<br>
 create mode 100644 recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99475.patch<br>
<br>
diff --git a/recipes/gcc/gcc-4.5.inc b/recipes/gcc/gcc-4.5.inc<br>
index b630528..1f089f6 100644<br>
--- a/recipes/gcc/gcc-4.5.inc<br>
+++ b/recipes/gcc/gcc-4.5.inc<br>
@@ -10,7 +10,7 @@ NATIVEDEPS = &quot;mpfr-native gmp-native libmpc-native&quot;<br>
<br>
 INC_PR = &quot;r31&quot;<br>
<br>
-SRCREV = &quot;168622&quot;<br>
+SRCREV = &quot;170123&quot;<br>
 PV = &quot;4.5&quot;<br>
 # BINV should be incremented after updating to a revision<br>
 # after a minor gcc release (e.g. 4.5.1 or 4.5.2) has been made<br>
@@ -29,7 +29,6 @@ SRC_URI = &quot;svn://<a href="http://gcc.gnu.org/svn/gcc/branches;module=$%7BBRANCH%7D" target="_blank">gcc.gnu.org/svn/gcc/branches;module=${BRANCH}</a> \<br>
           file://cache-amnesia.patch \<br>
           file://gcc-flags-for-build.patch \<br>
           file://libstdc++-emit-__cxa_end_cleanup-in-text.patch \<br>
-          file://arm-bswapsi2.patch \<br>
           file://Makefile.in.patch \<br>
           file://gcc-armv4-pass-fix-v4bx-to-ld.patch \<br>
           file://sh4-multilib.patch \<br>
@@ -154,7 +153,6 @@ SRC_URI = &quot;svn://<a href="http://gcc.gnu.org/svn/gcc/branches;module=$%7BBRANCH%7D" target="_blank">gcc.gnu.org/svn/gcc/branches;module=${BRANCH}</a> \<br>
           file://linaro/gcc-4.5-linaro-r99442.patch \<br>
           file://linaro/gcc-4.5-linaro-r99443.patch \<br>
           file://linaro/gcc-4.5-linaro-r99444.patch \<br>
-          file://linaro/gcc-4.5-linaro-r99448.patch \<br>
           file://linaro/gcc-4.5-linaro-r99449.patch \<br>
           file://linaro/gcc-4.5-linaro-r99450.patch \<br>
           file://linaro/gcc-4.5-linaro-r99451.patch \<br>
@@ -162,8 +160,13 @@ SRC_URI = &quot;svn://<a href="http://gcc.gnu.org/svn/gcc/branches;module=$%7BBRANCH%7D" target="_blank">gcc.gnu.org/svn/gcc/branches;module=${BRANCH}</a> \<br>
           file://linaro/gcc-4.5-linaro-r99453.patch \<br>
           file://linaro/gcc-4.5-linaro-r99454.patch \<br>
           file://linaro/gcc-4.5-linaro-r99455.patch \<br>
-#         file://linaro/gcc-4.5-linaro-r99456.patch \<br>
-#         file://linaro/gcc-4.5-linaro-r99457.patch \<br>
+          file://linaro/gcc-4.5-linaro-r99464.patch \<br>
+          file://linaro/gcc-4.5-linaro-r99465.patch \<br>
+          file://linaro/gcc-4.5-linaro-r99466.patch \<br>
+          file://linaro/gcc-4.5-linaro-r99468.patch \<br>
+          file://linaro/gcc-4.5-linaro-r99473.patch \<br>
+          file://linaro/gcc-4.5-linaro-r99474.patch \<br>
+          file://linaro/gcc-4.5-linaro-r99475.patch \<br>
           file://gcc-scalar-widening-pr45847.patch \<br>
           file://gcc-arm-volatile-bitfield-fix.patch \<br>
          &quot;<br>
diff --git a/recipes/gcc/gcc-4.5/arm-bswapsi2.patch b/recipes/gcc/gcc-4.5/arm-bswapsi2.patch<br>
deleted file mode 100644<br>
index 7ac61a6..0000000<br>
--- a/recipes/gcc/gcc-4.5/arm-bswapsi2.patch<br>
+++ /dev/null<br>
@@ -1,13 +0,0 @@<br>
-Index: gcc-4.5/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a><br>
-===================================================================<br>
---- gcc-4.5.orig/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a> 2010-06-17 09:13:07.000000000 -0700<br>
-+++ gcc-4.5/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a>      2010-06-22 08:08:45.397212002 -0700<br>
-@@ -11267,7 +11267,7 @@<br>
- (define_expand &quot;bswapsi2&quot;<br>
-   [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
-       (bswap:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;)))]<br>
--&quot;TARGET_EITHER&quot;<br>
-+&quot;TARGET_EITHER &amp;&amp; (arm_arch6 &amp;&amp; !optimize_size)&quot;<br>
- &quot;<br>
-   if (!arm_arch6)<br>
-     {<br>
diff --git a/recipes/gcc/gcc-4.5/gcc-arm-volatile-bitfield-fix.patch b/recipes/gcc/gcc-4.5/gcc-arm-volatile-bitfield-fix.patch<br>
index d5a31d1..f833358 100644<br>
--- a/recipes/gcc/gcc-4.5/gcc-arm-volatile-bitfield-fix.patch<br>
+++ b/recipes/gcc/gcc-4.5/gcc-arm-volatile-bitfield-fix.patch<br>
@@ -89,9 +89,9 @@ ChangeLog<br>
<br>
 Index: gcc-4_5-branch/gcc/expr.c<br>
 ===================================================================<br>
---- gcc-4_5-branch.orig/gcc/expr.c     2010-12-23 00:42:11.690101002 -0800<br>
-+++ gcc-4_5-branch/gcc/expr.c  2010-12-24 15:07:39.400101000 -0800<br>
-@@ -9029,7 +9029,8 @@<br>
+--- gcc-4_5-branch.orig/gcc/expr.c<br>
++++ gcc-4_5-branch/gcc/expr.c<br>
+@@ -9033,7 +9033,8 @@ expand_expr_real_1 (tree exp, rtx target<br>
                &amp;&amp; modifier != EXPAND_INITIALIZER)<br>
            /* If the field is volatile, we always want an aligned<br>
               access.  */<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch<br>
deleted file mode 100644<br>
index 9f3d47f..0000000<br>
--- a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99448.patch<br>
+++ /dev/null<br>
@@ -1,147 +0,0 @@<br>
-2010-12-13  Chung-Lin Tang  &lt;<a href="mailto:cltang@codesourcery.com">cltang@codesourcery.com</a>&gt;<br>
-<br>
-       Backport from mainline:<br>
-<br>
-       2010-12-10  Jakub Jelinek  &lt;<a href="mailto:jakub@redhat.com">jakub@redhat.com</a>&gt;<br>
-<br>
-       PR rtl-optimization/46865<br>
-<br>
-       * rtl.c (rtx_equal_p_cb, rtx_equal_p): For last operand of<br>
-       ASM_OPERANDS and ASM_INPUT if integers are different,<br>
-       call locator_eq.<br>
-       * jump.c (rtx_renumbered_equal_p): Likewise.<br>
-<br>
-       gcc/testsuite/<br>
-       * gcc.target/i386/pr46865-1.c: New test.<br>
-       * gcc.target/i386/pr46865-2.c: New test.<br>
-<br>
-=== modified file &#39;gcc/jump.c&#39;<br>
---- old/gcc/jump.c     2009-11-25 10:55:54 +0000<br>
-+++ new/gcc/jump.c     2010-12-13 10:05:52 +0000<br>
-@@ -1728,7 +1728,13 @@<br>
-<br>
-       case &#39;i&#39;:<br>
-         if (XINT (x, i) != XINT (y, i))<br>
--          return 0;<br>
-+          {<br>
-+            if (((code == ASM_OPERANDS &amp;&amp; i == 6)<br>
-+                 || (code == ASM_INPUT &amp;&amp; i == 1))<br>
-+                &amp;&amp; locator_eq (XINT (x, i), XINT (y, i)))<br>
-+              break;<br>
-+            return 0;<br>
-+          }<br>
-         break;<br>
-<br>
-       case &#39;t&#39;:<br>
-<br>
-=== modified file &#39;gcc/rtl.c&#39;<br>
---- old/gcc/rtl.c      2009-11-25 10:55:54 +0000<br>
-+++ new/gcc/rtl.c      2010-12-13 10:05:52 +0000<br>
-@@ -429,7 +429,15 @@<br>
-       case &#39;n&#39;:<br>
-       case &#39;i&#39;:<br>
-         if (XINT (x, i) != XINT (y, i))<br>
--          return 0;<br>
-+          {<br>
-+#ifndef GENERATOR_FILE<br>
-+            if (((code == ASM_OPERANDS &amp;&amp; i == 6)<br>
-+                 || (code == ASM_INPUT &amp;&amp; i == 1))<br>
-+                &amp;&amp; locator_eq (XINT (x, i), XINT (y, i)))<br>
-+              break;<br>
-+#endif<br>
-+            return 0;<br>
-+          }<br>
-         break;<br>
-<br>
-       case &#39;V&#39;:<br>
-@@ -549,7 +557,15 @@<br>
-       case &#39;n&#39;:<br>
-       case &#39;i&#39;:<br>
-         if (XINT (x, i) != XINT (y, i))<br>
--          return 0;<br>
-+          {<br>
-+#ifndef GENERATOR_FILE<br>
-+            if (((code == ASM_OPERANDS &amp;&amp; i == 6)<br>
-+                 || (code == ASM_INPUT &amp;&amp; i == 1))<br>
-+                &amp;&amp; locator_eq (XINT (x, i), XINT (y, i)))<br>
-+              break;<br>
-+#endif<br>
-+            return 0;<br>
-+          }<br>
-         break;<br>
-<br>
-       case &#39;V&#39;:<br>
-<br>
-=== added file &#39;gcc/testsuite/gcc.target/i386/pr46865-1.c&#39;<br>
---- old/gcc/testsuite/gcc.target/i386/pr46865-1.c      1970-01-01 00:00:00 +0000<br>
-+++ new/gcc/testsuite/gcc.target/i386/pr46865-1.c      2010-12-13 10:05:52 +0000<br>
-@@ -0,0 +1,31 @@<br>
-+/* PR rtl-optimization/46865 */<br>
-+/* { dg-do compile } */<br>
-+/* { dg-options &quot;-O2&quot; } */<br>
-+<br>
-+extern unsigned long f;<br>
-+<br>
-+#define m1(f)                                                 \<br>
-+  if (f &amp; 1)                                                  \<br>
-+    asm volatile (&quot;nop /* asmnop */\n&quot;);                      \<br>
-+  else                                                                \<br>
-+    asm volatile (&quot;nop /* asmnop */\n&quot;);<br>
-+<br>
-+#define m2(f)                                                 \<br>
-+  if (f &amp; 1)                                                  \<br>
-+    asm volatile (&quot;nop /* asmnop */\n&quot; : : &quot;i&quot; (6) : &quot;cx&quot;);   \<br>
-+  else                                                                \<br>
-+    asm volatile (&quot;nop /* asmnop */\n&quot; : : &quot;i&quot; (6) : &quot;cx&quot;);<br>
-+<br>
-+void<br>
-+foo (void)<br>
-+{<br>
-+  m1 (f);<br>
-+}<br>
-+<br>
-+void<br>
-+bar (void)<br>
-+{<br>
-+  m2 (f);<br>
-+}<br>
-+<br>
-+/* { dg-final { scan-assembler-times &quot;asmnop&quot; 2 } } */<br>
-<br>
-=== added file &#39;gcc/testsuite/gcc.target/i386/pr46865-2.c&#39;<br>
---- old/gcc/testsuite/gcc.target/i386/pr46865-2.c      1970-01-01 00:00:00 +0000<br>
-+++ new/gcc/testsuite/gcc.target/i386/pr46865-2.c      2010-12-13 10:05:52 +0000<br>
-@@ -0,0 +1,32 @@<br>
-+/* PR rtl-optimization/46865 */<br>
-+/* { dg-do compile } */<br>
-+/* { dg-options &quot;-O2 -save-temps&quot; } */<br>
-+<br>
-+extern unsigned long f;<br>
-+<br>
-+#define m1(f)                                                 \<br>
-+  if (f &amp; 1)                                                  \<br>
-+    asm volatile (&quot;nop /* asmnop */\n&quot;);                      \<br>
-+  else                                                                \<br>
-+    asm volatile (&quot;nop /* asmnop */\n&quot;);<br>
-+<br>
-+#define m2(f)                                                 \<br>
-+  if (f &amp; 1)                                                  \<br>
-+    asm volatile (&quot;nop /* asmnop */\n&quot; : : &quot;i&quot; (6) : &quot;cx&quot;);   \<br>
-+  else                                                                \<br>
-+    asm volatile (&quot;nop /* asmnop */\n&quot; : : &quot;i&quot; (6) : &quot;cx&quot;);<br>
-+<br>
-+void<br>
-+foo (void)<br>
-+{<br>
-+  m1 (f);<br>
-+}<br>
-+<br>
-+void<br>
-+bar (void)<br>
-+{<br>
-+  m2 (f);<br>
-+}<br>
-+<br>
-+/* { dg-final { scan-assembler-times &quot;asmnop&quot; 2 } } */<br>
-+/* { dg-final { cleanup-saved-temps } } */<br>
-<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch<br>
deleted file mode 100644<br>
index 35f98d2..0000000<br>
--- a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99456.patch<br>
+++ /dev/null<br>
@@ -1,3163 +0,0 @@<br>
-2011-01-03  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
-<br>
-       gcc/<br>
-       * doc/tm.texi (RETURN_ADDR_REGNUM): Document.<br>
-       * doc/md.texi (simple_return): Document pattern.<br>
-       (return): Add a sentence to clarify.<br>
-       * doc/rtl.texi (simple_return): Document.<br>
-       * doc/invoke.texi (Optimize Options): Document -fshrink-wrap.<br>
-       * common.opt (fshrink-wrap): New.<br>
-       * opts.c (decode_options): Set it for -O2 and above.<br>
-       * gengenrtl.c (special_rtx): PC, CC0, RETURN and SIMPLE_RETURN<br>
-       are special.<br>
-       * rtl.h (ANY_RETURN_P): New macro.<br>
-       (global_rtl_index): Add GR_RETURN and GR_SIMPLE_RETURN.<br>
-       (ret_rtx, simple_return_rtx): New macros.<br>
-       * genemit.c (gen_exp): RETURN and SIMPLE_RETURN have unique rtxs.<br>
-       (gen_expand, gen_split): Use ANY_RETURN_P.<br>
-       * rtl.c (copy_rtx): RETURN and SIMPLE_RETURN are shared.<br>
-       * emit-rtl.c (verify_rtx_sharing): Likewise.<br>
-       (skip_consecutive_labels): Return the argument if it is a return rtx.<br>
-       (classify_insn): Handle both kinds of return.<br>
-       (init_emit_regs): Create global rtl for ret_rtx and simple_return_rtx.<br>
-       * df-scan.c (df_uses_record): Handle SIMPLE_RETURN.<br>
-       * rtl.def (SIMPLE_RETURN): New.<br>
-       * rtlanal.c (tablejump_p): Check JUMP_LABEL for returns.<br>
-       * final.c (final_scan_insn): Recognize both kinds of return.<br>
-       * reorg.c (function_return_label, function_simple_return_label): New<br>
-       static variables.<br>
-       (end_of_function_label): Remove.<br>
-       (simplejump_or_return_p): New static function.<br>
-       (find_end_label): Add a new arg, KIND.  All callers changed.<br>
-       Depending on KIND, look for a label suitable for return or<br>
-       simple_return.<br>
-       (make_return_insns): Make corresponding changes.<br>
-       (get_jump_flags): Check JUMP_LABELs for returns.<br>
-       (follow_jumps): Likewise.<br>
-       (get_branch_condition): Check target for return patterns rather<br>
-       than NULL.<br>
-       (own_thread_p): Likewise for thread.<br>
-       (steal_delay_list_from_target): Check JUMP_LABELs for returns.<br>
-       Use simplejump_or_return_p.<br>
-       (fill_simple_delay_slots): Likewise.<br>
-       (optimize_skip): Likewise.<br>
-       (fill_slots_from_thread): Likewise.<br>
-       (relax_delay_slots): Likewise.<br>
-       (dbr_schedule): Adjust handling of end_of_function_label for the<br>
-       two new variables.<br>
-       * ifcvt.c (find_if_case_1): Take care when redirecting jumps to the<br>
-       exit block.<br>
-       (dead_or_predicable): Change NEW_DEST arg to DEST_EDGE.  All callers<br>
-       changed.  Ensure that the right label is passed to redirect_jump.<br>
-       * jump.c (condjump_p, condjump_in_parallel_p, any_condjump_p,<br>
-       returnjump_p): Handle SIMPLE_RETURNs.<br>
-       (delete_related_insns): Check JUMP_LABEL for returns.<br>
-       (redirect_target): New static function.<br>
-       (redirect_exp_1): Use it.  Handle any kind of return rtx as a label<br>
-       rather than interpreting NULL as a return.<br>
-       (redirect_jump_1): Assert that nlabel is not NULL.<br>
-       (redirect_jump): Likewise.<br>
-       (redirect_jump_2): Handle any kind of return rtx as a label rather<br>
-       than interpreting NULL as a return.<br>
-       * dwarf2out.c (compute_barrier_args_size_1): Check JUMP_LABEL for<br>
-       returns.<br>
-       * function.c (emit_return_into_block): Remove useless declaration.<br>
-       (record_hard_reg_sets, frame_required_for_rtx, gen_return_pattern,<br>
-       requires_stack_frame_p): New static functions.<br>
-       (emit_return_into_block): New arg SIMPLE_P.  All callers changed.<br>
-       Generate either kind of return pattern and update the JUMP_LABEL.<br>
-       (thread_prologue_and_epilogue_insns): Implement a form of<br>
-       shrink-wrapping.  Ensure JUMP_LABELs for return insns are set.<br>
-       * print-rtl.c (print_rtx): Handle returns in JUMP_LABELs.<br>
-       * cfglayout.c (fixup_reorder_chain): Ensure JUMP_LABELs for returns<br>
-       remain correct.<br>
-       * resource.c (find_dead_or_set_registers): Check JUMP_LABELs for<br>
-       returns.<br>
-       (mark_target_live_regs): Don&#39;t pass a return rtx to next_active_insn.<br>
-       * basic-block.h (force_nonfallthru_and_redirect): Declare.<br>
-       * sched-vis.c (print_pattern): Add case for SIMPLE_RETURN.<br>
-       * cfgrtl.c (force_nonfallthru_and_redirect): No longer static.  New arg<br>
-       JUMP_LABEL.  All callers changed.  Use the label when generating<br>
-       return insns.<br>
-<br>
-       * config/i386/<a href="http://i386.md" target="_blank">i386.md</a> (returns, return_str, return_cond): New<br>
-       code_iterator and corresponding code_attrs.<br>
-       (&lt;return_str&gt;return): Renamed from return and adapted.<br>
-       (&lt;return_str&gt;return_internal): Likewise for return_internal.<br>
-       (&lt;return_str&gt;return_internal_long): Likewise for return_internal_long.<br>
-       (&lt;return_str&gt;return_pop_internal): Likewise for return_pop_internal.<br>
-       (&lt;return_str&gt;return_indirect_internal): Likewise for<br>
-       return_indirect_internal.<br>
-       * config/i386/i386.c (ix86_expand_epilogue): Expand a simple_return as<br>
-       the last insn.<br>
-       (ix86_pad_returns): Handle both kinds of return rtx.<br>
-       * config/arm/arm.c (use_simple_return_p): new function.<br>
-       (is_jump_table): Handle returns in JUMP_LABELs.<br>
-       (output_return_instruction): New arg SIMPLE.  All callers changed.<br>
-       Use it to determine which kind of return to generate.<br>
-       (arm_final_prescan_insn): Handle both kinds of return.<br>
-       * config/arm/<a href="http://arm.md" target="_blank">arm.md</a> (returns, return_str, return_simple_p,<br>
-       return_cond): New code_iterator and corresponding code_attrs.<br>
-       (&lt;return_str&gt;return): Renamed from return and adapted.<br>
-       (arm_&lt;return_str&gt;return): Renamed from arm_return and adapted.<br>
-       (cond_&lt;return_str&gt;return): Renamed from cond_return and adapted.<br>
-       (cond_&lt;return_str&gt;return_inverted): Renamed from cond_return_inverted<br>
-       and adapted.<br>
-       (epilogue): Use ret_rtx instead of gen_rtx_RETURN.<br>
-       * config/arm/<a href="http://thumb2.md" target="_blank">thumb2.md</a> (thumb2_&lt;return_str&gt;return): Renamed from<br>
-       thumb2_return and adapted.<br>
-       * config/arm/arm.h (RETURN_ADDR_REGNUM): Define.<br>
-       * config/arm/arm-protos.h (use_simple_return_p): Declare.<br>
-       (output_return_instruction): Adjust declaration.<br>
-       * config/mips/mips.c (mips_expand_epilogue): Generate a simple_return<br>
-       as final insn.<br>
-       * config/mips/<a href="http://mips.md" target="_blank">mips.md</a> (simple_return): New expander.<br>
-       (*simple_return, simple_return_internal): New patterns.<br>
-       * config/sh/sh.c (barrier_align): Handle return in a JUMP_LABEL.<br>
-       (split_branches): Don&#39;t pass a null label to redirect_jump.<br>
-<br>
-       From mainline:<br>
-       * vec.h (FOR_EACH_VEC_ELT, FOR_EACH_VEC_ELT_REVERSE): New macros.<br>
-       * haifa-sched.c (find_fallthru_edge_from): Rename from<br>
-       find_fallthru_edge.  All callers changed.<br>
-       * sched-int.h (find_fallthru_edge_from): Rename declaration as well.<br>
-       * basic-block.h (find_fallthru_edge): New inline function.<br>
-<br>
-=== modified file &#39;gcc/basic-block.h&#39;<br>
---- old/gcc/basic-block.h      2010-09-01 13:29:58 +0000<br>
-+++ new/gcc/basic-block.h      2011-01-05 12:12:18 +0000<br>
-@@ -884,6 +884,7 @@<br>
-<br>
- /* In cfgrtl.c  */<br>
- extern basic_block force_nonfallthru (edge);<br>
-+extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);<br>
- extern rtx block_label (basic_block);<br>
- extern bool purge_all_dead_edges (void);<br>
- extern bool purge_dead_edges (basic_block);<br>
-@@ -1004,6 +1005,20 @@<br>
-   return false;<br>
- }<br>
-<br>
-+/* Return the fallthru edge in EDGES if it exists, NULL otherwise.  */<br>
-+static inline edge<br>
-+find_fallthru_edge (VEC(edge,gc) *edges)<br>
-+{<br>
-+  edge e;<br>
-+  edge_iterator ei;<br>
-+<br>
-+  FOR_EACH_EDGE (e, ei, edges)<br>
-+    if (e-&gt;flags &amp; EDGE_FALLTHRU)<br>
-+      break;<br>
-+<br>
-+  return e;<br>
-+}<br>
-+<br>
- /* In cfgloopmanip.c.  */<br>
- extern edge mfb_kj_edge;<br>
- extern bool mfb_keep_just (edge);<br>
-<br>
-=== modified file &#39;gcc/cfganal.c&#39;<br>
---- old/gcc/cfganal.c  2009-11-25 10:55:54 +0000<br>
-+++ new/gcc/cfganal.c  2011-01-05 12:12:18 +0000<br>
-@@ -271,6 +271,37 @@<br>
-       EDGE_SUCC (bb, 0)-&gt;flags |= EDGE_CAN_FALLTHRU;<br>
-       EDGE_SUCC (bb, 1)-&gt;flags |= EDGE_CAN_FALLTHRU;<br>
-     }<br>
-+  /* dwarf2out expects that a NOTE_INSN_EPILOGUE_BEGIN is always paired<br>
-+     with a return or a sibcall.  Ensure that this remains the case if<br>
-+     they are in different basic blocks.  */<br>
-+  FOR_EACH_BB (bb)<br>
-+    {<br>
-+      edge e;<br>
-+      edge_iterator ei;<br>
-+      rtx insn, end;<br>
-+<br>
-+      end = BB_END (bb);<br>
-+      FOR_BB_INSNS (bb, insn)<br>
-+      if (GET_CODE (insn) == NOTE<br>
-+          &amp;&amp; NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG<br>
-+          &amp;&amp; !(CALL_P (end) &amp;&amp; SIBLING_CALL_P (end))<br>
-+          &amp;&amp; !returnjump_p (end))<br>
-+        {<br>
-+          basic_block other_bb = NULL;<br>
-+          FOR_EACH_EDGE (e, ei, bb-&gt;succs)<br>
-+            {<br>
-+              if (e-&gt;flags &amp; EDGE_FALLTHRU)<br>
-+                other_bb = e-&gt;dest;<br>
-+              else<br>
-+                e-&gt;flags &amp;= ~EDGE_CAN_FALLTHRU;<br>
-+            }<br>
-+          FOR_EACH_EDGE (e, ei, other_bb-&gt;preds)<br>
-+            {<br>
-+              if (!(e-&gt;flags &amp; EDGE_FALLTHRU))<br>
-+                e-&gt;flags &amp;= ~EDGE_CAN_FALLTHRU;<br>
-+            }<br>
-+        }<br>
-+    }<br>
- }<br>
-<br>
- /* Find unreachable blocks.  An unreachable block will have 0 in<br>
-<br>
-=== modified file &#39;gcc/cfglayout.c&#39;<br>
---- old/gcc/cfglayout.c        2010-05-17 16:30:54 +0000<br>
-+++ new/gcc/cfglayout.c        2011-01-05 12:12:18 +0000<br>
-@@ -766,6 +766,7 @@<br>
-     {<br>
-       edge e_fall, e_taken, e;<br>
-       rtx bb_end_insn;<br>
-+      rtx ret_label = NULL_RTX;<br>
-       basic_block nb;<br>
-       edge_iterator ei;<br>
-<br>
-@@ -785,6 +786,7 @@<br>
-       bb_end_insn = BB_END (bb);<br>
-       if (JUMP_P (bb_end_insn))<br>
-       {<br>
-+        ret_label = JUMP_LABEL (bb_end_insn);<br>
-         if (any_condjump_p (bb_end_insn))<br>
-           {<br>
-             /* This might happen if the conditional jump has side<br>
-@@ -899,7 +901,7 @@<br>
-       }<br>
-<br>
-       /* We got here if we need to add a new jump insn.  */<br>
--      nb = force_nonfallthru (e_fall);<br>
-+      nb = force_nonfallthru_and_redirect (e_fall, e_fall-&gt;dest, ret_label);<br>
-       if (nb)<br>
-       {<br>
-         nb-&gt;il.rtl-&gt;visited = 1;<br>
-@@ -1118,24 +1120,30 @@<br>
- bool<br>
- cfg_layout_can_duplicate_bb_p (const_basic_block bb)<br>
- {<br>
-+  rtx insn;<br>
-+<br>
-   /* Do not attempt to duplicate tablejumps, as we need to unshare<br>
-      the dispatch table.  This is difficult to do, as the instructions<br>
-      computing jump destination may be hoisted outside the basic block.  */<br>
-   if (tablejump_p (BB_END (bb), NULL, NULL))<br>
-     return false;<br>
-<br>
--  /* Do not duplicate blocks containing insns that can&#39;t be copied.  */<br>
--  if (targetm.cannot_copy_insn_p)<br>
-+  insn = BB_HEAD (bb);<br>
-+  while (1)<br>
-     {<br>
--      rtx insn = BB_HEAD (bb);<br>
--      while (1)<br>
--      {<br>
--        if (INSN_P (insn) &amp;&amp; targetm.cannot_copy_insn_p (insn))<br>
--          return false;<br>
--        if (insn == BB_END (bb))<br>
--          break;<br>
--        insn = NEXT_INSN (insn);<br>
--      }<br>
-+      /* Do not duplicate blocks containing insns that can&#39;t be copied.  */<br>
-+      if (INSN_P (insn) &amp;&amp; targetm.cannot_copy_insn_p<br>
-+        &amp;&amp; targetm.cannot_copy_insn_p (insn))<br>
-+      return false;<br>
-+      /* dwarf2out expects that these notes are always paired with a<br>
-+       returnjump or sibling call.  */<br>
-+      if (NOTE_P (insn) &amp;&amp; NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG<br>
-+        &amp;&amp; !returnjump_p (BB_END (bb))<br>
-+        &amp;&amp; (!CALL_P (BB_END (bb)) || !SIBLING_CALL_P (BB_END (bb))))<br>
-+      return false;<br>
-+      if (insn == BB_END (bb))<br>
-+      break;<br>
-+      insn = NEXT_INSN (insn);<br>
-     }<br>
-<br>
-   return true;<br>
-@@ -1167,6 +1175,9 @@<br>
-             || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)<br>
-           break;<br>
-         copy = emit_copy_of_insn_after (insn, get_last_insn ());<br>
-+        if (JUMP_P (insn) &amp;&amp; JUMP_LABEL (insn) != NULL_RTX<br>
-+            &amp;&amp; ANY_RETURN_P (JUMP_LABEL (insn)))<br>
-+          JUMP_LABEL (copy) = JUMP_LABEL (insn);<br>
-           maybe_copy_epilogue_insn (insn, copy);<br>
-         break;<br>
-<br>
-<br>
-=== modified file &#39;gcc/cfgrtl.c&#39;<br>
---- old/gcc/cfgrtl.c   2010-09-20 21:30:35 +0000<br>
-+++ new/gcc/cfgrtl.c   2011-01-05 12:12:18 +0000<br>
-@@ -1107,10 +1107,13 @@<br>
- }<br>
-<br>
- /* Like force_nonfallthru below, but additionally performs redirection<br>
--   Used by redirect_edge_and_branch_force.  */<br>
-+   Used by redirect_edge_and_branch_force.  JUMP_LABEL is used only<br>
-+   when redirecting to the EXIT_BLOCK, it is either a return or a<br>
-+   simple_return rtx indicating which kind of returnjump to create.<br>
-+   It should be NULL otherwise.  */<br>
-<br>
--static basic_block<br>
--force_nonfallthru_and_redirect (edge e, basic_block target)<br>
-+basic_block<br>
-+force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)<br>
- {<br>
-   basic_block jump_block, new_bb = NULL, src = e-&gt;src;<br>
-   rtx note;<br>
-@@ -1242,11 +1245,25 @@<br>
-   e-&gt;flags &amp;= ~EDGE_FALLTHRU;<br>
-   if (target == EXIT_BLOCK_PTR)<br>
-     {<br>
-+      if (jump_label == ret_rtx)<br>
-+      {<br>
- #ifdef HAVE_return<br>
--      emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block), loc);<br>
--#else<br>
--      gcc_unreachable ();<br>
--#endif<br>
-+        emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block),<br>
-+                                     loc);<br>
-+#else<br>
-+        gcc_unreachable ();<br>
-+#endif<br>
-+      }<br>
-+      else<br>
-+      {<br>
-+        gcc_assert (jump_label == simple_return_rtx);<br>
-+#ifdef HAVE_simple_return<br>
-+        emit_jump_insn_after_setloc (gen_simple_return (),<br>
-+                                     BB_END (jump_block), loc);<br>
-+#else<br>
-+        gcc_unreachable ();<br>
-+#endif<br>
-+      }<br>
-     }<br>
-   else<br>
-     {<br>
-@@ -1273,7 +1290,7 @@<br>
- basic_block<br>
- force_nonfallthru (edge e)<br>
- {<br>
--  return force_nonfallthru_and_redirect (e, e-&gt;dest);<br>
-+  return force_nonfallthru_and_redirect (e, e-&gt;dest, NULL_RTX);<br>
- }<br>
-<br>
- /* Redirect edge even at the expense of creating new jump insn or<br>
-@@ -1290,7 +1307,7 @@<br>
-   /* In case the edge redirection failed, try to force it to be non-fallthru<br>
-      and redirect newly created simplejump.  */<br>
-   df_set_bb_dirty (e-&gt;src);<br>
--  return force_nonfallthru_and_redirect (e, target);<br>
-+  return force_nonfallthru_and_redirect (e, target, NULL_RTX);<br>
- }<br>
-<br>
- /* The given edge should potentially be a fallthru edge.  If that is in<br>
-<br>
-=== modified file &#39;gcc/common.opt&#39;<br>
---- old/gcc/common.opt 2010-12-10 15:33:37 +0000<br>
-+++ new/gcc/common.opt 2011-01-05 12:12:18 +0000<br>
-@@ -1147,6 +1147,11 @@<br>
- Common C ObjC C++ ObjC++ Report Var(flag_show_column) Init(1)<br>
- Show column numbers in diagnostics, when available.  Default on<br>
-<br>
-+fshrink-wrap<br>
-+Common Report Var(flag_shrink_wrap) Optimization<br>
-+Emit function prologues only before parts of the function that need it,<br>
-+rather than at the top of the function.<br>
-+<br>
- fsignaling-nans<br>
- Common Report Var(flag_signaling_nans) Optimization<br>
- Disable optimizations observable by IEEE signaling NaNs<br>
-<br>
-=== modified file &#39;gcc/config/arm/arm-protos.h&#39;<br>
---- old/gcc/config/arm/arm-protos.h    2010-11-04 10:45:05 +0000<br>
-+++ new/gcc/config/arm/arm-protos.h    2011-01-05 12:12:18 +0000<br>
-@@ -26,6 +26,7 @@<br>
- extern void arm_override_options (void);<br>
- extern void arm_optimization_options (int, int);<br>
- extern int use_return_insn (int, rtx);<br>
-+extern bool use_simple_return_p (void);<br>
- extern enum reg_class arm_regno_class (int);<br>
- extern void arm_load_pic_register (unsigned long);<br>
- extern int arm_volatile_func (void);<br>
-@@ -137,7 +138,7 @@<br>
- extern const char *output_add_immediate (rtx *);<br>
- extern const char *arithmetic_instr (rtx, int);<br>
- extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);<br>
--extern const char *output_return_instruction (rtx, int, int);<br>
-+extern const char *output_return_instruction (rtx, bool, bool, bool);<br>
- extern void arm_poke_function_name (FILE *, const char *);<br>
- extern void arm_print_operand (FILE *, rtx, int);<br>
- extern void arm_print_operand_address (FILE *, rtx);<br>
-<br>
-=== modified file &#39;gcc/config/arm/arm.c&#39;<br>
---- old/gcc/config/arm/arm.c   2011-01-05 11:32:50 +0000<br>
-+++ new/gcc/config/arm/arm.c   2011-01-05 12:12:18 +0000<br>
-@@ -2163,6 +2163,18 @@<br>
-   return addr;<br>
- }<br>
-<br>
-+/* Return true if we should try to use a simple_return insn, i.e. perform<br>
-+   shrink-wrapping if possible.  This is the case if we need to emit a<br>
-+   prologue, which we can test by looking at the offsets.  */<br>
-+bool<br>
-+use_simple_return_p (void)<br>
-+{<br>
-+  arm_stack_offsets *offsets;<br>
-+<br>
-+  offsets = arm_get_frame_offsets ();<br>
-+  return offsets-&gt;outgoing_args != 0;<br>
-+}<br>
-+<br>
- /* Return 1 if it is possible to return using a single instruction.<br>
-    If SIBLING is non-null, this is a test for a return before a sibling<br>
-    call.  SIBLING is the call insn, so we can examine its register usage.  */<br>
-@@ -11284,6 +11296,7 @@<br>
-<br>
-   if (GET_CODE (insn) == JUMP_INSN<br>
-       &amp;&amp; JUMP_LABEL (insn) != NULL<br>
-+      &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (insn))<br>
-       &amp;&amp; ((table = next_real_insn (JUMP_LABEL (insn)))<br>
-         == next_real_insn (insn))<br>
-       &amp;&amp; table != NULL<br>
-@@ -14168,7 +14181,7 @@<br>
- /* Generate a function exit sequence.  If REALLY_RETURN is false, then do<br>
-    everything bar the final return instruction.  */<br>
- const char *<br>
--output_return_instruction (rtx operand, int really_return, int reverse)<br>
-+output_return_instruction (rtx operand, bool really_return, bool reverse, bool simple)<br>
- {<br>
-   char conditional[10];<br>
-   char instr[100];<br>
-@@ -14206,10 +14219,15 @@<br>
-<br>
-   sprintf (conditional, &quot;%%?%%%c0&quot;, reverse ? &#39;D&#39; : &#39;d&#39;);<br>
-<br>
--  cfun-&gt;machine-&gt;return_used_this_function = 1;<br>
-+  if (simple)<br>
-+    live_regs_mask = 0;<br>
-+  else<br>
-+    {<br>
-+      cfun-&gt;machine-&gt;return_used_this_function = 1;<br>
-<br>
--  offsets = arm_get_frame_offsets ();<br>
--  live_regs_mask = offsets-&gt;saved_regs_mask;<br>
-+      offsets = arm_get_frame_offsets ();<br>
-+      live_regs_mask = offsets-&gt;saved_regs_mask;<br>
-+    }<br>
-<br>
-   if (live_regs_mask)<br>
-     {<br>
-@@ -17108,6 +17126,7 @@<br>
-<br>
-   /* If we start with a return insn, we only succeed if we find another one.  */<br>
-   int seeking_return = 0;<br>
-+  enum rtx_code return_code = UNKNOWN;<br>
-<br>
-   /* START_INSN will hold the insn from where we start looking.  This is the<br>
-      first insn after the following code_label if REVERSE is true.  */<br>
-@@ -17146,7 +17165,7 @@<br>
-         else<br>
-           return;<br>
-       }<br>
--      else if (GET_CODE (body) == RETURN)<br>
-+      else if (ANY_RETURN_P (body))<br>
-         {<br>
-         start_insn = next_nonnote_insn (start_insn);<br>
-         if (GET_CODE (start_insn) == BARRIER)<br>
-@@ -17157,6 +17176,7 @@<br>
-           {<br>
-             reverse = TRUE;<br>
-             seeking_return = 1;<br>
-+            return_code = GET_CODE (body);<br>
-           }<br>
-         else<br>
-           return;<br>
-@@ -17197,11 +17217,15 @@<br>
-         label = XEXP (XEXP (SET_SRC (body), 2), 0);<br>
-         then_not_else = FALSE;<br>
-       }<br>
--      else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)<br>
--      seeking_return = 1;<br>
--      else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)<br>
-+      else if (ANY_RETURN_P (XEXP (SET_SRC (body), 1)))<br>
-+      {<br>
-+        seeking_return = 1;<br>
-+        return_code = GET_CODE (XEXP (SET_SRC (body), 1));<br>
-+      }<br>
-+      else if (ANY_RETURN_P (XEXP (SET_SRC (body), 2)))<br>
-         {<br>
-         seeking_return = 1;<br>
-+        return_code = GET_CODE (XEXP (SET_SRC (body), 2));<br>
-         then_not_else = FALSE;<br>
-         }<br>
-       else<br>
-@@ -17302,8 +17326,7 @@<br>
-                      &amp;&amp; !use_return_insn (TRUE, NULL)<br>
-                      &amp;&amp; !optimize_size)<br>
-               fail = TRUE;<br>
--            else if (GET_CODE (scanbody) == RETURN<br>
--                     &amp;&amp; seeking_return)<br>
-+            else if (GET_CODE (scanbody) == return_code)<br>
-               {<br>
-                 arm_ccfsm_state = 2;<br>
-                 succeed = TRUE;<br>
-<br>
-=== modified file &#39;gcc/config/arm/arm.h&#39;<br>
---- old/gcc/config/arm/arm.h   2010-11-11 11:12:14 +0000<br>
-+++ new/gcc/config/arm/arm.h   2011-01-05 12:12:18 +0000<br>
-@@ -2622,6 +2622,8 @@<br>
- #define RETURN_ADDR_RTX(COUNT, FRAME) \<br>
-   arm_return_addr (COUNT, FRAME)<br>
-<br>
-+#define RETURN_ADDR_REGNUM LR_REGNUM<br>
-+<br>
- /* Mask of the bits in the PC that contain the real return address<br>
-    when running in 26-bit mode.  */<br>
- #define RETURN_ADDR_MASK26 (0x03fffffc)<br>
-<br>
-=== modified file &#39;gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a>&#39;<br>
---- old/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a>  2011-01-05 11:52:16 +0000<br>
-+++ new/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a>  2011-01-05 12:12:18 +0000<br>
-@@ -8882,66 +8882,72 @@<br>
-   [(set_attr &quot;type&quot; &quot;call&quot;)]<br>
- )<br>
-<br>
--(define_expand &quot;return&quot;<br>
--  [(return)]<br>
--  &quot;TARGET_32BIT &amp;&amp; USE_RETURN_INSN (FALSE)&quot;<br>
-+;; Both kinds of return insn.<br>
-+(define_code_iterator returns [return simple_return])<br>
-+(define_code_attr return_str [(return &quot;&quot;) (simple_return &quot;simple_&quot;)])<br>
-+(define_code_attr return_simple_p [(return &quot;false&quot;) (simple_return &quot;true&quot;)])<br>
-+(define_code_attr return_cond [(return &quot; &amp;&amp; USE_RETURN_INSN (FALSE)&quot;)<br>
-+                             (simple_return &quot; &amp;&amp; use_simple_return_p ()&quot;)])<br>
-+<br>
-+(define_expand &quot;&lt;return_str&gt;return&quot;<br>
-+  [(returns)]<br>
-+  &quot;TARGET_32BIT&lt;return_cond&gt;&quot;<br>
-   &quot;&quot;)<br>
-<br>
--;; Often the return insn will be the same as loading from memory, so set attr<br>
--(define_insn &quot;*arm_return&quot;<br>
--  [(return)]<br>
--  &quot;TARGET_ARM &amp;&amp; USE_RETURN_INSN (FALSE)&quot;<br>
--  &quot;*<br>
--  {<br>
--    if (arm_ccfsm_state == 2)<br>
--      {<br>
--        arm_ccfsm_state += 2;<br>
--        return \&quot;\&quot;;<br>
--      }<br>
--    return output_return_instruction (const_true_rtx, TRUE, FALSE);<br>
--  }&quot;<br>
-+(define_insn &quot;*arm_&lt;return_str&gt;return&quot;<br>
-+  [(returns)]<br>
-+  &quot;TARGET_ARM&lt;return_cond&gt;&quot;<br>
-+{<br>
-+  if (arm_ccfsm_state == 2)<br>
-+    {<br>
-+      arm_ccfsm_state += 2;<br>
-+      return &quot;&quot;;<br>
-+    }<br>
-+  return output_return_instruction (const_true_rtx, true, false,<br>
-+                                  &lt;return_simple_p&gt;);<br>
-+}<br>
-   [(set_attr &quot;type&quot; &quot;load1&quot;)<br>
-    (set_attr &quot;length&quot; &quot;12&quot;)<br>
-    (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
- )<br>
-<br>
--(define_insn &quot;*cond_return&quot;<br>
-+(define_insn &quot;*cond_&lt;return_str&gt;return&quot;<br>
-   [(set (pc)<br>
-         (if_then_else (match_operator 0 &quot;arm_comparison_operator&quot;<br>
-                      [(match_operand 1 &quot;cc_register&quot; &quot;&quot;) (const_int 0)])<br>
--                      (return)<br>
-+                      (returns)<br>
-                       (pc)))]<br>
--  &quot;TARGET_ARM &amp;&amp; USE_RETURN_INSN (TRUE)&quot;<br>
--  &quot;*<br>
--  {<br>
--    if (arm_ccfsm_state == 2)<br>
--      {<br>
--        arm_ccfsm_state += 2;<br>
--        return \&quot;\&quot;;<br>
--      }<br>
--    return output_return_instruction (operands[0], TRUE, FALSE);<br>
--  }&quot;<br>
-+  &quot;TARGET_ARM&lt;return_cond&gt;&quot;<br>
-+{<br>
-+  if (arm_ccfsm_state == 2)<br>
-+    {<br>
-+      arm_ccfsm_state += 2;<br>
-+      return &quot;&quot;;<br>
-+    }<br>
-+  return output_return_instruction (operands[0], true, false,<br>
-+                                  &lt;return_simple_p&gt;);<br>
-+}<br>
-   [(set_attr &quot;conds&quot; &quot;use&quot;)<br>
-    (set_attr &quot;length&quot; &quot;12&quot;)<br>
-    (set_attr &quot;type&quot; &quot;load1&quot;)]<br>
- )<br>
-<br>
--(define_insn &quot;*cond_return_inverted&quot;<br>
-+(define_insn &quot;*cond_&lt;return_str&gt;return_inverted&quot;<br>
-   [(set (pc)<br>
-         (if_then_else (match_operator 0 &quot;arm_comparison_operator&quot;<br>
-                      [(match_operand 1 &quot;cc_register&quot; &quot;&quot;) (const_int 0)])<br>
-                       (pc)<br>
--                    (return)))]<br>
--  &quot;TARGET_ARM &amp;&amp; USE_RETURN_INSN (TRUE)&quot;<br>
--  &quot;*<br>
--  {<br>
--    if (arm_ccfsm_state == 2)<br>
--      {<br>
--        arm_ccfsm_state += 2;<br>
--        return \&quot;\&quot;;<br>
--      }<br>
--    return output_return_instruction (operands[0], TRUE, TRUE);<br>
--  }&quot;<br>
-+                    (returns)))]<br>
-+  &quot;TARGET_ARM&lt;return_cond&gt;&quot;<br>
-+{<br>
-+  if (arm_ccfsm_state == 2)<br>
-+    {<br>
-+      arm_ccfsm_state += 2;<br>
-+      return &quot;&quot;;<br>
-+    }<br>
-+  return output_return_instruction (operands[0], true, true,<br>
-+                                  &lt;return_simple_p&gt;);<br>
-+}<br>
-   [(set_attr &quot;conds&quot; &quot;use&quot;)<br>
-    (set_attr &quot;length&quot; &quot;12&quot;)<br>
-    (set_attr &quot;type&quot; &quot;load1&quot;)]<br>
-@@ -10809,8 +10815,7 @@<br>
-       DONE;<br>
-     }<br>
-   emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,<br>
--      gen_rtvec (1,<br>
--              gen_rtx_RETURN (VOIDmode)),<br>
-+      gen_rtvec (1, ret_rtx),<br>
-       VUNSPEC_EPILOGUE));<br>
-   DONE;<br>
-   &quot;<br>
-@@ -10827,7 +10832,7 @@<br>
-   &quot;TARGET_32BIT&quot;<br>
-   &quot;*<br>
-   if (use_return_insn (FALSE, next_nonnote_insn (insn)))<br>
--    return output_return_instruction (const_true_rtx, FALSE, FALSE);<br>
-+    return output_return_instruction (const_true_rtx, false, false, false);<br>
-   return arm_output_epilogue (next_nonnote_insn (insn));<br>
-   &quot;<br>
- ;; Length is absolute worst case<br>
-<br>
-=== modified file &#39;gcc/config/arm/<a href="http://thumb2.md" target="_blank">thumb2.md</a>&#39;<br>
---- old/gcc/config/arm/<a href="http://thumb2.md" target="_blank">thumb2.md</a>       2010-09-22 05:54:42 +0000<br>
-+++ new/gcc/config/arm/<a href="http://thumb2.md" target="_blank">thumb2.md</a>       2011-01-05 12:12:18 +0000<br>
-@@ -1020,16 +1020,15 @@<br>
-<br>
- ;; Note: this is not predicable, to avoid issues with linker-generated<br>
- ;; interworking stubs.<br>
--(define_insn &quot;*thumb2_return&quot;<br>
--  [(return)]<br>
--  &quot;TARGET_THUMB2 &amp;&amp; USE_RETURN_INSN (FALSE)&quot;<br>
--  &quot;*<br>
--  {<br>
--    return output_return_instruction (const_true_rtx, TRUE, FALSE);<br>
--  }&quot;<br>
-+(define_insn &quot;*thumb2_&lt;return_str&gt;return&quot;<br>
-+  [(returns)]<br>
-+  &quot;TARGET_THUMB2&lt;return_cond&gt;&quot;<br>
-+{<br>
-+  return output_return_instruction (const_true_rtx, true, false,<br>
-+                                  &lt;return_simple_p&gt;);<br>
-+}<br>
-   [(set_attr &quot;type&quot; &quot;load1&quot;)<br>
--   (set_attr &quot;length&quot; &quot;12&quot;)]<br>
--)<br>
-+   (set_attr &quot;length&quot; &quot;12&quot;)])<br>
-<br>
- (define_insn_and_split &quot;thumb2_eh_return&quot;<br>
-   [(unspec_volatile [(match_operand:SI 0 &quot;s_register_operand&quot; &quot;r&quot;)]<br>
-<br>
-=== modified file &#39;gcc/config/i386/i386.c&#39;<br>
---- old/gcc/config/i386/i386.c 2010-11-16 18:05:53 +0000<br>
-+++ new/gcc/config/i386/i386.c 2011-01-05 12:12:18 +0000<br>
-@@ -9308,13 +9308,13 @@<br>
-<br>
-         pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,<br>
-                                    popc, -1, true);<br>
--        emit_jump_insn (gen_return_indirect_internal (ecx));<br>
-+        emit_jump_insn (gen_simple_return_indirect_internal (ecx));<br>
-       }<br>
-       else<br>
--      emit_jump_insn (gen_return_pop_internal (popc));<br>
-+      emit_jump_insn (gen_simple_return_pop_internal (popc));<br>
-     }<br>
-   else<br>
--    emit_jump_insn (gen_return_internal ());<br>
-+    emit_jump_insn (gen_simple_return_internal ());<br>
-<br>
-   /* Restore the state back to the state from the prologue,<br>
-      so that it&#39;s correct for the next epilogue.  */<br>
-@@ -26596,7 +26596,7 @@<br>
-       rtx prev;<br>
-       bool replace = false;<br>
-<br>
--      if (!JUMP_P (ret) || GET_CODE (PATTERN (ret)) != RETURN<br>
-+      if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))<br>
-         || optimize_bb_for_size_p (bb))<br>
-       continue;<br>
-       for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))<br>
-@@ -26626,7 +26626,10 @@<br>
-       }<br>
-       if (replace)<br>
-       {<br>
--        emit_jump_insn_before (gen_return_internal_long (), ret);<br>
-+        if (PATTERN (ret) == ret_rtx)<br>
-+          emit_jump_insn_before (gen_return_internal_long (), ret);<br>
-+        else<br>
-+          emit_jump_insn_before (gen_simple_return_internal_long (), ret);<br>
-         delete_insn (ret);<br>
-       }<br>
-     }<br>
-<br>
-=== modified file &#39;gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a>&#39;<br>
---- old/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a>        2010-11-27 15:24:12 +0000<br>
-+++ new/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a>        2011-01-05 12:12:18 +0000<br>
-@@ -13797,24 +13797,29 @@<br>
-   &quot;&quot;<br>
-   [(set_attr &quot;length&quot; &quot;0&quot;)])<br>
-<br>
-+(define_code_iterator returns [return simple_return])<br>
-+(define_code_attr return_str [(return &quot;&quot;) (simple_return &quot;simple_&quot;)])<br>
-+(define_code_attr return_cond [(return &quot;ix86_can_use_return_insn_p ()&quot;)<br>
-+                             (simple_return &quot;&quot;)])<br>
-+<br>
- ;; Insn emitted into the body of a function to return from a function.<br>
- ;; This is only done if the function&#39;s epilogue is known to be simple.<br>
- ;; See comments for ix86_can_use_return_insn_p in i386.c.<br>
-<br>
--(define_expand &quot;return&quot;<br>
--  [(return)]<br>
--  &quot;ix86_can_use_return_insn_p ()&quot;<br>
-+(define_expand &quot;&lt;return_str&gt;return&quot;<br>
-+  [(returns)]<br>
-+  &quot;&lt;return_cond&gt;&quot;<br>
- {<br>
-   if (crtl-&gt;args.pops_args)<br>
-     {<br>
-       rtx popc = GEN_INT (crtl-&gt;args.pops_args);<br>
--      emit_jump_insn (gen_return_pop_internal (popc));<br>
-+      emit_jump_insn (gen_&lt;return_str&gt;return_pop_internal (popc));<br>
-       DONE;<br>
-     }<br>
- })<br>
-<br>
--(define_insn &quot;return_internal&quot;<br>
--  [(return)]<br>
-+(define_insn &quot;&lt;return_str&gt;return_internal&quot;<br>
-+  [(returns)]<br>
-   &quot;reload_completed&quot;<br>
-   &quot;ret&quot;<br>
-   [(set_attr &quot;length&quot; &quot;1&quot;)<br>
-@@ -13825,8 +13830,8 @@<br>
- ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET<br>
- ;; instruction Athlon and K8 have.<br>
-<br>
--(define_insn &quot;return_internal_long&quot;<br>
--  [(return)<br>
-+(define_insn &quot;&lt;return_str&gt;return_internal_long&quot;<br>
-+  [(returns)<br>
-    (unspec [(const_int 0)] UNSPEC_REP)]<br>
-   &quot;reload_completed&quot;<br>
-   &quot;rep\;ret&quot;<br>
-@@ -13836,8 +13841,8 @@<br>
-    (set_attr &quot;prefix_rep&quot; &quot;1&quot;)<br>
-    (set_attr &quot;modrm&quot; &quot;0&quot;)])<br>
-<br>
--(define_insn &quot;return_pop_internal&quot;<br>
--  [(return)<br>
-+(define_insn &quot;&lt;return_str&gt;return_pop_internal&quot;<br>
-+  [(returns)<br>
-    (use (match_operand:SI 0 &quot;const_int_operand&quot; &quot;&quot;))]<br>
-   &quot;reload_completed&quot;<br>
-   &quot;ret\t%0&quot;<br>
-@@ -13846,8 +13851,8 @@<br>
-    (set_attr &quot;length_immediate&quot; &quot;2&quot;)<br>
-    (set_attr &quot;modrm&quot; &quot;0&quot;)])<br>
-<br>
--(define_insn &quot;return_indirect_internal&quot;<br>
--  [(return)<br>
-+(define_insn &quot;&lt;return_str&gt;return_indirect_internal&quot;<br>
-+  [(returns)<br>
-    (use (match_operand:SI 0 &quot;register_operand&quot; &quot;r&quot;))]<br>
-   &quot;reload_completed&quot;<br>
-   &quot;jmp\t%A0&quot;<br>
-<br>
-=== modified file &#39;gcc/config/mips/mips.c&#39;<br>
---- old/gcc/config/mips/mips.c 2010-11-21 10:38:43 +0000<br>
-+++ new/gcc/config/mips/mips.c 2011-01-05 12:12:18 +0000<br>
-@@ -10497,7 +10497,8 @@<br>
-           regno = GP_REG_FIRST + 7;<br>
-         else<br>
-           regno = RETURN_ADDR_REGNUM;<br>
--        emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, regno)));<br>
-+        emit_jump_insn (gen_simple_return_internal (gen_rtx_REG (Pmode,<br>
-+                                                                 regno)));<br>
-       }<br>
-     }<br>
-<br>
-<br>
-=== modified file &#39;gcc/config/mips/<a href="http://mips.md" target="_blank">mips.md</a>&#39;<br>
---- old/gcc/config/mips/<a href="http://mips.md" target="_blank">mips.md</a>        2010-04-02 18:54:46 +0000<br>
-+++ new/gcc/config/mips/<a href="http://mips.md" target="_blank">mips.md</a>        2011-01-05 12:12:18 +0000<br>
-@@ -5815,6 +5815,18 @@<br>
-   [(set_attr &quot;type&quot;   &quot;jump&quot;)<br>
-    (set_attr &quot;mode&quot;   &quot;none&quot;)])<br>
-<br>
-+(define_expand &quot;simple_return&quot;<br>
-+  [(simple_return)]<br>
-+  &quot;!mips_can_use_return_insn ()&quot;<br>
-+  { mips_expand_before_return (); })<br>
-+<br>
-+(define_insn &quot;*simple_return&quot;<br>
-+  [(simple_return)]<br>
-+  &quot;!mips_can_use_return_insn ()&quot;<br>
-+  &quot;%*j\t$31%/&quot;<br>
-+  [(set_attr &quot;type&quot;   &quot;jump&quot;)<br>
-+   (set_attr &quot;mode&quot;   &quot;none&quot;)])<br>
-+<br>
- ;; Normal return.<br>
-<br>
- (define_insn &quot;return_internal&quot;<br>
-@@ -5825,6 +5837,14 @@<br>
-   [(set_attr &quot;type&quot;   &quot;jump&quot;)<br>
-    (set_attr &quot;mode&quot;   &quot;none&quot;)])<br>
-<br>
-+(define_insn &quot;simple_return_internal&quot;<br>
-+  [(simple_return)<br>
-+   (use (match_operand 0 &quot;pmode_register_operand&quot; &quot;&quot;))]<br>
-+  &quot;&quot;<br>
-+  &quot;%*j\t%0%/&quot;<br>
-+  [(set_attr &quot;type&quot;   &quot;jump&quot;)<br>
-+   (set_attr &quot;mode&quot;   &quot;none&quot;)])<br>
-+<br>
- ;; Exception return.<br>
- (define_insn &quot;mips_eret&quot;<br>
-   [(return)<br>
-<br>
-=== modified file &#39;gcc/config/sh/sh.c&#39;<br>
---- old/gcc/config/sh/sh.c     2010-12-10 15:34:19 +0000<br>
-+++ new/gcc/config/sh/sh.c     2011-01-05 12:12:18 +0000<br>
-@@ -5252,7 +5252,8 @@<br>
-       }<br>
-       if (prev<br>
-         &amp;&amp; JUMP_P (prev)<br>
--        &amp;&amp; JUMP_LABEL (prev))<br>
-+        &amp;&amp; JUMP_LABEL (prev)<br>
-+        &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (prev)))<br>
-       {<br>
-         rtx x;<br>
-         if (jump_to_next<br>
-@@ -5951,7 +5952,7 @@<br>
-                       JUMP_LABEL (insn) = far_label;<br>
-                       LABEL_NUSES (far_label)++;<br>
-                     }<br>
--                  redirect_jump (insn, NULL_RTX, 1);<br>
-+                  redirect_jump (insn, ret_rtx, 1);<br>
-                   far_label = 0;<br>
-                 }<br>
-             }<br>
-<br>
-=== modified file &#39;gcc/df-scan.c&#39;<br>
---- old/gcc/df-scan.c  2010-11-16 22:17:17 +0000<br>
-+++ new/gcc/df-scan.c  2011-01-05 12:12:18 +0000<br>
-@@ -3296,6 +3296,7 @@<br>
-       }<br>
-<br>
-     case RETURN:<br>
-+    case SIMPLE_RETURN:<br>
-       break;<br>
-<br>
-     case ASM_OPERANDS:<br>
-<br>
-=== modified file &#39;gcc/doc/invoke.texi&#39;<br>
---- old/gcc/doc/invoke.texi    2010-11-04 14:29:09 +0000<br>
-+++ new/gcc/doc/invoke.texi    2011-01-05 12:12:18 +0000<br>
-@@ -5750,6 +5750,7 @@<br>
- -fipa-pure-const @gol<br>
- -fipa-reference @gol<br>
- -fmerge-constants<br>
-+-fshrink-wrap @gol<br>
- -fsplit-wide-types @gol<br>
- -ftree-builtin-call-dce @gol<br>
- -ftree-ccp @gol<br>
-@@ -6504,6 +6505,12 @@<br>
- When pipelining loops during selective scheduling, also pipeline outer loops.<br>
- This option has no effect until @option{-fsel-sched-pipelining} is turned on.<br>
-<br>
-+@item -fshrink-wrap<br>
-+@opindex fshrink-wrap<br>
-+Emit function prologues only before parts of the function that need it,<br>
-+rather than at the top of the function.  This flag is enabled by default at<br>
-+@option{-O} and higher.<br>
-+<br>
- @item -fcaller-saves<br>
- @opindex fcaller-saves<br>
- Enable values to be allocated in registers that will be clobbered by<br>
-<br>
-=== modified file &#39;gcc/doc/md.texi&#39;<br>
---- old/gcc/doc/md.texi        2009-12-15 18:36:44 +0000<br>
-+++ new/gcc/doc/md.texi        2011-01-05 12:12:18 +0000<br>
-@@ -4801,7 +4801,19 @@<br>
- multiple instructions are usually needed to return from a function, but<br>
- some class of functions only requires one instruction to implement a<br>
- return.  Normally, the applicable functions are those which do not need<br>
--to save any registers or allocate stack space.<br>
-+to save any registers or allocate stack space, although some targets<br>
-+have instructions that can perform both the epilogue and function return<br>
-+in one instruction.<br>
-+<br>
-+@cindex @code{simple_return} instruction pattern<br>
-+@item @samp{simple_return}<br>
-+Subroutine return instruction.  This instruction pattern name should be<br>
-+defined only if a single instruction can do all the work of returning<br>
-+from a function on a path where no epilogue is required.  This pattern<br>
-+is very similar to the @code{return} instruction pattern, but it is emitted<br>
-+only by the shrink-wrapping optimization on paths where the function<br>
-+prologue has not been executed, and a function return should occur without<br>
-+any of the effects of the epilogue.<br>
-<br>
- @findex reload_completed<br>
- @findex leaf_function_p<br>
-<br>
-=== modified file &#39;gcc/doc/rtl.texi&#39;<br>
---- old/gcc/doc/rtl.texi       2010-07-06 19:23:53 +0000<br>
-+++ new/gcc/doc/rtl.texi       2011-01-05 12:12:18 +0000<br>
-@@ -2888,6 +2888,13 @@<br>
- Note that an insn pattern of @code{(return)} is logically equivalent to<br>
- @code{(set (pc) (return))}, but the latter form is never used.<br>
-<br>
-+@findex simple_return<br>
-+@item (simple_return)<br>
-+Like @code{(return)}, but truly represents only a function return, while<br>
-+@code{(return)} may represent an insn that also performs other functions<br>
-+of the function epilogue.  Like @code{(return)}, this may also occur in<br>
-+conditional jumps.<br>
-+<br>
- @findex call<br>
- @item (call @var{function} @var{nargs})<br>
- Represents a function call.  @var{function} is a @code{mem} expression<br>
-@@ -3017,7 +3024,7 @@<br>
- brackets stand for a vector; the operand of @code{parallel} is a<br>
- vector of expressions.  @var{x0}, @var{x1} and so on are individual<br>
- side effect expressions---expressions of code @code{set}, @code{call},<br>
--@code{return}, @code{clobber} or @code{use}.<br>
-+@code{return}, @code{simple_return}, @code{clobber} or @code{use}.<br>
-<br>
- ``In parallel&#39;&#39; means that first all the values used in the individual<br>
- side-effects are computed, and second all the actual side-effects are<br>
-@@ -3656,14 +3663,16 @@<br>
- @table @code<br>
- @findex PATTERN<br>
- @item PATTERN (@var{i})<br>
--An expression for the side effect performed by this insn.  This must be<br>
--one of the following codes: @code{set}, @code{call}, @code{use},<br>
--@code{clobber}, @code{return}, @code{asm_input}, @code{asm_output},<br>
--@code{addr_vec}, @code{addr_diff_vec}, @code{trap_if}, @code{unspec},<br>
--@code{unspec_volatile}, @code{parallel}, @code{cond_exec}, or @code{sequence}.  If it is a @code{parallel},<br>
--each element of the @code{parallel} must be one these codes, except that<br>
--@code{parallel} expressions cannot be nested and @code{addr_vec} and<br>
--@code{addr_diff_vec} are not permitted inside a @code{parallel} expression.<br>
-+An expression for the side effect performed by this insn.  This must<br>
-+be one of the following codes: @code{set}, @code{call}, @code{use},<br>
-+@code{clobber}, @code{return}, @code{simple_return}, @code{asm_input},<br>
-+@code{asm_output}, @code{addr_vec}, @code{addr_diff_vec},<br>
-+@code{trap_if}, @code{unspec}, @code{unspec_volatile},<br>
-+@code{parallel}, @code{cond_exec}, or @code{sequence}.  If it is a<br>
-+@code{parallel}, each element of the @code{parallel} must be one these<br>
-+codes, except that @code{parallel} expressions cannot be nested and<br>
-+@code{addr_vec} and @code{addr_diff_vec} are not permitted inside a<br>
-+@code{parallel} expression.<br>
-<br>
- @findex INSN_CODE<br>
- @item INSN_CODE (@var{i})<br>
-<br>
-=== modified file &#39;gcc/doc/tm.texi&#39;<br>
---- old/gcc/doc/tm.texi        2010-09-01 13:29:58 +0000<br>
-+++ new/gcc/doc/tm.texi        2011-01-05 12:12:18 +0000<br>
-@@ -3287,6 +3287,12 @@<br>
- from the frame pointer of the previous stack frame.<br>
- @end defmac<br>
-<br>
-+@defmac RETURN_ADDR_REGNUM<br>
-+If defined, a C expression whose value is the register number of the return<br>
-+address for the current function.  Targets that pass the return address on<br>
-+the stack should not define this macro.<br>
-+@end defmac<br>
-+<br>
- @defmac INCOMING_RETURN_ADDR_RTX<br>
- A C expression whose value is RTL representing the location of the<br>
- incoming return address at the beginning of any function, before the<br>
-<br>
-=== modified file &#39;gcc/dwarf2out.c&#39;<br>
---- old/gcc/dwarf2out.c        2010-12-21 18:46:10 +0000<br>
-+++ new/gcc/dwarf2out.c        2011-01-05 12:12:18 +0000<br>
-@@ -1396,7 +1396,7 @@<br>
-     {<br>
-       rtx dest = JUMP_LABEL (insn);<br>
-<br>
--      if (dest)<br>
-+      if (dest &amp;&amp; !ANY_RETURN_P (dest))<br>
-       {<br>
-         if (barrier_args_size [INSN_UID (dest)] &lt; 0)<br>
-           {<br>
-<br>
-=== modified file &#39;gcc/emit-rtl.c&#39;<br>
---- old/gcc/emit-rtl.c 2010-10-04 00:50:43 +0000<br>
-+++ new/gcc/emit-rtl.c 2011-01-05 12:12:18 +0000<br>
-@@ -2432,6 +2432,8 @@<br>
-     case CODE_LABEL:<br>
-     case PC:<br>
-     case CC0:<br>
-+    case RETURN:<br>
-+    case SIMPLE_RETURN:<br>
-     case SCRATCH:<br>
-       return;<br>
-       /* SCRATCH must be shared because they represent distinct values.  */<br>
-@@ -3323,14 +3325,17 @@<br>
-   return insn;<br>
- }<br>
-<br>
--/* Return the last label to mark the same position as LABEL.  Return null<br>
--   if LABEL itself is null.  */<br>
-+/* Return the last label to mark the same position as LABEL.  Return LABEL<br>
-+   itself if it is null or any return rtx.  */<br>
-<br>
- rtx<br>
- skip_consecutive_labels (rtx label)<br>
- {<br>
-   rtx insn;<br>
-<br>
-+  if (label &amp;&amp; ANY_RETURN_P (label))<br>
-+    return label;<br>
-+<br>
-   for (insn = label; insn != 0 &amp;&amp; !INSN_P (insn); insn = NEXT_INSN (insn))<br>
-     if (LABEL_P (insn))<br>
-       label = insn;<br>
-@@ -5209,7 +5214,7 @@<br>
-     return CODE_LABEL;<br>
-   if (GET_CODE (x) == CALL)<br>
-     return CALL_INSN;<br>
--  if (GET_CODE (x) == RETURN)<br>
-+  if (GET_CODE (x) == RETURN || GET_CODE (x) == SIMPLE_RETURN)<br>
-     return JUMP_INSN;<br>
-   if (GET_CODE (x) == SET)<br>
-     {<br>
-@@ -5715,8 +5720,10 @@<br>
-   init_reg_modes_target ();<br>
-<br>
-   /* Assign register numbers to the globally defined register rtx.  */<br>
--  pc_rtx = gen_rtx_PC (VOIDmode);<br>
--  cc0_rtx = gen_rtx_CC0 (VOIDmode);<br>
-+  pc_rtx = gen_rtx_fmt_ (PC, VOIDmode);<br>
-+  ret_rtx = gen_rtx_fmt_ (RETURN, VOIDmode);<br>
-+  simple_return_rtx = gen_rtx_fmt_ (SIMPLE_RETURN, VOIDmode);<br>
-+  cc0_rtx = gen_rtx_fmt_ (CC0, VOIDmode);<br>
-   stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);<br>
-   frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);<br>
-   hard_frame_pointer_rtx = gen_raw_REG (Pmode, HARD_FRAME_POINTER_REGNUM);<br>
-<br>
-=== modified file &#39;gcc/final.c&#39;<br>
---- old/gcc/final.c    2010-03-26 16:18:51 +0000<br>
-+++ new/gcc/final.c    2011-01-05 12:12:18 +0000<br>
-@@ -2428,7 +2428,7 @@<br>
-               delete_insn (insn);<br>
-               break;<br>
-             }<br>
--          else if (GET_CODE (SET_SRC (body)) == RETURN)<br>
-+          else if (ANY_RETURN_P (SET_SRC (body)))<br>
-             /* Replace (set (pc) (return)) with (return).  */<br>
-             PATTERN (insn) = body = SET_SRC (body);<br>
-<br>
-<br>
-=== modified file &#39;gcc/function.c&#39;<br>
---- old/gcc/function.c 2010-08-16 19:18:08 +0000<br>
-+++ new/gcc/function.c 2011-01-05 12:12:18 +0000<br>
-@@ -147,9 +147,6 @@<br>
-    can always export `prologue_epilogue_contains&#39;.  */<br>
- static void record_insns (rtx, rtx, htab_t *) ATTRIBUTE_UNUSED;<br>
- static bool contains (const_rtx, htab_t);<br>
--#ifdef HAVE_return<br>
--static void emit_return_into_block (basic_block);<br>
--#endif<br>
- static void prepare_function_start (void);<br>
- static void do_clobber_return_reg (rtx, void *);<br>
- static void do_use_return_reg (rtx, void *);<br>
-@@ -4987,35 +4984,189 @@<br>
-   return 0;<br>
- }<br>
-<br>
-+#ifdef HAVE_simple_return<br>
-+/* This collects sets and clobbers of hard registers in a HARD_REG_SET,<br>
-+   which is pointed to by DATA.  */<br>
-+static void<br>
-+record_hard_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)<br>
-+{<br>
-+  HARD_REG_SET *pset = (HARD_REG_SET *)data;<br>
-+  if (REG_P (x) &amp;&amp; REGNO (x) &lt; FIRST_PSEUDO_REGISTER)<br>
-+    {<br>
-+      int nregs = hard_regno_nregs[REGNO (x)][GET_MODE (x)];<br>
-+      while (nregs-- &gt; 0)<br>
-+      SET_HARD_REG_BIT (*pset, REGNO (x) + nregs);<br>
-+    }<br>
-+}<br>
-+<br>
-+/* A subroutine of requires_stack_frame_p, called via for_each_rtx.<br>
-+   If any change is made, set CHANGED<br>
-+   to true.  */<br>
-+<br>
-+static int<br>
-+frame_required_for_rtx (rtx *loc, void *data ATTRIBUTE_UNUSED)<br>
-+{<br>
-+  rtx x = *loc;<br>
-+  if (x == stack_pointer_rtx || x == hard_frame_pointer_rtx<br>
-+      || x == arg_pointer_rtx || x == pic_offset_table_rtx<br>
-+#ifdef RETURN_ADDR_REGNUM<br>
-+      || (REG_P (x) &amp;&amp; REGNO (x) == RETURN_ADDR_REGNUM)<br>
-+#endif<br>
-+      )<br>
-+    return 1;<br>
-+  return 0;<br>
-+}<br>
-+<br>
-+static bool<br>
-+requires_stack_frame_p (rtx insn)<br>
-+{<br>
-+  HARD_REG_SET hardregs;<br>
-+  unsigned regno;<br>
-+<br>
-+  if (!INSN_P (insn) || DEBUG_INSN_P (insn))<br>
-+    return false;<br>
-+  if (CALL_P (insn))<br>
-+    return !SIBLING_CALL_P (insn);<br>
-+  if (for_each_rtx (&amp;PATTERN (insn), frame_required_for_rtx, NULL))<br>
-+    return true;<br>
-+  CLEAR_HARD_REG_SET (hardregs);<br>
-+  note_stores (PATTERN (insn), record_hard_reg_sets, &amp;hardregs);<br>
-+  AND_COMPL_HARD_REG_SET (hardregs, call_used_reg_set);<br>
-+  for (regno = 0; regno &lt; FIRST_PSEUDO_REGISTER; regno++)<br>
-+    if (TEST_HARD_REG_BIT (hardregs, regno)<br>
-+      &amp;&amp; df_regs_ever_live_p (regno))<br>
-+      return true;<br>
-+  return false;<br>
-+}<br>
-+#endif<br>
-+<br>
- #ifdef HAVE_return<br>
--/* Insert gen_return at the end of block BB.  This also means updating<br>
--   block_for_insn appropriately.  */<br>
-+<br>
-+static rtx<br>
-+gen_return_pattern (bool simple_p)<br>
-+{<br>
-+#ifdef HAVE_simple_return<br>
-+  return simple_p ? gen_simple_return () : gen_return ();<br>
-+#else<br>
-+  gcc_assert (!simple_p);<br>
-+  return gen_return ();<br>
-+#endif<br>
-+}<br>
-+<br>
-+/* Insert an appropriate return pattern at the end of block BB.  This<br>
-+   also means updating block_for_insn appropriately.  */<br>
-<br>
- static void<br>
--emit_return_into_block (basic_block bb)<br>
-+emit_return_into_block (bool simple_p, basic_block bb)<br>
- {<br>
--  emit_jump_insn_after (gen_return (), BB_END (bb));<br>
-+  rtx jump;<br>
-+  jump = emit_jump_insn_after (gen_return_pattern (simple_p), BB_END (bb));<br>
-+  JUMP_LABEL (jump) = simple_p ? simple_return_rtx : ret_rtx;<br>
- }<br>
--#endif /* HAVE_return */<br>
-+#endif<br>
-<br>
- /* Generate the prologue and epilogue RTL if the machine supports it.  Thread<br>
-    this into place with notes indicating where the prologue ends and where<br>
--   the epilogue begins.  Update the basic block information when possible.  */<br>
-+   the epilogue begins.  Update the basic block information when possible.<br>
-+<br>
-+   Notes on epilogue placement:<br>
-+   There are several kinds of edges to the exit block:<br>
-+   * a single fallthru edge from LAST_BB<br>
-+   * possibly, edges from blocks containing sibcalls<br>
-+   * possibly, fake edges from infinite loops<br>
-+<br>
-+   The epilogue is always emitted on the fallthru edge from the last basic<br>
-+   block in the function, LAST_BB, into the exit block.<br>
-+<br>
-+   If LAST_BB is empty except for a label, it is the target of every<br>
-+   other basic block in the function that ends in a return.  If a<br>
-+   target has a return or simple_return pattern (possibly with<br>
-+   conditional variants), these basic blocks can be changed so that a<br>
-+   return insn is emitted into them, and their target is adjusted to<br>
-+   the real exit block.<br>
-+<br>
-+   Notes on shrink wrapping: We implement a fairly conservative<br>
-+   version of shrink-wrapping rather than the textbook one.  We only<br>
-+   generate a single prologue and a single epilogue.  This is<br>
-+   sufficient to catch a number of interesting cases involving early<br>
-+   exits.<br>
-+<br>
-+   First, we identify the blocks that require the prologue to occur before<br>
-+   them.  These are the ones that modify a call-saved register, or reference<br>
-+   any of the stack or frame pointer registers.  To simplify things, we then<br>
-+   mark everything reachable from these blocks as also requiring a prologue.<br>
-+   This takes care of loops automatically, and avoids the need to examine<br>
-+   whether MEMs reference the frame, since it is sufficient to check for<br>
-+   occurrences of the stack or frame pointer.<br>
-+<br>
-+   We then compute the set of blocks for which the need for a prologue<br>
-+   is anticipatable (borrowing terminology from the shrink-wrapping<br>
-+   description in Muchnick&#39;s book).  These are the blocks which either<br>
-+   require a prologue themselves, or those that have only successors<br>
-+   where the prologue is anticipatable.  The prologue needs to be<br>
-+   inserted on all edges from BB1-&gt;BB2 where BB2 is in ANTIC and BB1<br>
-+   is not.  For the moment, we ensure that only one such edge exists.<br>
-+<br>
-+   The epilogue is placed as described above, but we make a<br>
-+   distinction between inserting return and simple_return patterns<br>
-+   when modifying other blocks that end in a return.  Blocks that end<br>
-+   in a sibcall omit the sibcall_epilogue if the block is not in<br>
-+   ANTIC.  */<br>
-<br>
- static void<br>
- thread_prologue_and_epilogue_insns (void)<br>
- {<br>
-   int inserted = 0;<br>
-+  basic_block last_bb;<br>
-+  bool last_bb_active;<br>
-+#ifdef HAVE_simple_return<br>
-+  bool unconverted_simple_returns = false;<br>
-+  basic_block simple_return_block = NULL;<br>
-+#endif<br>
-+  rtx returnjump ATTRIBUTE_UNUSED;<br>
-+  rtx seq ATTRIBUTE_UNUSED, epilogue_end ATTRIBUTE_UNUSED;<br>
-+  rtx prologue_seq ATTRIBUTE_UNUSED, split_prologue_seq ATTRIBUTE_UNUSED;<br>
-+  edge entry_edge, orig_entry_edge, exit_fallthru_edge;<br>
-   edge e;<br>
--#if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) || defined (HAVE_return) || defined (HAVE_prologue)<br>
--  rtx seq;<br>
--#endif<br>
--#if defined (HAVE_epilogue) || defined(HAVE_return)<br>
--  rtx epilogue_end = NULL_RTX;<br>
--#endif<br>
-   edge_iterator ei;<br>
-+  bitmap_head bb_flags;<br>
-+<br>
-+  df_analyze ();<br>
-<br>
-   rtl_profile_for_bb (ENTRY_BLOCK_PTR);<br>
-+<br>
-+  epilogue_end = NULL_RTX;<br>
-+<br>
-+  /* Can&#39;t deal with multiple successors of the entry block at the<br>
-+     moment.  Function should always have at least one entry<br>
-+     point.  */<br>
-+  gcc_assert (single_succ_p (ENTRY_BLOCK_PTR));<br>
-+  entry_edge = single_succ_edge (ENTRY_BLOCK_PTR);<br>
-+  orig_entry_edge = entry_edge;<br>
-+<br>
-+  exit_fallthru_edge = find_fallthru_edge (EXIT_BLOCK_PTR-&gt;preds);<br>
-+  if (exit_fallthru_edge != NULL)<br>
-+    {<br>
-+      rtx label;<br>
-+<br>
-+      last_bb = exit_fallthru_edge-&gt;src;<br>
-+      /* Test whether there are active instructions in the last block.  */<br>
-+      label = BB_END (last_bb);<br>
-+      while (label &amp;&amp; !LABEL_P (label))<br>
-+      {<br>
-+        if (active_insn_p (label))<br>
-+          break;<br>
-+        label = PREV_INSN (label);<br>
-+      }<br>
-+<br>
-+      last_bb_active = BB_HEAD (last_bb) != label || !LABEL_P (label);<br>
-+    }<br>
-+  else<br>
-+    {<br>
-+      last_bb = NULL;<br>
-+      last_bb_active = false;<br>
-+    }<br>
-+<br>
- #ifdef HAVE_prologue<br>
-   if (HAVE_prologue)<br>
-     {<br>
-@@ -5040,19 +5191,168 @@<br>
-         emit_insn (gen_blockage ());<br>
- #endif<br>
-<br>
--      seq = get_insns ();<br>
-+      prologue_seq = get_insns ();<br>
-       end_sequence ();<br>
-       set_insn_locators (seq, prologue_locator);<br>
--<br>
--      /* Can&#39;t deal with multiple successors of the entry block<br>
--         at the moment.  Function should always have at least one<br>
--         entry point.  */<br>
--      gcc_assert (single_succ_p (ENTRY_BLOCK_PTR));<br>
--<br>
--      insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));<br>
--      inserted = 1;<br>
--    }<br>
--#endif<br>
-+    }<br>
-+#endif<br>
-+<br>
-+  bitmap_initialize (&amp;bb_flags, &amp;bitmap_default_obstack);<br>
-+<br>
-+#ifdef HAVE_simple_return<br>
-+  /* Try to perform a kind of shrink-wrapping, making sure the<br>
-+     prologue/epilogue is emitted only around those parts of the<br>
-+     function that require it.  */<br>
-+<br>
-+  if (flag_shrink_wrap &amp;&amp; HAVE_simple_return &amp;&amp; !flag_non_call_exceptions<br>
-+      &amp;&amp; HAVE_prologue &amp;&amp; !crtl-&gt;calls_eh_return)<br>
-+    {<br>
-+      HARD_REG_SET prologue_clobbered, live_on_edge;<br>
-+      rtx p_insn;<br>
-+      VEC(basic_block, heap) *vec;<br>
-+      basic_block bb;<br>
-+      bitmap_head bb_antic_flags;<br>
-+      bitmap_head bb_on_list;<br>
-+<br>
-+      bitmap_initialize (&amp;bb_antic_flags, &amp;bitmap_default_obstack);<br>
-+      bitmap_initialize (&amp;bb_on_list, &amp;bitmap_default_obstack);<br>
-+<br>
-+      vec = VEC_alloc (basic_block, heap, n_basic_blocks);<br>
-+<br>
-+      FOR_EACH_BB (bb)<br>
-+      {<br>
-+        rtx insn;<br>
-+        FOR_BB_INSNS (bb, insn)<br>
-+          {<br>
-+            if (requires_stack_frame_p (insn))<br>
-+              {<br>
-+                bitmap_set_bit (&amp;bb_flags, bb-&gt;index);<br>
-+                VEC_quick_push (basic_block, vec, bb);<br>
-+                break;<br>
-+              }<br>
-+          }<br>
-+      }<br>
-+<br>
-+      /* For every basic block that needs a prologue, mark all blocks<br>
-+       reachable from it, so as to ensure they are also seen as<br>
-+       requiring a prologue.  */<br>
-+      while (!VEC_empty (basic_block, vec))<br>
-+      {<br>
-+        basic_block tmp_bb = VEC_pop (basic_block, vec);<br>
-+        edge e;<br>
-+        edge_iterator ei;<br>
-+        FOR_EACH_EDGE (e, ei, tmp_bb-&gt;succs)<br>
-+          {<br>
-+            if (e-&gt;dest == EXIT_BLOCK_PTR<br>
-+                || bitmap_bit_p (&amp;bb_flags, e-&gt;dest-&gt;index))<br>
-+              continue;<br>
-+            bitmap_set_bit (&amp;bb_flags, e-&gt;dest-&gt;index);<br>
-+            VEC_quick_push (basic_block, vec, e-&gt;dest);<br>
-+          }<br>
-+      }<br>
-+      /* If the last basic block contains only a label, we&#39;ll be able<br>
-+       to convert jumps to it to (potentially conditional) return<br>
-+       insns later.  This means we don&#39;t necessarily need a prologue<br>
-+       for paths reaching it.  */<br>
-+      if (last_bb)<br>
-+      {<br>
-+        if (!last_bb_active)<br>
-+          bitmap_clear_bit (&amp;bb_flags, last_bb-&gt;index);<br>
-+        else if (!bitmap_bit_p (&amp;bb_flags, last_bb-&gt;index))<br>
-+          goto fail_shrinkwrap;<br>
-+      }<br>
-+<br>
-+      /* Now walk backwards from every block that is marked as needing<br>
-+       a prologue to compute the bb_antic_flags bitmap.  */<br>
-+      bitmap_copy (&amp;bb_antic_flags, &amp;bb_flags);<br>
-+      FOR_EACH_BB (bb)<br>
-+      {<br>
-+        edge e;<br>
-+        edge_iterator ei;<br>
-+        if (!bitmap_bit_p (&amp;bb_flags, bb-&gt;index))<br>
-+          continue;<br>
-+        FOR_EACH_EDGE (e, ei, bb-&gt;preds)<br>
-+          if (!bitmap_bit_p (&amp;bb_antic_flags, e-&gt;src-&gt;index))<br>
-+            {<br>
-+              VEC_quick_push (basic_block, vec, e-&gt;src);<br>
-+              bitmap_set_bit (&amp;bb_on_list, e-&gt;src-&gt;index);<br>
-+            }<br>
-+      }<br>
-+      while (!VEC_empty (basic_block, vec))<br>
-+      {<br>
-+        basic_block tmp_bb = VEC_pop (basic_block, vec);<br>
-+        edge e;<br>
-+        edge_iterator ei;<br>
-+        bool all_set = true;<br>
-+<br>
-+        bitmap_clear_bit (&amp;bb_on_list, tmp_bb-&gt;index);<br>
-+        FOR_EACH_EDGE (e, ei, tmp_bb-&gt;succs)<br>
-+          {<br>
-+            if (!bitmap_bit_p (&amp;bb_antic_flags, e-&gt;dest-&gt;index))<br>
-+              {<br>
-+                all_set = false;<br>
-+                break;<br>
-+              }<br>
-+          }<br>
-+        if (all_set)<br>
-+          {<br>
-+            bitmap_set_bit (&amp;bb_antic_flags, tmp_bb-&gt;index);<br>
-+            FOR_EACH_EDGE (e, ei, tmp_bb-&gt;preds)<br>
-+              if (!bitmap_bit_p (&amp;bb_antic_flags, e-&gt;src-&gt;index))<br>
-+                {<br>
-+                  VEC_quick_push (basic_block, vec, e-&gt;src);<br>
-+                  bitmap_set_bit (&amp;bb_on_list, e-&gt;src-&gt;index);<br>
-+                }<br>
-+          }<br>
-+      }<br>
-+      /* Find exactly one edge that leads to a block in ANTIC from<br>
-+       a block that isn&#39;t.  */<br>
-+      if (!bitmap_bit_p (&amp;bb_antic_flags, entry_edge-&gt;dest-&gt;index))<br>
-+      FOR_EACH_BB (bb)<br>
-+        {<br>
-+          if (!bitmap_bit_p (&amp;bb_antic_flags, bb-&gt;index))<br>
-+            continue;<br>
-+          FOR_EACH_EDGE (e, ei, bb-&gt;preds)<br>
-+            if (!bitmap_bit_p (&amp;bb_antic_flags, e-&gt;src-&gt;index))<br>
-+              {<br>
-+                if (entry_edge != orig_entry_edge)<br>
-+                  {<br>
-+                    entry_edge = orig_entry_edge;<br>
-+                    goto fail_shrinkwrap;<br>
-+                  }<br>
-+                entry_edge = e;<br>
-+              }<br>
-+        }<br>
-+<br>
-+      /* Test whether the prologue is known to clobber any register<br>
-+       (other than FP or SP) which are live on the edge.  */<br>
-+      CLEAR_HARD_REG_SET (prologue_clobbered);<br>
-+      for (p_insn = prologue_seq; p_insn; p_insn = NEXT_INSN (p_insn))<br>
-+      if (NONDEBUG_INSN_P (p_insn))<br>
-+        note_stores (PATTERN (p_insn), record_hard_reg_sets,<br>
-+                     &amp;prologue_clobbered);<br>
-+      CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM);<br>
-+      if (frame_pointer_needed)<br>
-+      CLEAR_HARD_REG_BIT (prologue_clobbered, HARD_FRAME_POINTER_REGNUM);<br>
-+<br>
-+      CLEAR_HARD_REG_SET (live_on_edge);<br>
-+      reg_set_to_hard_reg_set (&amp;live_on_edge,<br>
-+                             df_get_live_in (entry_edge-&gt;dest));<br>
-+      if (hard_reg_set_intersect_p (live_on_edge, prologue_clobbered))<br>
-+      entry_edge = orig_entry_edge;<br>
-+<br>
-+    fail_shrinkwrap:<br>
-+      bitmap_clear (&amp;bb_antic_flags);<br>
-+      bitmap_clear (&amp;bb_on_list);<br>
-+      VEC_free (basic_block, heap, vec);<br>
-+    }<br>
-+#endif<br>
-+<br>
-+  if (prologue_seq != NULL_RTX)<br>
-+    {<br>
-+      insert_insn_on_edge (prologue_seq, entry_edge);<br>
-+      inserted = true;<br>
-+    }<br>
-<br>
-   /* If the exit block has no non-fake predecessors, we don&#39;t need<br>
-      an epilogue.  */<br>
-@@ -5063,100 +5363,130 @@<br>
-     goto epilogue_done;<br>
-<br>
-   rtl_profile_for_bb (EXIT_BLOCK_PTR);<br>
-+<br>
- #ifdef HAVE_return<br>
--  if (optimize &amp;&amp; HAVE_return)<br>
-+  /* If we&#39;re allowed to generate a simple return instruction, then by<br>
-+     definition we don&#39;t need a full epilogue.  If the last basic<br>
-+     block before the exit block does not contain active instructions,<br>
-+     examine its predecessors and try to emit (conditional) return<br>
-+     instructions.  */<br>
-+  if (optimize &amp;&amp; !last_bb_active<br>
-+      &amp;&amp; (HAVE_return || entry_edge != orig_entry_edge))<br>
-     {<br>
--      /* If we&#39;re allowed to generate a simple return instruction,<br>
--       then by definition we don&#39;t need a full epilogue.  Examine<br>
--       the block that falls through to EXIT.   If it does not<br>
--       contain any code, examine its predecessors and try to<br>
--       emit (conditional) return instructions.  */<br>
--<br>
--      basic_block last;<br>
-+      edge_iterator ei2;<br>
-+      int i;<br>
-+      basic_block bb;<br>
-       rtx label;<br>
-+      VEC(basic_block,heap) *src_bbs;<br>
-<br>
--      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR-&gt;preds)<br>
--      if (e-&gt;flags &amp; EDGE_FALLTHRU)<br>
--        break;<br>
--      if (e == NULL)<br>
-+      if (exit_fallthru_edge == NULL)<br>
-       goto epilogue_done;<br>
--      last = e-&gt;src;<br>
--<br>
--      /* Verify that there are no active instructions in the last block.  */<br>
--      label = BB_END (last);<br>
--      while (label &amp;&amp; !LABEL_P (label))<br>
-+      label = BB_HEAD (last_bb);<br>
-+<br>
-+      src_bbs = VEC_alloc (basic_block, heap, EDGE_COUNT (last_bb-&gt;preds));<br>
-+      FOR_EACH_EDGE (e, ei2, last_bb-&gt;preds)<br>
-+      if (e-&gt;src != ENTRY_BLOCK_PTR)<br>
-+        VEC_quick_push (basic_block, src_bbs, e-&gt;src);<br>
-+<br>
-+      FOR_EACH_VEC_ELT (basic_block, src_bbs, i, bb)<br>
-       {<br>
--        if (active_insn_p (label))<br>
--          break;<br>
--        label = PREV_INSN (label);<br>
-+        bool simple_p;<br>
-+        rtx jump;<br>
-+        e = find_edge (bb, last_bb);<br>
-+<br>
-+        jump = BB_END (bb);<br>
-+<br>
-+#ifdef HAVE_simple_return<br>
-+        simple_p = (entry_edge != orig_entry_edge<br>
-+                    ? !bitmap_bit_p (&amp;bb_flags, bb-&gt;index) : false);<br>
-+#else<br>
-+        simple_p = false;<br>
-+#endif<br>
-+<br>
-+        if (!simple_p<br>
-+            &amp;&amp; (!HAVE_return || !JUMP_P (jump)<br>
-+                || JUMP_LABEL (jump) != label))<br>
-+          continue;<br>
-+<br>
-+        /* If we have an unconditional jump, we can replace that<br>
-+           with a simple return instruction.  */<br>
-+        if (!JUMP_P (jump))<br>
-+          {<br>
-+            emit_barrier_after (BB_END (bb));<br>
-+            emit_return_into_block (simple_p, bb);<br>
-+          }<br>
-+        else if (simplejump_p (jump))<br>
-+          {<br>
-+            emit_return_into_block (simple_p, bb);<br>
-+            delete_insn (jump);<br>
-+          }<br>
-+        else if (condjump_p (jump) &amp;&amp; JUMP_LABEL (jump) != label)<br>
-+          {<br>
-+            basic_block new_bb;<br>
-+            edge new_e;<br>
-+<br>
-+            gcc_assert (simple_p);<br>
-+            new_bb = split_edge (e);<br>
-+            emit_barrier_after (BB_END (new_bb));<br>
-+            emit_return_into_block (simple_p, new_bb);<br>
-+#ifdef HAVE_simple_return<br>
-+            simple_return_block = new_bb;<br>
-+#endif<br>
-+            new_e = single_succ_edge (new_bb);<br>
-+            redirect_edge_succ (new_e, EXIT_BLOCK_PTR);<br>
-+<br>
-+            continue;<br>
-+          }<br>
-+        /* If we have a conditional jump branching to the last<br>
-+           block, we can try to replace that with a conditional<br>
-+           return instruction.  */<br>
-+        else if (condjump_p (jump))<br>
-+          {<br>
-+            rtx dest;<br>
-+            if (simple_p)<br>
-+              dest = simple_return_rtx;<br>
-+            else<br>
-+              dest = ret_rtx;<br>
-+            if (! redirect_jump (jump, dest, 0))<br>
-+              {<br>
-+#ifdef HAVE_simple_return<br>
-+                if (simple_p)<br>
-+                  unconverted_simple_returns = true;<br>
-+#endif<br>
-+                continue;<br>
-+              }<br>
-+<br>
-+            /* If this block has only one successor, it both jumps<br>
-+               and falls through to the fallthru block, so we can&#39;t<br>
-+               delete the edge.  */<br>
-+            if (single_succ_p (bb))<br>
-+              continue;<br>
-+          }<br>
-+        else<br>
-+          {<br>
-+#ifdef HAVE_simple_return<br>
-+            if (simple_p)<br>
-+              unconverted_simple_returns = true;<br>
-+#endif<br>
-+            continue;<br>
-+          }<br>
-+<br>
-+        /* Fix up the CFG for the successful change we just made.  */<br>
-+        redirect_edge_succ (e, EXIT_BLOCK_PTR);<br>
-       }<br>
-+      VEC_free (basic_block, heap, src_bbs);<br>
-<br>
--      if (BB_HEAD (last) == label &amp;&amp; LABEL_P (label))<br>
-+      if (HAVE_return)<br>
-       {<br>
--        edge_iterator ei2;<br>
--<br>
--        for (ei2 = ei_start (last-&gt;preds); (e = ei_safe_edge (ei2)); )<br>
--          {<br>
--            basic_block bb = e-&gt;src;<br>
--            rtx jump;<br>
--<br>
--            if (bb == ENTRY_BLOCK_PTR)<br>
--              {<br>
--                ei_next (&amp;ei2);<br>
--                continue;<br>
--              }<br>
--<br>
--            jump = BB_END (bb);<br>
--            if (!JUMP_P (jump) || JUMP_LABEL (jump) != label)<br>
--              {<br>
--                ei_next (&amp;ei2);<br>
--                continue;<br>
--              }<br>
--<br>
--            /* If we have an unconditional jump, we can replace that<br>
--               with a simple return instruction.  */<br>
--            if (simplejump_p (jump))<br>
--              {<br>
--                emit_return_into_block (bb);<br>
--                delete_insn (jump);<br>
--              }<br>
--<br>
--            /* If we have a conditional jump, we can try to replace<br>
--               that with a conditional return instruction.  */<br>
--            else if (condjump_p (jump))<br>
--              {<br>
--                if (! redirect_jump (jump, 0, 0))<br>
--                  {<br>
--                    ei_next (&amp;ei2);<br>
--                    continue;<br>
--                  }<br>
--<br>
--                /* If this block has only one successor, it both jumps<br>
--                   and falls through to the fallthru block, so we can&#39;t<br>
--                   delete the edge.  */<br>
--                if (single_succ_p (bb))<br>
--                  {<br>
--                    ei_next (&amp;ei2);<br>
--                    continue;<br>
--                  }<br>
--              }<br>
--            else<br>
--              {<br>
--                ei_next (&amp;ei2);<br>
--                continue;<br>
--              }<br>
--<br>
--            /* Fix up the CFG for the successful change we just made.  */<br>
--            redirect_edge_succ (e, EXIT_BLOCK_PTR);<br>
--          }<br>
--<br>
-         /* Emit a return insn for the exit fallthru block.  Whether<br>
-            this is still reachable will be determined later.  */<br>
-<br>
--        emit_barrier_after (BB_END (last));<br>
--        emit_return_into_block (last);<br>
--        epilogue_end = BB_END (last);<br>
--        single_succ_edge (last)-&gt;flags &amp;= ~EDGE_FALLTHRU;<br>
-+        emit_barrier_after (BB_END (last_bb));<br>
-+        emit_return_into_block (false, last_bb);<br>
-+        epilogue_end = BB_END (last_bb);<br>
-+        if (JUMP_P (epilogue_end))<br>
-+          JUMP_LABEL (epilogue_end) = ret_rtx;<br>
-+        single_succ_edge (last_bb)-&gt;flags &amp;= ~EDGE_FALLTHRU;<br>
-         goto epilogue_done;<br>
-       }<br>
-     }<br>
-@@ -5193,15 +5523,10 @@<br>
-     }<br>
- #endif<br>
-<br>
--  /* Find the edge that falls through to EXIT.  Other edges may exist<br>
--     due to RETURN instructions, but those don&#39;t need epilogues.<br>
--     There really shouldn&#39;t be a mixture -- either all should have<br>
--     been converted or none, however...  */<br>
-+  /* If nothing falls through into the exit block, we don&#39;t need an<br>
-+     epilogue.  */<br>
-<br>
--  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR-&gt;preds)<br>
--    if (e-&gt;flags &amp; EDGE_FALLTHRU)<br>
--      break;<br>
--  if (e == NULL)<br>
-+  if (exit_fallthru_edge == NULL)<br>
-     goto epilogue_done;<br>
-<br>
- #ifdef HAVE_epilogue<br>
-@@ -5217,25 +5542,38 @@<br>
-       set_insn_locators (seq, epilogue_locator);<br>
-<br>
-       seq = get_insns ();<br>
-+      returnjump = get_last_insn ();<br>
-       end_sequence ();<br>
-<br>
--      insert_insn_on_edge (seq, e);<br>
-+      insert_insn_on_edge (seq, exit_fallthru_edge);<br>
-       inserted = 1;<br>
-+      if (JUMP_P (returnjump))<br>
-+      {<br>
-+        rtx pat = PATTERN (returnjump);<br>
-+        if (GET_CODE (pat) == PARALLEL)<br>
-+          pat = XVECEXP (pat, 0, 0);<br>
-+        if (ANY_RETURN_P (pat))<br>
-+          JUMP_LABEL (returnjump) = pat;<br>
-+        else<br>
-+          JUMP_LABEL (returnjump) = ret_rtx;<br>
-+      }<br>
-+      else<br>
-+      returnjump = NULL_RTX;<br>
-     }<br>
-   else<br>
- #endif<br>
-     {<br>
-       basic_block cur_bb;<br>
-<br>
--      if (! next_active_insn (BB_END (e-&gt;src)))<br>
-+      if (! next_active_insn (BB_END (exit_fallthru_edge-&gt;src)))<br>
-       goto epilogue_done;<br>
-       /* We have a fall-through edge to the exit block, the source is not<br>
--         at the end of the function, and there will be an assembler epilogue<br>
--         at the end of the function.<br>
--         We can&#39;t use force_nonfallthru here, because that would try to<br>
--         use return.  Inserting a jump &#39;by hand&#39; is extremely messy, so<br>
-+       at the end of the function, and there will be an assembler epilogue<br>
-+       at the end of the function.<br>
-+       We can&#39;t use force_nonfallthru here, because that would try to<br>
-+       use return.  Inserting a jump &#39;by hand&#39; is extremely messy, so<br>
-        we take advantage of cfg_layout_finalize using<br>
--      fixup_fallthru_exit_predecessor.  */<br>
-+       fixup_fallthru_exit_predecessor.  */<br>
-       cfg_layout_initialize (0);<br>
-       FOR_EACH_BB (cur_bb)<br>
-       if (cur_bb-&gt;index &gt;= NUM_FIXED_BLOCKS<br>
-@@ -5244,6 +5582,7 @@<br>
-       cfg_layout_finalize ();<br>
-     }<br>
- epilogue_done:<br>
-+<br>
-   default_rtl_profile ();<br>
-<br>
-   if (inserted)<br>
-@@ -5260,33 +5599,93 @@<br>
-       }<br>
-     }<br>
-<br>
-+#ifdef HAVE_simple_return<br>
-+  /* If there were branches to an empty LAST_BB which we tried to<br>
-+     convert to conditional simple_returns, but couldn&#39;t for some<br>
-+     reason, create a block to hold a simple_return insn and redirect<br>
-+     those remaining edges.  */<br>
-+  if (unconverted_simple_returns)<br>
-+    {<br>
-+      edge_iterator ei2;<br>
-+      basic_block exit_pred = EXIT_BLOCK_PTR-&gt;prev_bb;<br>
-+<br>
-+      gcc_assert (entry_edge != orig_entry_edge);<br>
-+<br>
-+#ifdef HAVE_epilogue<br>
-+      if (simple_return_block == NULL &amp;&amp; returnjump != NULL_RTX<br>
-+        &amp;&amp; JUMP_LABEL (returnjump) == simple_return_rtx)<br>
-+      {<br>
-+        edge e = split_block (exit_fallthru_edge-&gt;src,<br>
-+                              PREV_INSN (returnjump));<br>
-+        simple_return_block = e-&gt;dest;<br>
-+      }<br>
-+#endif<br>
-+      if (simple_return_block == NULL)<br>
-+      {<br>
-+        basic_block bb;<br>
-+        rtx start;<br>
-+<br>
-+        bb = create_basic_block (NULL, NULL, exit_pred);<br>
-+        start = emit_jump_insn_after (gen_simple_return (),<br>
-+                                      BB_END (bb));<br>
-+        JUMP_LABEL (start) = simple_return_rtx;<br>
-+        emit_barrier_after (start);<br>
-+<br>
-+        simple_return_block = bb;<br>
-+        make_edge (bb, EXIT_BLOCK_PTR, 0);<br>
-+      }<br>
-+<br>
-+    restart_scan:<br>
-+      for (ei2 = ei_start (last_bb-&gt;preds); (e = ei_safe_edge (ei2)); )<br>
-+      {<br>
-+        basic_block bb = e-&gt;src;<br>
-+<br>
-+        if (bb != ENTRY_BLOCK_PTR<br>
-+            &amp;&amp; !bitmap_bit_p (&amp;bb_flags, bb-&gt;index))<br>
-+          {<br>
-+            redirect_edge_and_branch_force (e, simple_return_block);<br>
-+            goto restart_scan;<br>
-+          }<br>
-+        ei_next (&amp;ei2);<br>
-+<br>
-+      }<br>
-+    }<br>
-+#endif<br>
-+<br>
- #ifdef HAVE_sibcall_epilogue<br>
-   /* Emit sibling epilogues before any sibling call sites.  */<br>
-   for (ei = ei_start (EXIT_BLOCK_PTR-&gt;preds); (e = ei_safe_edge (ei)); )<br>
-     {<br>
-       basic_block bb = e-&gt;src;<br>
-       rtx insn = BB_END (bb);<br>
-+      rtx ep_seq;<br>
-<br>
-       if (!CALL_P (insn)<br>
--        || ! SIBLING_CALL_P (insn))<br>
-+        || ! SIBLING_CALL_P (insn)<br>
-+        || (entry_edge != orig_entry_edge<br>
-+            &amp;&amp; !bitmap_bit_p (&amp;bb_flags, bb-&gt;index)))<br>
-       {<br>
-         ei_next (&amp;ei);<br>
-         continue;<br>
-       }<br>
-<br>
--      start_sequence ();<br>
--      emit_note (NOTE_INSN_EPILOGUE_BEG);<br>
--      emit_insn (gen_sibcall_epilogue ());<br>
--      seq = get_insns ();<br>
--      end_sequence ();<br>
--<br>
--      /* Retain a map of the epilogue insns.  Used in life analysis to<br>
--       avoid getting rid of sibcall epilogue insns.  Do this before we<br>
--       actually emit the sequence.  */<br>
--      record_insns (seq, NULL, &amp;epilogue_insn_hash);<br>
--      set_insn_locators (seq, epilogue_locator);<br>
--<br>
--      emit_insn_before (seq, insn);<br>
-+      ep_seq = gen_sibcall_epilogue ();<br>
-+      if (ep_seq)<br>
-+      {<br>
-+        start_sequence ();<br>
-+        emit_note (NOTE_INSN_EPILOGUE_BEG);<br>
-+        emit_insn (ep_seq);<br>
-+        seq = get_insns ();<br>
-+        end_sequence ();<br>
-+<br>
-+        /* Retain a map of the epilogue insns.  Used in life analysis to<br>
-+           avoid getting rid of sibcall epilogue insns.  Do this before we<br>
-+           actually emit the sequence.  */<br>
-+        record_insns (seq, NULL, &amp;epilogue_insn_hash);<br>
-+        set_insn_locators (seq, epilogue_locator);<br>
-+<br>
-+        emit_insn_before (seq, insn);<br>
-+      }<br>
-       ei_next (&amp;ei);<br>
-     }<br>
- #endif<br>
-@@ -5311,6 +5710,8 @@<br>
-     }<br>
- #endif<br>
-<br>
-+  bitmap_clear (&amp;bb_flags);<br>
-+<br>
-   /* Threading the prologue and epilogue changes the artificial refs<br>
-      in the entry and exit blocks.  */<br>
-   epilogue_completed = 1;<br>
-<br>
-=== modified file &#39;gcc/genemit.c&#39;<br>
---- old/gcc/genemit.c  2009-11-27 11:37:06 +0000<br>
-+++ new/gcc/genemit.c  2011-01-05 12:12:18 +0000<br>
-@@ -222,6 +222,12 @@<br>
-     case PC:<br>
-       printf (&quot;pc_rtx&quot;);<br>
-       return;<br>
-+    case RETURN:<br>
-+      printf (&quot;ret_rtx&quot;);<br>
-+      return;<br>
-+    case SIMPLE_RETURN:<br>
-+      printf (&quot;simple_return_rtx&quot;);<br>
-+      return;<br>
-     case CLOBBER:<br>
-       if (REG_P (XEXP (x, 0)))<br>
-       {<br>
-@@ -544,8 +550,8 @@<br>
-         || (GET_CODE (next) == PARALLEL<br>
-             &amp;&amp; ((GET_CODE (XVECEXP (next, 0, 0)) == SET<br>
-                  &amp;&amp; GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)<br>
--                || GET_CODE (XVECEXP (next, 0, 0)) == RETURN))<br>
--        || GET_CODE (next) == RETURN)<br>
-+                || ANY_RETURN_P (XVECEXP (next, 0, 0))))<br>
-+        || ANY_RETURN_P (next))<br>
-       printf (&quot;  emit_jump_insn (&quot;);<br>
-       else if ((GET_CODE (next) == SET &amp;&amp; GET_CODE (SET_SRC (next)) == CALL)<br>
-              || GET_CODE (next) == CALL<br>
-@@ -660,7 +666,7 @@<br>
-         || (GET_CODE (next) == PARALLEL<br>
-             &amp;&amp; GET_CODE (XVECEXP (next, 0, 0)) == SET<br>
-             &amp;&amp; GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)<br>
--        || GET_CODE (next) == RETURN)<br>
-+        || ANY_RETURN_P (next))<br>
-       printf (&quot;  emit_jump_insn (&quot;);<br>
-       else if ((GET_CODE (next) == SET &amp;&amp; GET_CODE (SET_SRC (next)) == CALL)<br>
-              || GET_CODE (next) == CALL<br>
-<br>
-=== modified file &#39;gcc/gengenrtl.c&#39;<br>
---- old/gcc/gengenrtl.c        2007-08-22 23:30:39 +0000<br>
-+++ new/gcc/gengenrtl.c        2011-01-05 12:12:18 +0000<br>
-@@ -146,6 +146,10 @@<br>
-         || strcmp (defs[idx].enumname, &quot;REG&quot;) == 0<br>
-         || strcmp (defs[idx].enumname, &quot;SUBREG&quot;) == 0<br>
-         || strcmp (defs[idx].enumname, &quot;MEM&quot;) == 0<br>
-+        || strcmp (defs[idx].enumname, &quot;PC&quot;) == 0<br>
-+        || strcmp (defs[idx].enumname, &quot;CC0&quot;) == 0<br>
-+        || strcmp (defs[idx].enumname, &quot;RETURN&quot;) == 0<br>
-+        || strcmp (defs[idx].enumname, &quot;SIMPLE_RETURN&quot;) == 0<br>
-         || strcmp (defs[idx].enumname, &quot;CONST_VECTOR&quot;) == 0);<br>
- }<br>
-<br>
-<br>
-=== modified file &#39;gcc/haifa-sched.c&#39;<br>
---- old/gcc/haifa-sched.c      2010-08-12 08:14:47 +0000<br>
-+++ new/gcc/haifa-sched.c      2011-01-05 12:12:18 +0000<br>
-@@ -4231,7 +4231,7 @@<br>
- /* Helper function.<br>
-    Find fallthru edge from PRED.  */<br>
- edge<br>
--find_fallthru_edge (basic_block pred)<br>
-+find_fallthru_edge_from (basic_block pred)<br>
- {<br>
-   edge e;<br>
-   edge_iterator ei;<br>
-@@ -4298,7 +4298,7 @@<br>
-   edge e;<br>
-<br>
-   last = EXIT_BLOCK_PTR-&gt;prev_bb;<br>
--  e = find_fallthru_edge (last);<br>
-+  e = find_fallthru_edge_from (last);<br>
-<br>
-   if (e)<br>
-     {<br>
-@@ -5234,6 +5234,11 @@<br>
-                   gcc_assert (/* Usual case.  */<br>
-                                 (EDGE_COUNT (bb-&gt;succs) &gt; 1<br>
-                                  &amp;&amp; !BARRIER_P (NEXT_INSN (head)))<br>
-+                              /* Special cases, see cfglayout.c:<br>
-+                                 fixup_reorder_chain.  */<br>
-+                              || (EDGE_COUNT (bb-&gt;succs) == 1<br>
-+                                  &amp;&amp; (!onlyjump_p (head)<br>
-+                                      || returnjump_p (head)))<br>
-                                 /* Or jump to the next instruction.  */<br>
-                                 || (EDGE_COUNT (bb-&gt;succs) == 1<br>
-                                     &amp;&amp; (BB_HEAD (EDGE_I (bb-&gt;succs, 0)-&gt;dest)<br>
-<br>
-=== modified file &#39;gcc/ifcvt.c&#39;<br>
---- old/gcc/ifcvt.c    2010-11-26 12:03:32 +0000<br>
-+++ new/gcc/ifcvt.c    2011-01-05 12:12:18 +0000<br>
-@@ -105,7 +105,7 @@<br>
- static int find_if_case_2 (basic_block, edge, edge);<br>
- static int find_memory (rtx *, void *);<br>
- static int dead_or_predicable (basic_block, basic_block, basic_block,<br>
--                             basic_block, int);<br>
-+                             edge, int);<br>
- static void noce_emit_move_insn (rtx, rtx);<br>
- static rtx block_has_only_trap (basic_block);<br>
-<br>
-@@ -3791,6 +3791,7 @@<br>
-   basic_block then_bb = then_edge-&gt;dest;<br>
-   basic_block else_bb = else_edge-&gt;dest;<br>
-   basic_block new_bb;<br>
-+  rtx else_target = NULL_RTX;<br>
-   int then_bb_index;<br>
-<br>
-   /* If we are partitioning hot/cold basic blocks, we don&#39;t want to<br>
-@@ -3840,9 +3841,16 @@<br>
-                                   predictable_edge_p (then_edge)))))<br>
-     return FALSE;<br>
-<br>
-+  if (else_bb == EXIT_BLOCK_PTR)<br>
-+    {<br>
-+      rtx jump = BB_END (else_edge-&gt;src);<br>
-+      gcc_assert (JUMP_P (jump));<br>
-+      else_target = JUMP_LABEL (jump);<br>
-+    }<br>
-+<br>
-   /* Registers set are dead, or are predicable.  */<br>
-   if (! dead_or_predicable (test_bb, then_bb, else_bb,<br>
--                          single_succ (then_bb), 1))<br>
-+                          single_succ_edge (then_bb), 1))<br>
-     return FALSE;<br>
-<br>
-   /* Conversion went ok, including moving the insns and fixing up the<br>
-@@ -3859,6 +3867,9 @@<br>
-       redirect_edge_succ (FALLTHRU_EDGE (test_bb), else_bb);<br>
-       new_bb = 0;<br>
-     }<br>
-+  else if (else_bb == EXIT_BLOCK_PTR)<br>
-+    new_bb = force_nonfallthru_and_redirect (FALLTHRU_EDGE (test_bb),<br>
-+                                           else_bb, else_target);<br>
-   else<br>
-     new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb),<br>
-                                            else_bb);<br>
-@@ -3957,7 +3968,7 @@<br>
-     return FALSE;<br>
-<br>
-   /* Registers set are dead, or are predicable.  */<br>
--  if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ-&gt;dest, 0))<br>
-+  if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, 0))<br>
-     return FALSE;<br>
-<br>
-   /* Conversion went ok, including moving the insns and fixing up the<br>
-@@ -3995,12 +4006,34 @@<br>
-<br>
- static int<br>
- dead_or_predicable (basic_block test_bb, basic_block merge_bb,<br>
--                  basic_block other_bb, basic_block new_dest, int reversep)<br>
-+                  basic_block other_bb, edge dest_edge, int reversep)<br>
- {<br>
--  rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;<br>
-+  basic_block new_dest = dest_edge-&gt;dest;<br>
-+  rtx head, end, jump, earliest = NULL_RTX, old_dest;<br>
-   bitmap merge_set = NULL;<br>
-   /* Number of pending changes.  */<br>
-   int n_validated_changes = 0;<br>
-+  rtx new_dest_label;<br>
-+<br>
-+  jump = BB_END (dest_edge-&gt;src);<br>
-+  if (JUMP_P (jump))<br>
-+    {<br>
-+      new_dest_label = JUMP_LABEL (jump);<br>
-+      if (new_dest_label == NULL_RTX)<br>
-+      {<br>
-+        new_dest_label = PATTERN (jump);<br>
-+        gcc_assert (ANY_RETURN_P (new_dest_label));<br>
-+      }<br>
-+    }<br>
-+  else if (other_bb != new_dest)<br>
-+    {<br>
-+      if (new_dest == EXIT_BLOCK_PTR)<br>
-+      new_dest_label = ret_rtx;<br>
-+      else<br>
-+      new_dest_label = block_label (new_dest);<br>
-+    }<br>
-+  else<br>
-+    new_dest_label = NULL_RTX;<br>
-<br>
-   jump = BB_END (test_bb);<br>
-<br>
-@@ -4220,10 +4253,9 @@<br>
-   old_dest = JUMP_LABEL (jump);<br>
-   if (other_bb != new_dest)<br>
-     {<br>
--      new_label = block_label (new_dest);<br>
-       if (reversep<br>
--        ? ! invert_jump_1 (jump, new_label)<br>
--        : ! redirect_jump_1 (jump, new_label))<br>
-+        ? ! invert_jump_1 (jump, new_dest_label)<br>
-+        : ! redirect_jump_1 (jump, new_dest_label))<br>
-       goto cancel;<br>
-     }<br>
-<br>
-@@ -4234,7 +4266,7 @@<br>
-<br>
-   if (other_bb != new_dest)<br>
-     {<br>
--      redirect_jump_2 (jump, old_dest, new_label, 0, reversep);<br>
-+      redirect_jump_2 (jump, old_dest, new_dest_label, 0, reversep);<br>
-<br>
-       redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);<br>
-       if (reversep)<br>
-<br>
-=== modified file &#39;gcc/jump.c&#39;<br>
---- old/gcc/jump.c     2010-12-13 10:05:52 +0000<br>
-+++ new/gcc/jump.c     2011-01-05 12:12:18 +0000<br>
-@@ -29,7 +29,8 @@<br>
-    JUMP_LABEL internal field.  With this we can detect labels that<br>
-    become unused because of the deletion of all the jumps that<br>
-    formerly used them.  The JUMP_LABEL info is sometimes looked<br>
--   at by later passes.<br>
-+   at by later passes.  For return insns, it contains either a<br>
-+   RETURN or a SIMPLE_RETURN rtx.<br>
-<br>
-    The subroutines redirect_jump and invert_jump are used<br>
-    from other passes as well.  */<br>
-@@ -742,10 +743,10 @@<br>
-     return (GET_CODE (x) == IF_THEN_ELSE<br>
-           &amp;&amp; ((GET_CODE (XEXP (x, 2)) == PC<br>
-                &amp;&amp; (GET_CODE (XEXP (x, 1)) == LABEL_REF<br>
--                   || GET_CODE (XEXP (x, 1)) == RETURN))<br>
-+                   || ANY_RETURN_P (XEXP (x, 1))))<br>
-               || (GET_CODE (XEXP (x, 1)) == PC<br>
-                   &amp;&amp; (GET_CODE (XEXP (x, 2)) == LABEL_REF<br>
--                      || GET_CODE (XEXP (x, 2)) == RETURN))));<br>
-+                      || ANY_RETURN_P (XEXP (x, 2))))));<br>
- }<br>
-<br>
- /* Return nonzero if INSN is a (possibly) conditional jump inside a<br>
-@@ -774,11 +775,11 @@<br>
-     return 0;<br>
-   if (XEXP (SET_SRC (x), 2) == pc_rtx<br>
-       &amp;&amp; (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF<br>
--        || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))<br>
-+        || ANY_RETURN_P (XEXP (SET_SRC (x), 1)) == RETURN))<br>
-     return 1;<br>
-   if (XEXP (SET_SRC (x), 1) == pc_rtx<br>
-       &amp;&amp; (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF<br>
--        || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))<br>
-+        || ANY_RETURN_P (XEXP (SET_SRC (x), 2))))<br>
-     return 1;<br>
-   return 0;<br>
- }<br>
-@@ -840,8 +841,9 @@<br>
-   a = GET_CODE (XEXP (SET_SRC (x), 1));<br>
-   b = GET_CODE (XEXP (SET_SRC (x), 2));<br>
-<br>
--  return ((b == PC &amp;&amp; (a == LABEL_REF || a == RETURN))<br>
--        || (a == PC &amp;&amp; (b == LABEL_REF || b == RETURN)));<br>
-+  return ((b == PC &amp;&amp; (a == LABEL_REF || a == RETURN || a == SIMPLE_RETURN))<br>
-+        || (a == PC<br>
-+            &amp;&amp; (b == LABEL_REF || b == RETURN || b == SIMPLE_RETURN)));<br>
- }<br>
-<br>
- /* Return the label of a conditional jump.  */<br>
-@@ -878,6 +880,7 @@<br>
-   switch (GET_CODE (x))<br>
-     {<br>
-     case RETURN:<br>
-+    case SIMPLE_RETURN:<br>
-     case EH_RETURN:<br>
-       return true;<br>
-<br>
-@@ -1200,7 +1203,7 @@<br>
-   /* If deleting a jump, decrement the count of the label,<br>
-      and delete the label if it is now unused.  */<br>
-<br>
--  if (JUMP_P (insn) &amp;&amp; JUMP_LABEL (insn))<br>
-+  if (JUMP_P (insn) &amp;&amp; JUMP_LABEL (insn) &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (insn)))<br>
-     {<br>
-       rtx lab = JUMP_LABEL (insn), lab_next;<br>
-<br>
-@@ -1331,6 +1334,18 @@<br>
-      is also an unconditional jump in that case.  */<br>
- }<br>
-<br>
-+/* A helper function for redirect_exp_1; examines its input X and returns<br>
-+   either a LABEL_REF around a label, or a RETURN if X was NULL.  */<br>
-+static rtx<br>
-+redirect_target (rtx x)<br>
-+{<br>
-+  if (x == NULL_RTX)<br>
-+    return ret_rtx;<br>
-+  if (!ANY_RETURN_P (x))<br>
-+    return gen_rtx_LABEL_REF (Pmode, x);<br>
-+  return x;<br>
-+}<br>
-+<br>
- /* Throughout LOC, redirect OLABEL to NLABEL.  Treat null OLABEL or<br>
-    NLABEL as a return.  Accrue modifications into the change group.  */<br>
-<br>
-@@ -1342,37 +1357,19 @@<br>
-   int i;<br>
-   const char *fmt;<br>
-<br>
--  if (code == LABEL_REF)<br>
--    {<br>
--      if (XEXP (x, 0) == olabel)<br>
--      {<br>
--        rtx n;<br>
--        if (nlabel)<br>
--          n = gen_rtx_LABEL_REF (Pmode, nlabel);<br>
--        else<br>
--          n = gen_rtx_RETURN (VOIDmode);<br>
--<br>
--        validate_change (insn, loc, n, 1);<br>
--        return;<br>
--      }<br>
--    }<br>
--  else if (code == RETURN &amp;&amp; olabel == 0)<br>
--    {<br>
--      if (nlabel)<br>
--      x = gen_rtx_LABEL_REF (Pmode, nlabel);<br>
--      else<br>
--      x = gen_rtx_RETURN (VOIDmode);<br>
--      if (loc == &amp;PATTERN (insn))<br>
--      x = gen_rtx_SET (VOIDmode, pc_rtx, x);<br>
--      validate_change (insn, loc, x, 1);<br>
-+  if ((code == LABEL_REF &amp;&amp; XEXP (x, 0) == olabel)<br>
-+      || x == olabel)<br>
-+    {<br>
-+      validate_change (insn, loc, redirect_target (nlabel), 1);<br>
-       return;<br>
-     }<br>
-<br>
--  if (code == SET &amp;&amp; nlabel == 0 &amp;&amp; SET_DEST (x) == pc_rtx<br>
-+  if (code == SET &amp;&amp; SET_DEST (x) == pc_rtx<br>
-+      &amp;&amp; ANY_RETURN_P (nlabel)<br>
-       &amp;&amp; GET_CODE (SET_SRC (x)) == LABEL_REF<br>
-       &amp;&amp; XEXP (SET_SRC (x), 0) == olabel)<br>
-     {<br>
--      validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);<br>
-+      validate_change (insn, loc, nlabel, 1);<br>
-       return;<br>
-     }<br>
-<br>
-@@ -1409,6 +1406,7 @@<br>
-   int ochanges = num_validated_changes ();<br>
-   rtx *loc, asmop;<br>
-<br>
-+  gcc_assert (nlabel);<br>
-   asmop = extract_asm_operands (PATTERN (jump));<br>
-   if (asmop)<br>
-     {<br>
-@@ -1430,17 +1428,20 @@<br>
-    jump target label is unused as a result, it and the code following<br>
-    it may be deleted.<br>
-<br>
--   If NLABEL is zero, we are to turn the jump into a (possibly conditional)<br>
--   RETURN insn.<br>
-+   Normally, NLABEL will be a label, but it may also be a RETURN or<br>
-+   SIMPLE_RETURN rtx; in that case we are to turn the jump into a<br>
-+   (possibly conditional) return insn.<br>
-<br>
-    The return value will be 1 if the change was made, 0 if it wasn&#39;t<br>
--   (this can only occur for NLABEL == 0).  */<br>
-+   (this can only occur when trying to produce return insns).  */<br>
-<br>
- int<br>
- redirect_jump (rtx jump, rtx nlabel, int delete_unused)<br>
- {<br>
-   rtx olabel = JUMP_LABEL (jump);<br>
-<br>
-+  gcc_assert (nlabel != NULL_RTX);<br>
-+<br>
-   if (nlabel == olabel)<br>
-     return 1;<br>
-<br>
-@@ -1452,7 +1453,7 @@<br>
- }<br>
-<br>
- /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with<br>
--   NLABEL in JUMP.<br>
-+   NEW_DEST in JUMP.<br>
-    If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref<br>
-    count has dropped to zero.  */<br>
- void<br>
-@@ -1468,13 +1469,14 @@<br>
-      about this.  */<br>
-   gcc_assert (delete_unused &gt;= 0);<br>
-   JUMP_LABEL (jump) = nlabel;<br>
--  if (nlabel)<br>
-+  if (nlabel &amp;&amp; !ANY_RETURN_P (nlabel))<br>
-     ++LABEL_NUSES (nlabel);<br>
-<br>
-   /* Update labels in any REG_EQUAL note.  */<br>
-   if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)<br>
-     {<br>
--      if (!nlabel || (invert &amp;&amp; !invert_exp_1 (XEXP (note, 0), jump)))<br>
-+      if (ANY_RETURN_P (nlabel)<br>
-+        || (invert &amp;&amp; !invert_exp_1 (XEXP (note, 0), jump)))<br>
-       remove_note (jump, note);<br>
-       else<br>
-       {<br>
-@@ -1483,7 +1485,8 @@<br>
-       }<br>
-     }<br>
-<br>
--  if (olabel &amp;&amp; --LABEL_NUSES (olabel) == 0 &amp;&amp; delete_unused &gt; 0<br>
-+  if (olabel &amp;&amp; !ANY_RETURN_P (olabel)<br>
-+      &amp;&amp; --LABEL_NUSES (olabel) == 0 &amp;&amp; delete_unused &gt; 0<br>
-       /* Undefined labels will remain outside the insn stream.  */<br>
-       &amp;&amp; INSN_UID (olabel))<br>
-     delete_related_insns (olabel);<br>
-<br>
-=== modified file &#39;gcc/opts.c&#39;<br>
---- old/gcc/opts.c     2010-12-10 15:33:37 +0000<br>
-+++ new/gcc/opts.c     2011-01-05 12:12:18 +0000<br>
-@@ -908,6 +908,7 @@<br>
-   flag_ipa_cp = opt2;<br>
-   flag_ipa_sra = opt2;<br>
-   flag_ee = opt2;<br>
-+  flag_shrink_wrap = opt2;<br>
-<br>
-   /* Track fields in field-sensitive alias analysis.  */<br>
-   set_param_value (&quot;max-fields-for-field-sensitive&quot;,<br>
-<br>
-=== modified file &#39;gcc/print-rtl.c&#39;<br>
---- old/gcc/print-rtl.c        2010-03-26 16:18:51 +0000<br>
-+++ new/gcc/print-rtl.c        2011-01-05 12:12:18 +0000<br>
-@@ -308,9 +308,16 @@<br>
-             }<br>
-         }<br>
-       else if (i == 8 &amp;&amp; JUMP_P (in_rtx) &amp;&amp; JUMP_LABEL (in_rtx) != NULL)<br>
--        /* Output the JUMP_LABEL reference.  */<br>
--        fprintf (outfile, &quot;\n%s%*s -&gt; %d&quot;, print_rtx_head, indent * 2, &quot;&quot;,<br>
--                 INSN_UID (JUMP_LABEL (in_rtx)));<br>
-+        {<br>
-+          /* Output the JUMP_LABEL reference.  */<br>
-+          fprintf (outfile, &quot;\n%s%*s -&gt; &quot;, print_rtx_head, indent * 2, &quot;&quot;);<br>
-+          if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)<br>
-+            fprintf (outfile, &quot;return&quot;);<br>
-+          else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)<br>
-+            fprintf (outfile, &quot;simple_return&quot;);<br>
-+          else<br>
-+            fprintf (outfile, &quot;%d&quot;, INSN_UID (JUMP_LABEL (in_rtx)));<br>
-+        }<br>
-       else if (i == 0 &amp;&amp; GET_CODE (in_rtx) == VALUE)<br>
-         {<br>
- #ifndef GENERATOR_FILE<br>
-<br>
-=== modified file &#39;gcc/reorg.c&#39;<br>
---- old/gcc/reorg.c    2010-09-15 22:51:44 +0000<br>
-+++ new/gcc/reorg.c    2011-01-05 12:12:18 +0000<br>
-@@ -161,8 +161,11 @@<br>
- #define unfilled_slots_next   \<br>
-   ((rtx *) obstack_next_free (&amp;unfilled_slots_obstack))<br>
-<br>
--/* Points to the label before the end of the function.  */<br>
--static rtx end_of_function_label;<br>
-+/* Points to the label before the end of the function, or before a<br>
-+   return insn.  */<br>
-+static rtx function_return_label;<br>
-+/* Likewise for a simple_return.  */<br>
-+static rtx function_simple_return_label;<br>
-<br>
- /* Mapping between INSN_UID&#39;s and position in the code since INSN_UID&#39;s do<br>
-    not always monotonically increase.  */<br>
-@@ -175,7 +178,7 @@<br>
- static int resource_conflicts_p (struct resources *, struct resources *);<br>
- static int insn_references_resource_p (rtx, struct resources *, bool);<br>
- static int insn_sets_resource_p (rtx, struct resources *, bool);<br>
--static rtx find_end_label (void);<br>
-+static rtx find_end_label (rtx);<br>
- static rtx emit_delay_sequence (rtx, rtx, int);<br>
- static rtx add_to_delay_list (rtx, rtx);<br>
- static rtx delete_from_delay_slot (rtx);<br>
-@@ -220,6 +223,15 @@<br>
- static void make_return_insns (rtx);<br>
- #endif<br>
-<br>
-+/* Return true iff INSN is a simplejump, or any kind of return insn.  */<br>
-+<br>
-+static bool<br>
-+simplejump_or_return_p (rtx insn)<br>
-+{<br>
-+  return (JUMP_P (insn)<br>
-+        &amp;&amp; (simplejump_p (insn) || ANY_RETURN_P (PATTERN (insn))));<br>
-+}<br>
-+ <br>
- /* Return TRUE if this insn should stop the search for insn to fill delay<br>
-    slots.  LABELS_P indicates that labels should terminate the search.<br>
-    In all cases, jumps terminate the search.  */<br>
-@@ -335,23 +347,29 @@<br>
-<br>
-    ??? There may be a problem with the current implementation.  Suppose<br>
-    we start with a bare RETURN insn and call find_end_label.  It may set<br>
--   end_of_function_label just before the RETURN.  Suppose the machinery<br>
-+   function_return_label just before the RETURN.  Suppose the machinery<br>
-    is able to fill the delay slot of the RETURN insn afterwards.  Then<br>
--   end_of_function_label is no longer valid according to the property<br>
-+   function_return_label is no longer valid according to the property<br>
-    described above and find_end_label will still return it unmodified.<br>
-    Note that this is probably mitigated by the following observation:<br>
--   once end_of_function_label is made, it is very likely the target of<br>
-+   once function_return_label is made, it is very likely the target of<br>
-    a jump, so filling the delay slot of the RETURN will be much more<br>
-    difficult.  */<br>
-<br>
- static rtx<br>
--find_end_label (void)<br>
-+find_end_label (rtx kind)<br>
- {<br>
-   rtx insn;<br>
-+  rtx *plabel;<br>
-+<br>
-+  if (kind == ret_rtx)<br>
-+    plabel = &amp;function_return_label;<br>
-+  else<br>
-+    plabel = &amp;function_simple_return_label;<br>
-<br>
-   /* If we found one previously, return it.  */<br>
--  if (end_of_function_label)<br>
--    return end_of_function_label;<br>
-+  if (*plabel)<br>
-+    return *plabel;<br>
-<br>
-   /* Otherwise, see if there is a label at the end of the function.  If there<br>
-      is, it must be that RETURN insns aren&#39;t needed, so that is our return<br>
-@@ -366,44 +384,44 @@<br>
-<br>
-   /* When a target threads its epilogue we might already have a<br>
-      suitable return insn.  If so put a label before it for the<br>
--     end_of_function_label.  */<br>
-+     function_return_label.  */<br>
-   if (BARRIER_P (insn)<br>
-       &amp;&amp; JUMP_P (PREV_INSN (insn))<br>
--      &amp;&amp; GET_CODE (PATTERN (PREV_INSN (insn))) == RETURN)<br>
-+      &amp;&amp; PATTERN (PREV_INSN (insn)) == kind)<br>
-     {<br>
-       rtx temp = PREV_INSN (PREV_INSN (insn));<br>
--      end_of_function_label = gen_label_rtx ();<br>
--      LABEL_NUSES (end_of_function_label) = 0;<br>
-+      rtx label = gen_label_rtx ();<br>
-+      LABEL_NUSES (label) = 0;<br>
-<br>
-       /* Put the label before an USE insns that may precede the RETURN insn.  */<br>
-       while (GET_CODE (temp) == USE)<br>
-       temp = PREV_INSN (temp);<br>
-<br>
--      emit_label_after (end_of_function_label, temp);<br>
-+      emit_label_after (label, temp);<br>
-+      *plabel = label;<br>
-     }<br>
-<br>
-   else if (LABEL_P (insn))<br>
--    end_of_function_label = insn;<br>
-+    *plabel = insn;<br>
-   else<br>
-     {<br>
--      end_of_function_label = gen_label_rtx ();<br>
--      LABEL_NUSES (end_of_function_label) = 0;<br>
-+      rtx label = gen_label_rtx ();<br>
-+      LABEL_NUSES (label) = 0;<br>
-       /* If the basic block reorder pass moves the return insn to<br>
-        some other place try to locate it again and put our<br>
--       end_of_function_label there.  */<br>
--      while (insn &amp;&amp; ! (JUMP_P (insn)<br>
--                      &amp;&amp; (GET_CODE (PATTERN (insn)) == RETURN)))<br>
-+       function_return_label there.  */<br>
-+      while (insn &amp;&amp; ! (JUMP_P (insn) &amp;&amp; (PATTERN (insn) == kind)))<br>
-       insn = PREV_INSN (insn);<br>
-       if (insn)<br>
-       {<br>
-         insn = PREV_INSN (insn);<br>
-<br>
--        /* Put the label before an USE insns that may proceed the<br>
-+        /* Put the label before an USE insns that may precede the<br>
-            RETURN insn.  */<br>
-         while (GET_CODE (insn) == USE)<br>
-           insn = PREV_INSN (insn);<br>
-<br>
--        emit_label_after (end_of_function_label, insn);<br>
-+        emit_label_after (label, insn);<br>
-       }<br>
-       else<br>
-       {<br>
-@@ -413,19 +431,16 @@<br>
-             &amp;&amp; ! HAVE_return<br>
- #endif<br>
-             )<br>
--          {<br>
--            /* The RETURN insn has its delay slot filled so we cannot<br>
--               emit the label just before it.  Since we already have<br>
--               an epilogue and cannot emit a new RETURN, we cannot<br>
--               emit the label at all.  */<br>
--            end_of_function_label = NULL_RTX;<br>
--            return end_of_function_label;<br>
--          }<br>
-+          /* The RETURN insn has its delay slot filled so we cannot<br>
-+             emit the label just before it.  Since we already have<br>
-+             an epilogue and cannot emit a new RETURN, we cannot<br>
-+             emit the label at all.  */<br>
-+          return NULL_RTX;<br>
- #endif /* HAVE_epilogue */<br>
-<br>
-         /* Otherwise, make a new label and emit a RETURN and BARRIER,<br>
-            if needed.  */<br>
--        emit_label (end_of_function_label);<br>
-+        emit_label (label);<br>
- #ifdef HAVE_return<br>
-         /* We don&#39;t bother trying to create a return insn if the<br>
-            epilogue has filled delay-slots; we would have to try and<br>
-@@ -437,19 +452,21 @@<br>
-             /* The return we make may have delay slots too.  */<br>
-             rtx insn = gen_return ();<br>
-             insn = emit_jump_insn (insn);<br>
-+            JUMP_LABEL (insn) = ret_rtx;<br>
-             emit_barrier ();<br>
-             if (num_delay_slots (insn) &gt; 0)<br>
-               obstack_ptr_grow (&amp;unfilled_slots_obstack, insn);<br>
-           }<br>
- #endif<br>
-       }<br>
-+      *plabel = label;<br>
-     }<br>
-<br>
-   /* Show one additional use for this label so it won&#39;t go away until<br>
-      we are done.  */<br>
--  ++LABEL_NUSES (end_of_function_label);<br>
-+  ++LABEL_NUSES (*plabel);<br>
-<br>
--  return end_of_function_label;<br>
-+  return *plabel;<br>
- }<br>
-<br>
- /* Put INSN and LIST together in a SEQUENCE rtx of LENGTH, and replace<br>
-@@ -797,10 +814,8 @@<br>
-   if ((next_trial == next_active_insn (JUMP_LABEL (insn))<br>
-        &amp;&amp; ! (next_trial == 0 &amp;&amp; crtl-&gt;epilogue_delay_list != 0))<br>
-       || (next_trial != 0<br>
--        &amp;&amp; JUMP_P (next_trial)<br>
--        &amp;&amp; JUMP_LABEL (insn) == JUMP_LABEL (next_trial)<br>
--        &amp;&amp; (simplejump_p (next_trial)<br>
--            || GET_CODE (PATTERN (next_trial)) == RETURN)))<br>
-+        &amp;&amp; simplejump_or_return_p (next_trial)<br>
-+        &amp;&amp; JUMP_LABEL (insn) == JUMP_LABEL (next_trial)))<br>
-     {<br>
-       if (eligible_for_annul_false (insn, 0, trial, flags))<br>
-       {<br>
-@@ -819,13 +834,11 @@<br>
-        branch, thread our jump to the target of that branch.  Don&#39;t<br>
-        change this into a RETURN here, because it may not accept what<br>
-        we have in the delay slot.  We&#39;ll fix this up later.  */<br>
--      if (next_trial &amp;&amp; JUMP_P (next_trial)<br>
--        &amp;&amp; (simplejump_p (next_trial)<br>
--            || GET_CODE (PATTERN (next_trial)) == RETURN))<br>
-+      if (next_trial &amp;&amp; simplejump_or_return_p (next_trial))<br>
-       {<br>
-         rtx target_label = JUMP_LABEL (next_trial);<br>
--        if (target_label == 0)<br>
--          target_label = find_end_label ();<br>
-+        if (ANY_RETURN_P (target_label))<br>
-+          target_label = find_end_label (target_label);<br>
-<br>
-         if (target_label)<br>
-           {<br>
-@@ -866,7 +879,7 @@<br>
-   if (JUMP_P (insn)<br>
-       &amp;&amp; (condjump_p (insn) || condjump_in_parallel_p (insn))<br>
-       &amp;&amp; INSN_UID (insn) &lt;= max_uid<br>
--      &amp;&amp; label != 0<br>
-+      &amp;&amp; label != 0 &amp;&amp; !ANY_RETURN_P (label)<br>
-       &amp;&amp; INSN_UID (label) &lt;= max_uid)<br>
-     flags<br>
-       = (uid_to_ruid[INSN_UID (label)] &gt; uid_to_ruid[INSN_UID (insn)])<br>
-@@ -1038,7 +1051,7 @@<br>
-     pat = XVECEXP (pat, 0, 0);<br>
-<br>
-   if (GET_CODE (pat) == RETURN)<br>
--    return target == 0 ? const_true_rtx : 0;<br>
-+    return ANY_RETURN_P (target) ? const_true_rtx : 0;<br>
-<br>
-   else if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)<br>
-     return 0;<br>
-@@ -1318,7 +1331,11 @@<br>
-     }<br>
-<br>
-   /* Show the place to which we will be branching.  */<br>
--  *pnew_thread = next_active_insn (JUMP_LABEL (XVECEXP (seq, 0, 0)));<br>
-+  temp = JUMP_LABEL (XVECEXP (seq, 0, 0));<br>
-+  if (ANY_RETURN_P (temp))<br>
-+    *pnew_thread = temp;<br>
-+  else<br>
-+    *pnew_thread = next_active_insn (temp);<br>
-<br>
-   /* Add any new insns to the delay list and update the count of the<br>
-      number of slots filled.  */<br>
-@@ -1358,8 +1375,7 @@<br>
-   /* We can&#39;t do anything if SEQ&#39;s delay insn isn&#39;t an<br>
-      unconditional branch.  */<br>
-<br>
--  if (! simplejump_p (XVECEXP (seq, 0, 0))<br>
--      &amp;&amp; GET_CODE (PATTERN (XVECEXP (seq, 0, 0))) != RETURN)<br>
-+  if (! simplejump_or_return_p (XVECEXP (seq, 0, 0)))<br>
-     return delay_list;<br>
-<br>
-   for (i = 1; i &lt; XVECLEN (seq, 0); i++)<br>
-@@ -1827,7 +1843,7 @@<br>
-   rtx insn;<br>
-<br>
-   /* We don&#39;t own the function end.  */<br>
--  if (thread == 0)<br>
-+  if (ANY_RETURN_P (thread))<br>
-     return 0;<br>
-<br>
-   /* Get the first active insn, or THREAD, if it is an active insn.  */<br>
-@@ -2245,7 +2261,8 @@<br>
-         &amp;&amp; (!JUMP_P (insn)<br>
-             || ((condjump_p (insn) || condjump_in_parallel_p (insn))<br>
-                 &amp;&amp; ! simplejump_p (insn)<br>
--                &amp;&amp; JUMP_LABEL (insn) != 0)))<br>
-+                &amp;&amp; JUMP_LABEL (insn) != 0<br>
-+                &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (insn)))))<br>
-       {<br>
-         /* Invariant: If insn is a JUMP_INSN, the insn&#39;s jump<br>
-            label.  Otherwise, zero.  */<br>
-@@ -2270,7 +2287,7 @@<br>
-               target = JUMP_LABEL (insn);<br>
-           }<br>
-<br>
--        if (target == 0)<br>
-+        if (target == 0 || ANY_RETURN_P (target))<br>
-           for (trial = next_nonnote_insn (insn); trial; trial = next_trial)<br>
-             {<br>
-               next_trial = next_nonnote_insn (trial);<br>
-@@ -2349,6 +2366,7 @@<br>
-             &amp;&amp; JUMP_P (trial)<br>
-             &amp;&amp; simplejump_p (trial)<br>
-             &amp;&amp; (target == 0 || JUMP_LABEL (trial) == target)<br>
-+            &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (trial))<br>
-             &amp;&amp; (next_trial = next_active_insn (JUMP_LABEL (trial))) != 0<br>
-             &amp;&amp; ! (NONJUMP_INSN_P (next_trial)<br>
-                   &amp;&amp; GET_CODE (PATTERN (next_trial)) == SEQUENCE)<br>
-@@ -2371,7 +2389,7 @@<br>
-             if (new_label != 0)<br>
-               new_label = get_label_before (new_label);<br>
-             else<br>
--              new_label = find_end_label ();<br>
-+              new_label = find_end_label (simple_return_rtx);<br>
-<br>
-             if (new_label)<br>
-               {<br>
-@@ -2503,7 +2521,8 @@<br>
-<br>
- /* Follow any unconditional jump at LABEL;<br>
-    return the ultimate label reached by any such chain of jumps.<br>
--   Return null if the chain ultimately leads to a return instruction.<br>
-+   Return a suitable return rtx if the chain ultimately leads to a<br>
-+   return instruction.<br>
-    If LABEL is not followed by a jump, return LABEL.<br>
-    If the chain loops or we can&#39;t find end, return LABEL,<br>
-    since that tells caller to avoid changing the insn.  */<br>
-@@ -2518,6 +2537,7 @@<br>
-<br>
-   for (depth = 0;<br>
-        (depth &lt; 10<br>
-+      &amp;&amp; !ANY_RETURN_P (value)<br>
-       &amp;&amp; (insn = next_active_insn (value)) != 0<br>
-       &amp;&amp; JUMP_P (insn)<br>
-       &amp;&amp; ((JUMP_LABEL (insn) != 0 &amp;&amp; any_uncondjump_p (insn)<br>
-@@ -2527,18 +2547,22 @@<br>
-       &amp;&amp; BARRIER_P (next));<br>
-        depth++)<br>
-     {<br>
--      rtx tem;<br>
-+      rtx this_label = JUMP_LABEL (insn);<br>
-<br>
-       /* If we have found a cycle, make the insn jump to itself.  */<br>
--      if (JUMP_LABEL (insn) == label)<br>
-+      if (this_label == label)<br>
-       return label;<br>
-<br>
--      tem = next_active_insn (JUMP_LABEL (insn));<br>
--      if (tem &amp;&amp; (GET_CODE (PATTERN (tem)) == ADDR_VEC<br>
-+      if (!ANY_RETURN_P (this_label))<br>
-+      {<br>
-+        rtx tem = next_active_insn (this_label);<br>
-+        if (tem<br>
-+            &amp;&amp; (GET_CODE (PATTERN (tem)) == ADDR_VEC<br>
-                 || GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))<br>
--      break;<br>
-+          break;<br>
-+      }<br>
-<br>
--      value = JUMP_LABEL (insn);<br>
-+      value = this_label;<br>
-     }<br>
-   if (depth == 10)<br>
-     return label;<br>
-@@ -2901,6 +2925,7 @@<br>
-      arithmetic insn after the jump insn and put the arithmetic insn in the<br>
-      delay slot.  If we can&#39;t do this, return.  */<br>
-   if (delay_list == 0 &amp;&amp; likely &amp;&amp; new_thread<br>
-+      &amp;&amp; !ANY_RETURN_P (new_thread)<br>
-       &amp;&amp; NONJUMP_INSN_P (new_thread)<br>
-       &amp;&amp; GET_CODE (PATTERN (new_thread)) != ASM_INPUT<br>
-       &amp;&amp; asm_noperands (PATTERN (new_thread)) &lt; 0)<br>
-@@ -2985,16 +3010,14 @@<br>
-<br>
-       gcc_assert (thread_if_true);<br>
-<br>
--      if (new_thread &amp;&amp; JUMP_P (new_thread)<br>
--        &amp;&amp; (simplejump_p (new_thread)<br>
--            || GET_CODE (PATTERN (new_thread)) == RETURN)<br>
-+      if (new_thread &amp;&amp; simplejump_or_return_p (new_thread)<br>
-         &amp;&amp; redirect_with_delay_list_safe_p (insn,<br>
-                                             JUMP_LABEL (new_thread),<br>
-                                             delay_list))<br>
-       new_thread = follow_jumps (JUMP_LABEL (new_thread));<br>
-<br>
--      if (new_thread == 0)<br>
--      label = find_end_label ();<br>
-+      if (ANY_RETURN_P (new_thread))<br>
-+      label = find_end_label (new_thread);<br>
-       else if (LABEL_P (new_thread))<br>
-       label = new_thread;<br>
-       else<br>
-@@ -3340,11 +3363,12 @@<br>
-        group of consecutive labels.  */<br>
-       if (JUMP_P (insn)<br>
-         &amp;&amp; (condjump_p (insn) || condjump_in_parallel_p (insn))<br>
--        &amp;&amp; (target_label = JUMP_LABEL (insn)) != 0)<br>
-+        &amp;&amp; (target_label = JUMP_LABEL (insn)) != 0<br>
-+        &amp;&amp; !ANY_RETURN_P (target_label))<br>
-       {<br>
-         target_label = skip_consecutive_labels (follow_jumps (target_label));<br>
--        if (target_label == 0)<br>
--          target_label = find_end_label ();<br>
-+        if (ANY_RETURN_P (target_label))<br>
-+          target_label = find_end_label (target_label);<br>
-<br>
-         if (target_label &amp;&amp; next_active_insn (target_label) == next<br>
-             &amp;&amp; ! condjump_in_parallel_p (insn))<br>
-@@ -3359,9 +3383,8 @@<br>
-         /* See if this jump conditionally branches around an unconditional<br>
-            jump.  If so, invert this jump and point it to the target of the<br>
-            second jump.  */<br>
--        if (next &amp;&amp; JUMP_P (next)<br>
-+        if (next &amp;&amp; simplejump_or_return_p (next)<br>
-             &amp;&amp; any_condjump_p (insn)<br>
--            &amp;&amp; (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN)<br>
-             &amp;&amp; target_label<br>
-             &amp;&amp; next_active_insn (target_label) == next_active_insn (next)<br>
-             &amp;&amp; no_labels_between_p (insn, next))<br>
-@@ -3403,8 +3426,7 @@<br>
-        Don&#39;t do this if we expect the conditional branch to be true, because<br>
-        we would then be making the more common case longer.  */<br>
-<br>
--      if (JUMP_P (insn)<br>
--        &amp;&amp; (simplejump_p (insn) || GET_CODE (PATTERN (insn)) == RETURN)<br>
-+      if (simplejump_or_return_p (insn)<br>
-         &amp;&amp; (other = prev_active_insn (insn)) != 0<br>
-         &amp;&amp; any_condjump_p (other)<br>
-         &amp;&amp; no_labels_between_p (other, insn)<br>
-@@ -3445,10 +3467,10 @@<br>
-        Only do so if optimizing for size since this results in slower, but<br>
-        smaller code.  */<br>
-       if (optimize_function_for_size_p (cfun)<br>
--        &amp;&amp; GET_CODE (PATTERN (delay_insn)) == RETURN<br>
-+        &amp;&amp; ANY_RETURN_P (PATTERN (delay_insn))<br>
-         &amp;&amp; next<br>
-         &amp;&amp; JUMP_P (next)<br>
--        &amp;&amp; GET_CODE (PATTERN (next)) == RETURN)<br>
-+        &amp;&amp; PATTERN (next) == PATTERN (delay_insn))<br>
-       {<br>
-         rtx after;<br>
-         int i;<br>
-@@ -3487,14 +3509,16 @@<br>
-       continue;<br>
-<br>
-       target_label = JUMP_LABEL (delay_insn);<br>
-+      if (target_label &amp;&amp; ANY_RETURN_P (target_label))<br>
-+      continue;<br>
-<br>
-       if (target_label)<br>
-       {<br>
-         /* If this jump goes to another unconditional jump, thread it, but<br>
-            don&#39;t convert a jump into a RETURN here.  */<br>
-         trial = skip_consecutive_labels (follow_jumps (target_label));<br>
--        if (trial == 0)<br>
--          trial = find_end_label ();<br>
-+        if (ANY_RETURN_P (trial))<br>
-+          trial = find_end_label (trial);<br>
-<br>
-         if (trial &amp;&amp; trial != target_label<br>
-             &amp;&amp; redirect_with_delay_slots_safe_p (delay_insn, trial, insn))<br>
-@@ -3517,7 +3541,7 @@<br>
-                later incorrectly compute register live/death info.  */<br>
-             rtx tmp = next_active_insn (trial);<br>
-             if (tmp == 0)<br>
--              tmp = find_end_label ();<br>
-+              tmp = find_end_label (simple_return_rtx);<br>
-<br>
-             if (tmp)<br>
-               {<br>
-@@ -3537,14 +3561,12 @@<br>
-            delay list and that insn is redundant, thread the jump.  */<br>
-         if (trial &amp;&amp; GET_CODE (PATTERN (trial)) == SEQUENCE<br>
-             &amp;&amp; XVECLEN (PATTERN (trial), 0) == 2<br>
--            &amp;&amp; JUMP_P (XVECEXP (PATTERN (trial), 0, 0))<br>
--            &amp;&amp; (simplejump_p (XVECEXP (PATTERN (trial), 0, 0))<br>
--                || GET_CODE (PATTERN (XVECEXP (PATTERN (trial), 0, 0))) == RETURN)<br>
-+            &amp;&amp; simplejump_or_return_p (XVECEXP (PATTERN (trial), 0, 0))<br>
-             &amp;&amp; redundant_insn (XVECEXP (PATTERN (trial), 0, 1), insn, 0))<br>
-           {<br>
-             target_label = JUMP_LABEL (XVECEXP (PATTERN (trial), 0, 0));<br>
--            if (target_label == 0)<br>
--              target_label = find_end_label ();<br>
-+            if (ANY_RETURN_P (target_label))<br>
-+              target_label = find_end_label (target_label);<br>
-<br>
-             if (target_label<br>
-                 &amp;&amp; redirect_with_delay_slots_safe_p (delay_insn, target_label,<br>
-@@ -3622,16 +3644,15 @@<br>
-        a RETURN here.  */<br>
-       if (! INSN_ANNULLED_BRANCH_P (delay_insn)<br>
-         &amp;&amp; any_condjump_p (delay_insn)<br>
--        &amp;&amp; next &amp;&amp; JUMP_P (next)<br>
--        &amp;&amp; (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN)<br>
-+        &amp;&amp; next &amp;&amp; simplejump_or_return_p (next)<br>
-         &amp;&amp; next_active_insn (target_label) == next_active_insn (next)<br>
-         &amp;&amp; no_labels_between_p (insn, next))<br>
-       {<br>
-         rtx label = JUMP_LABEL (next);<br>
-         rtx old_label = JUMP_LABEL (delay_insn);<br>
-<br>
--        if (label == 0)<br>
--          label = find_end_label ();<br>
-+        if (ANY_RETURN_P (label))<br>
-+          label = find_end_label (label);<br>
-<br>
-         /* find_end_label can generate a new label. Check this first.  */<br>
-         if (label<br>
-@@ -3692,7 +3713,8 @@<br>
- make_return_insns (rtx first)<br>
- {<br>
-   rtx insn, jump_insn, pat;<br>
--  rtx real_return_label = end_of_function_label;<br>
-+  rtx real_return_label = function_return_label;<br>
-+  rtx real_simple_return_label = function_simple_return_label;<br>
-   int slots, i;<br>
-<br>
- #ifdef DELAY_SLOTS_FOR_EPILOGUE<br>
-@@ -3707,18 +3729,25 @@<br>
- #endif<br>
-<br>
-   /* See if there is a RETURN insn in the function other than the one we<br>
--     made for END_OF_FUNCTION_LABEL.  If so, set up anything we can&#39;t change<br>
-+     made for FUNCTION_RETURN_LABEL.  If so, set up anything we can&#39;t change<br>
-      into a RETURN to jump to it.  */<br>
-   for (insn = first; insn; insn = NEXT_INSN (insn))<br>
--    if (JUMP_P (insn) &amp;&amp; GET_CODE (PATTERN (insn)) == RETURN)<br>
-+    if (JUMP_P (insn) &amp;&amp; ANY_RETURN_P (PATTERN (insn)))<br>
-       {<br>
--      real_return_label = get_label_before (insn);<br>
-+      rtx t = get_label_before (insn);<br>
-+      if (PATTERN (insn) == ret_rtx)<br>
-+        real_return_label = t;<br>
-+      else<br>
-+        real_simple_return_label = t;<br>
-       break;<br>
-       }<br>
-<br>
-   /* Show an extra usage of REAL_RETURN_LABEL so it won&#39;t go away if it<br>
--     was equal to END_OF_FUNCTION_LABEL.  */<br>
--  LABEL_NUSES (real_return_label)++;<br>
-+     was equal to FUNCTION_RETURN_LABEL.  */<br>
-+  if (real_return_label)<br>
-+    LABEL_NUSES (real_return_label)++;<br>
-+  if (real_simple_return_label)<br>
-+    LABEL_NUSES (real_simple_return_label)++;<br>
-<br>
-   /* Clear the list of insns to fill so we can use it.  */<br>
-   obstack_free (&amp;unfilled_slots_obstack, unfilled_firstobj);<br>
-@@ -3726,13 +3755,27 @@<br>
-   for (insn = first; insn; insn = NEXT_INSN (insn))<br>
-     {<br>
-       int flags;<br>
-+      rtx kind, real_label;<br>
-<br>
-       /* Only look at filled JUMP_INSNs that go to the end of function<br>
-        label.  */<br>
-       if (!NONJUMP_INSN_P (insn)<br>
-         || GET_CODE (PATTERN (insn)) != SEQUENCE<br>
--        || !JUMP_P (XVECEXP (PATTERN (insn), 0, 0))<br>
--        || JUMP_LABEL (XVECEXP (PATTERN (insn), 0, 0)) != end_of_function_label)<br>
-+        || !JUMP_P (XVECEXP (PATTERN (insn), 0, 0)))<br>
-+      continue;<br>
-+<br>
-+      if (JUMP_LABEL (XVECEXP (PATTERN (insn), 0, 0)) == function_return_label)<br>
-+      {<br>
-+        kind = ret_rtx;<br>
-+        real_label = real_return_label;<br>
-+      }<br>
-+      else if (JUMP_LABEL (XVECEXP (PATTERN (insn), 0, 0))<br>
-+             == function_simple_return_label)<br>
-+      {<br>
-+        kind = simple_return_rtx;<br>
-+        real_label = real_simple_return_label;<br>
-+      }<br>
-+      else<br>
-       continue;<br>
-<br>
-       pat = PATTERN (insn);<br>
-@@ -3740,14 +3783,12 @@<br>
-<br>
-       /* If we can&#39;t make the jump into a RETURN, try to redirect it to the best<br>
-        RETURN and go on to the next insn.  */<br>
--      if (! reorg_redirect_jump (jump_insn, NULL_RTX))<br>
-+      if (! reorg_redirect_jump (jump_insn, kind))<br>
-       {<br>
-         /* Make sure redirecting the jump will not invalidate the delay<br>
-            slot insns.  */<br>
--        if (redirect_with_delay_slots_safe_p (jump_insn,<br>
--                                              real_return_label,<br>
--                                              insn))<br>
--          reorg_redirect_jump (jump_insn, real_return_label);<br>
-+        if (redirect_with_delay_slots_safe_p (jump_insn, real_label, insn))<br>
-+          reorg_redirect_jump (jump_insn, real_label);<br>
-         continue;<br>
-       }<br>
-<br>
-@@ -3787,7 +3828,7 @@<br>
-        RETURN, delete the SEQUENCE and output the individual insns,<br>
-        followed by the RETURN.  Then set things up so we try to find<br>
-        insns for its delay slots, if it needs some.  */<br>
--      if (GET_CODE (PATTERN (jump_insn)) == RETURN)<br>
-+      if (ANY_RETURN_P (PATTERN (jump_insn)))<br>
-       {<br>
-         rtx prev = PREV_INSN (insn);<br>
-<br>
-@@ -3804,13 +3845,16 @@<br>
-       else<br>
-       /* It is probably more efficient to keep this with its current<br>
-          delay slot as a branch to a RETURN.  */<br>
--      reorg_redirect_jump (jump_insn, real_return_label);<br>
-+      reorg_redirect_jump (jump_insn, real_label);<br>
-     }<br>
-<br>
-   /* Now delete REAL_RETURN_LABEL if we never used it.  Then try to fill any<br>
-      new delay slots we have created.  */<br>
--  if (--LABEL_NUSES (real_return_label) == 0)<br>
-+  if (real_return_label != NULL_RTX &amp;&amp; --LABEL_NUSES (real_return_label) == 0)<br>
-     delete_related_insns (real_return_label);<br>
-+  if (real_simple_return_label != NULL_RTX<br>
-+      &amp;&amp; --LABEL_NUSES (real_simple_return_label) == 0)<br>
-+    delete_related_insns (real_simple_return_label);<br>
-<br>
-   fill_simple_delay_slots (1);<br>
-   fill_simple_delay_slots (0);<br>
-@@ -3878,7 +3922,7 @@<br>
-   init_resource_info (epilogue_insn);<br>
-<br>
-   /* Show we haven&#39;t computed an end-of-function label yet.  */<br>
--  end_of_function_label = 0;<br>
-+  function_return_label = function_simple_return_label = NULL_RTX;<br>
-<br>
-   /* Initialize the statistics for this function.  */<br>
-   memset (num_insns_needing_delays, 0, sizeof num_insns_needing_delays);<br>
-@@ -3900,11 +3944,23 @@<br>
-   /* If we made an end of function label, indicate that it is now<br>
-      safe to delete it by undoing our prior adjustment to LABEL_NUSES.<br>
-      If it is now unused, delete it.  */<br>
--  if (end_of_function_label &amp;&amp; --LABEL_NUSES (end_of_function_label) == 0)<br>
--    delete_related_insns (end_of_function_label);<br>
-+  if (function_return_label &amp;&amp; --LABEL_NUSES (function_return_label) == 0)<br>
-+    delete_related_insns (function_return_label);<br>
-+  if (function_simple_return_label<br>
-+      &amp;&amp; --LABEL_NUSES (function_simple_return_label) == 0)<br>
-+    delete_related_insns (function_simple_return_label);<br>
-<br>
-+#if defined HAVE_return || defined HAVE_simple_return<br>
-+  if (<br>
- #ifdef HAVE_return<br>
--  if (HAVE_return &amp;&amp; end_of_function_label != 0)<br>
-+      (HAVE_return &amp;&amp; function_return_label != 0)<br>
-+#else<br>
-+      0<br>
-+#endif<br>
-+#ifdef HAVE_simple_return<br>
-+      || (HAVE_simple_return &amp;&amp; function_simple_return_label != 0)<br>
-+#endif<br>
-+      )<br>
-     make_return_insns (first);<br>
- #endif<br>
-<br>
-<br>
-=== modified file &#39;gcc/resource.c&#39;<br>
---- old/gcc/resource.c 2009-11-25 10:55:54 +0000<br>
-+++ new/gcc/resource.c 2011-01-05 12:12:18 +0000<br>
-@@ -495,6 +495,8 @@<br>
-                 || GET_CODE (PATTERN (this_jump_insn)) == RETURN)<br>
-               {<br>
-                 next = JUMP_LABEL (this_jump_insn);<br>
-+                if (next &amp;&amp; ANY_RETURN_P (next))<br>
-+                  next = NULL_RTX;<br>
-                 if (jump_insn == 0)<br>
-                   {<br>
-                     jump_insn = insn;<br>
-@@ -562,9 +564,10 @@<br>
-                 AND_COMPL_HARD_REG_SET (scratch, needed.regs);<br>
-                 AND_COMPL_HARD_REG_SET (fallthrough_res.regs, scratch);<br>
-<br>
--                find_dead_or_set_registers (JUMP_LABEL (this_jump_insn),<br>
--                                            &amp;target_res, 0, jump_count,<br>
--                                            target_set, needed);<br>
-+                if (!ANY_RETURN_P (JUMP_LABEL (this_jump_insn)))<br>
-+                  find_dead_or_set_registers (JUMP_LABEL (this_jump_insn),<br>
-+                                              &amp;target_res, 0, jump_count,<br>
-+                                              target_set, needed);<br>
-                 find_dead_or_set_registers (next,<br>
-                                             &amp;fallthrough_res, 0, jump_count,<br>
-                                             set, needed);<br>
-@@ -1097,6 +1100,8 @@<br>
-       struct resources new_resources;<br>
-       rtx stop_insn = next_active_insn (jump_insn);<br>
-<br>
-+      if (jump_target &amp;&amp; ANY_RETURN_P (jump_target))<br>
-+      jump_target = NULL_RTX;<br>
-       mark_target_live_regs (insns, next_active_insn (jump_target),<br>
-                            &amp;new_resources);<br>
-       CLEAR_RESOURCE (&amp;set);<br>
-<br>
-=== modified file &#39;gcc/rtl.c&#39;<br>
---- old/gcc/rtl.c      2010-12-13 10:05:52 +0000<br>
-+++ new/gcc/rtl.c      2011-01-05 12:12:18 +0000<br>
-@@ -256,6 +256,8 @@<br>
-     case CODE_LABEL:<br>
-     case PC:<br>
-     case CC0:<br>
-+    case RETURN:<br>
-+    case SIMPLE_RETURN:<br>
-     case SCRATCH:<br>
-       /* SCRATCH must be shared because they represent distinct values.  */<br>
-       return orig;<br>
-<br>
-=== modified file &#39;gcc/rtl.def&#39;<br>
---- old/gcc/rtl.def    2010-04-02 18:54:46 +0000<br>
-+++ new/gcc/rtl.def    2011-01-05 12:12:18 +0000<br>
-@@ -296,6 +296,10 @@<br>
-<br>
- DEF_RTL_EXPR(RETURN, &quot;return&quot;, &quot;&quot;, RTX_EXTRA)<br>
-<br>
-+/* A plain return, to be used on paths that are reached without going<br>
-+   through the function prologue.  */<br>
-+DEF_RTL_EXPR(SIMPLE_RETURN, &quot;simple_return&quot;, &quot;&quot;, RTX_EXTRA)<br>
-+<br>
- /* Special for EH return from subroutine.  */<br>
-<br>
- DEF_RTL_EXPR(EH_RETURN, &quot;eh_return&quot;, &quot;&quot;, RTX_EXTRA)<br>
-<br>
-=== modified file &#39;gcc/rtl.h&#39;<br>
---- old/gcc/rtl.h      2010-11-16 22:17:17 +0000<br>
-+++ new/gcc/rtl.h      2011-01-05 12:12:18 +0000<br>
-@@ -411,6 +411,10 @@<br>
-   (JUMP_P (INSN) &amp;&amp; (GET_CODE (PATTERN (INSN)) == ADDR_VEC || \<br>
-                    GET_CODE (PATTERN (INSN)) == ADDR_DIFF_VEC))<br>
-<br>
-+/* Predicate yielding nonzero iff X is a return or simple_preturn.  */<br>
-+#define ANY_RETURN_P(X) \<br>
-+  (GET_CODE (X) == RETURN || GET_CODE (X) == SIMPLE_RETURN)<br>
-+<br>
- /* 1 if X is a unary operator.  */<br>
-<br>
- #define UNARY_P(X)   \<br>
-@@ -1998,6 +2002,8 @@<br>
- {<br>
-   GR_PC,<br>
-   GR_CC0,<br>
-+  GR_RETURN,<br>
-+  GR_SIMPLE_RETURN,<br>
-   GR_STACK_POINTER,<br>
-   GR_FRAME_POINTER,<br>
- /* For register elimination to work properly these hard_frame_pointer_rtx,<br>
-@@ -2032,6 +2038,8 @@<br>
-<br>
- /* Standard pieces of rtx, to be substituted directly into things.  */<br>
- #define pc_rtx                  (global_rtl[GR_PC])<br>
-+#define ret_rtx                 (global_rtl[GR_RETURN])<br>
-+#define simple_return_rtx       (global_rtl[GR_SIMPLE_RETURN])<br>
- #define cc0_rtx                 (global_rtl[GR_CC0])<br>
-<br>
- /* All references to certain hard regs, except those created<br>
-<br>
-=== modified file &#39;gcc/rtlanal.c&#39;<br>
---- old/gcc/rtlanal.c  2010-11-16 22:17:17 +0000<br>
-+++ new/gcc/rtlanal.c  2011-01-05 12:12:18 +0000<br>
-@@ -2673,6 +2673,7 @@<br>
-<br>
-   if (JUMP_P (insn)<br>
-       &amp;&amp; (label = JUMP_LABEL (insn)) != NULL_RTX<br>
-+      &amp;&amp; !ANY_RETURN_P (label)<br>
-       &amp;&amp; (table = next_active_insn (label)) != NULL_RTX<br>
-       &amp;&amp; JUMP_TABLE_DATA_P (table))<br>
-     {<br>
-<br>
-=== modified file &#39;gcc/sched-int.h&#39;<br>
---- old/gcc/sched-int.h        2010-06-02 16:31:39 +0000<br>
-+++ new/gcc/sched-int.h        2011-01-05 12:12:18 +0000<br>
-@@ -199,7 +199,7 @@<br>
-<br>
- extern void ebb_compute_jump_reg_dependencies (rtx, regset, regset, regset);<br>
-<br>
--extern edge find_fallthru_edge (basic_block);<br>
-+extern edge find_fallthru_edge_from (basic_block);<br>
-<br>
- extern void (* sched_init_only_bb) (basic_block, basic_block);<br>
- extern basic_block (* sched_split_block) (basic_block, rtx);<br>
-<br>
-=== modified file &#39;gcc/sched-vis.c&#39;<br>
---- old/gcc/sched-vis.c        2009-11-25 10:55:54 +0000<br>
-+++ new/gcc/sched-vis.c        2011-01-05 12:12:18 +0000<br>
-@@ -549,6 +549,9 @@<br>
-     case RETURN:<br>
-       sprintf (buf, &quot;return&quot;);<br>
-       break;<br>
-+    case SIMPLE_RETURN:<br>
-+      sprintf (buf, &quot;simple_return&quot;);<br>
-+      break;<br>
-     case CALL:<br>
-       print_exp (buf, x, verbose);<br>
-       break;<br>
-<br>
-=== modified file &#39;gcc/sel-sched-ir.c&#39;<br>
---- old/gcc/sel-sched-ir.c     2010-08-31 11:52:01 +0000<br>
-+++ new/gcc/sel-sched-ir.c     2011-01-05 12:12:18 +0000<br>
-@@ -686,7 +686,7 @@<br>
-<br>
-       /* Find fallthrough edge.  */<br>
-       gcc_assert (BLOCK_FOR_INSN (insn)-&gt;prev_bb);<br>
--      candidate = find_fallthru_edge (BLOCK_FOR_INSN (insn)-&gt;prev_bb);<br>
-+      candidate = find_fallthru_edge_from (BLOCK_FOR_INSN (insn)-&gt;prev_bb);<br>
-<br>
-       if (!candidate<br>
-           || (candidate-&gt;src != BLOCK_FOR_INSN (last_scheduled_insn)<br>
-<br>
-=== modified file &#39;gcc/sel-sched.c&#39;<br>
---- old/gcc/sel-sched.c        2010-11-12 15:47:38 +0000<br>
-+++ new/gcc/sel-sched.c        2011-01-05 12:12:18 +0000<br>
-@@ -617,8 +617,8 @@<br>
-   if (bb == BLOCK_FOR_INSN (succ))<br>
-     return true;<br>
-<br>
--  if (find_fallthru_edge (bb))<br>
--    bb = find_fallthru_edge (bb)-&gt;dest;<br>
-+  if (find_fallthru_edge_from (bb))<br>
-+    bb = find_fallthru_edge_from (bb)-&gt;dest;<br>
-   else<br>
-     return false;<br>
-<br>
-@@ -4911,7 +4911,7 @@<br>
-   next = PREV_INSN (insn);<br>
-   BND_TO (bnd) = insn;<br>
-<br>
--  ft_edge = find_fallthru_edge (block_from);<br>
-+  ft_edge = find_fallthru_edge_from (block_from);<br>
-   block_next = ft_edge-&gt;dest;<br>
-   /* There must be a fallthrough block (or where should go<br>
-   control flow in case of false jump predicate otherwise?).  */<br>
-<br>
-=== modified file &#39;gcc/vec.h&#39;<br>
---- old/gcc/vec.h      2010-01-09 14:46:25 +0000<br>
-+++ new/gcc/vec.h      2011-01-05 12:12:18 +0000<br>
-@@ -188,6 +188,18 @@<br>
-<br>
- #define VEC_iterate(T,V,I,P)  (VEC_OP(T,base,iterate)(VEC_BASE(V),I,&amp;(P)))<br>
-<br>
-+/* Convenience macro for forward iteration.  */<br>
-+<br>
-+#define FOR_EACH_VEC_ELT(T, V, I, P)          \<br>
-+  for (I = 0; VEC_iterate (T, (V), (I), (P)); ++(I))<br>
-+<br>
-+/* Convenience macro for reverse iteration.  */<br>
-+<br>
-+#define FOR_EACH_VEC_ELT_REVERSE(T,V,I,P) \<br>
-+  for (I = VEC_length (T, (V)) - 1;           \<br>
-+       VEC_iterate (T, (V), (I), (P));          \<br>
-+       (I)--)<br>
-+<br>
- /* Allocate new vector.<br>
-    VEC(T,A) *VEC_T_A_alloc(int reserve);<br>
-<br>
-<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99457.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99457.patch<br>
deleted file mode 100644<br>
index 47b897d..0000000<br>
--- a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99457.patch<br>
+++ /dev/null<br>
@@ -1,4236 +0,0 @@<br>
-2010-12-03  Yao Qi  &lt;<a href="mailto:yao@codesourcery.com">yao@codesourcery.com</a>&gt;<br>
-<br>
-       * config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>: Rewrite ldm/stm RTL patterns to fix<br>
-       regressions.<br>
-       * config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>: Regenreate.<br>
-<br>
-2010-12-03  Yao Qi  &lt;<a href="mailto:yao@codesourcery.com">yao@codesourcery.com</a>&gt;<br>
-<br>
-       Backport from FSF mainline:<br>
-<br>
-       2010-08-02  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
-<br>
-       PR target/40457<br>
-       * config/arm/arm.h (arm_regs_in_sequence): Declare.<br>
-       * config/arm/arm-protos.h (emit_ldm_seq, emit_stm_seq,<br>
-       load_multiple_sequence, store_multiple_sequence): Delete<br>
-       declarations.<br>
-       (arm_gen_load_multiple, arm_gen_store_multiple): Adjust<br>
-       declarations.<br>
-       * config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>: New file.<br>
-       * config/arm/arm.c (arm_regs_in_sequence): New array.<br>
-       (load_multiple_sequence): Now static.  New args SAVED_ORDER,<br>
-       CHECK_REGS.  All callers changed.<br>
-       If SAVED_ORDER is nonnull, copy the computed order into it.<br>
-       If CHECK_REGS is false, don&#39;t sort REGS.  Handle Thumb mode.<br>
-       (store_multiple_sequence): Now static.  New args NOPS_TOTAL,<br>
-       SAVED_ORDER, REG_RTXS and CHECK_REGS.  All callers changed.<br>
-       If SAVED_ORDER is nonnull, copy the computed order into it.<br>
-       If CHECK_REGS is false, don&#39;t sort REGS.  Set up REG_RTXS just<br>
-       like REGS.  Handle Thumb mode.<br>
-       (arm_gen_load_multiple_1): New function, broken out of<br>
-       arm_gen_load_multiple.<br>
-       (arm_gen_store_multiple_1): New function, broken out of<br>
-       arm_gen_store_multiple.<br>
-       (arm_gen_multiple_op): New function, with code from<br>
-       arm_gen_load_multiple and arm_gen_store_multiple moved here.<br>
-       (arm_gen_load_multiple, arm_gen_store_multiple): Now just<br>
-       wrappers around arm_gen_multiple_op.  Remove argument UP, all callers<br>
-       changed.<br>
-       (gen_ldm_seq, gen_stm_seq, gen_const_stm_seq): New functions.<br>
-       * config/arm/<a href="http://predicates.md" target="_blank">predicates.md</a> (commutative_binary_operator): New.<br>
-       (load_multiple_operation, store_multiple_operation): Handle more<br>
-       variants of these patterns with different starting offsets.  Handle<br>
-       Thumb-1.<br>
-       * config/arm/<a href="http://arm.md" target="_blank">arm.md</a>: Include &quot;<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>&quot;.<br>
-       (ldmsi_postinc4, ldmsi_postinc4_thumb1, ldmsi_postinc3, ldmsi_postinc2,<br>
-       ldmsi4, ldmsi3, ldmsi2, stmsi_postinc4, stmsi_postinc4_thumb1,<br>
-       stmsi_postinc3, stmsi_postinc2, stmsi4, stmsi3, stmsi2 and related<br>
-       peepholes): Delete.<br>
-       * config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>: New file.<br>
-       * config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>: New file.<br>
-<br>
-       * config/arm/arm.c (arm_rtx_costs_1): Remove second clause from the<br>
-       if statement which adds extra costs to frame-related expressions.<br>
-<br>
-       2010-05-06  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
-<br>
-       * config/arm/arm.h (MAX_LDM_STM_OPS): New macro.<br>
-       * config/arm/arm.c (multiple_operation_profitable_p,<br>
-       compute_offset_order): New static functions.<br>
-       (load_multiple_sequence, store_multiple_sequence): Use them.<br>
-       Replace constant 4 with MAX_LDM_STM_OPS.  Compute order[0] from<br>
-       memory offsets, not register numbers.<br>
-       (emit_ldm_seq, emit_stm_seq): Replace constant 4 with MAX_LDM_STM_OPS.<br>
-<br>
-       2010-04-16  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
-<br>
-       * recog.h (struct recog_data): New field is_operator.<br>
-       (struct insn_operand_data): New field is_operator.<br>
-       * recog.c (extract_insn): Set recog_data.is_operator.<br>
-       * genoutput.c (output_operand_data): Emit code to set the<br>
-       is_operator field.<br>
-       * reload.c (find_reloads): Use it rather than testing for an<br>
-       empty constraint string.<br>
-<br>
-=== added file &#39;gcc/config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>&#39;<br>
---- old/gcc/config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>   1970-01-01 00:00:00 +0000<br>
-+++ new/gcc/config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>   2010-11-16 13:08:47 +0000<br>
-@@ -0,0 +1,333 @@<br>
-+(* Auto-generate ARM ldm/stm patterns<br>
-+   Copyright (C) 2010 Free Software Foundation, Inc.<br>
-+   Contributed by CodeSourcery.<br>
-+<br>
-+   This file is part of GCC.<br>
-+<br>
-+   GCC is free software; you can redistribute it and/or modify it under<br>
-+   the terms of the GNU General Public License as published by the Free<br>
-+   Software Foundation; either version 3, or (at your option) any later<br>
-+   version.<br>
-+<br>
-+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY<br>
-+   WARRANTY; without even the implied warranty of MERCHANTABILITY or<br>
-+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License<br>
-+   for more details.<br>
-+<br>
-+   You should have received a copy of the GNU General Public License<br>
-+   along with GCC; see the file COPYING3.  If not see<br>
-+   &lt;<a href="http://www.gnu.org/licenses/" target="_blank">http://www.gnu.org/licenses/</a>&gt;.<br>
-+<br>
-+   This is an O&#39;Caml program.  The O&#39;Caml compiler is available from:<br>
-+<br>
-+     <a href="http://caml.inria.fr/" target="_blank">http://caml.inria.fr/</a><br>
-+<br>
-+   Or from your favourite OS&#39;s friendly packaging system. Tested with version<br>
-+   3.09.2, though other versions will probably work too.<br>
-+<br>
-+   Run with:<br>
-+     ocaml <a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a> &gt;/path/to/gcc/config/arm/<a href="http://ldmstm.ml" target="_blank">ldmstm.ml</a><br>
-+*)<br>
-+<br>
-+type amode = IA | IB | DA | DB<br>
-+<br>
-+type optype = IN | OUT | INOUT<br>
-+<br>
-+let rec string_of_addrmode addrmode =<br>
-+  match addrmode with<br>
-+    IA -&gt; &quot;ia&quot; | IB -&gt; &quot;ib&quot; | DA -&gt; &quot;da&quot; | DB -&gt; &quot;db&quot;<br>
-+<br>
-+let rec initial_offset addrmode nregs =<br>
-+  match addrmode with<br>
-+    IA -&gt; 0<br>
-+  | IB -&gt; 4<br>
-+  | DA -&gt; -4 * nregs + 4<br>
-+  | DB -&gt; -4 * nregs<br>
-+<br>
-+let rec final_offset addrmode nregs =<br>
-+  match addrmode with<br>
-+    IA -&gt; nregs * 4<br>
-+  | IB -&gt; nregs * 4<br>
-+  | DA -&gt; -4 * nregs<br>
-+  | DB -&gt; -4 * nregs<br>
-+<br>
-+let constr thumb =<br>
-+  if thumb then &quot;l&quot; else &quot;rk&quot;<br>
-+<br>
-+let inout_constr op_type =<br>
-+  match op_type with<br>
-+  OUT -&gt; &quot;=&quot;<br>
-+  | INOUT -&gt; &quot;+&amp;&quot;<br>
-+  | IN -&gt; &quot;&quot;<br>
-+<br>
-+let destreg nregs first op_type thumb =<br>
-+  if not first then<br>
-+    Printf.sprintf &quot;(match_dup %d)&quot; (nregs)<br>
-+  else<br>
-+    Printf.sprintf (&quot;(match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;%s%s\&quot;)&quot;)<br>
-+    (nregs) (inout_constr op_type) (constr thumb)<br>
-+<br>
-+let write_ldm_set thumb nregs offset opnr first =<br>
-+  let indent = &quot;     &quot; in<br>
-+  Printf.printf &quot;%s&quot; (if first then &quot;    [&quot; else indent);<br>
-+  Printf.printf &quot;(set (match_operand:SI %d \&quot;arm_hard_register_operand\&quot; \&quot;\&quot;)\n&quot; opnr;<br>
-+  Printf.printf &quot;%s     (mem:SI &quot; indent;<br>
-+  begin if offset != 0 then Printf.printf &quot;(plus:SI &quot; end;<br>
-+  Printf.printf &quot;%s&quot; (destreg nregs first IN thumb);<br>
-+  begin if offset != 0 then Printf.printf &quot;\n%s             (const_int %d))&quot; indent offset end;<br>
-+  Printf.printf &quot;))&quot;<br>
-+<br>
-+let write_stm_set thumb nregs offset opnr first =<br>
-+  let indent = &quot;     &quot; in<br>
-+  Printf.printf &quot;%s&quot; (if first then &quot;    [&quot; else indent);<br>
-+  Printf.printf &quot;(set (mem:SI &quot;;<br>
-+  begin if offset != 0 then Printf.printf &quot;(plus:SI &quot; end;<br>
-+  Printf.printf &quot;%s&quot; (destreg nregs first IN thumb);<br>
-+  begin if offset != 0 then Printf.printf &quot; (const_int %d))&quot; offset end;<br>
-+  Printf.printf &quot;)\n%s     (match_operand:SI %d \&quot;arm_hard_register_operand\&quot; \&quot;\&quot;))&quot; indent opnr<br>
-+<br>
-+let write_ldm_peep_set extra_indent nregs opnr first =<br>
-+  let indent = &quot;   &quot; ^ extra_indent in<br>
-+  Printf.printf &quot;%s&quot; (if first then extra_indent ^ &quot;  [&quot; else indent);<br>
-+  Printf.printf &quot;(set (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; opnr;<br>
-+  Printf.printf &quot;%s     (match_operand:SI %d \&quot;memory_operand\&quot; \&quot;\&quot;))&quot; indent (nregs + opnr)<br>
-+<br>
-+let write_stm_peep_set extra_indent nregs opnr first =<br>
-+  let indent = &quot;   &quot; ^ extra_indent in<br>
-+  Printf.printf &quot;%s&quot; (if first then extra_indent ^ &quot;  [&quot; else indent);<br>
-+  Printf.printf &quot;(set (match_operand:SI %d \&quot;memory_operand\&quot; \&quot;\&quot;)\n&quot; (nregs + opnr);<br>
-+  Printf.printf &quot;%s     (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;))&quot; indent opnr<br>
-+<br>
-+let write_any_load optype nregs opnr first =<br>
-+  let indent = &quot;   &quot; in<br>
-+  Printf.printf &quot;%s&quot; (if first then &quot;  [&quot; else indent);<br>
-+  Printf.printf &quot;(set (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; opnr;<br>
-+  Printf.printf &quot;%s     (match_operand:SI %d \&quot;%s\&quot; \&quot;\&quot;))&quot; indent (nregs * 2 + opnr) optype<br>
-+<br>
-+let write_const_store nregs opnr first =<br>
-+  let indent = &quot;   &quot; in<br>
-+  Printf.printf &quot;%s(set (match_operand:SI %d \&quot;memory_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs + opnr);<br>
-+  Printf.printf &quot;%s     (match_dup %d))&quot; indent opnr<br>
-+<br>
-+let write_const_stm_peep_set nregs opnr first =<br>
-+  write_any_load &quot;const_int_operand&quot; nregs opnr first;<br>
-+  Printf.printf &quot;\n&quot;;<br>
-+  write_const_store nregs opnr false<br>
-+<br>
-+<br>
-+let rec write_pat_sets func opnr offset first n_left =<br>
-+  func offset opnr first;<br>
-+  begin<br>
-+    if n_left &gt; 1 then begin<br>
-+      Printf.printf &quot;\n&quot;;<br>
-+      write_pat_sets func (opnr + 1) (offset + 4) false (n_left - 1);<br>
-+    end else<br>
-+      Printf.printf &quot;]&quot;<br>
-+  end<br>
-+<br>
-+let rec write_peep_sets func opnr first n_left =<br>
-+  func opnr first;<br>
-+  begin<br>
-+    if n_left &gt; 1 then begin<br>
-+      Printf.printf &quot;\n&quot;;<br>
-+      write_peep_sets func (opnr + 1) false (n_left - 1);<br>
-+    end<br>
-+  end<br>
-+<br>
-+let can_thumb addrmode update is_store =<br>
-+  match addrmode, update, is_store with<br>
-+    (* Thumb1 mode only supports IA with update.  However, for LDMIA,<br>
-+       if the address register also appears in the list of loaded<br>
-+       registers, the loaded value is stored, hence the RTL pattern<br>
-+       to describe such an insn does not have an update.  We check<br>
-+       in the match_parallel predicate that the condition described<br>
-+       above is met.  *)<br>
-+    IA, _, false -&gt; true<br>
-+  | IA, true, true -&gt; true<br>
-+  | _ -&gt; false<br>
-+<br>
-+let target addrmode thumb =<br>
-+  match addrmode, thumb with<br>
-+    IA, true -&gt; &quot;TARGET_THUMB1&quot;<br>
-+  | IA, false -&gt; &quot;TARGET_32BIT&quot;<br>
-+  | DB, false -&gt; &quot;TARGET_32BIT&quot;<br>
-+  | _, false -&gt; &quot;TARGET_ARM&quot;<br>
-+<br>
-+let write_pattern_1 name ls addrmode nregs write_set_fn update thumb =<br>
-+  let astr = string_of_addrmode addrmode in<br>
-+  Printf.printf &quot;(define_insn \&quot;*%s%s%d_%s%s\&quot;\n&quot;<br>
-+    (if thumb then &quot;thumb_&quot; else &quot;&quot;) name nregs astr<br>
-+    (if update then &quot;_update&quot; else &quot;&quot;);<br>
-+  Printf.printf &quot;  [(match_parallel 0 \&quot;%s_multiple_operation\&quot;\n&quot; ls;<br>
-+  begin<br>
-+    if update then begin<br>
-+      Printf.printf &quot;    [(set %s\n          (plus:SI &quot;<br>
-+      (destreg 1 true OUT thumb); (*destreg 2 true IN thumb*)<br>
-+      Printf.printf &quot;(match_operand:SI 2 \&quot;s_register_operand\&quot; \&quot;1\&quot;)&quot;;<br>
-+      Printf.printf &quot; (const_int %d)))\n&quot;<br>
-+      (final_offset addrmode nregs)<br>
-+    end<br>
-+  end;<br>
-+  write_pat_sets<br>
-+    (write_set_fn thumb (if update then 2 else 1)) (if update then 3 else 2)<br>
-+    (initial_offset addrmode nregs)<br>
-+    (not update) nregs;<br>
-+  Printf.printf &quot;)]\n  \&quot;%s &amp;&amp; XVECLEN (operands[0], 0) == %d\&quot;\n&quot;<br>
-+    (target addrmode thumb)<br>
-+    (if update then nregs + 1 else nregs);<br>
-+  Printf.printf &quot;  \&quot;%s%%(%s%%)\\t%%%d%s, {&quot;<br>
-+    name astr (1) (if update then &quot;!&quot; else &quot;&quot;);<br>
-+  for n = 1 to nregs; do<br>
-+    Printf.printf &quot;%%%d%s&quot; (n+(if update then 2 else 1)) (if n &lt; nregs then &quot;, &quot; else &quot;&quot;)<br>
-+  done;<br>
-+  Printf.printf &quot;}\&quot;\n&quot;;<br>
-+  Printf.printf &quot;  [(set_attr \&quot;type\&quot; \&quot;%s%d\&quot;)&quot; ls nregs;<br>
-+  begin if not thumb then<br>
-+    Printf.printf &quot;\n   (set_attr \&quot;predicable\&quot; \&quot;yes\&quot;)&quot;;<br>
-+  end;<br>
-+  Printf.printf &quot;])\n\n&quot;<br>
-+<br>
-+let write_ldm_pattern addrmode nregs update =<br>
-+  write_pattern_1 &quot;ldm&quot; &quot;load&quot; addrmode nregs write_ldm_set update false;<br>
-+  begin if can_thumb addrmode update false then<br>
-+    write_pattern_1 &quot;ldm&quot; &quot;load&quot; addrmode nregs write_ldm_set update true;<br>
-+  end<br>
-+<br>
-+let write_stm_pattern addrmode nregs update =<br>
-+  write_pattern_1 &quot;stm&quot; &quot;store&quot; addrmode nregs write_stm_set update false;<br>
-+  begin if can_thumb addrmode update true then<br>
-+    write_pattern_1 &quot;stm&quot; &quot;store&quot; addrmode nregs write_stm_set update true;<br>
-+  end<br>
-+<br>
-+let write_ldm_commutative_peephole thumb =<br>
-+  let nregs = 2 in<br>
-+  Printf.printf &quot;(define_peephole2\n&quot;;<br>
-+  write_peep_sets (write_ldm_peep_set &quot;&quot; nregs) 0 true nregs;<br>
-+  let indent = &quot;   &quot; in<br>
-+  if thumb then begin<br>
-+    Printf.printf &quot;\n%s(set (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs * 2);<br>
-+    Printf.printf &quot;%s     (match_operator:SI %d \&quot;commutative_binary_operator\&quot;\n&quot; indent (nregs * 2 + 1);<br>
-+    Printf.printf &quot;%s      [(match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs * 2 + 2);<br>
-+    Printf.printf &quot;%s       (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)]))]\n&quot; indent (nregs * 2 + 3)<br>
-+  end else begin<br>
-+    Printf.printf &quot;\n%s(parallel\n&quot; indent;<br>
-+    Printf.printf &quot;%s  [(set (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs * 2);<br>
-+    Printf.printf &quot;%s        (match_operator:SI %d \&quot;commutative_binary_operator\&quot;\n&quot; indent (nregs * 2 + 1);<br>
-+    Printf.printf &quot;%s         [(match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs * 2 + 2);<br>
-+    Printf.printf &quot;%s          (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)]))\n&quot; indent (nregs * 2 + 3);<br>
-+    Printf.printf &quot;%s   (clobber (reg:CC CC_REGNUM))])]\n&quot; indent<br>
-+  end;<br>
-+  Printf.printf &quot;  \&quot;(((operands[%d] == operands[0] &amp;&amp; operands[%d] == operands[1])\n&quot; (nregs * 2 + 2) (nregs * 2 + 3);<br>
-+  Printf.printf &quot;     || (operands[%d] == operands[0] &amp;&amp; operands[%d] == operands[1]))\n&quot; (nregs * 2 + 3) (nregs * 2 + 2);<br>
-+  Printf.printf &quot;    &amp;&amp; peep2_reg_dead_p (%d, operands[0]) &amp;&amp; peep2_reg_dead_p (%d, operands[1]))\&quot;\n&quot; (nregs + 1) (nregs + 1);<br>
-+  begin<br>
-+    if thumb then<br>
-+      Printf.printf &quot;  [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))]\n&quot;<br>
-+      (nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3)<br>
-+    else begin<br>
-+      Printf.printf &quot;  [(parallel\n&quot;;<br>
-+      Printf.printf &quot;    [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))\n&quot;<br>
-+      (nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3);<br>
-+      Printf.printf &quot;     (clobber (reg:CC CC_REGNUM))])]\n&quot;<br>
-+    end<br>
-+  end;<br>
-+  Printf.printf &quot;{\n  if (!gen_ldm_seq (operands, %d, true))\n    FAIL;\n&quot; nregs;<br>
-+  Printf.printf &quot;})\n\n&quot;<br>
-+<br>
-+let write_ldm_peephole nregs =<br>
-+  Printf.printf &quot;(define_peephole2\n&quot;;<br>
-+  write_peep_sets (write_ldm_peep_set &quot;&quot; nregs) 0 true nregs;<br>
-+  Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
-+  Printf.printf &quot;  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
-+<br>
-+let write_ldm_peephole_b nregs =<br>
-+  if nregs &gt; 2 then begin<br>
-+    Printf.printf &quot;(define_peephole2\n&quot;;<br>
-+    write_ldm_peep_set &quot;&quot; nregs 0 true;<br>
-+    Printf.printf &quot;\n   (parallel\n&quot;;<br>
-+    write_peep_sets (write_ldm_peep_set &quot;  &quot; nregs) 1 true (nregs - 1);<br>
-+    Printf.printf &quot;])]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
-+    Printf.printf &quot;  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
-+  end<br>
-+<br>
-+let write_stm_peephole nregs =<br>
-+  Printf.printf &quot;(define_peephole2\n&quot;;<br>
-+  write_peep_sets (write_stm_peep_set &quot;&quot; nregs) 0 true nregs;<br>
-+  Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
-+  Printf.printf &quot;  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
-+<br>
-+let write_stm_peephole_b nregs =<br>
-+  if nregs &gt; 2 then begin<br>
-+    Printf.printf &quot;(define_peephole2\n&quot;;<br>
-+    write_stm_peep_set &quot;&quot; nregs 0 true;<br>
-+    Printf.printf &quot;\n   (parallel\n&quot;;<br>
-+    write_peep_sets (write_stm_peep_set &quot;&quot; nregs) 1 true (nregs - 1);<br>
-+    Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
-+    Printf.printf &quot;  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
-+  end<br>
-+<br>
-+let write_const_stm_peephole_a nregs =<br>
-+  Printf.printf &quot;(define_peephole2\n&quot;;<br>
-+  write_peep_sets (write_const_stm_peep_set nregs) 0 true nregs;<br>
-+  Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
-+  Printf.printf &quot;  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
-+<br>
-+let write_const_stm_peephole_b nregs =<br>
-+  Printf.printf &quot;(define_peephole2\n&quot;;<br>
-+  write_peep_sets (write_any_load &quot;const_int_operand&quot; nregs) 0 true nregs;<br>
-+  Printf.printf &quot;\n&quot;;<br>
-+  write_peep_sets (write_const_store nregs) 0 false nregs;<br>
-+  Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
-+  Printf.printf &quot;  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
-+<br>
-+let patterns () =<br>
-+  let addrmodes = [ IA; IB; DA; DB ]  in<br>
-+  let sizes = [ 4; 3; 2] in<br>
-+  List.iter<br>
-+    (fun n -&gt;<br>
-+      List.iter<br>
-+      (fun addrmode -&gt;<br>
-+        write_ldm_pattern addrmode n false;<br>
-+        write_ldm_pattern addrmode n true;<br>
-+        write_stm_pattern addrmode n false;<br>
-+        write_stm_pattern addrmode n true)<br>
-+      addrmodes;<br>
-+      write_ldm_peephole n;<br>
-+      write_ldm_peephole_b n;<br>
-+      write_const_stm_peephole_a n;<br>
-+      write_const_stm_peephole_b n;<br>
-+      write_stm_peephole n;)<br>
-+    sizes;<br>
-+  write_ldm_commutative_peephole false;<br>
-+  write_ldm_commutative_peephole true<br>
-+<br>
-+let print_lines = List.iter (fun s -&gt; Format.printf &quot;%s@\n&quot; s)<br>
-+<br>
-+(* Do it.  *)<br>
-+<br>
-+let _ =<br>
-+  print_lines [<br>
-+&quot;/* ARM ldm/stm instruction patterns.  This file was automatically generated&quot;;<br>
-+&quot;   using <a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>.  Please do not edit manually.&quot;;<br>
-+&quot;&quot;;<br>
-+&quot;   Copyright (C) 2010 Free Software Foundation, Inc.&quot;;<br>
-+&quot;   Contributed by CodeSourcery.&quot;;<br>
-+&quot;&quot;;<br>
-+&quot;   This file is part of GCC.&quot;;<br>
-+&quot;&quot;;<br>
-+&quot;   GCC is free software; you can redistribute it and/or modify it&quot;;<br>
-+&quot;   under the terms of the GNU General Public License as published&quot;;<br>
-+&quot;   by the Free Software Foundation; either version 3, or (at your&quot;;<br>
-+&quot;   option) any later version.&quot;;<br>
-+&quot;&quot;;<br>
-+&quot;   GCC is distributed in the hope that it will be useful, but WITHOUT&quot;;<br>
-+&quot;   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY&quot;;<br>
-+&quot;   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public&quot;;<br>
-+&quot;   License for more details.&quot;;<br>
-+&quot;&quot;;<br>
-+&quot;   You should have received a copy of the GNU General Public License and&quot;;<br>
-+&quot;   a copy of the GCC Runtime Library Exception along with this program;&quot;;<br>
-+&quot;   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see&quot;;<br>
-+&quot;   &lt;<a href="http://www.gnu.org/licenses/" target="_blank">http://www.gnu.org/licenses/</a>&gt;.  */&quot;;<br>
-+&quot;&quot;];<br>
-+  patterns ();<br>
-<br>
-=== modified file &#39;gcc/config/arm/arm-protos.h&#39;<br>
---- old/gcc/config/arm/arm-protos.h    2011-01-05 12:12:18 +0000<br>
-+++ new/gcc/config/arm/arm-protos.h    2011-01-05 18:20:37 +0000<br>
-@@ -100,14 +100,11 @@<br>
- extern int label_mentioned_p (rtx);<br>
- extern RTX_CODE minmax_code (rtx);<br>
- extern int adjacent_mem_locations (rtx, rtx);<br>
--extern int load_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);<br>
--extern const char *emit_ldm_seq (rtx *, int);<br>
--extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);<br>
--extern const char * emit_stm_seq (rtx *, int);<br>
--extern rtx arm_gen_load_multiple (int, int, rtx, int, int,<br>
--                                rtx, HOST_WIDE_INT *);<br>
--extern rtx arm_gen_store_multiple (int, int, rtx, int, int,<br>
--                                 rtx, HOST_WIDE_INT *);<br>
-+extern bool gen_ldm_seq (rtx *, int, bool);<br>
-+extern bool gen_stm_seq (rtx *, int);<br>
-+extern bool gen_const_stm_seq (rtx *, int);<br>
-+extern rtx arm_gen_load_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *);<br>
-+extern rtx arm_gen_store_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *);<br>
- extern int arm_gen_movmemqi (rtx *);<br>
- extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);<br>
- extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx,<br>
-<br>
-=== modified file &#39;gcc/config/arm/arm.c&#39;<br>
---- old/gcc/config/arm/arm.c   2011-01-05 12:12:18 +0000<br>
-+++ new/gcc/config/arm/arm.c   2011-01-05 18:20:37 +0000<br>
-@@ -753,6 +753,12 @@<br>
-   &quot;hi&quot;, &quot;ls&quot;, &quot;ge&quot;, &quot;lt&quot;, &quot;gt&quot;, &quot;le&quot;, &quot;al&quot;, &quot;nv&quot;<br>
- };<br>
-<br>
-+/* The register numbers in sequence, for passing to arm_gen_load_multiple.  */<br>
-+int arm_regs_in_sequence[] =<br>
-+{<br>
-+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15<br>
-+};<br>
-+<br>
- #define ARM_LSL_NAME (TARGET_UNIFIED_ASM ? &quot;lsl&quot; : &quot;asl&quot;)<br>
- #define streq(string1, string2) (strcmp (string1, string2) == 0)<br>
-<br>
-@@ -9680,142 +9686,16 @@<br>
-   return 0;<br>
- }<br>
-<br>
--int<br>
--load_multiple_sequence (rtx *operands, int nops, int *regs, int *base,<br>
--                      HOST_WIDE_INT *load_offset)<br>
--{<br>
--  int unsorted_regs[4];<br>
--  HOST_WIDE_INT unsorted_offsets[4];<br>
--  int order[4];<br>
--  int base_reg = -1;<br>
--  int i;<br>
--<br>
--  if (low_irq_latency)<br>
--    return 0;<br>
--<br>
--  /* Can only handle 2, 3, or 4 insns at present,<br>
--     though could be easily extended if required.  */<br>
--  gcc_assert (nops &gt;= 2 &amp;&amp; nops &lt;= 4);<br>
--<br>
--  memset (order, 0, 4 * sizeof (int));<br>
--<br>
--  /* Loop over the operands and check that the memory references are<br>
--     suitable (i.e. immediate offsets from the same base register).  At<br>
--     the same time, extract the target register, and the memory<br>
--     offsets.  */<br>
--  for (i = 0; i &lt; nops; i++)<br>
--    {<br>
--      rtx reg;<br>
--      rtx offset;<br>
--<br>
--      /* Convert a subreg of a mem into the mem itself.  */<br>
--      if (GET_CODE (operands[nops + i]) == SUBREG)<br>
--      operands[nops + i] = alter_subreg (operands + (nops + i));<br>
--<br>
--      gcc_assert (GET_CODE (operands[nops + i]) == MEM);<br>
--<br>
--      /* Don&#39;t reorder volatile memory references; it doesn&#39;t seem worth<br>
--       looking for the case where the order is ok anyway.  */<br>
--      if (MEM_VOLATILE_P (operands[nops + i]))<br>
--      return 0;<br>
--<br>
--      offset = const0_rtx;<br>
--<br>
--      if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG<br>
--         || (GET_CODE (reg) == SUBREG<br>
--             &amp;&amp; GET_CODE (reg = SUBREG_REG (reg)) == REG))<br>
--        || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS<br>
--            &amp;&amp; ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))<br>
--                 == REG)<br>
--                || (GET_CODE (reg) == SUBREG<br>
--                    &amp;&amp; GET_CODE (reg = SUBREG_REG (reg)) == REG))<br>
--            &amp;&amp; (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))<br>
--                == CONST_INT)))<br>
--      {<br>
--        if (i == 0)<br>
--          {<br>
--            base_reg = REGNO (reg);<br>
--            unsorted_regs[0] = (GET_CODE (operands[i]) == REG<br>
--                                ? REGNO (operands[i])<br>
--                                : REGNO (SUBREG_REG (operands[i])));<br>
--            order[0] = 0;<br>
--          }<br>
--        else<br>
--          {<br>
--            if (base_reg != (int) REGNO (reg))<br>
--              /* Not addressed from the same base register.  */<br>
--              return 0;<br>
--<br>
--            unsorted_regs[i] = (GET_CODE (operands[i]) == REG<br>
--                                ? REGNO (operands[i])<br>
--                                : REGNO (SUBREG_REG (operands[i])));<br>
--            if (unsorted_regs[i] &lt; unsorted_regs[order[0]])<br>
--              order[0] = i;<br>
--          }<br>
--<br>
--        /* If it isn&#39;t an integer register, or if it overwrites the<br>
--           base register but isn&#39;t the last insn in the list, then<br>
--           we can&#39;t do this.  */<br>
--        if (unsorted_regs[i] &lt; 0 || unsorted_regs[i] &gt; 14<br>
--            || (i != nops - 1 &amp;&amp; unsorted_regs[i] == base_reg))<br>
--          return 0;<br>
--<br>
--        unsorted_offsets[i] = INTVAL (offset);<br>
--      }<br>
--      else<br>
--      /* Not a suitable memory address.  */<br>
--      return 0;<br>
--    }<br>
--<br>
--  /* All the useful information has now been extracted from the<br>
--     operands into unsorted_regs and unsorted_offsets; additionally,<br>
--     order[0] has been set to the lowest numbered register in the<br>
--     list.  Sort the registers into order, and check that the memory<br>
--     offsets are ascending and adjacent.  */<br>
--<br>
--  for (i = 1; i &lt; nops; i++)<br>
--    {<br>
--      int j;<br>
--<br>
--      order[i] = order[i - 1];<br>
--      for (j = 0; j &lt; nops; j++)<br>
--      if (unsorted_regs[j] &gt; unsorted_regs[order[i - 1]]<br>
--          &amp;&amp; (order[i] == order[i - 1]<br>
--              || unsorted_regs[j] &lt; unsorted_regs[order[i]]))<br>
--        order[i] = j;<br>
--<br>
--      /* Have we found a suitable register? if not, one must be used more<br>
--       than once.  */<br>
--      if (order[i] == order[i - 1])<br>
--      return 0;<br>
--<br>
--      /* Is the memory address adjacent and ascending? */<br>
--      if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)<br>
--      return 0;<br>
--    }<br>
--<br>
--  if (base)<br>
--    {<br>
--      *base = base_reg;<br>
--<br>
--      for (i = 0; i &lt; nops; i++)<br>
--      regs[i] = unsorted_regs[order[i]];<br>
--<br>
--      *load_offset = unsorted_offsets[order[0]];<br>
--    }<br>
--<br>
--  if (unsorted_offsets[order[0]] == 0)<br>
--    return 1; /* ldmia */<br>
--<br>
--  if (TARGET_ARM &amp;&amp; unsorted_offsets[order[0]] == 4)<br>
--    return 2; /* ldmib */<br>
--<br>
--  if (TARGET_ARM &amp;&amp; unsorted_offsets[order[nops - 1]] == 0)<br>
--    return 3; /* ldmda */<br>
--<br>
--  if (unsorted_offsets[order[nops - 1]] == -4)<br>
--    return 4; /* ldmdb */<br>
--<br>
-+<br>
-+/* Return true iff it would be profitable to turn a sequence of NOPS loads<br>
-+   or stores (depending on IS_STORE) into a load-multiple or store-multiple<br>
-+   instruction.  ADD_OFFSET is nonzero if the base address register needs<br>
-+   to be modified with an add instruction before we can use it.  */<br>
-+<br>
-+static bool<br>
-+multiple_operation_profitable_p (bool is_store ATTRIBUTE_UNUSED,<br>
-+                               int nops, HOST_WIDE_INT add_offset)<br>
-+ {<br>
-   /* For ARM8,9 &amp; StrongARM, 2 ldr instructions are faster than an ldm<br>
-      if the offset isn&#39;t small enough.  The reason 2 ldrs are faster<br>
-      is because these ARMs are able to do more than one cache access<br>
-@@ -9845,91 +9725,239 @@<br>
-      We cheat here and test &#39;arm_ld_sched&#39; which we currently know to<br>
-      only be true for the ARM8, ARM9 and StrongARM.  If this ever<br>
-      changes, then the test below needs to be reworked.  */<br>
--  if (nops == 2 &amp;&amp; arm_ld_sched)<br>
-+  if (nops == 2 &amp;&amp; arm_ld_sched &amp;&amp; add_offset != 0)<br>
-+    return false;<br>
-+<br>
-+  return true;<br>
-+}<br>
-+<br>
-+/* Subroutine of load_multiple_sequence and store_multiple_sequence.<br>
-+   Given an array of UNSORTED_OFFSETS, of which there are NOPS, compute<br>
-+   an array ORDER which describes the sequence to use when accessing the<br>
-+   offsets that produces an ascending order.  In this sequence, each<br>
-+   offset must be larger by exactly 4 than the previous one.  ORDER[0]<br>
-+   must have been filled in with the lowest offset by the caller.<br>
-+   If UNSORTED_REGS is nonnull, it is an array of register numbers that<br>
-+   we use to verify that ORDER produces an ascending order of registers.<br>
-+   Return true if it was possible to construct such an order, false if<br>
-+   not.  */<br>
-+<br>
-+static bool<br>
-+compute_offset_order (int nops, HOST_WIDE_INT *unsorted_offsets, int *order,<br>
-+                    int *unsorted_regs)<br>
-+{<br>
-+  int i;<br>
-+  for (i = 1; i &lt; nops; i++)<br>
-+    {<br>
-+      int j;<br>
-+<br>
-+      order[i] = order[i - 1];<br>
-+      for (j = 0; j &lt; nops; j++)<br>
-+      if (unsorted_offsets[j] == unsorted_offsets[order[i - 1]] + 4)<br>
-+        {<br>
-+          /* We must find exactly one offset that is higher than the<br>
-+             previous one by 4.  */<br>
-+          if (order[i] != order[i - 1])<br>
-+            return false;<br>
-+          order[i] = j;<br>
-+        }<br>
-+      if (order[i] == order[i - 1])<br>
-+      return false;<br>
-+      /* The register numbers must be ascending.  */<br>
-+      if (unsorted_regs != NULL<br>
-+        &amp;&amp; unsorted_regs[order[i]] &lt;= unsorted_regs[order[i - 1]])<br>
-+      return false;<br>
-+    }<br>
-+  return true;<br>
-+}<br>
-+<br>
-+/* Used to determine in a peephole whether a sequence of load<br>
-+   instructions can be changed into a load-multiple instruction.<br>
-+   NOPS is the number of separate load instructions we are examining.  The<br>
-+   first NOPS entries in OPERANDS are the destination registers, the<br>
-+   next NOPS entries are memory operands.  If this function is<br>
-+   successful, *BASE is set to the common base register of the memory<br>
-+   accesses; *LOAD_OFFSET is set to the first memory location&#39;s offset<br>
-+   from that base register.<br>
-+   REGS is an array filled in with the destination register numbers.<br>
-+   SAVED_ORDER (if nonnull), is an array filled in with an order that maps<br>
-+   insn numbers to to an ascending order of stores.  If CHECK_REGS is true,<br>
-+   the sequence of registers in REGS matches the loads from ascending memory<br>
-+   locations, and the function verifies that the register numbers are<br>
-+   themselves ascending.  If CHECK_REGS is false, the register numbers<br>
-+   are stored in the order they are found in the operands.  */<br>
-+static int<br>
-+load_multiple_sequence (rtx *operands, int nops, int *regs, int *saved_order,<br>
-+                      int *base, HOST_WIDE_INT *load_offset, bool check_regs)<br>
-+{<br>
-+  int unsorted_regs[MAX_LDM_STM_OPS];<br>
-+  HOST_WIDE_INT unsorted_offsets[MAX_LDM_STM_OPS];<br>
-+  int order[MAX_LDM_STM_OPS];<br>
-+  rtx base_reg_rtx = NULL;<br>
-+  int base_reg = -1;<br>
-+  int i, ldm_case;<br>
-+<br>
-+  if (low_irq_latency)<br>
-     return 0;<br>
-<br>
--  /* Can&#39;t do it without setting up the offset, only do this if it takes<br>
--     no more than one insn.  */<br>
--  return (const_ok_for_arm (unsorted_offsets[order[0]])<br>
--        || const_ok_for_arm (-unsorted_offsets[order[0]])) ? 5 : 0;<br>
--}<br>
--<br>
--const char *<br>
--emit_ldm_seq (rtx *operands, int nops)<br>
--{<br>
--  int regs[4];<br>
--  int base_reg;<br>
--  HOST_WIDE_INT offset;<br>
--  char buf[100];<br>
--  int i;<br>
--<br>
--  switch (load_multiple_sequence (operands, nops, regs, &amp;base_reg, &amp;offset))<br>
-+  /* Can only handle up to MAX_LDM_STM_OPS insns at present, though could be<br>
-+     easily extended if required.  */<br>
-+  gcc_assert (nops &gt;= 2 &amp;&amp; nops &lt;= MAX_LDM_STM_OPS);<br>
-+<br>
-+  memset (order, 0, MAX_LDM_STM_OPS * sizeof (int));<br>
-+<br>
-+  /* Loop over the operands and check that the memory references are<br>
-+     suitable (i.e. immediate offsets from the same base register).  At<br>
-+     the same time, extract the target register, and the memory<br>
-+     offsets.  */<br>
-+  for (i = 0; i &lt; nops; i++)<br>
-     {<br>
--    case 1:<br>
--      strcpy (buf, &quot;ldm%(ia%)\t&quot;);<br>
--      break;<br>
--<br>
--    case 2:<br>
--      strcpy (buf, &quot;ldm%(ib%)\t&quot;);<br>
--      break;<br>
--<br>
--    case 3:<br>
--      strcpy (buf, &quot;ldm%(da%)\t&quot;);<br>
--      break;<br>
--<br>
--    case 4:<br>
--      strcpy (buf, &quot;ldm%(db%)\t&quot;);<br>
--      break;<br>
--<br>
--    case 5:<br>
--      if (offset &gt;= 0)<br>
--      sprintf (buf, &quot;add%%?\t%s%s, %s%s, #%ld&quot;, REGISTER_PREFIX,<br>
--               reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],<br>
--               (long) offset);<br>
-+      rtx reg;<br>
-+      rtx offset;<br>
-+<br>
-+      /* Convert a subreg of a mem into the mem itself.  */<br>
-+      if (GET_CODE (operands[nops + i]) == SUBREG)<br>
-+      operands[nops + i] = alter_subreg (operands + (nops + i));<br>
-+<br>
-+      gcc_assert (GET_CODE (operands[nops + i]) == MEM);<br>
-+<br>
-+      /* Don&#39;t reorder volatile memory references; it doesn&#39;t seem worth<br>
-+       looking for the case where the order is ok anyway.  */<br>
-+      if (MEM_VOLATILE_P (operands[nops + i]))<br>
-+      return 0;<br>
-+<br>
-+      offset = const0_rtx;<br>
-+<br>
-+      if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG<br>
-+         || (GET_CODE (reg) == SUBREG<br>
-+             &amp;&amp; GET_CODE (reg = SUBREG_REG (reg)) == REG))<br>
-+        || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS<br>
-+            &amp;&amp; ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))<br>
-+                 == REG)<br>
-+                || (GET_CODE (reg) == SUBREG<br>
-+                    &amp;&amp; GET_CODE (reg = SUBREG_REG (reg)) == REG))<br>
-+            &amp;&amp; (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))<br>
-+                == CONST_INT)))<br>
-+      {<br>
-+        if (i == 0)<br>
-+          {<br>
-+            base_reg = REGNO (reg);<br>
-+            base_reg_rtx = reg;<br>
-+            if (TARGET_THUMB1 &amp;&amp; base_reg &gt; LAST_LO_REGNUM)<br>
-+              return 0;<br>
-+          }<br>
-+        else if (base_reg != (int) REGNO (reg))<br>
-+          /* Not addressed from the same base register.  */<br>
-+          return 0;<br>
-+<br>
-+        unsorted_regs[i] = (GET_CODE (operands[i]) == REG<br>
-+                            ? REGNO (operands[i])<br>
-+                            : REGNO (SUBREG_REG (operands[i])));<br>
-+<br>
-+        /* If it isn&#39;t an integer register, or if it overwrites the<br>
-+           base register but isn&#39;t the last insn in the list, then<br>
-+           we can&#39;t do this.  */<br>
-+        if (unsorted_regs[i] &lt; 0<br>
-+            || (TARGET_THUMB1 &amp;&amp; unsorted_regs[i] &gt; LAST_LO_REGNUM)<br>
-+            || unsorted_regs[i] &gt; 14<br>
-+            || (i != nops - 1 &amp;&amp; unsorted_regs[i] == base_reg))<br>
-+          return 0;<br>
-+<br>
-+        unsorted_offsets[i] = INTVAL (offset);<br>
-+        if (i == 0 || unsorted_offsets[i] &lt; unsorted_offsets[order[0]])<br>
-+          order[0] = i;<br>
-+      }<br>
-       else<br>
--      sprintf (buf, &quot;sub%%?\t%s%s, %s%s, #%ld&quot;, REGISTER_PREFIX,<br>
--               reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],<br>
--               (long) -offset);<br>
--      output_asm_insn (buf, operands);<br>
--      base_reg = regs[0];<br>
--      strcpy (buf, &quot;ldm%(ia%)\t&quot;);<br>
--      break;<br>
--<br>
--    default:<br>
--      gcc_unreachable ();<br>
--    }<br>
--<br>
--  sprintf (buf + strlen (buf), &quot;%s%s, {%s%s&quot;, REGISTER_PREFIX,<br>
--         reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);<br>
--<br>
--  for (i = 1; i &lt; nops; i++)<br>
--    sprintf (buf + strlen (buf), &quot;, %s%s&quot;, REGISTER_PREFIX,<br>
--           reg_names[regs[i]]);<br>
--<br>
--  strcat (buf, &quot;}\t%@ phole ldm&quot;);<br>
--<br>
--  output_asm_insn (buf, operands);<br>
--  return &quot;&quot;;<br>
-+      /* Not a suitable memory address.  */<br>
-+      return 0;<br>
-+    }<br>
-+<br>
-+  /* All the useful information has now been extracted from the<br>
-+     operands into unsorted_regs and unsorted_offsets; additionally,<br>
-+     order[0] has been set to the lowest offset in the list.  Sort<br>
-+     the offsets into order, verifying that they are adjacent, and<br>
-+     check that the register numbers are ascending.  */<br>
-+  if (!compute_offset_order (nops, unsorted_offsets, order,<br>
-+                           check_regs ? unsorted_regs : NULL))<br>
-+    return 0;<br>
-+<br>
-+  if (saved_order)<br>
-+    memcpy (saved_order, order, sizeof order);<br>
-+<br>
-+  if (base)<br>
-+    {<br>
-+      *base = base_reg;<br>
-+<br>
-+      for (i = 0; i &lt; nops; i++)<br>
-+      regs[i] = unsorted_regs[check_regs ? order[i] : i];<br>
-+<br>
-+      *load_offset = unsorted_offsets[order[0]];<br>
-+    }<br>
-+<br>
-+  if (TARGET_THUMB1<br>
-+      &amp;&amp; !peep2_reg_dead_p (nops, base_reg_rtx))<br>
-+    return 0;<br>
-+<br>
-+  if (unsorted_offsets[order[0]] == 0)<br>
-+    ldm_case = 1; /* ldmia */<br>
-+  else if (TARGET_ARM &amp;&amp; unsorted_offsets[order[0]] == 4)<br>
-+    ldm_case = 2; /* ldmib */<br>
-+  else if (TARGET_ARM &amp;&amp; unsorted_offsets[order[nops - 1]] == 0)<br>
-+    ldm_case = 3; /* ldmda */<br>
-+  else if (TARGET_32BIT &amp;&amp; unsorted_offsets[order[nops - 1]] == -4)<br>
-+    ldm_case = 4; /* ldmdb */<br>
-+  else if (const_ok_for_arm (unsorted_offsets[order[0]])<br>
-+         || const_ok_for_arm (-unsorted_offsets[order[0]]))<br>
-+    ldm_case = 5;<br>
-+  else<br>
-+    return 0;<br>
-+<br>
-+  if (!multiple_operation_profitable_p (false, nops,<br>
-+                                      ldm_case == 5<br>
-+                                      ? unsorted_offsets[order[0]] : 0))<br>
-+    return 0;<br>
-+<br>
-+  return ldm_case;<br>
- }<br>
-<br>
--int<br>
--store_multiple_sequence (rtx *operands, int nops, int *regs, int *base,<br>
--                       HOST_WIDE_INT * load_offset)<br>
-+/* Used to determine in a peephole whether a sequence of store instructions can<br>
-+   be changed into a store-multiple instruction.<br>
-+   NOPS is the number of separate store instructions we are examining.<br>
-+   NOPS_TOTAL is the total number of instructions recognized by the peephole<br>
-+   pattern.<br>
-+   The first NOPS entries in OPERANDS are the source registers, the next<br>
-+   NOPS entries are memory operands.  If this function is successful, *BASE is<br>
-+   set to the common base register of the memory accesses; *LOAD_OFFSET is set<br>
-+   to the first memory location&#39;s offset from that base register.  REGS is an<br>
-+   array filled in with the source register numbers, REG_RTXS (if nonnull) is<br>
-+   likewise filled with the corresponding rtx&#39;s.<br>
-+   SAVED_ORDER (if nonnull), is an array filled in with an order that maps insn<br>
-+   numbers to to an ascending order of stores.<br>
-+   If CHECK_REGS is true, the sequence of registers in *REGS matches the stores<br>
-+   from ascending memory locations, and the function verifies that the register<br>
-+   numbers are themselves ascending.  If CHECK_REGS is false, the register<br>
-+   numbers are stored in the order they are found in the operands.  */<br>
-+static int<br>
-+store_multiple_sequence (rtx *operands, int nops, int nops_total,<br>
-+                       int *regs, rtx *reg_rtxs, int *saved_order, int *base,<br>
-+                       HOST_WIDE_INT *load_offset, bool check_regs)<br>
- {<br>
--  int unsorted_regs[4];<br>
--  HOST_WIDE_INT unsorted_offsets[4];<br>
--  int order[4];<br>
-+  int unsorted_regs[MAX_LDM_STM_OPS];<br>
-+  rtx unsorted_reg_rtxs[MAX_LDM_STM_OPS];<br>
-+  HOST_WIDE_INT unsorted_offsets[MAX_LDM_STM_OPS];<br>
-+  int order[MAX_LDM_STM_OPS];<br>
-   int base_reg = -1;<br>
--  int i;<br>
-+  rtx base_reg_rtx = NULL;<br>
-+  int i, stm_case;<br>
-<br>
-   if (low_irq_latency)<br>
-     return 0;<br>
-<br>
--  /* Can only handle 2, 3, or 4 insns at present, though could be easily<br>
--     extended if required.  */<br>
--  gcc_assert (nops &gt;= 2 &amp;&amp; nops &lt;= 4);<br>
-+  /* Can only handle up to MAX_LDM_STM_OPS insns at present, though could be<br>
-+     easily extended if required.  */<br>
-+  gcc_assert (nops &gt;= 2 &amp;&amp; nops &lt;= MAX_LDM_STM_OPS);<br>
-<br>
--  memset (order, 0, 4 * sizeof (int));<br>
-+  memset (order, 0, MAX_LDM_STM_OPS * sizeof (int));<br>
-<br>
-   /* Loop over the operands and check that the memory references are<br>
-      suitable (i.e. immediate offsets from the same base register).  At<br>
-@@ -9964,32 +9992,32 @@<br>
-             &amp;&amp; (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))<br>
-                 == CONST_INT)))<br>
-       {<br>
-+        unsorted_reg_rtxs[i] = (GET_CODE (operands[i]) == REG<br>
-+                                ? operands[i] : SUBREG_REG (operands[i]));<br>
-+        unsorted_regs[i] = REGNO (unsorted_reg_rtxs[i]);<br>
-+<br>
-         if (i == 0)<br>
-           {<br>
-             base_reg = REGNO (reg);<br>
--            unsorted_regs[0] = (GET_CODE (operands[i]) == REG<br>
--                                ? REGNO (operands[i])<br>
--                                : REGNO (SUBREG_REG (operands[i])));<br>
--            order[0] = 0;<br>
--          }<br>
--        else<br>
--          {<br>
--            if (base_reg != (int) REGNO (reg))<br>
--              /* Not addressed from the same base register.  */<br>
-+            base_reg_rtx = reg;<br>
-+            if (TARGET_THUMB1 &amp;&amp; base_reg &gt; LAST_LO_REGNUM)<br>
-               return 0;<br>
--<br>
--            unsorted_regs[i] = (GET_CODE (operands[i]) == REG<br>
--                                ? REGNO (operands[i])<br>
--                                : REGNO (SUBREG_REG (operands[i])));<br>
--            if (unsorted_regs[i] &lt; unsorted_regs[order[0]])<br>
--              order[0] = i;<br>
-           }<br>
-+        else if (base_reg != (int) REGNO (reg))<br>
-+          /* Not addressed from the same base register.  */<br>
-+          return 0;<br>
-<br>
-         /* If it isn&#39;t an integer register, then we can&#39;t do this.  */<br>
--        if (unsorted_regs[i] &lt; 0 || unsorted_regs[i] &gt; 14)<br>
-+        if (unsorted_regs[i] &lt; 0<br>
-+            || (TARGET_THUMB1 &amp;&amp; unsorted_regs[i] &gt; LAST_LO_REGNUM)<br>
-+            || (TARGET_THUMB2 &amp;&amp; unsorted_regs[i] == base_reg)<br>
-+            || (TARGET_THUMB2 &amp;&amp; unsorted_regs[i] == SP_REGNUM)<br>
-+            || unsorted_regs[i] &gt; 14)<br>
-           return 0;<br>
-<br>
-         unsorted_offsets[i] = INTVAL (offset);<br>
-+        if (i == 0 || unsorted_offsets[i] &lt; unsorted_offsets[order[0]])<br>
-+          order[0] = i;<br>
-       }<br>
-       else<br>
-       /* Not a suitable memory address.  */<br>
-@@ -9998,111 +10026,65 @@<br>
-<br>
-   /* All the useful information has now been extracted from the<br>
-      operands into unsorted_regs and unsorted_offsets; additionally,<br>
--     order[0] has been set to the lowest numbered register in the<br>
--     list.  Sort the registers into order, and check that the memory<br>
--     offsets are ascending and adjacent.  */<br>
--<br>
--  for (i = 1; i &lt; nops; i++)<br>
--    {<br>
--      int j;<br>
--<br>
--      order[i] = order[i - 1];<br>
--      for (j = 0; j &lt; nops; j++)<br>
--      if (unsorted_regs[j] &gt; unsorted_regs[order[i - 1]]<br>
--          &amp;&amp; (order[i] == order[i - 1]<br>
--              || unsorted_regs[j] &lt; unsorted_regs[order[i]]))<br>
--        order[i] = j;<br>
--<br>
--      /* Have we found a suitable register? if not, one must be used more<br>
--       than once.  */<br>
--      if (order[i] == order[i - 1])<br>
--      return 0;<br>
--<br>
--      /* Is the memory address adjacent and ascending? */<br>
--      if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)<br>
--      return 0;<br>
--    }<br>
-+     order[0] has been set to the lowest offset in the list.  Sort<br>
-+     the offsets into order, verifying that they are adjacent, and<br>
-+     check that the register numbers are ascending.  */<br>
-+  if (!compute_offset_order (nops, unsorted_offsets, order,<br>
-+                           check_regs ? unsorted_regs : NULL))<br>
-+    return 0;<br>
-+<br>
-+  if (saved_order)<br>
-+    memcpy (saved_order, order, sizeof order);<br>
-<br>
-   if (base)<br>
-     {<br>
-       *base = base_reg;<br>
-<br>
-       for (i = 0; i &lt; nops; i++)<br>
--      regs[i] = unsorted_regs[order[i]];<br>
-+      {<br>
-+        regs[i] = unsorted_regs[check_regs ? order[i] : i];<br>
-+        if (reg_rtxs)<br>
-+          reg_rtxs[i] = unsorted_reg_rtxs[check_regs ? order[i] : i];<br>
-+      }<br>
-<br>
-       *load_offset = unsorted_offsets[order[0]];<br>
-     }<br>
-<br>
-+  if (TARGET_THUMB1<br>
-+      &amp;&amp; !peep2_reg_dead_p (nops_total, base_reg_rtx))<br>
-+    return 0;<br>
-+<br>
-   if (unsorted_offsets[order[0]] == 0)<br>
--    return 1; /* stmia */<br>
--<br>
--  if (unsorted_offsets[order[0]] == 4)<br>
--    return 2; /* stmib */<br>
--<br>
--  if (unsorted_offsets[order[nops - 1]] == 0)<br>
--    return 3; /* stmda */<br>
--<br>
--  if (unsorted_offsets[order[nops - 1]] == -4)<br>
--    return 4; /* stmdb */<br>
--<br>
--  return 0;<br>
--}<br>
--<br>
--const char *<br>
--emit_stm_seq (rtx *operands, int nops)<br>
--{<br>
--  int regs[4];<br>
--  int base_reg;<br>
--  HOST_WIDE_INT offset;<br>
--  char buf[100];<br>
--  int i;<br>
--<br>
--  switch (store_multiple_sequence (operands, nops, regs, &amp;base_reg, &amp;offset))<br>
--    {<br>
--    case 1:<br>
--      strcpy (buf, &quot;stm%(ia%)\t&quot;);<br>
--      break;<br>
--<br>
--    case 2:<br>
--      strcpy (buf, &quot;stm%(ib%)\t&quot;);<br>
--      break;<br>
--<br>
--    case 3:<br>
--      strcpy (buf, &quot;stm%(da%)\t&quot;);<br>
--      break;<br>
--<br>
--    case 4:<br>
--      strcpy (buf, &quot;stm%(db%)\t&quot;);<br>
--      break;<br>
--<br>
--    default:<br>
--      gcc_unreachable ();<br>
--    }<br>
--<br>
--  sprintf (buf + strlen (buf), &quot;%s%s, {%s%s&quot;, REGISTER_PREFIX,<br>
--         reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);<br>
--<br>
--  for (i = 1; i &lt; nops; i++)<br>
--    sprintf (buf + strlen (buf), &quot;, %s%s&quot;, REGISTER_PREFIX,<br>
--           reg_names[regs[i]]);<br>
--<br>
--  strcat (buf, &quot;}\t%@ phole stm&quot;);<br>
--<br>
--  output_asm_insn (buf, operands);<br>
--  return &quot;&quot;;<br>
-+    stm_case = 1; /* stmia */<br>
-+  else if (TARGET_ARM &amp;&amp; unsorted_offsets[order[0]] == 4)<br>
-+    stm_case = 2; /* stmib */<br>
-+  else if (TARGET_ARM &amp;&amp; unsorted_offsets[order[nops - 1]] == 0)<br>
-+    stm_case = 3; /* stmda */<br>
-+  else if (TARGET_32BIT &amp;&amp; unsorted_offsets[order[nops - 1]] == -4)<br>
-+    stm_case = 4; /* stmdb */<br>
-+  else<br>
-+    return 0;<br>
-+<br>
-+  if (!multiple_operation_profitable_p (false, nops, 0))<br>
-+    return 0;<br>
-+<br>
-+  return stm_case;<br>
- }<br>
-<br>
- /* Routines for use in generating RTL.  */<br>
-<br>
--rtx<br>
--arm_gen_load_multiple (int base_regno, int count, rtx from, int up,<br>
--                     int write_back, rtx basemem, HOST_WIDE_INT *offsetp)<br>
-+/* Generate a load-multiple instruction.  COUNT is the number of loads in<br>
-+   the instruction; REGS and MEMS are arrays containing the operands.<br>
-+   BASEREG is the base register to be used in addressing the memory operands.<br>
-+   WBACK_OFFSET is nonzero if the instruction should update the base<br>
-+   register.  */<br>
-+<br>
-+static rtx<br>
-+arm_gen_load_multiple_1 (int count, int *regs, rtx *mems, rtx basereg,<br>
-+                       HOST_WIDE_INT wback_offset)<br>
- {<br>
--  HOST_WIDE_INT offset = *offsetp;<br>
-   int i = 0, j;<br>
-   rtx result;<br>
--  int sign = up ? 1 : -1;<br>
--  rtx mem, addr;<br>
-<br>
-   /* XScale has load-store double instructions, but they have stricter<br>
-      alignment requirements than load-store multiple, so we cannot<br>
-@@ -10139,18 +10121,10 @@<br>
-       start_sequence ();<br>
-<br>
-       for (i = 0; i &lt; count; i++)<br>
--      {<br>
--        addr = plus_constant (from, i * 4 * sign);<br>
--        mem = adjust_automodify_address (basemem, SImode, addr, offset);<br>
--        emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);<br>
--        offset += 4 * sign;<br>
--      }<br>
-+      emit_move_insn (gen_rtx_REG (SImode, regs[i]), mems[i]);<br>
-<br>
--      if (write_back)<br>
--      {<br>
--        emit_move_insn (from, plus_constant (from, count * 4 * sign));<br>
--        *offsetp = offset;<br>
--      }<br>
-+      if (wback_offset != 0)<br>
-+      emit_move_insn (basereg, plus_constant (basereg, wback_offset));<br>
-<br>
-       seq = get_insns ();<br>
-       end_sequence ();<br>
-@@ -10159,41 +10133,40 @@<br>
-     }<br>
-<br>
-   result = gen_rtx_PARALLEL (VOIDmode,<br>
--                           rtvec_alloc (count + (write_back ? 1 : 0)));<br>
--  if (write_back)<br>
-+                           rtvec_alloc (count + (wback_offset != 0 ? 1 : 0)));<br>
-+  if (wback_offset != 0)<br>
-     {<br>
-       XVECEXP (result, 0, 0)<br>
--      = gen_rtx_SET (VOIDmode, from, plus_constant (from, count * 4 * sign));<br>
-+      = gen_rtx_SET (VOIDmode, basereg,<br>
-+                     plus_constant (basereg, wback_offset));<br>
-       i = 1;<br>
-       count++;<br>
-     }<br>
-<br>
-   for (j = 0; i &lt; count; i++, j++)<br>
--    {<br>
--      addr = plus_constant (from, j * 4 * sign);<br>
--      mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);<br>
--      XVECEXP (result, 0, i)<br>
--      = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);<br>
--      offset += 4 * sign;<br>
--    }<br>
--<br>
--  if (write_back)<br>
--    *offsetp = offset;<br>
-+    XVECEXP (result, 0, i)<br>
-+      = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regs[j]), mems[j]);<br>
-<br>
-   return result;<br>
- }<br>
-<br>
--rtx<br>
--arm_gen_store_multiple (int base_regno, int count, rtx to, int up,<br>
--                      int write_back, rtx basemem, HOST_WIDE_INT *offsetp)<br>
-+/* Generate a store-multiple instruction.  COUNT is the number of stores in<br>
-+   the instruction; REGS and MEMS are arrays containing the operands.<br>
-+   BASEREG is the base register to be used in addressing the memory operands.<br>
-+   WBACK_OFFSET is nonzero if the instruction should update the base<br>
-+   register.  */<br>
-+<br>
-+static rtx<br>
-+arm_gen_store_multiple_1 (int count, int *regs, rtx *mems, rtx basereg,<br>
-+                        HOST_WIDE_INT wback_offset)<br>
- {<br>
--  HOST_WIDE_INT offset = *offsetp;<br>
-   int i = 0, j;<br>
-   rtx result;<br>
--  int sign = up ? 1 : -1;<br>
--  rtx mem, addr;<br>
--<br>
--  /* See arm_gen_load_multiple for discussion of<br>
-+<br>
-+  if (GET_CODE (basereg) == PLUS)<br>
-+    basereg = XEXP (basereg, 0);<br>
-+<br>
-+  /* See arm_gen_load_multiple_1 for discussion of<br>
-      the pros/cons of ldm/stm usage for XScale.  */<br>
-   if (low_irq_latency || (arm_tune_xscale &amp;&amp; count &lt;= 2 &amp;&amp; ! optimize_size))<br>
-     {<br>
-@@ -10202,18 +10175,10 @@<br>
-       start_sequence ();<br>
-<br>
-       for (i = 0; i &lt; count; i++)<br>
--      {<br>
--        addr = plus_constant (to, i * 4 * sign);<br>
--        mem = adjust_automodify_address (basemem, SImode, addr, offset);<br>
--        emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));<br>
--        offset += 4 * sign;<br>
--      }<br>
-+      emit_move_insn (mems[i], gen_rtx_REG (SImode, regs[i]));<br>
-<br>
--      if (write_back)<br>
--      {<br>
--        emit_move_insn (to, plus_constant (to, count * 4 * sign));<br>
--        *offsetp = offset;<br>
--      }<br>
-+      if (wback_offset != 0)<br>
-+      emit_move_insn (basereg, plus_constant (basereg, wback_offset));<br>
-<br>
-       seq = get_insns ();<br>
-       end_sequence ();<br>
-@@ -10222,29 +10187,319 @@<br>
-     }<br>
-<br>
-   result = gen_rtx_PARALLEL (VOIDmode,<br>
--                           rtvec_alloc (count + (write_back ? 1 : 0)));<br>
--  if (write_back)<br>
-+                           rtvec_alloc (count + (wback_offset != 0 ? 1 : 0)));<br>
-+  if (wback_offset != 0)<br>
-     {<br>
-       XVECEXP (result, 0, 0)<br>
--      = gen_rtx_SET (VOIDmode, to,<br>
--                     plus_constant (to, count * 4 * sign));<br>
-+      = gen_rtx_SET (VOIDmode, basereg,<br>
-+                     plus_constant (basereg, wback_offset));<br>
-       i = 1;<br>
-       count++;<br>
-     }<br>
-<br>
-   for (j = 0; i &lt; count; i++, j++)<br>
-+    XVECEXP (result, 0, i)<br>
-+      = gen_rtx_SET (VOIDmode, mems[j], gen_rtx_REG (SImode, regs[j]));<br>
-+<br>
-+  return result;<br>
-+}<br>
-+<br>
-+/* Generate either a load-multiple or a store-multiple instruction.  This<br>
-+   function can be used in situations where we can start with a single MEM<br>
-+   rtx and adjust its address upwards.<br>
-+   COUNT is the number of operations in the instruction, not counting a<br>
-+   possible update of the base register.  REGS is an array containing the<br>
-+   register operands.<br>
-+   BASEREG is the base register to be used in addressing the memory operands,<br>
-+   which are constructed from BASEMEM.<br>
-+   WRITE_BACK specifies whether the generated instruction should include an<br>
-+   update of the base register.<br>
-+   OFFSETP is used to pass an offset to and from this function; this offset<br>
-+   is not used when constructing the address (instead BASEMEM should have an<br>
-+   appropriate offset in its address), it is used only for setting<br>
-+   MEM_OFFSET.  It is updated only if WRITE_BACK is true.*/<br>
-+<br>
-+static rtx<br>
-+arm_gen_multiple_op (bool is_load, int *regs, int count, rtx basereg,<br>
-+                   bool write_back, rtx basemem, HOST_WIDE_INT *offsetp)<br>
-+{<br>
-+  rtx mems[MAX_LDM_STM_OPS];<br>
-+  HOST_WIDE_INT offset = *offsetp;<br>
-+  int i;<br>
-+<br>
-+  gcc_assert (count &lt;= MAX_LDM_STM_OPS);<br>
-+<br>
-+  if (GET_CODE (basereg) == PLUS)<br>
-+    basereg = XEXP (basereg, 0);<br>
-+<br>
-+  for (i = 0; i &lt; count; i++)<br>
-     {<br>
--      addr = plus_constant (to, j * 4 * sign);<br>
--      mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);<br>
--      XVECEXP (result, 0, i)<br>
--      = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));<br>
--      offset += 4 * sign;<br>
-+      rtx addr = plus_constant (basereg, i * 4);<br>
-+      mems[i] = adjust_automodify_address_nv (basemem, SImode, addr, offset);<br>
-+      offset += 4;<br>
-     }<br>
-<br>
-   if (write_back)<br>
-     *offsetp = offset;<br>
-<br>
--  return result;<br>
-+  if (is_load)<br>
-+    return arm_gen_load_multiple_1 (count, regs, mems, basereg,<br>
-+                                  write_back ? 4 * count : 0);<br>
-+  else<br>
-+    return arm_gen_store_multiple_1 (count, regs, mems, basereg,<br>
-+                                   write_back ? 4 * count : 0);<br>
-+}<br>
-+<br>
-+rtx<br>
-+arm_gen_load_multiple (int *regs, int count, rtx basereg, int write_back,<br>
-+                     rtx basemem, HOST_WIDE_INT *offsetp)<br>
-+{<br>
-+  return arm_gen_multiple_op (TRUE, regs, count, basereg, write_back, basemem,<br>
-+                            offsetp);<br>
-+}<br>
-+<br>
-+rtx<br>
-+arm_gen_store_multiple (int *regs, int count, rtx basereg, int write_back,<br>
-+                      rtx basemem, HOST_WIDE_INT *offsetp)<br>
-+{<br>
-+  return arm_gen_multiple_op (FALSE, regs, count, basereg, write_back, basemem,<br>
-+                            offsetp);<br>
-+}<br>
-+<br>
-+/* Called from a peephole2 expander to turn a sequence of loads into an<br>
-+   LDM instruction.  OPERANDS are the operands found by the peephole matcher;<br>
-+   NOPS indicates how many separate loads we are trying to combine.  SORT_REGS<br>
-+   is true if we can reorder the registers because they are used commutatively<br>
-+   subsequently.<br>
-+   Returns true iff we could generate a new instruction.  */<br>
-+<br>
-+bool<br>
-+gen_ldm_seq (rtx *operands, int nops, bool sort_regs)<br>
-+{<br>
-+  int regs[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];<br>
-+  rtx mems[MAX_LDM_STM_OPS];<br>
-+  int i, j, base_reg;<br>
-+  rtx base_reg_rtx;<br>
-+  HOST_WIDE_INT offset;<br>
-+  int write_back = FALSE;<br>
-+  int ldm_case;<br>
-+  rtx addr;<br>
-+<br>
-+  ldm_case = load_multiple_sequence (operands, nops, regs, mem_order,<br>
-+                                   &amp;base_reg, &amp;offset, !sort_regs);<br>
-+<br>
-+  if (ldm_case == 0)<br>
-+    return false;<br>
-+<br>
-+  if (sort_regs)<br>
-+    for (i = 0; i &lt; nops - 1; i++)<br>
-+      for (j = i + 1; j &lt; nops; j++)<br>
-+      if (regs[i] &gt; regs[j])<br>
-+        {<br>
-+          int t = regs[i];<br>
-+          regs[i] = regs[j];<br>
-+          regs[j] = t;<br>
-+        }<br>
-+  base_reg_rtx = gen_rtx_REG (Pmode, base_reg);<br>
-+<br>
-+  if (TARGET_THUMB1)<br>
-+    {<br>
-+      gcc_assert (peep2_reg_dead_p (nops, base_reg_rtx));<br>
-+      gcc_assert (ldm_case == 1 || ldm_case == 5);<br>
-+      write_back = TRUE;<br>
-+    }<br>
-+<br>
-+  if (ldm_case == 5)<br>
-+    {<br>
-+      rtx newbase = TARGET_THUMB1 ? base_reg_rtx : gen_rtx_REG (SImode, regs[0]);<br>
-+      emit_insn (gen_addsi3 (newbase, base_reg_rtx, GEN_INT (offset)));<br>
-+      offset = 0;<br>
-+      if (!TARGET_THUMB1)<br>
-+      {<br>
-+        base_reg = regs[0];<br>
-+        base_reg_rtx = newbase;<br>
-+      }<br>
-+    }<br>
-+<br>
-+  for (i = 0; i &lt; nops; i++)<br>
-+    {<br>
-+      addr = plus_constant (base_reg_rtx, offset + i * 4);<br>
-+      mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],<br>
-+                                            SImode, addr, 0);<br>
-+    }<br>
-+  emit_insn (arm_gen_load_multiple_1 (nops, regs, mems, base_reg_rtx,<br>
-+                                    write_back ? offset + i * 4 : 0));<br>
-+  return true;<br>
-+}<br>
-+<br>
-+/* Called from a peephole2 expander to turn a sequence of stores into an<br>
-+   STM instruction.  OPERANDS are the operands found by the peephole matcher;<br>
-+   NOPS indicates how many separate stores we are trying to combine.<br>
-+   Returns true iff we could generate a new instruction.  */<br>
-+<br>
-+bool<br>
-+gen_stm_seq (rtx *operands, int nops)<br>
-+{<br>
-+  int i;<br>
-+  int regs[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];<br>
-+  rtx mems[MAX_LDM_STM_OPS];<br>
-+  int base_reg;<br>
-+  rtx base_reg_rtx;<br>
-+  HOST_WIDE_INT offset;<br>
-+  int write_back = FALSE;<br>
-+  int stm_case;<br>
-+  rtx addr;<br>
-+  bool base_reg_dies;<br>
-+<br>
-+  stm_case = store_multiple_sequence (operands, nops, nops, regs, NULL,<br>
-+                                    mem_order, &amp;base_reg, &amp;offset, true);<br>
-+<br>
-+  if (stm_case == 0)<br>
-+    return false;<br>
-+<br>
-+  base_reg_rtx = gen_rtx_REG (Pmode, base_reg);<br>
-+<br>
-+  base_reg_dies = peep2_reg_dead_p (nops, base_reg_rtx);<br>
-+  if (TARGET_THUMB1)<br>
-+    {<br>
-+      gcc_assert (base_reg_dies);<br>
-+      write_back = TRUE;<br>
-+    }<br>
-+<br>
-+  if (stm_case == 5)<br>
-+    {<br>
-+      gcc_assert (base_reg_dies);<br>
-+      emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, GEN_INT (offset)));<br>
-+      offset = 0;<br>
-+    }<br>
-+<br>
-+  addr = plus_constant (base_reg_rtx, offset);<br>
-+<br>
-+  for (i = 0; i &lt; nops; i++)<br>
-+    {<br>
-+      addr = plus_constant (base_reg_rtx, offset + i * 4);<br>
-+      mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],<br>
-+                                            SImode, addr, 0);<br>
-+    }<br>
-+  emit_insn (arm_gen_store_multiple_1 (nops, regs, mems, base_reg_rtx,<br>
-+                                     write_back ? offset + i * 4 : 0));<br>
-+  return true;<br>
-+}<br>
-+<br>
-+/* Called from a peephole2 expander to turn a sequence of stores that are<br>
-+   preceded by constant loads into an STM instruction.  OPERANDS are the<br>
-+   operands found by the peephole matcher; NOPS indicates how many<br>
-+   separate stores we are trying to combine; there are 2 * NOPS<br>
-+   instructions in the peephole.<br>
-+   Returns true iff we could generate a new instruction.  */<br>
-+<br>
-+bool<br>
-+gen_const_stm_seq (rtx *operands, int nops)<br>
-+{<br>
-+  int regs[MAX_LDM_STM_OPS], sorted_regs[MAX_LDM_STM_OPS];<br>
-+  int reg_order[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];<br>
-+  rtx reg_rtxs[MAX_LDM_STM_OPS], orig_reg_rtxs[MAX_LDM_STM_OPS];<br>
-+  rtx mems[MAX_LDM_STM_OPS];<br>
-+  int base_reg;<br>
-+  rtx base_reg_rtx;<br>
-+  HOST_WIDE_INT offset;<br>
-+  int write_back = FALSE;<br>
-+  int stm_case;<br>
-+  rtx addr;<br>
-+  bool base_reg_dies;<br>
-+  int i, j;<br>
-+  HARD_REG_SET allocated;<br>
-+<br>
-+  stm_case = store_multiple_sequence (operands, nops, 2 * nops, regs, reg_rtxs,<br>
-+                                    mem_order, &amp;base_reg, &amp;offset, false);<br>
-+<br>
-+  if (stm_case == 0)<br>
-+    return false;<br>
-+<br>
-+  memcpy (orig_reg_rtxs, reg_rtxs, sizeof orig_reg_rtxs);<br>
-+<br>
-+  /* If the same register is used more than once, try to find a free<br>
-+     register.  */<br>
-+  CLEAR_HARD_REG_SET (allocated);<br>
-+  for (i = 0; i &lt; nops; i++)<br>
-+    {<br>
-+      for (j = i + 1; j &lt; nops; j++)<br>
-+      if (regs[i] == regs[j])<br>
-+        {<br>
-+          rtx t = peep2_find_free_register (0, nops * 2,<br>
-+                                            TARGET_THUMB1 ? &quot;l&quot; : &quot;r&quot;,<br>
-+                                            SImode, &amp;allocated);<br>
-+          if (t == NULL_RTX)<br>
-+            return false;<br>
-+          reg_rtxs[i] = t;<br>
-+          regs[i] = REGNO (t);<br>
-+        }<br>
-+    }<br>
-+<br>
-+  /* Compute an ordering that maps the register numbers to an ascending<br>
-+     sequence.  */<br>
-+  reg_order[0] = 0;<br>
-+  for (i = 0; i &lt; nops; i++)<br>
-+    if (regs[i] &lt; regs[reg_order[0]])<br>
-+      reg_order[0] = i;<br>
-+<br>
-+  for (i = 1; i &lt; nops; i++)<br>
-+    {<br>
-+      int this_order = reg_order[i - 1];<br>
-+      for (j = 0; j &lt; nops; j++)<br>
-+      if (regs[j] &gt; regs[reg_order[i - 1]]<br>
-+          &amp;&amp; (this_order == reg_order[i - 1]<br>
-+              || regs[j] &lt; regs[this_order]))<br>
-+        this_order = j;<br>
-+      reg_order[i] = this_order;<br>
-+    }<br>
-+<br>
-+  /* Ensure that registers that must be live after the instruction end<br>
-+     up with the correct value.  */<br>
-+  for (i = 0; i &lt; nops; i++)<br>
-+    {<br>
-+      int this_order = reg_order[i];<br>
-+      if ((this_order != mem_order[i]<br>
-+         || orig_reg_rtxs[this_order] != reg_rtxs[this_order])<br>
-+        &amp;&amp; !peep2_reg_dead_p (nops * 2, orig_reg_rtxs[this_order]))<br>
-+      return false;<br>
-+    }<br>
-+<br>
-+  /* Load the constants.  */<br>
-+  for (i = 0; i &lt; nops; i++)<br>
-+    {<br>
-+      rtx op = operands[2 * nops + mem_order[i]];<br>
-+      sorted_regs[i] = regs[reg_order[i]];<br>
-+      emit_move_insn (reg_rtxs[reg_order[i]], op);<br>
-+    }<br>
-+<br>
-+  base_reg_rtx = gen_rtx_REG (Pmode, base_reg);<br>
-+<br>
-+  base_reg_dies = peep2_reg_dead_p (nops * 2, base_reg_rtx);<br>
-+  if (TARGET_THUMB1)<br>
-+    {<br>
-+      gcc_assert (base_reg_dies);<br>
-+      write_back = TRUE;<br>
-+    }<br>
-+<br>
-+  if (stm_case == 5)<br>
-+    {<br>
-+      gcc_assert (base_reg_dies);<br>
-+      emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, GEN_INT (offset)));<br>
-+      offset = 0;<br>
-+    }<br>
-+<br>
-+  addr = plus_constant (base_reg_rtx, offset);<br>
-+<br>
-+  for (i = 0; i &lt; nops; i++)<br>
-+    {<br>
-+      addr = plus_constant (base_reg_rtx, offset + i * 4);<br>
-+      mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],<br>
-+                                            SImode, addr, 0);<br>
-+    }<br>
-+  emit_insn (arm_gen_store_multiple_1 (nops, sorted_regs, mems, base_reg_rtx,<br>
-+                                     write_back ? offset + i * 4 : 0));<br>
-+  return true;<br>
- }<br>
-<br>
- int<br>
-@@ -10280,20 +10535,21 @@<br>
-   for (i = 0; in_words_to_go &gt;= 2; i+=4)<br>
-     {<br>
-       if (in_words_to_go &gt; 4)<br>
--      emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,<br>
--                                        srcbase, &amp;srcoffset));<br>
-+      emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, src,<br>
-+                                        TRUE, srcbase, &amp;srcoffset));<br>
-       else<br>
--      emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE,<br>
--                                        FALSE, srcbase, &amp;srcoffset));<br>
-+      emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, in_words_to_go,<br>
-+                                        src, FALSE, srcbase,<br>
-+                                        &amp;srcoffset));<br>
-<br>
-       if (out_words_to_go)<br>
-       {<br>
-         if (out_words_to_go &gt; 4)<br>
--          emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,<br>
--                                             dstbase, &amp;dstoffset));<br>
-+          emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, dst,<br>
-+                                             TRUE, dstbase, &amp;dstoffset));<br>
-         else if (out_words_to_go != 1)<br>
--          emit_insn (arm_gen_store_multiple (0, out_words_to_go,<br>
--                                             dst, TRUE,<br>
-+          emit_insn (arm_gen_store_multiple (arm_regs_in_sequence,<br>
-+                                             out_words_to_go, dst,<br>
-                                              (last_bytes == 0<br>
-                                               ? FALSE : TRUE),<br>
-                                              dstbase, &amp;dstoffset));<br>
-<br>
-=== modified file &#39;gcc/config/arm/arm.h&#39;<br>
---- old/gcc/config/arm/arm.h   2011-01-05 12:12:18 +0000<br>
-+++ new/gcc/config/arm/arm.h   2011-01-05 18:20:37 +0000<br>
-@@ -1143,6 +1143,9 @@<br>
-   ((MODE) == TImode || (MODE) == EImode || (MODE) == OImode \<br>
-    || (MODE) == CImode || (MODE) == XImode)<br>
-<br>
-+/* The register numbers in sequence, for passing to arm_gen_load_multiple.  */<br>
-+extern int arm_regs_in_sequence[];<br>
-+<br>
- /* The order in which register should be allocated.  It is good to use ip<br>
-    since no saving is required (though calls clobber it) and it never contains<br>
-    function parameters.  It is quite good to use lr since other calls may<br>
-@@ -2823,4 +2826,8 @@<br>
- #define NEED_INDICATE_EXEC_STACK      0<br>
- #endif<br>
-<br>
-+/* The maximum number of parallel loads or stores we support in an ldm/stm<br>
-+   instruction.  */<br>
-+#define MAX_LDM_STM_OPS 4<br>
-+<br>
- #endif /* ! GCC_ARM_H */<br>
-<br>
-=== modified file &#39;gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a>&#39;<br>
---- old/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a>  2011-01-05 12:12:18 +0000<br>
-+++ new/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a>  2011-01-05 18:20:37 +0000<br>
-@@ -6282,7 +6282,7 @@<br>
-<br>
- ;; load- and store-multiple insns<br>
- ;; The arm can load/store any set of registers, provided that they are in<br>
--;; ascending order; but that is beyond GCC so stick with what it knows.<br>
-+;; ascending order, but these expanders assume a contiguous set.<br>
-<br>
- (define_expand &quot;load_multiple&quot;<br>
-   [(match_par_dup 3 [(set (match_operand:SI 0 &quot;&quot; &quot;&quot;)<br>
-@@ -6303,126 +6303,12 @@<br>
-     FAIL;<br>
-<br>
-   operands[3]<br>
--    = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),<br>
-+    = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),<br>
-+                           INTVAL (operands[2]),<br>
-                            force_reg (SImode, XEXP (operands[1], 0)),<br>
--                           TRUE, FALSE, operands[1], &amp;offset);<br>
-+                           FALSE, operands[1], &amp;offset);<br>
- })<br>
-<br>
--;; Load multiple with write-back<br>
--<br>
--(define_insn &quot;*ldmsi_postinc4&quot;<br>
--  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
--    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
--        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
--                 (const_int 16)))<br>
--     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (match_dup 2)))<br>
--     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 4))))<br>
--     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 8))))<br>
--     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
--  &quot;ldm%(ia%)\\t%1!, {%3, %4, %5, %6}&quot;<br>
--  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
--   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*ldmsi_postinc4_thumb1&quot;<br>
--  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
--    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
--        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
--                 (const_int 16)))<br>
--     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (match_dup 2)))<br>
--     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 4))))<br>
--     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 8))))<br>
--     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]<br>
--  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
--  &quot;ldmia\\t%1!, {%3, %4, %5, %6}&quot;<br>
--  [(set_attr &quot;type&quot; &quot;load4&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*ldmsi_postinc3&quot;<br>
--  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
--    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
--        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
--                 (const_int 12)))<br>
--     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (match_dup 2)))<br>
--     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 4))))<br>
--     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
--  &quot;ldm%(ia%)\\t%1!, {%3, %4, %5}&quot;<br>
--  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
--   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*ldmsi_postinc2&quot;<br>
--  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
--    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
--        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
--                 (const_int 8)))<br>
--     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (match_dup 2)))<br>
--     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
--  &quot;ldm%(ia%)\\t%1!, {%3, %4}&quot;<br>
--  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
--   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
--)<br>
--<br>
--;; Ordinary load multiple<br>
--<br>
--(define_insn &quot;*ldmsi4&quot;<br>
--  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
--    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;)))<br>
--     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 1) (const_int 4))))<br>
--     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 1) (const_int 8))))<br>
--     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
--  &quot;ldm%(ia%)\\t%1, {%2, %3, %4, %5}&quot;<br>
--  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
--   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*ldmsi3&quot;<br>
--  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
--    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;)))<br>
--     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 1) (const_int 4))))<br>
--     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
--  &quot;ldm%(ia%)\\t%1, {%2, %3, %4}&quot;<br>
--  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
--   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*ldmsi2&quot;<br>
--  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
--    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;)))<br>
--     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
--        (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
--  &quot;ldm%(ia%)\\t%1, {%2, %3}&quot;<br>
--  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
--   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
--)<br>
--<br>
- (define_expand &quot;store_multiple&quot;<br>
-   [(match_par_dup 3 [(set (match_operand:SI 0 &quot;&quot; &quot;&quot;)<br>
-                           (match_operand:SI 1 &quot;&quot; &quot;&quot;))<br>
-@@ -6442,125 +6328,12 @@<br>
-     FAIL;<br>
-<br>
-   operands[3]<br>
--    = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),<br>
-+    = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),<br>
-+                            INTVAL (operands[2]),<br>
-                             force_reg (SImode, XEXP (operands[0], 0)),<br>
--                            TRUE, FALSE, operands[0], &amp;offset);<br>
-+                            FALSE, operands[0], &amp;offset);<br>
- })<br>
-<br>
--;; Store multiple with write-back<br>
--<br>
--(define_insn &quot;*stmsi_postinc4&quot;<br>
--  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
--    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
--        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
--                 (const_int 16)))<br>
--     (set (mem:SI (match_dup 2))<br>
--        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
--        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
--        (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
--        (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
--  &quot;stm%(ia%)\\t%1!, {%3, %4, %5, %6}&quot;<br>
--  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
--   (set_attr &quot;type&quot; &quot;store4&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*stmsi_postinc4_thumb1&quot;<br>
--  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
--    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
--        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
--                 (const_int 16)))<br>
--     (set (mem:SI (match_dup 2))<br>
--        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
--        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
--        (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
--        (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
--  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
--  &quot;stmia\\t%1!, {%3, %4, %5, %6}&quot;<br>
--  [(set_attr &quot;type&quot; &quot;store4&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*stmsi_postinc3&quot;<br>
--  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
--    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
--        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
--                 (const_int 12)))<br>
--     (set (mem:SI (match_dup 2))<br>
--        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
--        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
--        (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
--  &quot;stm%(ia%)\\t%1!, {%3, %4, %5}&quot;<br>
--  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
--   (set_attr &quot;type&quot; &quot;store3&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*stmsi_postinc2&quot;<br>
--  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
--    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
--        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
--                 (const_int 8)))<br>
--     (set (mem:SI (match_dup 2))<br>
--        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
--        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
--  &quot;stm%(ia%)\\t%1!, {%3, %4}&quot;<br>
--  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
--   (set_attr &quot;type&quot; &quot;store2&quot;)]<br>
--)<br>
--<br>
--;; Ordinary store multiple<br>
--<br>
--(define_insn &quot;*stmsi4&quot;<br>
--  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
--    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;))<br>
--        (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
--        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
--        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))<br>
--        (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
--  &quot;stm%(ia%)\\t%1, {%2, %3, %4, %5}&quot;<br>
--  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
--   (set_attr &quot;type&quot; &quot;store4&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*stmsi3&quot;<br>
--  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
--    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;))<br>
--        (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
--        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
--        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
--  &quot;stm%(ia%)\\t%1, {%2, %3, %4}&quot;<br>
--  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
--   (set_attr &quot;type&quot; &quot;store3&quot;)]<br>
--)<br>
--<br>
--(define_insn &quot;*stmsi2&quot;<br>
--  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
--    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;))<br>
--        (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
--     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
--        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
--  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
--  &quot;stm%(ia%)\\t%1, {%2, %3}&quot;<br>
--  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
--   (set_attr &quot;type&quot; &quot;store2&quot;)]<br>
--)<br>
-<br>
- ;; Move a block of memory if it is word aligned and MORE than 2 words long.<br>
- ;; We could let this apply for blocks of less than this, but it clobbers so<br>
-@@ -9031,8 +8804,8 @@<br>
-       if (REGNO (reg) == R0_REGNUM)<br>
-         {<br>
-           /* On thumb we have to use a write-back instruction.  */<br>
--          emit_insn (arm_gen_store_multiple (R0_REGNUM, 4, addr, TRUE,<br>
--                      TARGET_THUMB ? TRUE : FALSE, mem, &amp;offset));<br>
-+          emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,<br>
-+                     TARGET_THUMB ? TRUE : FALSE, mem, &amp;offset));<br>
-           size = TARGET_ARM ? 16 : 0;<br>
-         }<br>
-       else<br>
-@@ -9078,8 +8851,8 @@<br>
-       if (REGNO (reg) == R0_REGNUM)<br>
-         {<br>
-           /* On thumb we have to use a write-back instruction.  */<br>
--          emit_insn (arm_gen_load_multiple (R0_REGNUM, 4, addr, TRUE,<br>
--                      TARGET_THUMB ? TRUE : FALSE, mem, &amp;offset));<br>
-+          emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,<br>
-+                     TARGET_THUMB ? TRUE : FALSE, mem, &amp;offset));<br>
-           size = TARGET_ARM ? 16 : 0;<br>
-         }<br>
-       else<br>
-@@ -10672,87 +10445,6 @@<br>
-   &quot;&quot;<br>
- )<br>
-<br>
--; Peepholes to spot possible load- and store-multiples, if the ordering is<br>
--; reversed, check that the memory references aren&#39;t volatile.<br>
--<br>
--(define_peephole<br>
--  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 4 &quot;memory_operand&quot; &quot;m&quot;))<br>
--   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 5 &quot;memory_operand&quot; &quot;m&quot;))<br>
--   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 6 &quot;memory_operand&quot; &quot;m&quot;))<br>
--   (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 7 &quot;memory_operand&quot; &quot;m&quot;))]<br>
--  &quot;TARGET_ARM &amp;&amp; load_multiple_sequence (operands, 4, NULL, NULL, NULL)&quot;<br>
--  &quot;*<br>
--  return emit_ldm_seq (operands, 4);<br>
--  &quot;<br>
--)<br>
--<br>
--(define_peephole<br>
--  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 3 &quot;memory_operand&quot; &quot;m&quot;))<br>
--   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 4 &quot;memory_operand&quot; &quot;m&quot;))<br>
--   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 5 &quot;memory_operand&quot; &quot;m&quot;))]<br>
--  &quot;TARGET_ARM &amp;&amp; load_multiple_sequence (operands, 3, NULL, NULL, NULL)&quot;<br>
--  &quot;*<br>
--  return emit_ldm_seq (operands, 3);<br>
--  &quot;<br>
--)<br>
--<br>
--(define_peephole<br>
--  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 2 &quot;memory_operand&quot; &quot;m&quot;))<br>
--   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
--        (match_operand:SI 3 &quot;memory_operand&quot; &quot;m&quot;))]<br>
--  &quot;TARGET_ARM &amp;&amp; load_multiple_sequence (operands, 2, NULL, NULL, NULL)&quot;<br>
--  &quot;*<br>
--  return emit_ldm_seq (operands, 2);<br>
--  &quot;<br>
--)<br>
--<br>
--(define_peephole<br>
--  [(set (match_operand:SI 4 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
--   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
--   (set (match_operand:SI 6 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 2 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
--   (set (match_operand:SI 7 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 3 &quot;s_register_operand&quot; &quot;rk&quot;))]<br>
--  &quot;TARGET_ARM &amp;&amp; store_multiple_sequence (operands, 4, NULL, NULL, NULL)&quot;<br>
--  &quot;*<br>
--  return emit_stm_seq (operands, 4);<br>
--  &quot;<br>
--)<br>
--<br>
--(define_peephole<br>
--  [(set (match_operand:SI 3 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
--   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
--   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 2 &quot;s_register_operand&quot; &quot;rk&quot;))]<br>
--  &quot;TARGET_ARM &amp;&amp; store_multiple_sequence (operands, 3, NULL, NULL, NULL)&quot;<br>
--  &quot;*<br>
--  return emit_stm_seq (operands, 3);<br>
--  &quot;<br>
--)<br>
--<br>
--(define_peephole<br>
--  [(set (match_operand:SI 2 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
--   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;=m&quot;)<br>
--        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))]<br>
--  &quot;TARGET_ARM &amp;&amp; store_multiple_sequence (operands, 2, NULL, NULL, NULL)&quot;<br>
--  &quot;*<br>
--  return emit_stm_seq (operands, 2);<br>
--  &quot;<br>
--)<br>
--<br>
- (define_split<br>
-   [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-       (and:SI (ge:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-@@ -11559,6 +11251,8 @@<br>
-   &quot;<br>
- )<br>
-<br>
-+;; Load the load/store multiple patterns<br>
-+(include &quot;<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>&quot;)<br>
- ;; Load the FPA co-processor patterns<br>
- (include &quot;<a href="http://fpa.md" target="_blank">fpa.md</a>&quot;)<br>
- ;; Load the Maverick co-processor patterns<br>
-<br>
-=== added file &#39;gcc/config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>&#39;<br>
---- old/gcc/config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>       1970-01-01 00:00:00 +0000<br>
-+++ new/gcc/config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>       2010-11-16 13:08:47 +0000<br>
-@@ -0,0 +1,1191 @@<br>
-+/* ARM ldm/stm instruction patterns.  This file was automatically generated<br>
-+   using <a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>.  Please do not edit manually.<br>
-+<br>
-+   Copyright (C) 2010 Free Software Foundation, Inc.<br>
-+   Contributed by CodeSourcery.<br>
-+<br>
-+   This file is part of GCC.<br>
-+<br>
-+   GCC is free software; you can redistribute it and/or modify it<br>
-+   under the terms of the GNU General Public License as published<br>
-+   by the Free Software Foundation; either version 3, or (at your<br>
-+   option) any later version.<br>
-+<br>
-+   GCC is distributed in the hope that it will be useful, but WITHOUT<br>
-+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY<br>
-+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public<br>
-+   License for more details.<br>
-+<br>
-+   You should have received a copy of the GNU General Public License and<br>
-+   a copy of the GCC Runtime Library Exception along with this program;<br>
-+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see<br>
-+   &lt;<a href="http://www.gnu.org/licenses/" target="_blank">http://www.gnu.org/licenses/</a>&gt;.  */<br>
-+<br>
-+(define_insn &quot;*ldm4_ia&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 8))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 12))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(ia%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_ldm4_ia&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;l&quot;)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 8))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 12))))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(ia%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm4_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 8))))<br>
-+     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 12))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;ldm%(ia%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_ldm4_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 8))))<br>
-+     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 12))))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;ldm%(ia%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm4_ia&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(ia%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm4_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
-+          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;stm%(ia%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_stm4_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
-+          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;stm%(ia%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm4_ib&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 8))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 12))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 16))))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(ib%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm4_ib_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 8))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 12))))<br>
-+     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 16))))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;ldm%(ib%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm4_ib&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int 4)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(ib%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm4_ib_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 16)))<br>
-+          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;stm%(ib%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm4_da&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int -12))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -4))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 1)))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(da%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm4_da_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -16)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -12))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -4))))<br>
-+     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;ldm%(da%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm4_da&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -12)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -8)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (match_dup 1))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(da%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm4_da_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -16)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -12)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;stm%(da%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm4_db&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int -16))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -12))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -4))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(db%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm4_db_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -16)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -16))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -12))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -4))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;ldm%(db%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm4_db&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -16)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -12)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -8)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(db%)\t%1, {%2, %3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm4_db_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -16)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -16)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -12)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
-+          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
-+  &quot;stm%(db%)\t%1!, {%3, %4, %5, %6}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_ldm_seq (operands, 4, false))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (parallel<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+          (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;))<br>
-+     (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+          (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;))<br>
-+     (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+          (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;))])]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_ldm_seq (operands, 4, false))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 8 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 0))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 9 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 1))<br>
-+   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 10 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 2))<br>
-+   (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 11 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 3))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_const_stm_seq (operands, 4))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 8 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 9 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 10 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 11 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 0))<br>
-+   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 1))<br>
-+   (set (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 2))<br>
-+   (set (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 3))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_const_stm_seq (operands, 4))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_stm_seq (operands, 4))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_insn &quot;*ldm3_ia&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 8))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(ia%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_ldm3_ia&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;l&quot;)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 8))))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(ia%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm3_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 8))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(ia%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_ldm3_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 8))))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(ia%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm3_ia&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(ia%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm3_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(ia%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_stm3_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(ia%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm3_ib&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 8))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 12))))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(ib%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm3_ib_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 8))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 12))))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(ib%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm3_ib&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int 4)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(ib%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm3_ib_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(ib%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm3_da&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 1)))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(da%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm3_da_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -12)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -4))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(da%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm3_da&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -8)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (match_dup 1))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(da%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm3_da_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -12)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(da%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm3_db&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int -12))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -4))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(db%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm3_db_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -12)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -12))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -4))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;ldm%(db%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm3_db&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -12)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -8)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(db%)\t%1, {%2, %3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm3_db_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -12)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -12)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
-+          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
-+  &quot;stm%(db%)\t%1!, {%3, %4, %5}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_ldm_seq (operands, 3, false))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (parallel<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+          (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;))<br>
-+     (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+          (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;))])]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_ldm_seq (operands, 3, false))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 6 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 0))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 7 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 1))<br>
-+   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 8 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 2))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_const_stm_seq (operands, 3))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 6 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 7 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 8 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 0))<br>
-+   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 1))<br>
-+   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 2))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_const_stm_seq (operands, 3))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_stm_seq (operands, 3))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_insn &quot;*ldm2_ia&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 4))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;ldm%(ia%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_ldm2_ia&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;l&quot;)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 4))))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;ldm%(ia%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm2_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(ia%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_ldm2_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(ia%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm2_ia&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;stm%(ia%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm2_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(ia%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*thumb_stm2_ia_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(ia%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm2_ib&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int 8))))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;ldm%(ib%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm2_ib_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int 8))))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(ib%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm2_ib&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int 4)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;stm%(ib%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm2_ib_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(ib%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm2_da&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int -4))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 1)))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;ldm%(da%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm2_da_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -8)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -4))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (match_dup 2)))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(da%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm2_da&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -4)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (match_dup 1))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;stm%(da%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm2_da_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -8)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (match_dup 2))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(da%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm2_db&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 1)<br>
-+                  (const_int -4))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;ldm%(db%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*ldm2_db_update&quot;<br>
-+  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -8)))<br>
-+     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -8))))<br>
-+     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
-+          (mem:SI (plus:SI (match_dup 2)<br>
-+                  (const_int -4))))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;ldm%(db%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm2_db&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -8)))<br>
-+          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
-+  &quot;stm%(db%)\t%1, {%2, %3}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_insn &quot;*stm2_db_update&quot;<br>
-+  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
-+    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
-+          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -8)))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
-+          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
-+     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
-+          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
-+  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
-+  &quot;stm%(db%)\t%1!, {%3, %4}&quot;<br>
-+  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
-+   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_ldm_seq (operands, 2, false))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 4 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 0))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 5 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 1))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_const_stm_seq (operands, 2))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 4 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 5 &quot;const_int_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 0))<br>
-+   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_dup 1))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_const_stm_seq (operands, 2))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;))]<br>
-+  &quot;&quot;<br>
-+  [(const_int 0)]<br>
-+{<br>
-+  if (gen_stm_seq (operands, 2))<br>
-+    DONE;<br>
-+  else<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (parallel<br>
-+     [(set (match_operand:SI 4 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+           (match_operator:SI 5 &quot;commutative_binary_operator&quot;<br>
-+            [(match_operand:SI 6 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+             (match_operand:SI 7 &quot;s_register_operand&quot; &quot;&quot;)]))<br>
-+      (clobber (reg:CC CC_REGNUM))])]<br>
-+  &quot;(((operands[6] == operands[0] &amp;&amp; operands[7] == operands[1])<br>
-+     || (operands[7] == operands[0] &amp;&amp; operands[6] == operands[1]))<br>
-+    &amp;&amp; peep2_reg_dead_p (3, operands[0]) &amp;&amp; peep2_reg_dead_p (3, operands[1]))&quot;<br>
-+  [(parallel<br>
-+    [(set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))<br>
-+     (clobber (reg:CC CC_REGNUM))])]<br>
-+{<br>
-+  if (!gen_ldm_seq (operands, 2, true))<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-+(define_peephole2<br>
-+  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))<br>
-+   (set (match_operand:SI 4 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+        (match_operator:SI 5 &quot;commutative_binary_operator&quot;<br>
-+         [(match_operand:SI 6 &quot;s_register_operand&quot; &quot;&quot;)<br>
-+          (match_operand:SI 7 &quot;s_register_operand&quot; &quot;&quot;)]))]<br>
-+  &quot;(((operands[6] == operands[0] &amp;&amp; operands[7] == operands[1])<br>
-+     || (operands[7] == operands[0] &amp;&amp; operands[6] == operands[1]))<br>
-+    &amp;&amp; peep2_reg_dead_p (3, operands[0]) &amp;&amp; peep2_reg_dead_p (3, operands[1]))&quot;<br>
-+  [(set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))]<br>
-+{<br>
-+  if (!gen_ldm_seq (operands, 2, true))<br>
-+    FAIL;<br>
-+})<br>
-+<br>
-<br>
-=== modified file &#39;gcc/config/arm/<a href="http://predicates.md" target="_blank">predicates.md</a>&#39;<br>
---- old/gcc/config/arm/<a href="http://predicates.md" target="_blank">predicates.md</a>   2010-11-04 10:45:05 +0000<br>
-+++ new/gcc/config/arm/<a href="http://predicates.md" target="_blank">predicates.md</a>   2010-11-16 12:32:34 +0000<br>
-@@ -211,6 +211,11 @@<br>
-   (and (match_code &quot;ior,xor,and&quot;)<br>
-        (match_test &quot;mode == GET_MODE (op)&quot;)))<br>
-<br>
-+;; True for commutative operators<br>
-+(define_special_predicate &quot;commutative_binary_operator&quot;<br>
-+  (and (match_code &quot;ior,xor,and,plus&quot;)<br>
-+       (match_test &quot;mode == GET_MODE (op)&quot;)))<br>
-+<br>
- ;; True for shift operators.<br>
- (define_special_predicate &quot;shift_operator&quot;<br>
-   (and (ior (ior (and (match_code &quot;mult&quot;)<br>
-@@ -334,16 +339,20 @@<br>
-   (match_code &quot;parallel&quot;)<br>
- {<br>
-   HOST_WIDE_INT count = XVECLEN (op, 0);<br>
--  int dest_regno;<br>
-+  unsigned dest_regno;<br>
-   rtx src_addr;<br>
-   HOST_WIDE_INT i = 1, base = 0;<br>
-+  HOST_WIDE_INT offset = 0;<br>
-   rtx elt;<br>
-+  bool addr_reg_loaded = false;<br>
-+  bool update = false;<br>
-<br>
-   if (low_irq_latency)<br>
-     return false;<br>
-<br>
-   if (count &lt;= 1<br>
--      || GET_CODE (XVECEXP (op, 0, 0)) != SET)<br>
-+      || GET_CODE (XVECEXP (op, 0, 0)) != SET<br>
-+      || !REG_P (SET_DEST (XVECEXP (op, 0, 0))))<br>
-     return false;<br>
-<br>
-   /* Check to see if this might be a write-back.  */<br>
-@@ -351,6 +360,7 @@<br>
-     {<br>
-       i++;<br>
-       base = 1;<br>
-+      update = true;<br>
-<br>
-       /* Now check it more carefully.  */<br>
-       if (GET_CODE (SET_DEST (elt)) != REG<br>
-@@ -369,6 +379,15 @@<br>
-<br>
-   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));<br>
-   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);<br>
-+  if (GET_CODE (src_addr) == PLUS)<br>
-+    {<br>
-+      if (GET_CODE (XEXP (src_addr, 1)) != CONST_INT)<br>
-+      return false;<br>
-+      offset = INTVAL (XEXP (src_addr, 1));<br>
-+      src_addr = XEXP (src_addr, 0);<br>
-+    }<br>
-+  if (!REG_P (src_addr))<br>
-+    return false;<br>
-<br>
-   for (; i &lt; count; i++)<br>
-     {<br>
-@@ -377,16 +396,28 @@<br>
-       if (GET_CODE (elt) != SET<br>
-           || GET_CODE (SET_DEST (elt)) != REG<br>
-           || GET_MODE (SET_DEST (elt)) != SImode<br>
--          || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)<br>
-+          || REGNO (SET_DEST (elt)) &lt;= dest_regno<br>
-           || GET_CODE (SET_SRC (elt)) != MEM<br>
-           || GET_MODE (SET_SRC (elt)) != SImode<br>
--          || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS<br>
--          || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)<br>
--          || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT<br>
--          || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)<br>
-+          || ((GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS<br>
-+             || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)<br>
-+             || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT<br>
-+             || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != offset + (i - base) * 4)<br>
-+            &amp;&amp; (!REG_P (XEXP (SET_SRC (elt), 0))<br>
-+                || offset + (i - base) * 4 != 0)))<br>
-         return false;<br>
-+      dest_regno = REGNO (SET_DEST (elt));<br>
-+      if (dest_regno == REGNO (src_addr))<br>
-+        addr_reg_loaded = true;<br>
-     }<br>
--<br>
-+  /* For Thumb, we only have updating instructions.  If the pattern does<br>
-+     not describe an update, it must be because the address register is<br>
-+     in the list of loaded registers - on the hardware, this has the effect<br>
-+     of overriding the update.  */<br>
-+  if (update &amp;&amp; addr_reg_loaded)<br>
-+    return false;<br>
-+  if (TARGET_THUMB1)<br>
-+    return update || addr_reg_loaded;<br>
-   return true;<br>
- })<br>
-<br>
-@@ -394,9 +425,9 @@<br>
-   (match_code &quot;parallel&quot;)<br>
- {<br>
-   HOST_WIDE_INT count = XVECLEN (op, 0);<br>
--  int src_regno;<br>
-+  unsigned src_regno;<br>
-   rtx dest_addr;<br>
--  HOST_WIDE_INT i = 1, base = 0;<br>
-+  HOST_WIDE_INT i = 1, base = 0, offset = 0;<br>
-   rtx elt;<br>
-<br>
-   if (low_irq_latency)<br>
-@@ -430,6 +461,16 @@<br>
-   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));<br>
-   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);<br>
-<br>
-+  if (GET_CODE (dest_addr) == PLUS)<br>
-+    {<br>
-+      if (GET_CODE (XEXP (dest_addr, 1)) != CONST_INT)<br>
-+      return false;<br>
-+      offset = INTVAL (XEXP (dest_addr, 1));<br>
-+      dest_addr = XEXP (dest_addr, 0);<br>
-+    }<br>
-+  if (!REG_P (dest_addr))<br>
-+    return false;<br>
-+<br>
-   for (; i &lt; count; i++)<br>
-     {<br>
-       elt = XVECEXP (op, 0, i);<br>
-@@ -437,14 +478,17 @@<br>
-       if (GET_CODE (elt) != SET<br>
-           || GET_CODE (SET_SRC (elt)) != REG<br>
-           || GET_MODE (SET_SRC (elt)) != SImode<br>
--          || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)<br>
-+          || REGNO (SET_SRC (elt)) &lt;= src_regno<br>
-           || GET_CODE (SET_DEST (elt)) != MEM<br>
-           || GET_MODE (SET_DEST (elt)) != SImode<br>
--          || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS<br>
--          || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)<br>
--          || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT<br>
--          || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)<br>
-+          || ((GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS<br>
-+             || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)<br>
-+             || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT<br>
-+               || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != offset + (i - base) * 4)<br>
-+            &amp;&amp; (!REG_P (XEXP (SET_DEST (elt), 0))<br>
-+                || offset + (i - base) * 4 != 0)))<br>
-         return false;<br>
-+      src_regno = REGNO (SET_SRC (elt));<br>
-     }<br>
-<br>
-   return true;<br>
-<br>
-=== modified file &#39;gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a>&#39;<br>
---- old/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a>        2011-01-05 12:12:18 +0000<br>
-+++ new/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a>        2011-01-05 18:20:37 +0000<br>
-@@ -20023,15 +20023,14 @@<br>
- ;;  leal    (%edx,%eax,4), %eax<br>
-<br>
- (define_peephole2<br>
--  [(parallel [(set (match_operand 0 &quot;register_operand&quot; &quot;&quot;)<br>
-+  [(match_scratch:SI 5 &quot;r&quot;)<br>
-+   (parallel [(set (match_operand 0 &quot;register_operand&quot; &quot;&quot;)<br>
-                  (ashift (match_operand 1 &quot;register_operand&quot; &quot;&quot;)<br>
-                          (match_operand 2 &quot;const_int_operand&quot; &quot;&quot;)))<br>
-              (clobber (reg:CC FLAGS_REG))])<br>
--   (set (match_operand 3 &quot;register_operand&quot;)<br>
--        (match_operand 4 &quot;x86_64_general_operand&quot; &quot;&quot;))<br>
--   (parallel [(set (match_operand 5 &quot;register_operand&quot; &quot;&quot;)<br>
--                 (plus (match_operand 6 &quot;register_operand&quot; &quot;&quot;)<br>
--                       (match_operand 7 &quot;register_operand&quot; &quot;&quot;)))<br>
-+   (parallel [(set (match_operand 3 &quot;register_operand&quot; &quot;&quot;)<br>
-+                 (plus (match_dup 0)<br>
-+                       (match_operand 4 &quot;x86_64_general_operand&quot; &quot;&quot;)))<br>
-                  (clobber (reg:CC FLAGS_REG))])]<br>
-   &quot;INTVAL (operands[2]) &gt;= 0 &amp;&amp; INTVAL (operands[2]) &lt;= 3<br>
-    /* Validate MODE for lea.  */<br>
-@@ -20041,30 +20040,21 @@<br>
-        || GET_MODE (operands[0]) == SImode<br>
-        || (TARGET_64BIT &amp;&amp; GET_MODE (operands[0]) == DImode))<br>
-    /* We reorder load and the shift.  */<br>
--   &amp;&amp; !rtx_equal_p (operands[1], operands[3])<br>
--   &amp;&amp; !reg_overlap_mentioned_p (operands[0], operands[4])<br>
--   /* Last PLUS must consist of operand 0 and 3.  */<br>
--   &amp;&amp; !rtx_equal_p (operands[0], operands[3])<br>
--   &amp;&amp; (rtx_equal_p (operands[3], operands[6])<br>
--       || rtx_equal_p (operands[3], operands[7]))<br>
--   &amp;&amp; (rtx_equal_p (operands[0], operands[6])<br>
--       || rtx_equal_p (operands[0], operands[7]))<br>
--   /* The intermediate operand 0 must die or be same as output.  */<br>
--   &amp;&amp; (rtx_equal_p (operands[0], operands[5])<br>
--       || peep2_reg_dead_p (3, operands[0]))&quot;<br>
--  [(set (match_dup 3) (match_dup 4))<br>
-+   &amp;&amp; !reg_overlap_mentioned_p (operands[0], operands[4])&quot;<br>
-+  [(set (match_dup 5) (match_dup 4))<br>
-    (set (match_dup 0) (match_dup 1))]<br>
- {<br>
--  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;<br>
-+  enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;<br>
-   int scale = 1 &lt;&lt; INTVAL (operands[2]);<br>
-   rtx index = gen_lowpart (Pmode, operands[1]);<br>
--  rtx base = gen_lowpart (Pmode, operands[3]);<br>
--  rtx dest = gen_lowpart (mode, operands[5]);<br>
-+  rtx base = gen_lowpart (Pmode, operands[5]);<br>
-+  rtx dest = gen_lowpart (mode, operands[3]);<br>
-<br>
-   operands[1] = gen_rtx_PLUS (Pmode, base,<br>
-                             gen_rtx_MULT (Pmode, index, GEN_INT (scale)));<br>
-   if (mode != Pmode)<br>
-     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);<br>
-+  operands[5] = base;<br>
-   operands[0] = dest;<br>
- })<br>
-<br>
-<br>
-=== modified file &#39;gcc/df-problems.c&#39;<br>
---- old/gcc/df-problems.c      2010-11-16 22:17:17 +0000<br>
-+++ new/gcc/df-problems.c      2010-12-02 13:42:47 +0000<br>
-@@ -3748,9 +3748,22 @@<br>
-   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)<br>
-     {<br>
-       df_ref def = *def_rec;<br>
--      /* If the def is to only part of the reg, it does<br>
--       not kill the other defs that reach here.  */<br>
--      if (!(DF_REF_FLAGS (def) &amp; (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))<br>
-+      bitmap_set_bit (defs, DF_REF_REGNO (def));<br>
-+    }<br>
-+}<br>
-+<br>
-+/* Find the set of real DEFs, which are not clobbers, for INSN.  */<br>
-+<br>
-+void<br>
-+df_simulate_find_noclobber_defs (rtx insn, bitmap defs)<br>
-+{<br>
-+  df_ref *def_rec;<br>
-+  unsigned int uid = INSN_UID (insn);<br>
-+<br>
-+  for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)<br>
-+    {<br>
-+      df_ref def = *def_rec;<br>
-+      if (!(DF_REF_FLAGS (def) &amp; (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))<br>
-       bitmap_set_bit (defs, DF_REF_REGNO (def));<br>
-     }<br>
- }<br>
-@@ -3921,7 +3934,7 @@<br>
-     {<br>
-       df_ref def = *def_rec;<br>
-       if (DF_REF_FLAGS (def) &amp; DF_REF_AT_TOP)<br>
--      bitmap_clear_bit (live, DF_REF_REGNO (def));<br>
-+      bitmap_set_bit (live, DF_REF_REGNO (def));<br>
-     }<br>
- }<br>
-<br>
-@@ -3942,7 +3955,7 @@<br>
-      while here the scan is performed forwards!  So, first assume that the<br>
-      def is live, and if this is not true REG_UNUSED notes will rectify the<br>
-      situation.  */<br>
--  df_simulate_find_defs (insn, live);<br>
-+  df_simulate_find_noclobber_defs (insn, live);<br>
-<br>
-   /* Clear all of the registers that go dead.  */<br>
-   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))<br>
-<br>
-=== modified file &#39;gcc/df.h&#39;<br>
---- old/gcc/df.h       2010-01-29 12:14:47 +0000<br>
-+++ new/gcc/df.h       2010-12-02 13:42:47 +0000<br>
-@@ -978,6 +978,7 @@<br>
- extern void df_md_add_problem (void);<br>
- extern void df_md_simulate_artificial_defs_at_top (basic_block, bitmap);<br>
- extern void df_md_simulate_one_insn (basic_block, rtx, bitmap);<br>
-+extern void df_simulate_find_noclobber_defs (rtx, bitmap);<br>
- extern void df_simulate_find_defs (rtx, bitmap);<br>
- extern void df_simulate_defs (rtx, bitmap);<br>
- extern void df_simulate_uses (rtx, bitmap);<br>
-<br>
-=== modified file &#39;gcc/fwprop.c&#39;<br>
---- old/gcc/fwprop.c   2010-04-02 18:54:46 +0000<br>
-+++ new/gcc/fwprop.c   2010-11-16 12:32:34 +0000<br>
-@@ -228,7 +228,10 @@<br>
-<br>
-   process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP);<br>
-   process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP);<br>
--  df_simulate_initialize_forwards (bb, local_lr);<br>
-+<br>
-+  /* We don&#39;t call df_simulate_initialize_forwards, as it may overestimate<br>
-+     the live registers if there are unused artificial defs.  We prefer<br>
-+     liveness to be underestimated.  */<br>
-<br>
-   FOR_BB_INSNS (bb, insn)<br>
-     if (INSN_P (insn))<br>
-<br>
-=== modified file &#39;gcc/genoutput.c&#39;<br>
---- old/gcc/genoutput.c        2009-04-08 14:00:34 +0000<br>
-+++ new/gcc/genoutput.c        2010-11-16 12:32:34 +0000<br>
-@@ -266,6 +266,8 @@<br>
-<br>
-       printf (&quot;    %d,\n&quot;, d-&gt;strict_low);<br>
-<br>
-+      printf (&quot;    %d,\n&quot;, d-&gt;constraint == NULL ? 1 : 0);<br>
-+<br>
-       printf (&quot;    %d\n&quot;, d-&gt;eliminable);<br>
-<br>
-       printf(&quot;  },\n&quot;);<br>
-<br>
-=== modified file &#39;gcc/genrecog.c&#39;<br>
---- old/gcc/genrecog.c 2009-06-22 09:29:13 +0000<br>
-+++ new/gcc/genrecog.c 2010-11-16 12:32:34 +0000<br>
-@@ -1782,20 +1782,11 @@<br>
-   int odepth = strlen (oldpos);<br>
-   int ndepth = strlen (newpos);<br>
-   int depth;<br>
--  int old_has_insn, new_has_insn;<br>
-<br>
-   /* Pop up as many levels as necessary.  */<br>
-   for (depth = odepth; strncmp (oldpos, newpos, depth) != 0; --depth)<br>
-     continue;<br>
-<br>
--  /* Hunt for the last [A-Z] in both strings.  */<br>
--  for (old_has_insn = odepth - 1; old_has_insn &gt;= 0; --old_has_insn)<br>
--    if (ISUPPER (oldpos[old_has_insn]))<br>
--      break;<br>
--  for (new_has_insn = ndepth - 1; new_has_insn &gt;= 0; --new_has_insn)<br>
--    if (ISUPPER (newpos[new_has_insn]))<br>
--      break;<br>
--<br>
-   /* Go down to desired level.  */<br>
-   while (depth &lt; ndepth)<br>
-     {<br>
-<br>
-=== modified file &#39;gcc/ifcvt.c&#39;<br>
---- old/gcc/ifcvt.c    2011-01-05 12:12:18 +0000<br>
-+++ new/gcc/ifcvt.c    2011-01-05 18:20:37 +0000<br>
-@@ -4011,6 +4011,7 @@<br>
-   basic_block new_dest = dest_edge-&gt;dest;<br>
-   rtx head, end, jump, earliest = NULL_RTX, old_dest;<br>
-   bitmap merge_set = NULL;<br>
-+  bitmap merge_set_noclobber  = NULL;<br>
-   /* Number of pending changes.  */<br>
-   int n_validated_changes = 0;<br>
-   rtx new_dest_label;<br>
-@@ -4169,6 +4170,7 @@<br>
-                      end of the block.  */<br>
-<br>
-       merge_set = BITMAP_ALLOC (&amp;reg_obstack);<br>
-+      merge_set_noclobber = BITMAP_ALLOC (&amp;reg_obstack);<br>
-<br>
-       /* If we allocated new pseudos (e.g. in the conditional move<br>
-        expander called from noce_emit_cmove), we must resize the<br>
-@@ -4187,6 +4189,7 @@<br>
-                 df_ref def = *def_rec;<br>
-                 bitmap_set_bit (merge_set, DF_REF_REGNO (def));<br>
-               }<br>
-+              df_simulate_find_noclobber_defs (insn, merge_set_noclobber);<br>
-           }<br>
-       }<br>
-<br>
-@@ -4197,7 +4200,7 @@<br>
-         unsigned i;<br>
-         bitmap_iterator bi;<br>
-<br>
--          EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)<br>
-+          EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)<br>
-           {<br>
-             if (i &lt; FIRST_PSEUDO_REGISTER<br>
-                 &amp;&amp; ! fixed_regs[i]<br>
-@@ -4233,7 +4236,7 @@<br>
-          TEST_SET &amp; DF_LIVE_IN (merge_bb)<br>
-        are empty.  */<br>
-<br>
--      if (bitmap_intersect_p (merge_set, test_set)<br>
-+      if (bitmap_intersect_p (merge_set_noclobber, test_set)<br>
-         || bitmap_intersect_p (merge_set, test_live)<br>
-         || bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))<br>
-       intersect = true;<br>
-@@ -4320,6 +4323,7 @@<br>
-           remove_reg_equal_equiv_notes_for_regno (i);<br>
-<br>
-         BITMAP_FREE (merge_set);<br>
-+          BITMAP_FREE (merge_set_noclobber);<br>
-       }<br>
-<br>
-       reorder_insns (head, end, PREV_INSN (earliest));<br>
-@@ -4340,7 +4344,10 @@<br>
-   cancel_changes (0);<br>
-  fail:<br>
-   if (merge_set)<br>
--    BITMAP_FREE (merge_set);<br>
-+    {<br>
-+      BITMAP_FREE (merge_set);<br>
-+      BITMAP_FREE (merge_set_noclobber);<br>
-+    }<br>
-   return FALSE;<br>
- }<br>
-<br>
-<br>
-=== modified file &#39;gcc/recog.c&#39;<br>
---- old/gcc/recog.c    2010-08-05 15:28:47 +0000<br>
-+++ new/gcc/recog.c    2010-11-16 12:32:34 +0000<br>
-@@ -2082,6 +2082,7 @@<br>
-                              recog_data.operand_loc,<br>
-                              recog_data.constraints,<br>
-                              recog_data.operand_mode, NULL);<br>
-+        memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);<br>
-         if (noperands &gt; 0)<br>
-           {<br>
-             const char *p =  recog_data.constraints[0];<br>
-@@ -2111,6 +2112,7 @@<br>
-       for (i = 0; i &lt; noperands; i++)<br>
-       {<br>
-         recog_data.constraints[i] = insn_data[icode].operand[i].constraint;<br>
-+        recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;<br>
-         recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;<br>
-         /* VOIDmode match_operands gets mode from their real operand.  */<br>
-         if (recog_data.operand_mode[i] == VOIDmode)<br>
-@@ -2909,6 +2911,10 @@<br>
-<br>
- static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];<br>
- static int peep2_current;<br>
-+<br>
-+static bool peep2_do_rebuild_jump_labels;<br>
-+static bool peep2_do_cleanup_cfg;<br>
-+<br>
- /* The number of instructions available to match a peep2.  */<br>
- int peep2_current_count;<br>
-<br>
-@@ -2917,6 +2923,16 @@<br>
-    DF_LIVE_OUT for the block.  */<br>
- #define PEEP2_EOB     pc_rtx<br>
-<br>
-+/* Wrap N to fit into the peep2_insn_data buffer.  */<br>
-+<br>
-+static int<br>
-+peep2_buf_position (int n)<br>
-+{<br>
-+  if (n &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
-+    n -= MAX_INSNS_PER_PEEP2 + 1;<br>
-+  return n;<br>
-+}<br>
-+<br>
- /* Return the Nth non-note insn after `current&#39;, or return NULL_RTX if it<br>
-    does not exist.  Used by the recognizer to find the next insn to match<br>
-    in a multi-insn pattern.  */<br>
-@@ -2926,9 +2942,7 @@<br>
- {<br>
-   gcc_assert (n &lt;= peep2_current_count);<br>
-<br>
--  n += peep2_current;<br>
--  if (n &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--    n -= MAX_INSNS_PER_PEEP2 + 1;<br>
-+  n = peep2_buf_position (peep2_current + n);<br>
-<br>
-   return peep2_insn_data[n].insn;<br>
- }<br>
-@@ -2941,9 +2955,7 @@<br>
- {<br>
-   gcc_assert (ofs &lt; MAX_INSNS_PER_PEEP2 + 1);<br>
-<br>
--  ofs += peep2_current;<br>
--  if (ofs &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--    ofs -= MAX_INSNS_PER_PEEP2 + 1;<br>
-+  ofs = peep2_buf_position (peep2_current + ofs);<br>
-<br>
-   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);<br>
-<br>
-@@ -2959,9 +2971,7 @@<br>
-<br>
-   gcc_assert (ofs &lt; MAX_INSNS_PER_PEEP2 + 1);<br>
-<br>
--  ofs += peep2_current;<br>
--  if (ofs &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--    ofs -= MAX_INSNS_PER_PEEP2 + 1;<br>
-+  ofs = peep2_buf_position (peep2_current + ofs);<br>
-<br>
-   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);<br>
-<br>
-@@ -2996,12 +3006,8 @@<br>
-   gcc_assert (from &lt; MAX_INSNS_PER_PEEP2 + 1);<br>
-   gcc_assert (to &lt; MAX_INSNS_PER_PEEP2 + 1);<br>
-<br>
--  from += peep2_current;<br>
--  if (from &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--    from -= MAX_INSNS_PER_PEEP2 + 1;<br>
--  to += peep2_current;<br>
--  if (to &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--    to -= MAX_INSNS_PER_PEEP2 + 1;<br>
-+  from = peep2_buf_position (peep2_current + from);<br>
-+  to = peep2_buf_position (peep2_current + to);<br>
-<br>
-   gcc_assert (peep2_insn_data[from].insn != NULL_RTX);<br>
-   REG_SET_TO_HARD_REG_SET (live, peep2_insn_data[from].live_before);<br>
-@@ -3010,8 +3016,7 @@<br>
-     {<br>
-       HARD_REG_SET this_live;<br>
-<br>
--      if (++from &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--      from = 0;<br>
-+      from = peep2_buf_position (from + 1);<br>
-       gcc_assert (peep2_insn_data[from].insn != NULL_RTX);<br>
-       REG_SET_TO_HARD_REG_SET (this_live, peep2_insn_data[from].live_before);<br>
-       IOR_HARD_REG_SET (live, this_live);<br>
-@@ -3104,19 +3109,234 @@<br>
-   COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);<br>
- }<br>
-<br>
-+/* While scanning basic block BB, we found a match of length MATCH_LEN,<br>
-+   starting at INSN.  Perform the replacement, removing the old insns and<br>
-+   replacing them with ATTEMPT.  Returns the last insn emitted.  */<br>
-+<br>
-+static rtx<br>
-+peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)<br>
-+{<br>
-+  int i;<br>
-+  rtx last, note, before_try, x;<br>
-+  bool was_call = false;<br>
-+<br>
-+  /* If we are splitting a CALL_INSN, look for the CALL_INSN<br>
-+     in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other<br>
-+     cfg-related call notes.  */<br>
-+  for (i = 0; i &lt;= match_len; ++i)<br>
-+    {<br>
-+      int j;<br>
-+      rtx old_insn, new_insn, note;<br>
-+<br>
-+      j = peep2_buf_position (peep2_current + i);<br>
-+      old_insn = peep2_insn_data[j].insn;<br>
-+      if (!CALL_P (old_insn))<br>
-+      continue;<br>
-+      was_call = true;<br>
-+<br>
-+      new_insn = attempt;<br>
-+      while (new_insn != NULL_RTX)<br>
-+      {<br>
-+        if (CALL_P (new_insn))<br>
-+          break;<br>
-+        new_insn = NEXT_INSN (new_insn);<br>
-+      }<br>
-+<br>
-+      gcc_assert (new_insn != NULL_RTX);<br>
-+<br>
-+      CALL_INSN_FUNCTION_USAGE (new_insn)<br>
-+      = CALL_INSN_FUNCTION_USAGE (old_insn);<br>
-+<br>
-+      for (note = REG_NOTES (old_insn);<br>
-+         note;<br>
-+         note = XEXP (note, 1))<br>
-+      switch (REG_NOTE_KIND (note))<br>
-+        {<br>
-+        case REG_NORETURN:<br>
-+        case REG_SETJMP:<br>
-+          add_reg_note (new_insn, REG_NOTE_KIND (note),<br>
-+                        XEXP (note, 0));<br>
-+          break;<br>
-+        default:<br>
-+          /* Discard all other reg notes.  */<br>
-+          break;<br>
-+        }<br>
-+<br>
-+      /* Croak if there is another call in the sequence.  */<br>
-+      while (++i &lt;= match_len)<br>
-+      {<br>
-+        j = peep2_buf_position (peep2_current + i);<br>
-+        old_insn = peep2_insn_data[j].insn;<br>
-+        gcc_assert (!CALL_P (old_insn));<br>
-+      }<br>
-+      break;<br>
-+    }<br>
-+<br>
-+  i = peep2_buf_position (peep2_current + match_len);<br>
-+<br>
-+  note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);<br>
-+<br>
-+  /* Replace the old sequence with the new.  */<br>
-+  last = emit_insn_after_setloc (attempt,<br>
-+                               peep2_insn_data[i].insn,<br>
-+                               INSN_LOCATOR (peep2_insn_data[i].insn));<br>
-+  before_try = PREV_INSN (insn);<br>
-+  delete_insn_chain (insn, peep2_insn_data[i].insn, false);<br>
-+<br>
-+  /* Re-insert the EH_REGION notes.  */<br>
-+  if (note || (was_call &amp;&amp; nonlocal_goto_handler_labels))<br>
-+    {<br>
-+      edge eh_edge;<br>
-+      edge_iterator ei;<br>
-+<br>
-+      FOR_EACH_EDGE (eh_edge, ei, bb-&gt;succs)<br>
-+      if (eh_edge-&gt;flags &amp; (EDGE_EH | EDGE_ABNORMAL_CALL))<br>
-+        break;<br>
-+<br>
-+      if (note)<br>
-+      copy_reg_eh_region_note_backward (note, last, before_try);<br>
-+<br>
-+      if (eh_edge)<br>
-+      for (x = last; x != before_try; x = PREV_INSN (x))<br>
-+        if (x != BB_END (bb)<br>
-+            &amp;&amp; (can_throw_internal (x)<br>
-+                || can_nonlocal_goto (x)))<br>
-+          {<br>
-+            edge nfte, nehe;<br>
-+            int flags;<br>
-+<br>
-+            nfte = split_block (bb, x);<br>
-+            flags = (eh_edge-&gt;flags<br>
-+                     &amp; (EDGE_EH | EDGE_ABNORMAL));<br>
-+            if (CALL_P (x))<br>
-+              flags |= EDGE_ABNORMAL_CALL;<br>
-+            nehe = make_edge (nfte-&gt;src, eh_edge-&gt;dest,<br>
-+                              flags);<br>
-+<br>
-+            nehe-&gt;probability = eh_edge-&gt;probability;<br>
-+            nfte-&gt;probability<br>
-+              = REG_BR_PROB_BASE - nehe-&gt;probability;<br>
-+<br>
-+            peep2_do_cleanup_cfg |= purge_dead_edges (nfte-&gt;dest);<br>
-+            bb = nfte-&gt;src;<br>
-+            eh_edge = nehe;<br>
-+          }<br>
-+<br>
-+      /* Converting possibly trapping insn to non-trapping is<br>
-+       possible.  Zap dummy outgoing edges.  */<br>
-+      peep2_do_cleanup_cfg |= purge_dead_edges (bb);<br>
-+    }<br>
-+<br>
-+  /* If we generated a jump instruction, it won&#39;t have<br>
-+     JUMP_LABEL set.  Recompute after we&#39;re done.  */<br>
-+  for (x = last; x != before_try; x = PREV_INSN (x))<br>
-+    if (JUMP_P (x))<br>
-+      {<br>
-+      peep2_do_rebuild_jump_labels = true;<br>
-+      break;<br>
-+      }<br>
-+<br>
-+  return last;<br>
-+}<br>
-+<br>
-+/* After performing a replacement in basic block BB, fix up the life<br>
-+   information in our buffer.  LAST is the last of the insns that we<br>
-+   emitted as a replacement.  PREV is the insn before the start of<br>
-+   the replacement.  MATCH_LEN is the number of instructions that were<br>
-+   matched, and which now need to be replaced in the buffer.  */<br>
-+<br>
-+static void<br>
-+peep2_update_life (basic_block bb, int match_len, rtx last, rtx prev)<br>
-+{<br>
-+  int i = peep2_buf_position (peep2_current + match_len + 1);<br>
-+  rtx x;<br>
-+  regset_head live;<br>
-+<br>
-+  INIT_REG_SET (&amp;live);<br>
-+  COPY_REG_SET (&amp;live, peep2_insn_data[i].live_before);<br>
-+<br>
-+  gcc_assert (peep2_current_count &gt;= match_len + 1);<br>
-+  peep2_current_count -= match_len + 1;<br>
-+<br>
-+  x = last;<br>
-+  do<br>
-+    {<br>
-+      if (INSN_P (x))<br>
-+      {<br>
-+        df_insn_rescan (x);<br>
-+        if (peep2_current_count &lt; MAX_INSNS_PER_PEEP2)<br>
-+          {<br>
-+            peep2_current_count++;<br>
-+            if (--i &lt; 0)<br>
-+              i = MAX_INSNS_PER_PEEP2;<br>
-+            peep2_insn_data[i].insn = x;<br>
-+            df_simulate_one_insn_backwards (bb, x, &amp;live);<br>
-+            COPY_REG_SET (peep2_insn_data[i].live_before, &amp;live);<br>
-+          }<br>
-+      }<br>
-+      x = PREV_INSN (x);<br>
-+    }<br>
-+  while (x != prev);<br>
-+  CLEAR_REG_SET (&amp;live);<br>
-+<br>
-+  peep2_current = i;<br>
-+}<br>
-+<br>
-+/* Add INSN, which is in BB, at the end of the peep2 insn buffer if possible.<br>
-+   Return true if we added it, false otherwise.  The caller will try to match<br>
-+   peepholes against the buffer if we return false; otherwise it will try to<br>
-+   add more instructions to the buffer.  */<br>
-+<br>
-+static bool<br>
-+peep2_fill_buffer (basic_block bb, rtx insn, regset live)<br>
-+{<br>
-+  int pos;<br>
-+<br>
-+  /* Once we have filled the maximum number of insns the buffer can hold,<br>
-+     allow the caller to match the insns against peepholes.  We wait until<br>
-+     the buffer is full in case the target has similar peepholes of different<br>
-+     length; we always want to match the longest if possible.  */<br>
-+  if (peep2_current_count == MAX_INSNS_PER_PEEP2)<br>
-+    return false;<br>
-+<br>
-+  /* If an insn has RTX_FRAME_RELATED_P set, peephole substitution would lose<br>
-+     the REG_FRAME_RELATED_EXPR that is attached.  */<br>
-+  if (RTX_FRAME_RELATED_P (insn))<br>
-+    {<br>
-+      /* Let the buffer drain first.  */<br>
-+      if (peep2_current_count &gt; 0)<br>
-+      return false;<br>
-+      /* Step over the insn then return true without adding the insn<br>
-+       to the buffer; this will cause us to process the next<br>
-+       insn.  */<br>
-+      df_simulate_one_insn_forwards (bb, insn, live);<br>
-+      return true;<br>
-+    }<br>
-+<br>
-+  pos = peep2_buf_position (peep2_current + peep2_current_count);<br>
-+  peep2_insn_data[pos].insn = insn;<br>
-+  COPY_REG_SET (peep2_insn_data[pos].live_before, live);<br>
-+  peep2_current_count++;<br>
-+<br>
-+  df_simulate_one_insn_forwards (bb, insn, live);<br>
-+  return true;<br>
-+}<br>
-+<br>
- /* Perform the peephole2 optimization pass.  */<br>
-<br>
- static void<br>
- peephole2_optimize (void)<br>
- {<br>
--  rtx insn, prev;<br>
-+  rtx insn;<br>
-   bitmap live;<br>
-   int i;<br>
-   basic_block bb;<br>
--  bool do_cleanup_cfg = false;<br>
--  bool do_rebuild_jump_labels = false;<br>
-+<br>
-+  peep2_do_cleanup_cfg = false;<br>
-+  peep2_do_rebuild_jump_labels = false;<br>
-<br>
-   df_set_flags (DF_LR_RUN_DCE);<br>
-+  df_note_add_problem ();<br>
-   df_analyze ();<br>
-<br>
-   /* Initialize the regsets we&#39;re going to use.  */<br>
-@@ -3126,214 +3346,59 @@<br>
-<br>
-   FOR_EACH_BB_REVERSE (bb)<br>
-     {<br>
-+      bool past_end = false;<br>
-+      int pos;<br>
-+<br>
-       rtl_profile_for_bb (bb);<br>
-<br>
-       /* Start up propagation.  */<br>
--      bitmap_copy (live, DF_LR_OUT (bb));<br>
--      df_simulate_initialize_backwards (bb, live);<br>
-+      bitmap_copy (live, DF_LR_IN (bb));<br>
-+      df_simulate_initialize_forwards (bb, live);<br>
-       peep2_reinit_state (live);<br>
-<br>
--      for (insn = BB_END (bb); ; insn = prev)<br>
-+      insn = BB_HEAD (bb);<br>
-+      for (;;)<br>
-       {<br>
--        prev = PREV_INSN (insn);<br>
--        if (NONDEBUG_INSN_P (insn))<br>
-+        rtx attempt, head;<br>
-+        int match_len;<br>
-+<br>
-+        if (!past_end &amp;&amp; !NONDEBUG_INSN_P (insn))<br>
-           {<br>
--            rtx attempt, before_try, x;<br>
--            int match_len;<br>
--            rtx note;<br>
--            bool was_call = false;<br>
--<br>
--            /* Record this insn.  */<br>
--            if (--peep2_current &lt; 0)<br>
--              peep2_current = MAX_INSNS_PER_PEEP2;<br>
--            if (peep2_current_count &lt; MAX_INSNS_PER_PEEP2<br>
--                &amp;&amp; peep2_insn_data[peep2_current].insn == NULL_RTX)<br>
--              peep2_current_count++;<br>
--            peep2_insn_data[peep2_current].insn = insn;<br>
--            df_simulate_one_insn_backwards (bb, insn, live);<br>
--            COPY_REG_SET (peep2_insn_data[peep2_current].live_before, live);<br>
--<br>
--            if (RTX_FRAME_RELATED_P (insn))<br>
--              {<br>
--                /* If an insn has RTX_FRAME_RELATED_P set, peephole<br>
--                   substitution would lose the<br>
--                   REG_FRAME_RELATED_EXPR that is attached.  */<br>
--                peep2_reinit_state (live);<br>
--                attempt = NULL;<br>
--              }<br>
--            else<br>
--              /* Match the peephole.  */<br>
--              attempt = peephole2_insns (PATTERN (insn), insn, &amp;match_len);<br>
--<br>
--            if (attempt != NULL)<br>
--              {<br>
--                /* If we are splitting a CALL_INSN, look for the CALL_INSN<br>
--                   in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other<br>
--                   cfg-related call notes.  */<br>
--                for (i = 0; i &lt;= match_len; ++i)<br>
--                  {<br>
--                    int j;<br>
--                    rtx old_insn, new_insn, note;<br>
--<br>
--                    j = i + peep2_current;<br>
--                    if (j &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--                      j -= MAX_INSNS_PER_PEEP2 + 1;<br>
--                    old_insn = peep2_insn_data[j].insn;<br>
--                    if (!CALL_P (old_insn))<br>
--                      continue;<br>
--                    was_call = true;<br>
--<br>
--                    new_insn = attempt;<br>
--                    while (new_insn != NULL_RTX)<br>
--                      {<br>
--                        if (CALL_P (new_insn))<br>
--                          break;<br>
--                        new_insn = NEXT_INSN (new_insn);<br>
--                      }<br>
--<br>
--                    gcc_assert (new_insn != NULL_RTX);<br>
--<br>
--                    CALL_INSN_FUNCTION_USAGE (new_insn)<br>
--                      = CALL_INSN_FUNCTION_USAGE (old_insn);<br>
--<br>
--                    for (note = REG_NOTES (old_insn);<br>
--                         note;<br>
--                         note = XEXP (note, 1))<br>
--                      switch (REG_NOTE_KIND (note))<br>
--                        {<br>
--                        case REG_NORETURN:<br>
--                        case REG_SETJMP:<br>
--                          add_reg_note (new_insn, REG_NOTE_KIND (note),<br>
--                                        XEXP (note, 0));<br>
--                          break;<br>
--                        default:<br>
--                          /* Discard all other reg notes.  */<br>
--                          break;<br>
--                        }<br>
--<br>
--                    /* Croak if there is another call in the sequence.  */<br>
--                    while (++i &lt;= match_len)<br>
--                      {<br>
--                        j = i + peep2_current;<br>
--                        if (j &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--                          j -= MAX_INSNS_PER_PEEP2 + 1;<br>
--                        old_insn = peep2_insn_data[j].insn;<br>
--                        gcc_assert (!CALL_P (old_insn));<br>
--                      }<br>
--                    break;<br>
--                  }<br>
--<br>
--                i = match_len + peep2_current;<br>
--                if (i &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--                  i -= MAX_INSNS_PER_PEEP2 + 1;<br>
--<br>
--                note = find_reg_note (peep2_insn_data[i].insn,<br>
--                                      REG_EH_REGION, NULL_RTX);<br>
--<br>
--                /* Replace the old sequence with the new.  */<br>
--                attempt = emit_insn_after_setloc (attempt,<br>
--                                                  peep2_insn_data[i].insn,<br>
--                                     INSN_LOCATOR (peep2_insn_data[i].insn));<br>
--                before_try = PREV_INSN (insn);<br>
--                delete_insn_chain (insn, peep2_insn_data[i].insn, false);<br>
--<br>
--                /* Re-insert the EH_REGION notes.  */<br>
--                if (note || (was_call &amp;&amp; nonlocal_goto_handler_labels))<br>
--                  {<br>
--                    edge eh_edge;<br>
--                    edge_iterator ei;<br>
--<br>
--                    FOR_EACH_EDGE (eh_edge, ei, bb-&gt;succs)<br>
--                      if (eh_edge-&gt;flags &amp; (EDGE_EH | EDGE_ABNORMAL_CALL))<br>
--                        break;<br>
--<br>
--                    if (note)<br>
--                      copy_reg_eh_region_note_backward (note, attempt,<br>
--                                                        before_try);<br>
--<br>
--                    if (eh_edge)<br>
--                      for (x = attempt ; x != before_try ; x = PREV_INSN (x))<br>
--                        if (x != BB_END (bb)<br>
--                            &amp;&amp; (can_throw_internal (x)<br>
--                                || can_nonlocal_goto (x)))<br>
--                          {<br>
--                            edge nfte, nehe;<br>
--                            int flags;<br>
--<br>
--                            nfte = split_block (bb, x);<br>
--                            flags = (eh_edge-&gt;flags<br>
--                                     &amp; (EDGE_EH | EDGE_ABNORMAL));<br>
--                            if (CALL_P (x))<br>
--                              flags |= EDGE_ABNORMAL_CALL;<br>
--                            nehe = make_edge (nfte-&gt;src, eh_edge-&gt;dest,<br>
--                                              flags);<br>
--<br>
--                            nehe-&gt;probability = eh_edge-&gt;probability;<br>
--                            nfte-&gt;probability<br>
--                              = REG_BR_PROB_BASE - nehe-&gt;probability;<br>
--<br>
--                            do_cleanup_cfg |= purge_dead_edges (nfte-&gt;dest);<br>
--                            bb = nfte-&gt;src;<br>
--                            eh_edge = nehe;<br>
--                          }<br>
--<br>
--                    /* Converting possibly trapping insn to non-trapping is<br>
--                       possible.  Zap dummy outgoing edges.  */<br>
--                    do_cleanup_cfg |= purge_dead_edges (bb);<br>
--                  }<br>
--<br>
--                if (targetm.have_conditional_execution ())<br>
--                  {<br>
--                    for (i = 0; i &lt; MAX_INSNS_PER_PEEP2 + 1; ++i)<br>
--                      peep2_insn_data[i].insn = NULL_RTX;<br>
--                    peep2_insn_data[peep2_current].insn = PEEP2_EOB;<br>
--                    peep2_current_count = 0;<br>
--                  }<br>
--                else<br>
--                  {<br>
--                    /* Back up lifetime information past the end of the<br>
--                       newly created sequence.  */<br>
--                    if (++i &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
--                      i = 0;<br>
--                    bitmap_copy (live, peep2_insn_data[i].live_before);<br>
--<br>
--                    /* Update life information for the new sequence.  */<br>
--                    x = attempt;<br>
--                    do<br>
--                      {<br>
--                        if (INSN_P (x))<br>
--                          {<br>
--                            if (--i &lt; 0)<br>
--                              i = MAX_INSNS_PER_PEEP2;<br>
--                            if (peep2_current_count &lt; MAX_INSNS_PER_PEEP2<br>
--                                &amp;&amp; peep2_insn_data[i].insn == NULL_RTX)<br>
--                              peep2_current_count++;<br>
--                            peep2_insn_data[i].insn = x;<br>
--                            df_insn_rescan (x);<br>
--                            df_simulate_one_insn_backwards (bb, x, live);<br>
--                            bitmap_copy (peep2_insn_data[i].live_before,<br>
--                                         live);<br>
--                          }<br>
--                        x = PREV_INSN (x);<br>
--                      }<br>
--                    while (x != prev);<br>
--<br>
--                    peep2_current = i;<br>
--                  }<br>
--<br>
--                /* If we generated a jump instruction, it won&#39;t have<br>
--                   JUMP_LABEL set.  Recompute after we&#39;re done.  */<br>
--                for (x = attempt; x != before_try; x = PREV_INSN (x))<br>
--                  if (JUMP_P (x))<br>
--                    {<br>
--                      do_rebuild_jump_labels = true;<br>
--                      break;<br>
--                    }<br>
--              }<br>
-+          next_insn:<br>
-+            insn = NEXT_INSN (insn);<br>
-+            if (insn == NEXT_INSN (BB_END (bb)))<br>
-+              past_end = true;<br>
-+            continue;<br>
-           }<br>
-+        if (!past_end &amp;&amp; peep2_fill_buffer (bb, insn, live))<br>
-+          goto next_insn;<br>
-<br>
--        if (insn == BB_HEAD (bb))<br>
-+        /* If we did not fill an empty buffer, it signals the end of the<br>
-+           block.  */<br>
-+        if (peep2_current_count == 0)<br>
-           break;<br>
-+<br>
-+        /* The buffer filled to the current maximum, so try to match.  */<br>
-+<br>
-+        pos = peep2_buf_position (peep2_current + peep2_current_count);<br>
-+        peep2_insn_data[pos].insn = PEEP2_EOB;<br>
-+        COPY_REG_SET (peep2_insn_data[pos].live_before, live);<br>
-+<br>
-+        /* Match the peephole.  */<br>
-+        head = peep2_insn_data[peep2_current].insn;<br>
-+        attempt = peephole2_insns (PATTERN (head), head, &amp;match_len);<br>
-+        if (attempt != NULL)<br>
-+          {<br>
-+            rtx last;<br>
-+            last = peep2_attempt (bb, head, match_len, attempt);<br>
-+            peep2_update_life (bb, match_len, last, PREV_INSN (attempt));<br>
-+          }<br>
-+        else<br>
-+          {<br>
-+            /* If no match, advance the buffer by one insn.  */<br>
-+            peep2_current = peep2_buf_position (peep2_current + 1);<br>
-+            peep2_current_count--;<br>
-+          }<br>
-       }<br>
-     }<br>
-<br>
-@@ -3341,7 +3406,7 @@<br>
-   for (i = 0; i &lt; MAX_INSNS_PER_PEEP2 + 1; ++i)<br>
-     BITMAP_FREE (peep2_insn_data[i].live_before);<br>
-   BITMAP_FREE (live);<br>
--  if (do_rebuild_jump_labels)<br>
-+  if (peep2_do_rebuild_jump_labels)<br>
-     rebuild_jump_labels (get_insns ());<br>
- }<br>
- #endif /* HAVE_peephole2 */<br>
-<br>
-=== modified file &#39;gcc/recog.h&#39;<br>
---- old/gcc/recog.h    2009-10-26 21:55:59 +0000<br>
-+++ new/gcc/recog.h    2010-11-16 12:32:34 +0000<br>
-@@ -194,6 +194,9 @@<br>
-   /* Gives the constraint string for operand N.  */<br>
-   const char *constraints[MAX_RECOG_OPERANDS];<br>
-<br>
-+  /* Nonzero if operand N is a match_operator or a match_parallel.  */<br>
-+  char is_operator[MAX_RECOG_OPERANDS];<br>
-+<br>
-   /* Gives the mode of operand N.  */<br>
-   enum machine_mode operand_mode[MAX_RECOG_OPERANDS];<br>
-<br>
-@@ -260,6 +263,8 @@<br>
-<br>
-   const char strict_low;<br>
-<br>
-+  const char is_operator;<br>
-+<br>
-   const char eliminable;<br>
- };<br>
-<br>
-<br>
-=== modified file &#39;gcc/reload.c&#39;<br>
---- old/gcc/reload.c   2009-12-21 16:32:44 +0000<br>
-+++ new/gcc/reload.c   2010-11-16 12:32:34 +0000<br>
-@@ -3631,7 +3631,7 @@<br>
-                  || modified[j] != RELOAD_WRITE)<br>
-                 &amp;&amp; j != i<br>
-                 /* Ignore things like match_operator operands.  */<br>
--                &amp;&amp; *recog_data.constraints[j] != 0<br>
-+                &amp;&amp; !recog_data.is_operator[j]<br>
-                 /* Don&#39;t count an input operand that is constrained to match<br>
-                    the early clobber operand.  */<br>
-                 &amp;&amp; ! (this_alternative_matches[j] == i<br>
-<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99464.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99464.patch<br>
new file mode 100644<br>
index 0000000..e8c8e63<br>
--- /dev/null<br>
+++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99464.patch<br>
@@ -0,0 +1,157 @@<br>
+       LP: #681138<br>
+       Backport from mainline:<br>
+<br>
+       gcc/<br>
+       * config/arm/<a href="http://sync.md" target="_blank">sync.md</a> (sync_clobber, sync_t2_reqd): New code attribute.<br>
+       (arm_sync_old_&lt;sync_optab&gt;si, arm_sync_old_&lt;sync_optab&gt;&lt;mode&gt;): Use<br>
+       the sync_clobber and sync_t2_reqd code attributes.<br>
+       * config/arm/arm.c (arm_output_sync_loop): Reverse the operation if<br>
+       the t2 argument is NULL.<br>
+<br>
+=== modified file &#39;gcc/config/arm/arm.c&#39;<br>
+Index: gcc-4_5-branch/gcc/config/arm/arm.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/arm.c<br>
++++ gcc-4_5-branch/gcc/config/arm/arm.c<br>
+@@ -23098,10 +23098,46 @@ arm_output_sync_loop (emit_f emit,<br>
+       break;<br>
+     }<br>
+<br>
+-  arm_output_strex (emit, mode, &quot;&quot;, t2, t1, memory);<br>
+-  operands[0] = t2;<br>
+-  arm_output_asm_insn (emit, 0, operands, &quot;teq\t%%0, #0&quot;);<br>
+-  arm_output_asm_insn (emit, 0, operands, &quot;bne\t%sLSYT%%=&quot;, LOCAL_LABEL_PREFIX);<br>
++  if (t2)<br>
++    {<br>
++       arm_output_strex (emit, mode, &quot;&quot;, t2, t1, memory);<br>
++       operands[0] = t2;<br>
++       arm_output_asm_insn (emit, 0, operands, &quot;teq\t%%0, #0&quot;);<br>
++       arm_output_asm_insn (emit, 0, operands, &quot;bne\t%sLSYT%%=&quot;,<br>
++                          LOCAL_LABEL_PREFIX);<br>
++    }<br>
++  else<br>
++    {<br>
++      /* Use old_value for the return value because for some operations<br>
++       the old_value can easily be restored.  This saves one register.  */<br>
++      arm_output_strex (emit, mode, &quot;&quot;, old_value, t1, memory);<br>
++      operands[0] = old_value;<br>
++      arm_output_asm_insn (emit, 0, operands, &quot;teq\t%%0, #0&quot;);<br>
++      arm_output_asm_insn (emit, 0, operands, &quot;bne\t%sLSYT%%=&quot;,<br>
++                         LOCAL_LABEL_PREFIX);<br>
++<br>
++      switch (sync_op)<br>
++      {<br>
++      case SYNC_OP_ADD:<br>
++        arm_output_op3 (emit, &quot;sub&quot;, old_value, t1, new_value);<br>
++        break;<br>
++<br>
++      case SYNC_OP_SUB:<br>
++        arm_output_op3 (emit, &quot;add&quot;, old_value, t1, new_value);<br>
++        break;<br>
++<br>
++      case SYNC_OP_XOR:<br>
++        arm_output_op3 (emit, &quot;eor&quot;, old_value, t1, new_value);<br>
++        break;<br>
++<br>
++      case SYNC_OP_NONE:<br>
++        arm_output_op2 (emit, &quot;mov&quot;, old_value, required_value);<br>
++        break;<br>
++<br>
++      default:<br>
++        gcc_unreachable ();<br>
++      }<br>
++    }<br>
+<br>
+   arm_process_output_memory_barrier (emit, NULL);<br>
+   arm_output_asm_insn (emit, 1, operands, &quot;%sLSYB%%=:&quot;, LOCAL_LABEL_PREFIX);<br>
+Index: gcc-4_5-branch/gcc/config/arm/<a href="http://sync.md" target="_blank">sync.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/<a href="http://sync.md" target="_blank">sync.md</a><br>
++++ gcc-4_5-branch/gcc/config/arm/<a href="http://sync.md" target="_blank">sync.md</a><br>
+@@ -103,6 +103,18 @@<br>
+                             (plus &quot;add&quot;)<br>
+                             (minus &quot;sub&quot;)])<br>
+<br>
++(define_code_attr sync_clobber [(ior &quot;=&amp;r&quot;)<br>
++                              (and &quot;=&amp;r&quot;)<br>
++                              (xor &quot;X&quot;)<br>
++                              (plus &quot;X&quot;)<br>
++                              (minus &quot;X&quot;)])<br>
++<br>
++(define_code_attr sync_t2_reqd [(ior &quot;4&quot;)<br>
++                              (and &quot;4&quot;)<br>
++                              (xor &quot;*&quot;)<br>
++                              (plus &quot;*&quot;)<br>
++                              (minus &quot;*&quot;)])<br>
++<br>
+ (define_expand &quot;sync_&lt;sync_optab&gt;si&quot;<br>
+   [(match_operand:SI 0 &quot;memory_operand&quot;)<br>
+    (match_operand:SI 1 &quot;s_register_operand&quot;)<br>
+@@ -286,7 +298,6 @@<br>
+         VUNSPEC_SYNC_COMPARE_AND_SWAP))<br>
+    (set (match_dup 1) (unspec_volatile:SI [(match_dup 2)]<br>
+                                           VUNSPEC_SYNC_COMPARE_AND_SWAP))<br>
+-   (clobber:SI (match_scratch:SI 4 &quot;=&amp;r&quot;))<br>
+    (set (reg:CC CC_REGNUM) (unspec_volatile:CC [(match_dup 1)]<br>
+                                                 VUNSPEC_SYNC_COMPARE_AND_SWAP))<br>
+    ]<br>
+@@ -299,7 +310,6 @@<br>
+    (set_attr &quot;sync_required_value&quot;  &quot;2&quot;)<br>
+    (set_attr &quot;sync_new_value&quot;       &quot;3&quot;)<br>
+    (set_attr &quot;sync_t1&quot;              &quot;0&quot;)<br>
+-   (set_attr &quot;sync_t2&quot;              &quot;4&quot;)<br>
+    (set_attr &quot;conds&quot; &quot;clob&quot;)<br>
+    (set_attr &quot;predicable&quot; &quot;no&quot;)])<br>
+<br>
+@@ -313,7 +323,6 @@<br>
+           VUNSPEC_SYNC_COMPARE_AND_SWAP)))<br>
+    (set (match_dup 1) (unspec_volatile:NARROW [(match_dup 2)]<br>
+                                           VUNSPEC_SYNC_COMPARE_AND_SWAP))<br>
+-   (clobber:SI (match_scratch:SI 4 &quot;=&amp;r&quot;))<br>
+    (set (reg:CC CC_REGNUM) (unspec_volatile:CC [(match_dup 1)]<br>
+                                                 VUNSPEC_SYNC_COMPARE_AND_SWAP))<br>
+    ]<br>
+@@ -326,7 +335,6 @@<br>
+    (set_attr &quot;sync_required_value&quot;  &quot;2&quot;)<br>
+    (set_attr &quot;sync_new_value&quot;       &quot;3&quot;)<br>
+    (set_attr &quot;sync_t1&quot;              &quot;0&quot;)<br>
+-   (set_attr &quot;sync_t2&quot;              &quot;4&quot;)<br>
+    (set_attr &quot;conds&quot; &quot;clob&quot;)<br>
+    (set_attr &quot;predicable&quot; &quot;no&quot;)])<br>
+<br>
+@@ -487,7 +495,7 @@<br>
+                           VUNSPEC_SYNC_OLD_OP))<br>
+    (clobber (reg:CC CC_REGNUM))<br>
+    (clobber (match_scratch:SI 3 &quot;=&amp;r&quot;))<br>
+-   (clobber (match_scratch:SI 4 &quot;=&amp;r&quot;))]<br>
++   (clobber (match_scratch:SI 4 &quot;&lt;sync_clobber&gt;&quot;))]<br>
+   &quot;TARGET_HAVE_LDREX &amp;&amp; TARGET_HAVE_MEMORY_BARRIER&quot;<br>
+   {<br>
+     return arm_output_sync_insn (insn, operands);<br>
+@@ -496,7 +504,7 @@<br>
+    (set_attr &quot;sync_memory&quot;          &quot;1&quot;)<br>
+    (set_attr &quot;sync_new_value&quot;       &quot;2&quot;)<br>
+    (set_attr &quot;sync_t1&quot;              &quot;3&quot;)<br>
+-   (set_attr &quot;sync_t2&quot;              &quot;4&quot;)<br>
++   (set_attr &quot;sync_t2&quot;              &quot;&lt;sync_t2_reqd&gt;&quot;)<br>
+    (set_attr &quot;sync_op&quot;              &quot;&lt;sync_optab&gt;&quot;)<br>
+    (set_attr &quot;conds&quot; &quot;clob&quot;)<br>
+    (set_attr &quot;predicable&quot; &quot;no&quot;)])<br>
+@@ -540,7 +548,7 @@<br>
+                           VUNSPEC_SYNC_OLD_OP))<br>
+    (clobber (reg:CC CC_REGNUM))<br>
+    (clobber (match_scratch:SI 3 &quot;=&amp;r&quot;))<br>
+-   (clobber (match_scratch:SI 4 &quot;=&amp;r&quot;))]<br>
++   (clobber (match_scratch:SI 4 &quot;&lt;sync_clobber&gt;&quot;))]<br>
+   &quot;TARGET_HAVE_LDREXBHD &amp;&amp; TARGET_HAVE_MEMORY_BARRIER&quot;<br>
+   {<br>
+     return arm_output_sync_insn (insn, operands);<br>
+@@ -549,7 +557,7 @@<br>
+    (set_attr &quot;sync_memory&quot;          &quot;1&quot;)<br>
+    (set_attr &quot;sync_new_value&quot;       &quot;2&quot;)<br>
+    (set_attr &quot;sync_t1&quot;              &quot;3&quot;)<br>
+-   (set_attr &quot;sync_t2&quot;              &quot;4&quot;)<br>
++   (set_attr &quot;sync_t2&quot;              &quot;&lt;sync_t2_reqd&gt;&quot;)<br>
+    (set_attr &quot;sync_op&quot;              &quot;&lt;sync_optab&gt;&quot;)<br>
+    (set_attr &quot;conds&quot;              &quot;clob&quot;)<br>
+    (set_attr &quot;predicable&quot; &quot;no&quot;)])<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99465.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99465.patch<br>
new file mode 100644<br>
index 0000000..32c2999<br>
--- /dev/null<br>
+++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99465.patch<br>
@@ -0,0 +1,94 @@<br>
+2011-01-18  Ulrich Weigand  &lt;<a href="mailto:uweigand@de.ibm.com">uweigand@de.ibm.com</a>&gt;<br>
+<br>
+       LP: #685352<br>
+       Backport from mainline:<br>
+<br>
+       2011-01-18  Jakub Jelinek  &lt;<a href="mailto:jakub@redhat.com">jakub@redhat.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       PR rtl-optimization/47299<br>
+       * expr.c (expand_expr_real_2) &lt;case WIDEN_MULT_EXPR&gt;: Don&#39;t use<br>
+       subtarget.  Use normal multiplication if both operands are<br>
+       constants.<br>
+       * expmed.c (expand_widening_mult): Don&#39;t try to optimize constant<br>
+       multiplication if op0 has VOIDmode.  Convert op1 constant to mode<br>
+       before using it.<br>
+<br>
+       gcc/testsuite/<br>
+       PR rtl-optimization/47299<br>
+       * gcc.c-torture/execute/pr47299.c: New test.<br>
+<br>
+=== modified file &#39;gcc/expmed.c&#39;<br>
+Index: gcc-4_5-branch/gcc/expmed.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/expmed.c<br>
++++ gcc-4_5-branch/gcc/expmed.c<br>
+@@ -3355,12 +3355,17 @@ expand_widening_mult (enum machine_mode<br>
+                     int unsignedp, optab this_optab)<br>
+ {<br>
+   bool speed = optimize_insn_for_speed_p ();<br>
++  rtx cop1;<br>
+<br>
+   if (CONST_INT_P (op1)<br>
+-      &amp;&amp; (INTVAL (op1) &gt;= 0<br>
++      &amp;&amp; GET_MODE (op0) != VOIDmode<br>
++      &amp;&amp; (cop1 = convert_modes (mode, GET_MODE (op0), op1,<br>
++                              this_optab == umul_widen_optab))<br>
++      &amp;&amp; CONST_INT_P (cop1)<br>
++      &amp;&amp; (INTVAL (cop1) &gt;= 0<br>
+         || GET_MODE_BITSIZE (mode) &lt;= HOST_BITS_PER_WIDE_INT))<br>
+     {<br>
+-      HOST_WIDE_INT coeff = INTVAL (op1);<br>
++      HOST_WIDE_INT coeff = INTVAL (cop1);<br>
+       int max_cost;<br>
+       enum mult_variant variant;<br>
+       struct algorithm algorithm;<br>
+Index: gcc-4_5-branch/gcc/expr.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/expr.c<br>
++++ gcc-4_5-branch/gcc/expr.c<br>
+@@ -7624,10 +7624,10 @@ expand_expr_real_2 (sepops ops, rtx targ<br>
+             if (optab_handler (this_optab, mode)-&gt;insn_code != CODE_FOR_nothing)<br>
+               {<br>
+                 if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))<br>
+-                  expand_operands (treeop0, treeop1, subtarget, &amp;op0, &amp;op1,<br>
++                  expand_operands (treeop0, treeop1, NULL_RTX, &amp;op0, &amp;op1,<br>
+                                    EXPAND_NORMAL);<br>
+                 else<br>
+-                  expand_operands (treeop0, treeop1, subtarget, &amp;op1, &amp;op0,<br>
++                  expand_operands (treeop0, treeop1, NULL_RTX, &amp;op1, &amp;op0,<br>
+                                    EXPAND_NORMAL);<br>
+                 goto binop3;<br>
+               }<br>
+@@ -7645,7 +7645,8 @@ expand_expr_real_2 (sepops ops, rtx targ<br>
+         optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;<br>
+         this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;<br>
+<br>
+-        if (mode == GET_MODE_2XWIDER_MODE (innermode))<br>
++        if (mode == GET_MODE_2XWIDER_MODE (innermode)<br>
++            &amp;&amp; TREE_CODE (treeop0) != INTEGER_CST)<br>
+           {<br>
+             if (optab_handler (this_optab, mode)-&gt;insn_code != CODE_FOR_nothing)<br>
+               {<br>
+Index: gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr47299.c<br>
+===================================================================<br>
+--- /dev/null<br>
++++ gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr47299.c<br>
+@@ -0,0 +1,17 @@<br>
++/* PR rtl-optimization/47299 */<br>
++<br>
++extern void abort (void);<br>
++<br>
++__attribute__ ((noinline, noclone)) unsigned short<br>
++foo (unsigned char x)<br>
++{<br>
++  return x * 255;<br>
++}<br>
++<br>
++int<br>
++main ()<br>
++{<br>
++  if (foo (0x40) != 0x3fc0)<br>
++    abort ();<br>
++  return 0;<br>
++}<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99466.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99466.patch<br>
new file mode 100644<br>
index 0000000..580d4f4<br>
--- /dev/null<br>
+++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99466.patch<br>
@@ -0,0 +1,38 @@<br>
+2011-01-19  Ramana Radhakrishnan  &lt;<a href="mailto:ramana.radhakrishnan@arm.com">ramana.radhakrishnan@arm.com</a>&gt;<br>
+<br>
+       Backport from FSF mainline<br>
+<br>
+       2011-01-18  Ramana Radhakrishnan  &lt;<a href="mailto:ramana.radhakrishnan@arm.com">ramana.radhakrishnan@arm.com</a>&gt;<br>
+<br>
+        * config/arm/<a href="http://cortex-a9.md" target="_blank">cortex-a9.md</a> (<a href="http://cortex-a9-neon.md" target="_blank">cortex-a9-neon.md</a>): Actually<br>
+        include.<br>
+        (cortex_a9_dp): Handle neon types correctly.<br>
+<br>
+=== modified file &#39;gcc/config/arm/<a href="http://cortex-a9.md" target="_blank">cortex-a9.md</a>&#39;<br>
+Index: gcc-4_5-branch/gcc/config/arm/<a href="http://cortex-a9.md" target="_blank">cortex-a9.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/<a href="http://cortex-a9.md" target="_blank">cortex-a9.md</a><br>
++++ gcc-4_5-branch/gcc/config/arm/<a href="http://cortex-a9.md" target="_blank">cortex-a9.md</a><br>
+@@ -79,10 +79,11 @@ cortex_a9_p1_e2 + cortex_a9_p0_e1 + cort<br>
+ ;; which can go down E2 without any problem.<br>
+ (define_insn_reservation &quot;cortex_a9_dp&quot; 2<br>
+   (and (eq_attr &quot;tune&quot; &quot;cortexa9&quot;)<br>
+-       (ior (eq_attr &quot;type&quot; &quot;alu&quot;)<br>
+-          (ior (and (eq_attr &quot;type&quot; &quot;alu_shift_reg, alu_shift&quot;)<br>
+-               (eq_attr &quot;insn&quot; &quot;mov&quot;))<br>
+-               (eq_attr &quot;neon_type&quot; &quot;none&quot;))))<br>
++         (ior (and (eq_attr &quot;type&quot; &quot;alu&quot;)<br>
++                        (eq_attr &quot;neon_type&quot; &quot;none&quot;))<br>
++            (and (and (eq_attr &quot;type&quot; &quot;alu_shift_reg, alu_shift&quot;)<br>
++                      (eq_attr &quot;insn&quot; &quot;mov&quot;))<br>
++                 (eq_attr &quot;neon_type&quot; &quot;none&quot;))))<br>
+   &quot;cortex_a9_p0_default|cortex_a9_p1_default&quot;)<br>
+<br>
+ ;; An instruction using the shifter will go down E1.<br>
+@@ -263,3 +264,6 @@ cortex_a9_store3_4, cortex_a9_store1_2,<br>
+   (and (eq_attr &quot;tune&quot; &quot;cortexa9&quot;)<br>
+        (eq_attr &quot;type&quot; &quot;fdivd&quot;))<br>
+   &quot;ca9fp_ds1 + ca9_issue_vfp_neon, nothing*24&quot;)<br>
++<br>
++;; Include Neon pipeline description<br>
++(include &quot;<a href="http://cortex-a9-neon.md" target="_blank">cortex-a9-neon.md</a>&quot;)<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99468.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99468.patch<br>
new file mode 100644<br>
index 0000000..cf22aaf<br>
--- /dev/null<br>
+++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99468.patch<br>
@@ -0,0 +1,811 @@<br>
+2010-12-13  Tom de Vries  &lt;<a href="mailto:tom@codesourcery.com">tom@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       * tree-if-switch-conversion.c: New pass.<br>
+       * tree-pass.h (pass_if_to_switch): Declare.<br>
+       * common.opt (ftree-if-to-switch-conversion): New switch.<br>
+       * opts.c (decode_options): Set flag_tree_if_to_switch_conversion at -O2<br>
+       and higher.<br>
+       * passes.c (init_optimization_passes): Use new pass.<br>
+       * params.def (PARAM_IF_TO_SWITCH_THRESHOLD): New param.<br>
+       * doc/invoke.texi (-ftree-if-to-switch-conversion)<br>
+       (if-to-switch-threshold): New item.<br>
+       * doc/invoke.texi (Optimization Options, option -O2): Add<br>
+       -ftree-if-to-switch-conversion.<br>
+       * Makefile.in (OBJS-common): Add tree-if-switch-conversion.o.<br>
+       * Makefile.in (tree-if-switch-conversion.o): New rule.<br>
+<br>
+=== modified file &#39;gcc/Makefile.in&#39;<br>
+Index: gcc-4_5-branch/gcc/Makefile.in<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/Makefile.in<br>
++++ gcc-4_5-branch/gcc/Makefile.in<br>
+@@ -1354,6 +1354,7 @@ OBJS-common = \<br>
+       tree-profile.o \<br>
+       tree-scalar-evolution.o \<br>
+       tree-sra.o \<br>
++      tree-if-switch-conversion.o \<br>
+       tree-switch-conversion.o \<br>
+       tree-ssa-address.o \<br>
+       tree-ssa-alias.o \<br>
+@@ -3013,6 +3014,11 @@ tree-sra.o : tree-sra.c $(CONFIG_H) $(SY<br>
+    $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) $(IPA_PROP_H) \<br>
+    $(DIAGNOSTIC_H) statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) \<br>
+    $(TARGET_H) $(FLAGS_H) $(EXPR_H) $(TREE_INLINE_H)<br>
++tree-if-switch-conversion.o : tree-if-switch-conversion.c $(CONFIG_H) \<br>
++    $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) \<br>
++    $(TREE_INLINE_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \<br>
++    $(GIMPLE_H) $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) output.h \<br>
++    $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H)<br>
+ tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \<br>
+     $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \<br>
+     $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \<br>
+Index: gcc-4_5-branch/gcc/common.opt<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/common.opt<br>
++++ gcc-4_5-branch/gcc/common.opt<br>
+@@ -1285,6 +1285,10 @@ ftree-switch-conversion<br>
+ Common Report Var(flag_tree_switch_conversion) Optimization<br>
+ Perform conversions of switch initializations.<br>
+<br>
++ftree-if-to-switch-conversion<br>
++Common Report Var(flag_tree_if_to_switch_conversion) Optimization<br>
++Perform conversions of chains of ifs into switches.<br>
++<br>
+ ftree-dce<br>
+ Common Report Var(flag_tree_dce) Optimization<br>
+ Enable SSA dead code elimination optimization on trees<br>
+Index: gcc-4_5-branch/gcc/doc/invoke.texi<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/doc/invoke.texi<br>
++++ gcc-4_5-branch/gcc/doc/invoke.texi<br>
+@@ -382,7 +382,8 @@ Objective-C and Objective-C++ Dialects}.<br>
+ -fstrict-aliasing -fstrict-overflow -fthread-jumps -ftracer @gol<br>
+ -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copy-prop @gol<br>
+ -ftree-copyrename -ftree-dce @gol<br>
+--ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-loop-im @gol<br>
++-ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre @gol<br>
++-ftree-if-to-switch-conversion -ftree-loop-im @gol<br>
+ -ftree-phiprop -ftree-loop-distribution @gol<br>
+ -ftree-loop-ivcanon -ftree-loop-linear -ftree-loop-optimize @gol<br>
+ -ftree-parallelize-loops=@var{n} -ftree-pre -ftree-pta -ftree-reassoc @gol<br>
+@@ -5798,6 +5799,7 @@ also turns on the following optimization<br>
+ -fsched-interblock  -fsched-spec @gol<br>
+ -fschedule-insns  -fschedule-insns2 @gol<br>
+ -fstrict-aliasing -fstrict-overflow @gol<br>
++-ftree-if-to-switch-conversion @gol<br>
+ -ftree-switch-conversion @gol<br>
+ -ftree-pre @gol<br>
+ -ftree-vrp}<br>
+@@ -6634,6 +6636,10 @@ Perform conversion of simple initializat<br>
+ initializations from a scalar array.  This flag is enabled by default<br>
+ at @option{-O2} and higher.<br>
+<br>
++@item -ftree-if-to-switch-conversion<br>
++Perform conversion of chains of ifs into switches.  This flag is enabled by<br>
++default at @option{-O2} and higher.<br>
++<br>
+ @item -ftree-dce<br>
+ @opindex ftree-dce<br>
+ Perform dead code elimination (DCE) on trees.  This flag is enabled by<br>
+@@ -8577,6 +8583,12 @@ loop in the loop nest by a given number<br>
+ length can be changed using the @option{loop-block-tile-size}<br>
+ parameter.  The default value is 51 iterations.<br>
+<br>
++@item if-to-switch-threshold<br>
++If-chain to switch conversion, enabled by<br>
++@option{-ftree-if-to-switch-conversion} convert chains of ifs of sufficient<br>
++length into switches.  The parameter @option{if-to-switch-threshold} can be<br>
++used to set the minimal required length.  The default value is 3.<br>
++<br>
+ @end table<br>
+ @end table<br>
+<br>
+Index: gcc-4_5-branch/gcc/opts.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/opts.c<br>
++++ gcc-4_5-branch/gcc/opts.c<br>
+@@ -905,6 +905,7 @@ decode_options (unsigned int argc, const<br>
+   flag_tree_builtin_call_dce = opt2;<br>
+   flag_tree_pre = opt2;<br>
+   flag_tree_switch_conversion = opt2;<br>
++  flag_tree_if_to_switch_conversion = opt2;<br>
+   flag_ipa_cp = opt2;<br>
+   flag_ipa_sra = opt2;<br>
+   flag_ee = opt2;<br>
+Index: gcc-4_5-branch/gcc/params.def<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/params.def<br>
++++ gcc-4_5-branch/gcc/params.def<br>
+@@ -826,6 +826,11 @@ DEFPARAM (PARAM_IPA_SRA_PTR_GROWTH_FACTO<br>
+         &quot;a pointer to an aggregate with&quot;,<br>
+         2, 0, 0)<br>
+<br>
++DEFPARAM (PARAM_IF_TO_SWITCH_THRESHOLD,<br>
++        &quot;if-to-switch-threshold&quot;,<br>
++        &quot;Threshold for converting an if-chain into a switch&quot;,<br>
++        3, 0, 0)<br>
++<br>
+ /*<br>
+ Local variables:<br>
+ mode:c<br>
+Index: gcc-4_5-branch/gcc/passes.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/passes.c<br>
++++ gcc-4_5-branch/gcc/passes.c<br>
+@@ -788,6 +788,7 @@ init_optimization_passes (void)<br>
+         NEXT_PASS (pass_cd_dce);<br>
+         NEXT_PASS (pass_early_ipa_sra);<br>
+         NEXT_PASS (pass_tail_recursion);<br>
++        NEXT_PASS (pass_if_to_switch);<br>
+         NEXT_PASS (pass_convert_switch);<br>
+           NEXT_PASS (pass_cleanup_eh);<br>
+           NEXT_PASS (pass_profile);<br>
+@@ -844,6 +845,7 @@ init_optimization_passes (void)<br>
+       NEXT_PASS (pass_phiprop);<br>
+       NEXT_PASS (pass_fre);<br>
+       NEXT_PASS (pass_copy_prop);<br>
++      NEXT_PASS (pass_if_to_switch);<br>
+       NEXT_PASS (pass_merge_phi);<br>
+       NEXT_PASS (pass_vrp);<br>
+       NEXT_PASS (pass_dce);<br>
+Index: gcc-4_5-branch/gcc/tree-if-switch-conversion.c<br>
+===================================================================<br>
+--- /dev/null<br>
++++ gcc-4_5-branch/gcc/tree-if-switch-conversion.c<br>
+@@ -0,0 +1,643 @@<br>
++/* Convert a chain of ifs into a switch.<br>
++   Copyright (C) 2010 Free Software Foundation, Inc.<br>
++   Contributed by Tom de Vries &lt;<a href="mailto:tom@codesourcery.com">tom@codesourcery.com</a>&gt;<br>
++<br>
++This file is part of GCC.<br>
++<br>
++GCC is free software; you can redistribute it and/or modify it<br>
++under the terms of the GNU General Public License as published by the<br>
++Free Software Foundation; either version 3, or (at your option) any<br>
++later version.<br>
++<br>
++GCC is distributed in the hope that it will be useful, but WITHOUT<br>
++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or<br>
++FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License<br>
++for more details.<br>
++<br>
++You should have received a copy of the GNU General Public License<br>
++along with GCC; see the file COPYING3.  If not, write to the Free<br>
++Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA<br>
++02110-1301, USA.  */<br>
++<br>
++<br>
++/* The following pass converts a chain of ifs into a switch.<br>
++<br>
++   The if-chain has the following properties:<br>
++   - all bbs end in a GIMPLE_COND.<br>
++   - all but the first bb are empty, apart from the GIMPLE_COND.<br>
++   - the GIMPLE_CONDs compare the same variable against integer constants.<br>
++   - the true gotos all target the same bb.<br>
++   - the false gotos target the next in the if-chain.<br>
++<br>
++   F.i., consider the following if-chain:<br>
++   ...<br>
++   &lt;bb 4&gt;:<br>
++   ...<br>
++   if (D.1993_3 == 32)<br>
++     goto &lt;bb 3&gt;;<br>
++   else<br>
++     goto &lt;bb 5&gt;;<br>
++<br>
++   &lt;bb 5&gt;:<br>
++   if (D.1993_3 == 13)<br>
++     goto &lt;bb 3&gt;;<br>
++   else<br>
++     goto &lt;bb 6&gt;;<br>
++<br>
++   &lt;bb 6&gt;:<br>
++   if (D.1993_3 == 10)<br>
++     goto &lt;bb 3&gt;;<br>
++   else<br>
++     goto &lt;bb 7&gt;;<br>
++<br>
++   &lt;bb 7&gt;:<br>
++   if (D.1993_3 == 9)<br>
++     goto &lt;bb 3&gt;;<br>
++   else<br>
++     goto &lt;bb 8&gt;;<br>
++   ...<br>
++<br>
++   The pass will report this if-chain like this:<br>
++   ...<br>
++   var: D.1993_3<br>
++   first: &lt;bb 4&gt;<br>
++   true: &lt;bb 3&gt;<br>
++   last: &lt;bb 7&gt;<br>
++   constants: 9 10 13 32<br>
++   ...<br>
++<br>
++   and then convert the if-chain into a switch:<br>
++   ...<br>
++   &lt;bb 4&gt;:<br>
++   ...<br>
++   switch (D.1993_3) &lt;default: &lt;L8&gt;,<br>
++                      case 9: &lt;L7&gt;,<br>
++                      case 10: &lt;L7&gt;,<br>
++                      case 13: &lt;L7&gt;,<br>
++                      case 32: &lt;L7&gt;&gt;<br>
++   ...<br>
++<br>
++   The conversion does not happen if the chain is too short.  The threshold is<br>
++   determined by the parameter PARAM_IF_TO_SWITCH_THRESHOLD.<br>
++<br>
++   The pass will try to construct a chain for each bb, unless the bb it is<br>
++   already contained in a chain.  This ensures that all chains will be found,<br>
++   and that no chain will be constructed twice.  The pass constructs and<br>
++   converts the chains one-by-one, rather than first calculating all the chains<br>
++   and then doing the conversions.<br>
++<br>
++   The pass could detect range-checks in analyze_bb as well, and handle them.<br>
++   Simple ones, like &#39;c &lt;= 5&#39;, and more complex ones, like<br>
++   &#39;(unsigned char) c + 247 &lt;= 1&#39;, which is generated by the C front-end from<br>
++   code like &#39;(c == 9 || c == 10)&#39; or &#39;(9 &lt;= c &amp;&amp; c &lt;= 10)&#39;.  */<br>
++<br>
++#include &quot;config.h&quot;<br>
++#include &quot;system.h&quot;<br>
++#include &quot;coretypes.h&quot;<br>
++#include &quot;tm.h&quot;<br>
++<br>
++#include &quot;params.h&quot;<br>
++#include &quot;flags.h&quot;<br>
++#include &quot;tree.h&quot;<br>
++#include &quot;basic-block.h&quot;<br>
++#include &quot;tree-flow.h&quot;<br>
++#include &quot;tree-flow-inline.h&quot;<br>
++#include &quot;tree-ssa-operands.h&quot;<br>
++#include &quot;diagnostic.h&quot;<br>
++#include &quot;tree-pass.h&quot;<br>
++#include &quot;tree-dump.h&quot;<br>
++#include &quot;timevar.h&quot;<br>
++<br>
++/* Information we&#39;ve collected about a single bb.  */<br>
++<br>
++struct ifsc_info<br>
++{<br>
++  /* The variable of the bb&#39;s ending GIMPLE_COND, NULL_TREE if not present.  */<br>
++  tree var;<br>
++  /* The cond_code of the bb&#39;s ending GIMPLE_COND.  */<br>
++  enum tree_code cond_code;<br>
++  /* The constant of the bb&#39;s ending GIMPLE_COND.  */<br>
++  tree constant;<br>
++  /* Successor edge of the bb if its GIMPLE_COND is true.  */<br>
++  edge true_edge;<br>
++  /* Successor edge of the bb if its GIMPLE_COND is false.  */<br>
++  edge false_edge;<br>
++  /* Set if the bb has valid ifsc_info.  */<br>
++   bool valid;<br>
++  /* Set if the bb is part of a chain.  */<br>
++  bool chained;<br>
++};<br>
++<br>
++/* Macros to access the fields of struct ifsc_info.  */<br>
++<br>
++#define BB_IFSC_VAR(bb) (((struct ifsc_info *)bb-&gt;aux)-&gt;var)<br>
++#define BB_IFSC_COND_CODE(bb) (((struct ifsc_info *)bb-&gt;aux)-&gt;cond_code)<br>
++#define BB_IFSC_CONSTANT(bb) (((struct ifsc_info *)bb-&gt;aux)-&gt;constant)<br>
++#define BB_IFSC_TRUE_EDGE(bb) (((struct ifsc_info *)bb-&gt;aux)-&gt;true_edge)<br>
++#define BB_IFSC_FALSE_EDGE(bb) (((struct ifsc_info *)bb-&gt;aux)-&gt;false_edge)<br>
++#define BB_IFSC_VALID(bb) (((struct ifsc_info *)bb-&gt;aux)-&gt;valid)<br>
++#define BB_IFSC_CHAINED(bb) (((struct ifsc_info *)bb-&gt;aux)-&gt;chained)<br>
++<br>
++/* Data-type describing an if-chain.  */<br>
++<br>
++struct if_chain<br>
++{<br>
++  /* First bb in the chain.  */<br>
++  basic_block first;<br>
++  /* Last bb in the chain.  */<br>
++  basic_block last;<br>
++  /* Variable that GIMPLE_CONDs of all bbs in chain compare against.  */<br>
++  tree var;<br>
++  /* bb that all GIMPLE_CONDs jump to if comparison succeeds.  */<br>
++  basic_block true_dest;<br>
++  /* Constants that GIMPLE_CONDs of all bbs in chain compare var against.  */<br>
++  VEC (tree, heap) *constants;<br>
++  /* Same as previous, but sorted and with duplicates removed.  */<br>
++  VEC (tree, heap) *unique_constants;<br>
++};<br>
++<br>
++/* Utility macro.  */<br>
++<br>
++#define SWAP(T, X, Y) do { T tmp = (X); (X) = (Y); (Y) = tmp; } while (0)<br>
++<br>
++/* Helper function for sort_constants.  */<br>
++<br>
++static int<br>
++compare_constants (const void *p1, const void *p2)<br>
++{<br>
++  const_tree const c1 = *(const_tree const*)p1;<br>
++  const_tree const c2 = *(const_tree const*)p2;<br>
++<br>
++  return tree_int_cst_compare (c1, c2);<br>
++}<br>
++<br>
++/* Sort constants in constants and copy to unique_constants, while skipping<br>
++   duplicates.  */<br>
++<br>
++static void<br>
++sort_constants (VEC (tree,heap) *constants, VEC (tree,heap) **unique_constants)<br>
++{<br>
++  size_t len = VEC_length (tree, constants);<br>
++  unsigned int ix;<br>
++  tree prev = NULL_TREE, constant;<br>
++<br>
++  /* Sort constants.  */<br>
++  qsort (VEC_address (tree, constants), len, sizeof (tree),<br>
++         compare_constants);<br>
++<br>
++  /* Copy to unique_constants, while skipping duplicates.  */<br>
++  for (ix = 0; VEC_iterate (tree, constants, ix, constant); ix++)<br>
++    {<br>
++      if (prev != NULL_TREE &amp;&amp; tree_int_cst_compare (prev, constant) == 0)<br>
++        continue;<br>
++      prev = constant;<br>
++<br>
++      VEC_safe_push (tree, heap, *unique_constants, constant);<br>
++    }<br>
++}<br>
++<br>
++/* Get true_edge and false_edge of a bb ending in a conditional jump.  */<br>
++<br>
++static void<br>
++get_edges (basic_block bb, edge *true_edge, edge *false_edge)<br>
++{<br>
++  edge e0, e1;<br>
++  int e0_true;<br>
++  int n = EDGE_COUNT (bb-&gt;succs);<br>
++  gcc_assert (n == 2);<br>
++<br>
++  e0 = EDGE_SUCC (bb, 0);<br>
++  e1 = EDGE_SUCC (bb, 1);<br>
++<br>
++  e0_true = e0-&gt;flags &amp; EDGE_TRUE_VALUE;<br>
++<br>
++  *true_edge = e0_true ? e0 : e1;<br>
++  *false_edge = e0_true ? e1 : e0;<br>
++<br>
++  gcc_assert ((*true_edge)-&gt;flags &amp; EDGE_TRUE_VALUE);<br>
++  gcc_assert ((*false_edge)-&gt;flags &amp; EDGE_FALSE_VALUE);<br>
++<br>
++  gcc_assert (((*true_edge)-&gt;flags &amp; EDGE_FALLTHRU) == 0);<br>
++  gcc_assert (((*false_edge)-&gt;flags &amp; EDGE_FALLTHRU) == 0);<br>
++}<br>
++<br>
++/* Analyze bb and store results in ifsc_info struct.  */<br>
++<br>
++static void<br>
++analyze_bb (basic_block bb)<br>
++{<br>
++  gimple stmt = last_stmt (bb);<br>
++  tree lhs, rhs, var, constant;<br>
++  edge true_edge, false_edge;<br>
++  enum tree_code cond_code;<br>
++<br>
++  /* Don&#39;t redo analysis.  */<br>
++  if (BB_IFSC_VALID (bb))<br>
++    return;<br>
++  BB_IFSC_VALID (bb) = true;<br>
++<br>
++<br>
++  /* bb needs to end in GIMPLE_COND.  */<br>
++  if (!stmt || gimple_code (stmt) != GIMPLE_COND)<br>
++    return;<br>
++<br>
++  /* bb needs to end in EQ_EXPR or NE_EXPR.  */<br>
++  cond_code = gimple_cond_code (stmt);<br>
++  if (cond_code != EQ_EXPR &amp;&amp; cond_code != NE_EXPR)<br>
++    return;<br>
++<br>
++  lhs = gimple_cond_lhs (stmt);<br>
++  rhs = gimple_cond_rhs (stmt);<br>
++<br>
++  /* GIMPLE_COND needs to compare variable to constant.  */<br>
++  if ((TREE_CONSTANT (lhs) == 0)<br>
++      == (TREE_CONSTANT (rhs) == 0))<br>
++    return;<br>
++<br>
++  var = TREE_CONSTANT (lhs) ? rhs : lhs;<br>
++  constant = TREE_CONSTANT (lhs)? lhs : rhs;<br>
++<br>
++  /* Switches cannot handle non-integral types.  */<br>
++  if (!INTEGRAL_TYPE_P(TREE_TYPE (var)))<br>
++    return;<br>
++<br>
++  get_edges (bb, &amp;true_edge, &amp;false_edge);<br>
++<br>
++  if (cond_code == NE_EXPR)<br>
++    SWAP (edge, true_edge, false_edge);<br>
++<br>
++  /* TODO: loosen this constraint.  In principle it&#39;s ok if true_edge-&gt;dest has<br>
++     phis, as long as for each phi all the edges coming from the chain have the<br>
++     same value.  */<br>
++  if (!gimple_seq_empty_p (phi_nodes (true_edge-&gt;dest)))<br>
++    return;<br>
++<br>
++  /* Store analysis in ifsc_info struct.  */<br>
++  BB_IFSC_VAR (bb) = var;<br>
++  BB_IFSC_COND_CODE (bb) = cond_code;<br>
++  BB_IFSC_CONSTANT (bb) = constant;<br>
++  BB_IFSC_TRUE_EDGE (bb) = true_edge;<br>
++  BB_IFSC_FALSE_EDGE (bb) = false_edge;<br>
++}<br>
++<br>
++/* Grow if-chain forward.  */<br>
++<br>
++static void<br>
++grow_if_chain_forward (struct if_chain *chain)<br>
++{<br>
++  basic_block next_bb;<br>
++<br>
++  while (1)<br>
++    {<br>
++      next_bb = BB_IFSC_FALSE_EDGE (chain-&gt;last)-&gt;dest;<br>
++<br>
++      /* next_bb is already part of another chain.  */<br>
++      if (BB_IFSC_CHAINED (next_bb))<br>
++        break;<br>
++<br>
++      /* next_bb needs to be dominated by the last bb.  */<br>
++      if (!single_pred_p (next_bb))<br>
++        break;<br>
++<br>
++      analyze_bb (next_bb);<br>
++<br>
++      /* Does next_bb fit in chain?  */<br>
++      if (BB_IFSC_VAR (next_bb) != chain-&gt;var<br>
++          || BB_IFSC_TRUE_EDGE (next_bb)-&gt;dest != chain-&gt;true_dest)<br>
++        break;<br>
++<br>
++      /* We can only add empty bbs at the end of the chain.  */<br>
++      if (first_stmt (next_bb) != last_stmt (next_bb))<br>
++        break;<br>
++<br>
++      /* Add next_bb at end of chain.  */<br>
++      VEC_safe_push (tree, heap, chain-&gt;constants, BB_IFSC_CONSTANT (next_bb));<br>
++      BB_IFSC_CHAINED (next_bb) = true;<br>
++      chain-&gt;last = next_bb;<br>
++    }<br>
++}<br>
++<br>
++/* Grow if-chain backward.  */<br>
++<br>
++static void<br>
++grow_if_chain_backward (struct if_chain *chain)<br>
++{<br>
++  basic_block prev_bb;<br>
++<br>
++  while (1)<br>
++    {<br>
++      /* First bb is not empty, cannot grow backwards.  */<br>
++      if (first_stmt (chain-&gt;first) != last_stmt (chain-&gt;first))<br>
++        break;<br>
++<br>
++      /* First bb has no single predecessor, cannot grow backwards.  */<br>
++      if (!single_pred_p (chain-&gt;first))<br>
++        break;<br>
++<br>
++      prev_bb = single_pred (chain-&gt;first);<br>
++<br>
++      /* prev_bb is already part of another chain.  */<br>
++      if (BB_IFSC_CHAINED (prev_bb))<br>
++        break;<br>
++<br>
++      analyze_bb (prev_bb);<br>
++<br>
++      /* Does prev_bb fit in chain?  */<br>
++      if (BB_IFSC_VAR (prev_bb) != chain-&gt;var<br>
++          || BB_IFSC_TRUE_EDGE (prev_bb)-&gt;dest != chain-&gt;true_dest)<br>
++        break;<br>
++<br>
++      /* Add prev_bb at beginning of chain.  */<br>
++      VEC_safe_push (tree, heap, chain-&gt;constants, BB_IFSC_CONSTANT (prev_bb));<br>
++      BB_IFSC_CHAINED (prev_bb) = true;<br>
++      chain-&gt;first = prev_bb;<br>
++    }<br>
++}<br>
++<br>
++/* Grow if-chain containing bb.  */<br>
++<br>
++static void<br>
++grow_if_chain (basic_block bb, struct if_chain *chain)<br>
++{<br>
++  /* Initialize chain to empty.  */<br>
++  VEC_truncate (tree, chain-&gt;constants, 0);<br>
++  VEC_truncate (tree, chain-&gt;unique_constants, 0);<br>
++<br>
++  /* bb is already part of another chain.  */<br>
++  if (BB_IFSC_CHAINED (bb))<br>
++    return;<br>
++<br>
++  analyze_bb (bb);<br>
++<br>
++  /* bb is not fit to be part of a chain.  */<br>
++  if (BB_IFSC_VAR (bb) == NULL_TREE)<br>
++    return;<br>
++<br>
++  /* Set bb as initial part of the chain.  */<br>
++  VEC_safe_push (tree, heap, chain-&gt;constants, BB_IFSC_CONSTANT (bb));<br>
++  chain-&gt;first = chain-&gt;last = bb;<br>
++  chain-&gt;var = BB_IFSC_VAR (bb);<br>
++  chain-&gt;true_dest = BB_IFSC_TRUE_EDGE (bb)-&gt;dest;<br>
++<br>
++  /* bb is part of a chain now.  */<br>
++  BB_IFSC_CHAINED (bb) = true;<br>
++<br>
++  /* Grow chain to its maximum size.  */<br>
++  grow_if_chain_forward (chain);<br>
++  grow_if_chain_backward (chain);<br>
++<br>
++  /* Sort constants and skip duplicates.  */<br>
++  sort_constants (chain-&gt;constants, &amp;chain-&gt;unique_constants);<br>
++}<br>
++<br>
++static void<br>
++dump_tree_vector (VEC (tree, heap) *vec)<br>
++{<br>
++  unsigned int ix;<br>
++  tree constant;<br>
++<br>
++  for (ix = 0; VEC_iterate (tree, vec, ix, constant); ix++)<br>
++    {<br>
++      if (ix != 0)<br>
++        fprintf (dump_file, &quot; &quot;);<br>
++      print_generic_expr (dump_file, constant, 0);<br>
++    }<br>
++  fprintf (dump_file, &quot;\n&quot;);<br>
++}<br>
++<br>
++/* Dump if-chain to dump_file.  */<br>
++<br>
++static void<br>
++dump_if_chain (struct if_chain *chain)<br>
++{<br>
++  if (!dump_file)<br>
++    return;<br>
++<br>
++  fprintf (dump_file, &quot;var: &quot;);<br>
++  print_generic_expr (dump_file, chain-&gt;var, 0);<br>
++  fprintf (dump_file, &quot;\n&quot;);<br>
++  fprintf (dump_file, &quot;first: &lt;bb %d&gt;\n&quot;, chain-&gt;first-&gt;index);<br>
++  fprintf (dump_file, &quot;true: &lt;bb %d&gt;\n&quot;, chain-&gt;true_dest-&gt;index);<br>
++  fprintf (dump_file, &quot;last: &lt;bb %d&gt;\n&quot;,chain-&gt;last-&gt;index);<br>
++<br>
++  fprintf (dump_file, &quot;constants: &quot;);<br>
++  dump_tree_vector (chain-&gt;constants);<br>
++<br>
++  if (VEC_length (tree, chain-&gt;unique_constants)<br>
++      != VEC_length (tree, chain-&gt;constants))<br>
++    {<br>
++      fprintf (dump_file, &quot;unique_constants: &quot;);<br>
++      dump_tree_vector (chain-&gt;unique_constants);<br>
++    }<br>
++}<br>
++<br>
++/* Remove redundant bbs and edges.  */<br>
++<br>
++static void<br>
++remove_redundant_bbs_and_edges (struct if_chain *chain, int *false_prob)<br>
++{<br>
++  basic_block bb, next;<br>
++  edge true_edge, false_edge;<br>
++<br>
++  for (bb = chain-&gt;first;; bb = next)<br>
++    {<br>
++      true_edge = BB_IFSC_TRUE_EDGE (bb);<br>
++      false_edge = BB_IFSC_FALSE_EDGE (bb);<br>
++<br>
++      /* Determine next, before we delete false_edge.  */<br>
++      next = false_edge-&gt;dest;<br>
++<br>
++      /* Accumulate probability.  */<br>
++      *false_prob = (*false_prob * false_edge-&gt;probability) / REG_BR_PROB_BASE;<br>
++<br>
++      /* Don&#39;t remove the new true_edge.  */<br>
++      if (bb != chain-&gt;first)<br>
++        remove_edge (true_edge);<br>
++<br>
++      /* Don&#39;t remove the new false_edge.  */<br>
++      if (bb != chain-&gt;last)<br>
++        remove_edge (false_edge);<br>
++<br>
++      /* Don&#39;t remove the first bb.  */<br>
++      if (bb != chain-&gt;first)<br>
++        delete_basic_block (bb);<br>
++<br>
++      /* Stop after last.  */<br>
++      if (bb == chain-&gt;last)<br>
++        break;<br>
++    }<br>
++}<br>
++<br>
++/* Update control flow graph.  */<br>
++<br>
++static void<br>
++update_cfg (struct if_chain *chain)<br>
++{<br>
++  edge true_edge, false_edge;<br>
++  int false_prob;<br>
++  int flags_mask = ~(EDGE_FALLTHRU|EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);<br>
++<br>
++  /* We keep these 2 edges, and remove the rest.  We need this specific<br>
++     false_edge, because a phi in chain-&gt;last-&gt;dest might reference (the index<br>
++     of) this edge.  For true_edge, we could pick any of them.  */<br>
++  true_edge = BB_IFSC_TRUE_EDGE (chain-&gt;first);<br>
++  false_edge = BB_IFSC_FALSE_EDGE (chain-&gt;last);<br>
++<br>
++  /* Update true edge.  */<br>
++  true_edge-&gt;flags &amp;= flags_mask;<br>
++<br>
++  /* Update false edge.  */<br>
++  redirect_edge_pred (false_edge, chain-&gt;first);<br>
++  false_edge-&gt;flags &amp;= flags_mask;<br>
++<br>
++  false_prob = REG_BR_PROB_BASE;<br>
++  remove_redundant_bbs_and_edges (chain, &amp;false_prob);<br>
++<br>
++  /* Repair probabilities.  */<br>
++  true_edge-&gt;probability = REG_BR_PROB_BASE - false_prob;<br>
++  false_edge-&gt;probability = false_prob;<br>
++<br>
++  /* Force recalculation of dominance info.  */<br>
++  free_dominance_info (CDI_DOMINATORS);<br>
++  free_dominance_info (CDI_POST_DOMINATORS);<br>
++}<br>
++<br>
++/* Create switch statement.  Borrows from gimplify_switch_expr.  */<br>
++<br>
++static void<br>
++convert_if_chain_to_switch (struct if_chain *chain)<br>
++{<br>
++  tree label_decl_true, label_decl_false;<br>
++  gimple label_true, label_false, gimple_switch;<br>
++  gimple_stmt_iterator gsi;<br>
++  tree default_case, other_case, constant;<br>
++  unsigned int ix;<br>
++  VEC (tree, heap) *labels;<br>
++<br>
++  labels = VEC_alloc (tree, heap, 8);<br>
++<br>
++  /* Create and insert true jump label.  */<br>
++  label_decl_true = create_artificial_label (UNKNOWN_LOCATION);<br>
++  label_true = gimple_build_label (label_decl_true);<br>
++  gsi = gsi_start_bb (chain-&gt;true_dest);<br>
++  gsi_insert_before (&amp;gsi, label_true, GSI_SAME_STMT);<br>
++<br>
++  /* Create and insert false jump label.  */<br>
++  label_decl_false = create_artificial_label (UNKNOWN_LOCATION);<br>
++  label_false = gimple_build_label (label_decl_false);<br>
++  gsi = gsi_start_bb (BB_IFSC_FALSE_EDGE (chain-&gt;last)-&gt;dest);<br>
++  gsi_insert_before (&amp;gsi, label_false, GSI_SAME_STMT);<br>
++<br>
++  /* Create default case label.  */<br>
++  default_case = build3 (CASE_LABEL_EXPR, void_type_node,<br>
++                         NULL_TREE, NULL_TREE,<br>
++                         label_decl_false);<br>
++<br>
++  /* Create case labels.  */<br>
++  for (ix = 0; VEC_iterate (tree, chain-&gt;unique_constants, ix, constant); ix++)<br>
++    {<br>
++      /* TODO: use ranges, as in gimplify_switch_expr.  */<br>
++      other_case = build3 (CASE_LABEL_EXPR, void_type_node,<br>
++                           constant, NULL_TREE,<br>
++                           label_decl_true);<br>
++      VEC_safe_push (tree, heap, labels, other_case);<br>
++    }<br>
++<br>
++  /* Create and insert switch.  */<br>
++  gimple_switch = gimple_build_switch_vec (chain-&gt;var, default_case, labels);<br>
++  gsi = gsi_for_stmt (last_stmt (chain-&gt;first));<br>
++  gsi_insert_before (&amp;gsi, gimple_switch, GSI_SAME_STMT);<br>
++<br>
++  /* Remove now obsolete if.  */<br>
++  gsi_remove (&amp;gsi, true);<br>
++<br>
++  VEC_free (tree, heap, labels);<br>
++}<br>
++<br>
++/* Allocation and initialization.  */<br>
++<br>
++static void<br>
++init_pass (struct if_chain *chain)<br>
++{<br>
++  alloc_aux_for_blocks (sizeof (struct ifsc_info));<br>
++<br>
++  chain-&gt;constants = VEC_alloc (tree, heap, 8);<br>
++  chain-&gt;unique_constants = VEC_alloc (tree, heap, 8);<br>
++}<br>
++<br>
++/* Deallocation.  */<br>
++<br>
++static void<br>
++finish_pass (struct if_chain *chain)<br>
++{<br>
++  free_aux_for_blocks ();<br>
++<br>
++  VEC_free (tree, heap, chain-&gt;constants);<br>
++  VEC_free (tree, heap, chain-&gt;unique_constants);<br>
++}<br>
++<br>
++/* Find if-chains and convert them to switches.  */<br>
++<br>
++static unsigned int<br>
++do_if_to_switch (void)<br>
++{<br>
++  basic_block bb;<br>
++  struct if_chain chain;<br>
++  unsigned int convert_threshold = PARAM_VALUE (PARAM_IF_TO_SWITCH_THRESHOLD);<br>
++<br>
++  init_pass (&amp;chain);<br>
++<br>
++  for (bb = cfun-&gt;cfg-&gt;x_entry_block_ptr-&gt;next_bb;<br>
++       bb != cfun-&gt;cfg-&gt;x_exit_block_ptr;)<br>
++    {<br>
++      grow_if_chain (bb, &amp;chain);<br>
++<br>
++      do<br>
++        bb = bb-&gt;next_bb;<br>
++      while (BB_IFSC_CHAINED (bb));<br>
++<br>
++      /* Determine if the chain is long enough.  */<br>
++      if (VEC_length (tree, chain.unique_constants) &lt; convert_threshold)<br>
++        continue;<br>
++<br>
++      dump_if_chain (&amp;chain);<br>
++<br>
++      convert_if_chain_to_switch (&amp;chain);<br>
++<br>
++      update_cfg (&amp;chain);<br>
++    }<br>
++<br>
++  finish_pass (&amp;chain);<br>
++<br>
++  return 0;<br>
++}<br>
++<br>
++/* The pass gate.  */<br>
++<br>
++static bool<br>
++if_to_switch_gate (void)<br>
++{<br>
++  return flag_tree_if_to_switch_conversion;<br>
++}<br>
++<br>
++/* The pass definition.  */<br>
++<br>
++struct gimple_opt_pass pass_if_to_switch =<br>
++{<br>
++ {<br>
++  GIMPLE_PASS,<br>
++  &quot;iftoswitch&quot;,                         /* name */<br>
++  if_to_switch_gate,                    /* gate */<br>
++  do_if_to_switch,                      /* execute */<br>
++  NULL,                                 /* sub */<br>
++  NULL,                                 /* next */<br>
++  0,                                    /* static_pass_number */<br>
++  TV_TREE_SWITCH_CONVERSION,            /* tv_id */<br>
++  PROP_cfg | PROP_ssa,                  /* properties_required */<br>
++  0,                                    /* properties_provided */<br>
++  0,                                    /* properties_destroyed */<br>
++  0,                                    /* todo_flags_start */<br>
++  TODO_update_ssa | TODO_dump_func<br>
++  | TODO_ggc_collect | TODO_verify_ssa  /* todo_flags_finish */<br>
++ }<br>
++};<br>
+Index: gcc-4_5-branch/gcc/tree-pass.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/tree-pass.h<br>
++++ gcc-4_5-branch/gcc/tree-pass.h<br>
+@@ -560,6 +560,7 @@ extern struct gimple_opt_pass pass_inlin<br>
+ extern struct gimple_opt_pass pass_all_early_optimizations;<br>
+ extern struct gimple_opt_pass pass_update_address_taken;<br>
+ extern struct gimple_opt_pass pass_convert_switch;<br>
++extern struct gimple_opt_pass pass_if_to_switch;<br>
+<br>
+ /* The root of the compilation pass tree, once constructed.  */<br>
+ extern struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes,<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99473.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99473.patch<br>
new file mode 100644<br>
index 0000000..3ac7f7f<br>
--- /dev/null<br>
+++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99473.patch<br>
@@ -0,0 +1,409 @@<br>
+2010-02-04  Tom de Vries  &lt;<a href="mailto:tom@codesourcery.com">tom@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       stmt.c (set_jump_prob): Fix assert condition.<br>
+<br>
+2010-01-27  Tom de Vries  &lt;<a href="mailto:tom@codesourcery.com">tom@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       stmt.c (rtx_seq_cost): Use insn_rtx_cost instead of rtx_cost.<br>
+<br>
+2010-01-26  Tom de Vries  &lt;<a href="mailto:tom@codesourcery.com">tom@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       * stmt.c (struct  case_bit_test): Add rev_hi and rev_lo field.<br>
+       * stmt.c (emit_case_bit_test_jump): New function.<br>
+       * stmt.c (rtx_seq_cost): New function.<br>
+       * stmt.c (choose_case_bit_test_expand_method): New function.<br>
+       * stmt.c (set_bit): New function.<br>
+       * stmt.c (emit_case_bit_test): Adjust comment.<br>
+       * stmt.c (emit_case_bit_test): Set and update rev_hi and rev_lo fields.<br>
+       * stmt.c (emit_case_bit_test): Use set_bit.<br>
+       * stmt.c (emit_case_bit_test): Use choose_case_bit_test_expand_method.<br>
+       * stmt.c (emit_case_bit_test): Use emit_case_bit_test_jump.<br>
+       * testsuite/gcc.dg/switch-bittest.c: New test.<br>
+<br>
+2010-01-25  Tom de Vries  &lt;<a href="mailto:tom@codesourcery.com">tom@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       * stmt.c (emit_case_bit_tests): Change prototype.<br>
+       * stmt.c (struct case_bit_test): Add prob field.<br>
+       * stmt.c (get_label_prob): New function.<br>
+       * stmt.c (set_jump_prob): New function.<br>
+       * stmt.c (emit_case_bit_tests): Use get_label_prob.<br>
+       * stmt.c (emit_case_bit_tests): Set prob field.<br>
+       * stmt.c (emit_case_bit_tests): Use set_jump_prob.<br>
+       * stmt.c (expand_case): Add new args to emit_case_bit_tests invocation.<br>
+       * testsuite/gcc.dg/switch-prob.c: Add test.<br>
+<br>
+=== modified file &#39;gcc/stmt.c&#39;<br>
+Index: gcc-4_5-branch/gcc/stmt.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/stmt.c<br>
++++ gcc-4_5-branch/gcc/stmt.c<br>
+@@ -117,7 +117,8 @@ static void expand_value_return (rtx);<br>
+ static int estimate_case_costs (case_node_ptr);<br>
+ static bool lshift_cheap_p (void);<br>
+ static int case_bit_test_cmp (const void *, const void *);<br>
+-static void emit_case_bit_tests (tree, tree, tree, tree, case_node_ptr, rtx);<br>
++static void emit_case_bit_tests (tree, tree, tree, tree, case_node_ptr, tree,<br>
++                                 rtx, basic_block);<br>
+ static void balance_case_nodes (case_node_ptr *, case_node_ptr);<br>
+ static int node_has_low_bound (case_node_ptr, tree);<br>
+ static int node_has_high_bound (case_node_ptr, tree);<br>
+@@ -2107,8 +2108,11 @@ struct case_bit_test<br>
+ {<br>
+   HOST_WIDE_INT hi;<br>
+   HOST_WIDE_INT lo;<br>
++  HOST_WIDE_INT rev_hi;<br>
++  HOST_WIDE_INT rev_lo;<br>
+   rtx label;<br>
+   int bits;<br>
++  int prob;<br>
+ };<br>
+<br>
+ /* Determine whether &quot;1 &lt;&lt; x&quot; is relatively cheap in word_mode.  */<br>
+@@ -2148,10 +2152,193 @@ case_bit_test_cmp (const void *p1, const<br>
+   return CODE_LABEL_NUMBER (d2-&gt;label) - CODE_LABEL_NUMBER (d1-&gt;label);<br>
+ }<br>
+<br>
++/* Emit a bit test and a conditional jump.  */<br>
++<br>
++static void<br>
++emit_case_bit_test_jump (unsigned int count, rtx index, rtx label,<br>
++                         unsigned int method, HOST_WIDE_INT hi,<br>
++                         HOST_WIDE_INT lo, HOST_WIDE_INT rev_hi,<br>
++                         HOST_WIDE_INT rev_lo)<br>
++{<br>
++  rtx expr;<br>
++<br>
++  if (method == 1)<br>
++    {<br>
++      /* (1 &lt;&lt; index). */<br>
++      if (count == 0)<br>
++        index = expand_binop (word_mode, ashl_optab, const1_rtx,<br>
++                              index, NULL_RTX, 1, OPTAB_WIDEN);<br>
++      /* CST.  */<br>
++      expr = immed_double_const (lo, hi, word_mode);<br>
++      /* ((1 &lt;&lt; index) &amp; CST).  */<br>
++      expr = expand_binop (word_mode, and_optab, index, expr,<br>
++                           NULL_RTX, 1, OPTAB_WIDEN);<br>
++      /* if (((1 &lt;&lt; index) &amp; CST)).   */<br>
++      emit_cmp_and_jump_insns (expr, const0_rtx, NE, NULL_RTX,<br>
++                               word_mode, 1, label);<br>
++    }<br>
++  else if (method == 2)<br>
++    {<br>
++      /* (bit_reverse (CST)) */<br>
++      expr = immed_double_const (rev_lo, rev_hi, word_mode);<br>
++      /* ((bit_reverse (CST)) &lt;&lt; index) */<br>
++      expr = expand_binop (word_mode, ashl_optab, expr,<br>
++                           index, NULL_RTX, 1, OPTAB_WIDEN);<br>
++      /* if (((bit_reverse (CST)) &lt;&lt; index) &lt; 0).  */<br>
++      emit_cmp_and_jump_insns (expr, const0_rtx, LT, NULL_RTX,<br>
++                               word_mode, 0, label);<br>
++    }<br>
++  else<br>
++    gcc_unreachable ();<br>
++}<br>
++<br>
++/* Return the cost of rtx sequence SEQ.  The sequence is supposed to contain one<br>
++   jump, which has no effect in the cost.  */<br>
++<br>
++static unsigned int<br>
++rtx_seq_cost (rtx seq)<br>
++{<br>
++  rtx one;<br>
++  unsigned int nr_branches = 0;<br>
++  unsigned int sum = 0, cost;<br>
++<br>
++  for (one = seq; one != NULL_RTX; one = NEXT_INSN (one))<br>
++    if (JUMP_P (one))<br>
++      nr_branches++;<br>
++    else<br>
++      {<br>
++        cost = insn_rtx_cost (PATTERN (one), optimize_insn_for_speed_p ());<br>
++        if (dump_file)<br>
++          {<br>
++            print_rtl_single (dump_file, one);<br>
++            fprintf (dump_file, &quot;cost: %u\n&quot;, cost);<br>
++          }<br>
++        sum += cost;<br>
++      }<br>
++<br>
++  gcc_assert (nr_branches == 1);<br>
++<br>
++  if (dump_file)<br>
++    fprintf (dump_file, &quot;total cost: %u\n&quot;, sum);<br>
++  return sum;<br>
++}<br>
++<br>
++/* Generate the rtx sequences for 2 bit test expansion methods, measure the cost<br>
++   and choose the cheapest.  */<br>
++<br>
++static unsigned int<br>
++choose_case_bit_test_expand_method (rtx label)<br>
++{<br>
++  rtx seq, index;<br>
++  unsigned int cost[2];<br>
++  static bool method_known = false;<br>
++  static unsigned int method;<br>
++<br>
++  /* If already known, return the method.  */<br>
++  if (method_known)<br>
++    return method;<br>
++<br>
++  index = gen_rtx_REG (word_mode, 10000);<br>
++<br>
++  for (method = 1; method &lt;= 2; ++method)<br>
++    {<br>
++      start_sequence ();<br>
++      emit_case_bit_test_jump (0, index, label, method, 0, 0x0f0f0f0f, 0,<br>
++                               0x0f0f0f0f);<br>
++      seq = get_insns ();<br>
++      end_sequence ();<br>
++      cost[method - 1] = rtx_seq_cost (seq);<br>
++    }<br>
++<br>
++  /* Determine method based on heuristic.  */<br>
++  method = ((cost[1] &lt; cost[0]) ? 1 : 0) + 1;<br>
++<br>
++  /* Save and return method.  */<br>
++  method_known = true;<br>
++  return method;<br>
++}<br>
++<br>
++/* Get the edge probability of the edge from SRC to LABEL_DECL.  */<br>
++<br>
++static int<br>
++get_label_prob (basic_block src, tree label_decl)<br>
++{<br>
++  basic_block dest;<br>
++  int prob = 0, nr_prob = 0;<br>
++  unsigned int i;<br>
++  edge e;<br>
++<br>
++  if (label_decl == NULL_TREE)<br>
++    return 0;<br>
++<br>
++  dest = VEC_index (basic_block, label_to_block_map,<br>
++                    LABEL_DECL_UID (label_decl));<br>
++<br>
++  for (i = 0; i &lt; EDGE_COUNT (src-&gt;succs); ++i)<br>
++    {<br>
++      e = EDGE_SUCC (src, i);<br>
++<br>
++      if (e-&gt;dest != dest)<br>
++        continue;<br>
++<br>
++      prob += e-&gt;probability;<br>
++      nr_prob++;<br>
++    }<br>
++<br>
++  gcc_assert (nr_prob == 1);<br>
++<br>
++  return prob;<br>
++}<br>
++<br>
++/* Add probability note with scaled PROB to JUMP and update INV_SCALE.  This<br>
++   function is intended to be used with a series of conditional jumps to L[i]<br>
++   where the probabilities p[i] to get to L[i] are known, and the jump<br>
++   probabilities j[i] need to be computed.<br>
++<br>
++   The algorithm to calculate the probabilities is<br>
++<br>
++   scale = REG_BR_PROB_BASE;<br>
++   for (i = 0; i &lt; n; ++i)<br>
++     {<br>
++       j[i] = p[i] * scale / REG_BR_PROB_BASE;<br>
++       f[i] = REG_BR_PROB_BASE - j[i];<br>
++       scale = scale / (f[i] / REG_BR_PROB_BASE);<br>
++     }<br>
++<br>
++   The implementation uses inv_scale (REG_BR_PROB_BASE / scale) instead of<br>
++   scale, because scale tends to grow bigger than REG_BR_PROB_BASE.  */<br>
++<br>
++static void<br>
++set_jump_prob (rtx jump, int prob, int *inv_scale)<br>
++{<br>
++  /* j[i] = p[i] * scale / REG_BR_PROB_BASE.  */<br>
++  int jump_prob = prob * REG_BR_PROB_BASE / *inv_scale;<br>
++  /* f[i] = REG_BR_PROB_BASE - j[i].  */<br>
++  int fallthrough_prob = REG_BR_PROB_BASE - jump_prob;<br>
++<br>
++  gcc_assert (jump_prob &lt;= REG_BR_PROB_BASE);<br>
++  add_reg_note (jump, REG_BR_PROB, GEN_INT (jump_prob));<br>
++<br>
++  /* scale = scale / (f[i] / REG_BR_PROB_BASE).  */<br>
++  *inv_scale = *inv_scale * fallthrough_prob / REG_BR_PROB_BASE;<br>
++}<br>
++<br>
++/* Set bit in hwi hi/lo pair.  */<br>
++<br>
++static void<br>
++set_bit (HOST_WIDE_INT *hi, HOST_WIDE_INT *lo, unsigned int j)<br>
++{<br>
++  if (j &gt;= HOST_BITS_PER_WIDE_INT)<br>
++    *hi |= (HOST_WIDE_INT) 1 &lt;&lt; (j - HOST_BITS_PER_INT);<br>
++  else<br>
++    *lo |= (HOST_WIDE_INT) 1 &lt;&lt; j;<br>
++}<br>
++<br>
+ /*  Expand a switch statement by a short sequence of bit-wise<br>
+     comparisons.  &quot;switch(x)&quot; is effectively converted into<br>
+-    &quot;if ((1 &lt;&lt; (x-MINVAL)) &amp; CST)&quot; where CST and MINVAL are<br>
+-    integer constants.<br>
++    &quot;if ((1 &lt;&lt; (x-MINVAL)) &amp; CST)&quot; or<br>
++    &quot;if (((bit_reverse (CST)) &lt;&lt; (x-MINVAL)) &lt; 0)&quot;, where CST<br>
++    and MINVAL are integer constants.<br>
+<br>
+     INDEX_EXPR is the value being switched on, which is of<br>
+     type INDEX_TYPE.  MINVAL is the lowest case value of in<br>
+@@ -2165,14 +2352,17 @@ case_bit_test_cmp (const void *p1, const<br>
+<br>
+ static void<br>
+ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,<br>
+-                   tree range, case_node_ptr nodes, rtx default_label)<br>
++                   tree range, case_node_ptr nodes, tree default_label_decl,<br>
++                   rtx default_label, basic_block bb)<br>
+ {<br>
+   struct case_bit_test test[MAX_CASE_BIT_TESTS];<br>
+   enum machine_mode mode;<br>
+   rtx expr, index, label;<br>
+   unsigned int i,j,lo,hi;<br>
+   struct case_node *n;<br>
+-  unsigned int count;<br>
++  unsigned int count, method;<br>
++  int inv_scale = REG_BR_PROB_BASE;<br>
++  int default_prob = get_label_prob (bb, default_label_decl);<br>
+<br>
+   count = 0;<br>
+   for (n = nodes; n; n = n-&gt;right)<br>
+@@ -2187,8 +2377,11 @@ emit_case_bit_tests (tree index_type, tr<br>
+         gcc_assert (count &lt; MAX_CASE_BIT_TESTS);<br>
+         test[i].hi = 0;<br>
+         test[i].lo = 0;<br>
++        test[i].rev_hi = 0;<br>
++        test[i].rev_lo = 0;<br>
+         test[i].label = label;<br>
+         test[i].bits = 1;<br>
++        test[i].prob = get_label_prob (bb, n-&gt;code_label);<br>
+         count++;<br>
+       }<br>
+       else<br>
+@@ -2199,10 +2392,11 @@ emit_case_bit_tests (tree index_type, tr<br>
+       hi = tree_low_cst (fold_build2 (MINUS_EXPR, index_type,<br>
+                                     n-&gt;high, minval), 1);<br>
+       for (j = lo; j &lt;= hi; j++)<br>
+-        if (j &gt;= HOST_BITS_PER_WIDE_INT)<br>
+-        test[i].hi |= (HOST_WIDE_INT) 1 &lt;&lt; (j - HOST_BITS_PER_INT);<br>
+-      else<br>
+-        test[i].lo |= (HOST_WIDE_INT) 1 &lt;&lt; j;<br>
++        {<br>
++          set_bit (&amp;test[i].hi, &amp;test[i].lo, j);<br>
++          set_bit (&amp;test[i].rev_hi, &amp;test[i].rev_lo,<br>
++                   GET_MODE_BITSIZE (word_mode) - j - 1);<br>
++        }<br>
+     }<br>
+<br>
+   qsort (test, count, sizeof(*test), case_bit_test_cmp);<br>
+@@ -2216,20 +2410,20 @@ emit_case_bit_tests (tree index_type, tr<br>
+   mode = TYPE_MODE (index_type);<br>
+   expr = expand_normal (range);<br>
+   if (default_label)<br>
+-    emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,<br>
+-                           default_label);<br>
++    {<br>
++      emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,<br>
++                               default_label);<br>
++      set_jump_prob (get_last_insn (), default_prob / 2, &amp;inv_scale);<br>
++    }<br>
+<br>
+   index = convert_to_mode (word_mode, index, 0);<br>
+-  index = expand_binop (word_mode, ashl_optab, const1_rtx,<br>
+-                      index, NULL_RTX, 1, OPTAB_WIDEN);<br>
+<br>
++  method = choose_case_bit_test_expand_method (test[0].label);<br>
+   for (i = 0; i &lt; count; i++)<br>
+     {<br>
+-      expr = immed_double_const (test[i].lo, test[i].hi, word_mode);<br>
+-      expr = expand_binop (word_mode, and_optab, index, expr,<br>
+-                         NULL_RTX, 1, OPTAB_WIDEN);<br>
+-      emit_cmp_and_jump_insns (expr, const0_rtx, NE, NULL_RTX,<br>
+-                             word_mode, 1, test[i].label);<br>
++      emit_case_bit_test_jump (i, index, test[i].label, method, test[i].hi,<br>
++                               test[i].lo, test[i].rev_hi, test[i].rev_lo);<br>
++      set_jump_prob (get_last_insn (), test[i].prob, &amp;inv_scale);<br>
+     }<br>
+<br>
+   if (default_label)<br>
+@@ -2400,7 +2594,8 @@ expand_case (gimple stmt)<br>
+             range = maxval;<br>
+           }<br>
+         emit_case_bit_tests (index_type, index_expr, minval, range,<br>
+-                             case_list, default_label);<br>
++                             case_list, default_label_decl, default_label,<br>
++                             gimple_bb (stmt));<br>
+       }<br>
+<br>
+       /* If range of values is much bigger than number of values,<br>
+Index: gcc-4_5-branch/gcc/testsuite/gcc.dg/switch-bittest.c<br>
+===================================================================<br>
+--- /dev/null<br>
++++ gcc-4_5-branch/gcc/testsuite/gcc.dg/switch-bittest.c<br>
+@@ -0,0 +1,25 @@<br>
++/* { dg-do compile } */<br>
++/* { dg-options &quot;-O2 -fdump-rtl-expand&quot; } */<br>
++<br>
++const char *<br>
++f (const char *p)<br>
++{<br>
++  while (1)<br>
++    {<br>
++      switch (*p)<br>
++        {<br>
++        case 9:<br>
++        case 10:<br>
++        case 13:<br>
++        case 32:<br>
++          break;<br>
++        default:<br>
++          return p;<br>
++        }<br>
++    }<br>
++}<br>
++<br>
++/* { dg-final { scan-rtl-dump-times &quot;jump_insn&quot; 4 &quot;expand&quot; { target mips*-*-* } } } */<br>
++/* { dg-final { scan-rtl-dump-times &quot;REG_BR_PROB&quot; 2 &quot;expand&quot; { target mips*-*-* } } } */<br>
++/* { dg-final { scan-rtl-dump-times &quot;lt &quot; 1 &quot;expand&quot;  { target mips*-*-* } } } */<br>
++/* { dg-final { cleanup-rtl-dump &quot;expand&quot; } } */<br>
+Index: gcc-4_5-branch/gcc/testsuite/gcc.dg/switch-prob.c<br>
+===================================================================<br>
+--- /dev/null<br>
++++ gcc-4_5-branch/gcc/testsuite/gcc.dg/switch-prob.c<br>
+@@ -0,0 +1,25 @@<br>
++/* { dg-do compile } */<br>
++/* { dg-options &quot;-O2 -fdump-rtl-expand&quot; } */<br>
++<br>
++const char *<br>
++f (const char *p)<br>
++{<br>
++  while (1)<br>
++    {<br>
++      switch (*p)<br>
++        {<br>
++        case 9:<br>
++        case 10:<br>
++        case 13:<br>
++        case 32:<br>
++          break;<br>
++        default:<br>
++          return p;<br>
++        }<br>
++    }<br>
++}<br>
++<br>
++/* { dg-final { scan-rtl-dump-times &quot;jump_insn&quot; 4 &quot;expand&quot; { target mips*-*-* } } } */<br>
++/* { dg-final { scan-rtl-dump-times &quot;REG_BR_PROB&quot; 2 &quot;expand&quot; { target mips*-*-* } } } */<br>
++/* { dg-final { scan-rtl-dump-times &quot;heuristics&quot; 0 &quot;expand&quot;  { target mips*-*-* } } } */<br>
++/* { dg-final { cleanup-rtl-dump &quot;expand&quot; } } */<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99474.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99474.patch<br>
new file mode 100644<br>
index 0000000..9b0fb0b<br>
--- /dev/null<br>
+++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99474.patch<br>
@@ -0,0 +1,3346 @@<br>
+2011-01-14  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       * function.c (thread_prologue_and_epilogue_insns): Avoid uninitialized<br>
+       variable.<br>
+<br>
+2011-01-12  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       * config/s390/s390.c (s390_emit_epilogue): Don&#39;t use gen_rtx_RETURN.<br>
+       * config/rx/rx.c (gen_rx_rtsd_vector): Likewise.<br>
+       * config/m68hc11/<a href="http://m68hc11.md" target="_blank">m68hc11.md</a> (return): Likewise.<br>
+       * config/cris/cris.c (cris_expand_return): Likewise.<br>
+       * config/m68k/m68k.c (m68k_expand_epilogue): Likewise.<br>
+       * config/picochip/picochip.c (picochip_expand_epilogue): Likewise.<br>
+       * config/h8300/h8300.c (h8300_push_pop, h8300_expand_epilogue):<br>
+       Likewise.<br>
+       * config/v850/v850.c (expand_epilogue): Likewise.<br>
+       * config/bfin/bfin.c (bfin_expand_call): Likewise.<br>
+<br>
+2011-01-04  Catherine Moore  &lt;<a href="mailto:clm@codesourcery.com">clm@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       * config/rs6000/rs6000.c (rs6000_make_savres_rtx): Change<br>
+       gen_rtx_RETURN to ret_rtx.<br>
+       (rs6000_emit_epilogue): Likewise.<br>
+       (rs6000_output_mi_thunk): Likewise.<br>
+<br>
+2011-01-03  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
+<br>
+       gcc/<br>
+       * doc/tm.texi (RETURN_ADDR_REGNUM): Document.<br>
+       * doc/md.texi (simple_return): Document pattern.<br>
+       (return): Add a sentence to clarify.<br>
+       * doc/rtl.texi (simple_return): Document.<br>
+       * doc/invoke.texi (Optimize Options): Document -fshrink-wrap.<br>
+       * common.opt (fshrink-wrap): New.<br>
+       * opts.c (decode_options): Set it for -O2 and above.<br>
+       * gengenrtl.c (special_rtx): PC, CC0, RETURN and SIMPLE_RETURN<br>
+       are special.<br>
+       * rtl.h (ANY_RETURN_P): New macro.<br>
+       (global_rtl_index): Add GR_RETURN and GR_SIMPLE_RETURN.<br>
+       (ret_rtx, simple_return_rtx): New macros.<br>
+       * genemit.c (gen_exp): RETURN and SIMPLE_RETURN have unique rtxs.<br>
+       (gen_expand, gen_split): Use ANY_RETURN_P.<br>
+       * rtl.c (copy_rtx): RETURN and SIMPLE_RETURN are shared.<br>
+       * emit-rtl.c (verify_rtx_sharing): Likewise.<br>
+       (skip_consecutive_labels): Return the argument if it is a return rtx.<br>
+       (classify_insn): Handle both kinds of return.<br>
+       (init_emit_regs): Create global rtl for ret_rtx and simple_return_rtx.<br>
+       * df-scan.c (df_uses_record): Handle SIMPLE_RETURN.<br>
+       * rtl.def (SIMPLE_RETURN): New.<br>
+       * rtlanal.c (tablejump_p): Check JUMP_LABEL for returns.<br>
+       * final.c (final_scan_insn): Recognize both kinds of return.<br>
+       * reorg.c (function_return_label, function_simple_return_label): New<br>
+       static variables.<br>
+       (end_of_function_label): Remove.<br>
+       (simplejump_or_return_p): New static function.<br>
+       (find_end_label): Add a new arg, KIND.  All callers changed.<br>
+       Depending on KIND, look for a label suitable for return or<br>
+       simple_return.<br>
+       (make_return_insns): Make corresponding changes.<br>
+       (get_jump_flags): Check JUMP_LABELs for returns.<br>
+       (follow_jumps): Likewise.<br>
+       (get_branch_condition): Check target for return patterns rather<br>
+       than NULL.<br>
+       (own_thread_p): Likewise for thread.<br>
+       (steal_delay_list_from_target): Check JUMP_LABELs for returns.<br>
+       Use simplejump_or_return_p.<br>
+       (fill_simple_delay_slots): Likewise.<br>
+       (optimize_skip): Likewise.<br>
+       (fill_slots_from_thread): Likewise.<br>
+       (relax_delay_slots): Likewise.<br>
+       (dbr_schedule): Adjust handling of end_of_function_label for the<br>
+       two new variables.<br>
+       * ifcvt.c (find_if_case_1): Take care when redirecting jumps to the<br>
+       exit block.<br>
+       (dead_or_predicable): Change NEW_DEST arg to DEST_EDGE.  All callers<br>
+       changed.  Ensure that the right label is passed to redirect_jump.<br>
+       * jump.c (condjump_p, condjump_in_parallel_p, any_condjump_p,<br>
+       returnjump_p): Handle SIMPLE_RETURNs.<br>
+       (delete_related_insns): Check JUMP_LABEL for returns.<br>
+       (redirect_target): New static function.<br>
+       (redirect_exp_1): Use it.  Handle any kind of return rtx as a label<br>
+       rather than interpreting NULL as a return.<br>
+       (redirect_jump_1): Assert that nlabel is not NULL.<br>
+       (redirect_jump): Likewise.<br>
+       (redirect_jump_2): Handle any kind of return rtx as a label rather<br>
+       than interpreting NULL as a return.<br>
+       * dwarf2out.c (compute_barrier_args_size_1): Check JUMP_LABEL for<br>
+       returns.<br>
+       * function.c (emit_return_into_block): Remove useless declaration.<br>
+       (record_hard_reg_sets, frame_required_for_rtx, gen_return_pattern,<br>
+       requires_stack_frame_p): New static functions.<br>
+       (emit_return_into_block): New arg SIMPLE_P.  All callers changed.<br>
+       Generate either kind of return pattern and update the JUMP_LABEL.<br>
+       (thread_prologue_and_epilogue_insns): Implement a form of<br>
+       shrink-wrapping.  Ensure JUMP_LABELs for return insns are set.<br>
+       * print-rtl.c (print_rtx): Handle returns in JUMP_LABELs.<br>
+       * cfglayout.c (fixup_reorder_chain): Ensure JUMP_LABELs for returns<br>
+       remain correct.<br>
+       * resource.c (find_dead_or_set_registers): Check JUMP_LABELs for<br>
+       returns.<br>
+       (mark_target_live_regs): Don&#39;t pass a return rtx to next_active_insn.<br>
+       * basic-block.h (force_nonfallthru_and_redirect): Declare.<br>
+       * sched-vis.c (print_pattern): Add case for SIMPLE_RETURN.<br>
+       * cfgrtl.c (force_nonfallthru_and_redirect): No longer static.  New arg<br>
+       JUMP_LABEL.  All callers changed.  Use the label when generating<br>
+       return insns.<br>
+<br>
+       * config/i386/<a href="http://i386.md" target="_blank">i386.md</a> (returns, return_str, return_cond): New<br>
+       code_iterator and corresponding code_attrs.<br>
+       (&lt;return_str&gt;return): Renamed from return and adapted.<br>
+       (&lt;return_str&gt;return_internal): Likewise for return_internal.<br>
+       (&lt;return_str&gt;return_internal_long): Likewise for return_internal_long.<br>
+       (&lt;return_str&gt;return_pop_internal): Likewise for return_pop_internal.<br>
+       (&lt;return_str&gt;return_indirect_internal): Likewise for<br>
+       return_indirect_internal.<br>
+       * config/i386/i386.c (ix86_expand_epilogue): Expand a simple_return as<br>
+       the last insn.<br>
+       (ix86_pad_returns): Handle both kinds of return rtx.<br>
+       * config/arm/arm.c (use_simple_return_p): new function.<br>
+       (is_jump_table): Handle returns in JUMP_LABELs.<br>
+       (output_return_instruction): New arg SIMPLE.  All callers changed.<br>
+       Use it to determine which kind of return to generate.<br>
+       (arm_final_prescan_insn): Handle both kinds of return.<br>
+       * config/arm/<a href="http://arm.md" target="_blank">arm.md</a> (returns, return_str, return_simple_p,<br>
+       return_cond): New code_iterator and corresponding code_attrs.<br>
+       (&lt;return_str&gt;return): Renamed from return and adapted.<br>
+       (arm_&lt;return_str&gt;return): Renamed from arm_return and adapted.<br>
+       (cond_&lt;return_str&gt;return): Renamed from cond_return and adapted.<br>
+       (cond_&lt;return_str&gt;return_inverted): Renamed from cond_return_inverted<br>
+       and adapted.<br>
+       (epilogue): Use ret_rtx instead of gen_rtx_RETURN.<br>
+       * config/arm/<a href="http://thumb2.md" target="_blank">thumb2.md</a> (thumb2_&lt;return_str&gt;return): Renamed from<br>
+       thumb2_return and adapted.<br>
+       * config/arm/arm.h (RETURN_ADDR_REGNUM): Define.<br>
+       * config/arm/arm-protos.h (use_simple_return_p): Declare.<br>
+       (output_return_instruction): Adjust declaration.<br>
+       * config/mips/mips.c (mips_expand_epilogue): Generate a simple_return<br>
+       as final insn.<br>
+       * config/mips/<a href="http://mips.md" target="_blank">mips.md</a> (simple_return): New expander.<br>
+       (*simple_return, simple_return_internal): New patterns.<br>
+       * config/sh/sh.c (barrier_align): Handle return in a JUMP_LABEL.<br>
+       (split_branches): Don&#39;t pass a null label to redirect_jump.<br>
+<br>
+       From mainline:<br>
+       * vec.h (FOR_EACH_VEC_ELT, FOR_EACH_VEC_ELT_REVERSE): New macros.<br>
+       * haifa-sched.c (find_fallthru_edge_from): Rename from<br>
+       find_fallthru_edge.  All callers changed.<br>
+       * sched-int.h (find_fallthru_edge_from): Rename declaration as well.<br>
+       * basic-block.h (find_fallthru_edge): New inline function.<br>
+<br>
+=== modified file &#39;gcc/basic-block.h&#39;<br>
+Index: gcc-4_5-branch/gcc/basic-block.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/basic-block.h<br>
++++ gcc-4_5-branch/gcc/basic-block.h<br>
+@@ -884,6 +884,7 @@ extern void flow_edge_list_print (const<br>
+<br>
+ /* In cfgrtl.c  */<br>
+ extern basic_block force_nonfallthru (edge);<br>
++extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);<br>
+ extern rtx block_label (basic_block);<br>
+ extern bool purge_all_dead_edges (void);<br>
+ extern bool purge_dead_edges (basic_block);<br>
+@@ -1004,6 +1005,20 @@ bb_has_abnormal_pred (basic_block bb)<br>
+   return false;<br>
+ }<br>
+<br>
++/* Return the fallthru edge in EDGES if it exists, NULL otherwise.  */<br>
++static inline edge<br>
++find_fallthru_edge (VEC(edge,gc) *edges)<br>
++{<br>
++  edge e;<br>
++  edge_iterator ei;<br>
++<br>
++  FOR_EACH_EDGE (e, ei, edges)<br>
++    if (e-&gt;flags &amp; EDGE_FALLTHRU)<br>
++      break;<br>
++<br>
++  return e;<br>
++}<br>
++<br>
+ /* In cfgloopmanip.c.  */<br>
+ extern edge mfb_kj_edge;<br>
+ extern bool mfb_keep_just (edge);<br>
+Index: gcc-4_5-branch/gcc/cfganal.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/cfganal.c<br>
++++ gcc-4_5-branch/gcc/cfganal.c<br>
+@@ -271,6 +271,37 @@ set_edge_can_fallthru_flag (void)<br>
+       EDGE_SUCC (bb, 0)-&gt;flags |= EDGE_CAN_FALLTHRU;<br>
+       EDGE_SUCC (bb, 1)-&gt;flags |= EDGE_CAN_FALLTHRU;<br>
+     }<br>
++  /* dwarf2out expects that a NOTE_INSN_EPILOGUE_BEGIN is always paired<br>
++     with a return or a sibcall.  Ensure that this remains the case if<br>
++     they are in different basic blocks.  */<br>
++  FOR_EACH_BB (bb)<br>
++    {<br>
++      edge e;<br>
++      edge_iterator ei;<br>
++      rtx insn, end;<br>
++<br>
++      end = BB_END (bb);<br>
++      FOR_BB_INSNS (bb, insn)<br>
++      if (GET_CODE (insn) == NOTE<br>
++          &amp;&amp; NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG<br>
++          &amp;&amp; !(CALL_P (end) &amp;&amp; SIBLING_CALL_P (end))<br>
++          &amp;&amp; !returnjump_p (end))<br>
++        {<br>
++          basic_block other_bb = NULL;<br>
++          FOR_EACH_EDGE (e, ei, bb-&gt;succs)<br>
++            {<br>
++              if (e-&gt;flags &amp; EDGE_FALLTHRU)<br>
++                other_bb = e-&gt;dest;<br>
++              else<br>
++                e-&gt;flags &amp;= ~EDGE_CAN_FALLTHRU;<br>
++            }<br>
++          FOR_EACH_EDGE (e, ei, other_bb-&gt;preds)<br>
++            {<br>
++              if (!(e-&gt;flags &amp; EDGE_FALLTHRU))<br>
++                e-&gt;flags &amp;= ~EDGE_CAN_FALLTHRU;<br>
++            }<br>
++        }<br>
++    }<br>
+ }<br>
+<br>
+ /* Find unreachable blocks.  An unreachable block will have 0 in<br>
+Index: gcc-4_5-branch/gcc/cfglayout.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/cfglayout.c<br>
++++ gcc-4_5-branch/gcc/cfglayout.c<br>
+@@ -766,6 +766,7 @@ fixup_reorder_chain (void)<br>
+     {<br>
+       edge e_fall, e_taken, e;<br>
+       rtx bb_end_insn;<br>
++      rtx ret_label = NULL_RTX;<br>
+       basic_block nb;<br>
+       edge_iterator ei;<br>
+<br>
+@@ -785,6 +786,7 @@ fixup_reorder_chain (void)<br>
+       bb_end_insn = BB_END (bb);<br>
+       if (JUMP_P (bb_end_insn))<br>
+       {<br>
++        ret_label = JUMP_LABEL (bb_end_insn);<br>
+         if (any_condjump_p (bb_end_insn))<br>
+           {<br>
+             /* This might happen if the conditional jump has side<br>
+@@ -899,7 +901,7 @@ fixup_reorder_chain (void)<br>
+       }<br>
+<br>
+       /* We got here if we need to add a new jump insn.  */<br>
+-      nb = force_nonfallthru (e_fall);<br>
++      nb = force_nonfallthru_and_redirect (e_fall, e_fall-&gt;dest, ret_label);<br>
+       if (nb)<br>
+       {<br>
+         nb-&gt;il.rtl-&gt;visited = 1;<br>
+@@ -1118,24 +1120,30 @@ extern bool cfg_layout_can_duplicate_bb_<br>
+ bool<br>
+ cfg_layout_can_duplicate_bb_p (const_basic_block bb)<br>
+ {<br>
++  rtx insn;<br>
++<br>
+   /* Do not attempt to duplicate tablejumps, as we need to unshare<br>
+      the dispatch table.  This is difficult to do, as the instructions<br>
+      computing jump destination may be hoisted outside the basic block.  */<br>
+   if (tablejump_p (BB_END (bb), NULL, NULL))<br>
+     return false;<br>
+<br>
+-  /* Do not duplicate blocks containing insns that can&#39;t be copied.  */<br>
+-  if (targetm.cannot_copy_insn_p)<br>
++  insn = BB_HEAD (bb);<br>
++  while (1)<br>
+     {<br>
+-      rtx insn = BB_HEAD (bb);<br>
+-      while (1)<br>
+-      {<br>
+-        if (INSN_P (insn) &amp;&amp; targetm.cannot_copy_insn_p (insn))<br>
+-          return false;<br>
+-        if (insn == BB_END (bb))<br>
+-          break;<br>
+-        insn = NEXT_INSN (insn);<br>
+-      }<br>
++      /* Do not duplicate blocks containing insns that can&#39;t be copied.  */<br>
++      if (INSN_P (insn) &amp;&amp; targetm.cannot_copy_insn_p<br>
++        &amp;&amp; targetm.cannot_copy_insn_p (insn))<br>
++      return false;<br>
++      /* dwarf2out expects that these notes are always paired with a<br>
++       returnjump or sibling call.  */<br>
++      if (NOTE_P (insn) &amp;&amp; NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG<br>
++        &amp;&amp; !returnjump_p (BB_END (bb))<br>
++        &amp;&amp; (!CALL_P (BB_END (bb)) || !SIBLING_CALL_P (BB_END (bb))))<br>
++      return false;<br>
++      if (insn == BB_END (bb))<br>
++      break;<br>
++      insn = NEXT_INSN (insn);<br>
+     }<br>
+<br>
+   return true;<br>
+@@ -1180,6 +1188,9 @@ duplicate_insn_chain (rtx from, rtx to)<br>
+             break;<br>
+           }<br>
+         copy = emit_copy_of_insn_after (insn, get_last_insn ());<br>
++        if (JUMP_P (insn) &amp;&amp; JUMP_LABEL (insn) != NULL_RTX<br>
++            &amp;&amp; ANY_RETURN_P (JUMP_LABEL (insn)))<br>
++          JUMP_LABEL (copy) = JUMP_LABEL (insn);<br>
+           maybe_copy_epilogue_insn (insn, copy);<br>
+         break;<br>
+<br>
+Index: gcc-4_5-branch/gcc/cfgrtl.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/cfgrtl.c<br>
++++ gcc-4_5-branch/gcc/cfgrtl.c<br>
+@@ -1107,10 +1107,13 @@ rtl_redirect_edge_and_branch (edge e, ba<br>
+ }<br>
+<br>
+ /* Like force_nonfallthru below, but additionally performs redirection<br>
+-   Used by redirect_edge_and_branch_force.  */<br>
++   Used by redirect_edge_and_branch_force.  JUMP_LABEL is used only<br>
++   when redirecting to the EXIT_BLOCK, it is either a return or a<br>
++   simple_return rtx indicating which kind of returnjump to create.<br>
++   It should be NULL otherwise.  */<br>
+<br>
+-static basic_block<br>
+-force_nonfallthru_and_redirect (edge e, basic_block target)<br>
++basic_block<br>
++force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)<br>
+ {<br>
+   basic_block jump_block, new_bb = NULL, src = e-&gt;src;<br>
+   rtx note;<br>
+@@ -1242,11 +1245,25 @@ force_nonfallthru_and_redirect (edge e,<br>
+   e-&gt;flags &amp;= ~EDGE_FALLTHRU;<br>
+   if (target == EXIT_BLOCK_PTR)<br>
+     {<br>
++      if (jump_label == ret_rtx)<br>
++      {<br>
+ #ifdef HAVE_return<br>
+-      emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block), loc);<br>
++        emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block),<br>
++                                     loc);<br>
+ #else<br>
+-      gcc_unreachable ();<br>
++        gcc_unreachable ();<br>
+ #endif<br>
++      }<br>
++      else<br>
++      {<br>
++        gcc_assert (jump_label == simple_return_rtx);<br>
++#ifdef HAVE_simple_return<br>
++        emit_jump_insn_after_setloc (gen_simple_return (),<br>
++                                     BB_END (jump_block), loc);<br>
++#else<br>
++        gcc_unreachable ();<br>
++#endif<br>
++      }<br>
+     }<br>
+   else<br>
+     {<br>
+@@ -1273,7 +1290,7 @@ force_nonfallthru_and_redirect (edge e,<br>
+ basic_block<br>
+ force_nonfallthru (edge e)<br>
+ {<br>
+-  return force_nonfallthru_and_redirect (e, e-&gt;dest);<br>
++  return force_nonfallthru_and_redirect (e, e-&gt;dest, NULL_RTX);<br>
+ }<br>
+<br>
+ /* Redirect edge even at the expense of creating new jump insn or<br>
+@@ -1290,7 +1307,7 @@ rtl_redirect_edge_and_branch_force (edge<br>
+   /* In case the edge redirection failed, try to force it to be non-fallthru<br>
+      and redirect newly created simplejump.  */<br>
+   df_set_bb_dirty (e-&gt;src);<br>
+-  return force_nonfallthru_and_redirect (e, target);<br>
++  return force_nonfallthru_and_redirect (e, target, NULL_RTX);<br>
+ }<br>
+<br>
+ /* The given edge should potentially be a fallthru edge.  If that is in<br>
+Index: gcc-4_5-branch/gcc/common.opt<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/common.opt<br>
++++ gcc-4_5-branch/gcc/common.opt<br>
+@@ -1147,6 +1147,11 @@ fshow-column<br>
+ Common C ObjC C++ ObjC++ Report Var(flag_show_column) Init(1)<br>
+ Show column numbers in diagnostics, when available.  Default on<br>
+<br>
++fshrink-wrap<br>
++Common Report Var(flag_shrink_wrap) Optimization<br>
++Emit function prologues only before parts of the function that need it,<br>
++rather than at the top of the function.<br>
++<br>
+ fsignaling-nans<br>
+ Common Report Var(flag_signaling_nans) Optimization<br>
+ Disable optimizations observable by IEEE signaling NaNs<br>
+Index: gcc-4_5-branch/gcc/config/arm/arm-protos.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/arm-protos.h<br>
++++ gcc-4_5-branch/gcc/config/arm/arm-protos.h<br>
+@@ -26,6 +26,7 @@<br>
+ extern void arm_override_options (void);<br>
+ extern void arm_optimization_options (int, int);<br>
+ extern int use_return_insn (int, rtx);<br>
++extern bool use_simple_return_p (void);<br>
+ extern enum reg_class arm_regno_class (int);<br>
+ extern void arm_load_pic_register (unsigned long);<br>
+ extern int arm_volatile_func (void);<br>
+@@ -137,7 +138,7 @@ extern int arm_address_offset_is_imm (rt<br>
+ extern const char *output_add_immediate (rtx *);<br>
+ extern const char *arithmetic_instr (rtx, int);<br>
+ extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);<br>
+-extern const char *output_return_instruction (rtx, int, int);<br>
++extern const char *output_return_instruction (rtx, bool, bool, bool);<br>
+ extern void arm_poke_function_name (FILE *, const char *);<br>
+ extern void arm_print_operand (FILE *, rtx, int);<br>
+ extern void arm_print_operand_address (FILE *, rtx);<br>
+Index: gcc-4_5-branch/gcc/config/arm/arm.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/arm.c<br>
++++ gcc-4_5-branch/gcc/config/arm/arm.c<br>
+@@ -2163,6 +2163,18 @@ arm_trampoline_adjust_address (rtx addr)<br>
+   return addr;<br>
+ }<br>
+<br>
++/* Return true if we should try to use a simple_return insn, i.e. perform<br>
++   shrink-wrapping if possible.  This is the case if we need to emit a<br>
++   prologue, which we can test by looking at the offsets.  */<br>
++bool<br>
++use_simple_return_p (void)<br>
++{<br>
++  arm_stack_offsets *offsets;<br>
++<br>
++  offsets = arm_get_frame_offsets ();<br>
++  return offsets-&gt;outgoing_args != 0;<br>
++}<br>
++<br>
+ /* Return 1 if it is possible to return using a single instruction.<br>
+    If SIBLING is non-null, this is a test for a return before a sibling<br>
+    call.  SIBLING is the call insn, so we can examine its register usage.  */<br>
+@@ -11284,6 +11296,7 @@ is_jump_table (rtx insn)<br>
+<br>
+   if (GET_CODE (insn) == JUMP_INSN<br>
+       &amp;&amp; JUMP_LABEL (insn) != NULL<br>
++      &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (insn))<br>
+       &amp;&amp; ((table = next_real_insn (JUMP_LABEL (insn)))<br>
+         == next_real_insn (insn))<br>
+       &amp;&amp; table != NULL<br>
+@@ -14168,7 +14181,7 @@ arm_get_vfp_saved_size (void)<br>
+ /* Generate a function exit sequence.  If REALLY_RETURN is false, then do<br>
+    everything bar the final return instruction.  */<br>
+ const char *<br>
+-output_return_instruction (rtx operand, int really_return, int reverse)<br>
++output_return_instruction (rtx operand, bool really_return, bool reverse, bool simple)<br>
+ {<br>
+   char conditional[10];<br>
+   char instr[100];<br>
+@@ -14206,10 +14219,15 @@ output_return_instruction (rtx operand,<br>
+<br>
+   sprintf (conditional, &quot;%%?%%%c0&quot;, reverse ? &#39;D&#39; : &#39;d&#39;);<br>
+<br>
+-  cfun-&gt;machine-&gt;return_used_this_function = 1;<br>
++  if (simple)<br>
++    live_regs_mask = 0;<br>
++  else<br>
++    {<br>
++      cfun-&gt;machine-&gt;return_used_this_function = 1;<br>
+<br>
+-  offsets = arm_get_frame_offsets ();<br>
+-  live_regs_mask = offsets-&gt;saved_regs_mask;<br>
++      offsets = arm_get_frame_offsets ();<br>
++      live_regs_mask = offsets-&gt;saved_regs_mask;<br>
++    }<br>
+<br>
+   if (live_regs_mask)<br>
+     {<br>
+@@ -17108,6 +17126,7 @@ arm_final_prescan_insn (rtx insn)<br>
+<br>
+   /* If we start with a return insn, we only succeed if we find another one.  */<br>
+   int seeking_return = 0;<br>
++  enum rtx_code return_code = UNKNOWN;<br>
+<br>
+   /* START_INSN will hold the insn from where we start looking.  This is the<br>
+      first insn after the following code_label if REVERSE is true.  */<br>
+@@ -17146,7 +17165,7 @@ arm_final_prescan_insn (rtx insn)<br>
+         else<br>
+           return;<br>
+       }<br>
+-      else if (GET_CODE (body) == RETURN)<br>
++      else if (ANY_RETURN_P (body))<br>
+         {<br>
+         start_insn = next_nonnote_insn (start_insn);<br>
+         if (GET_CODE (start_insn) == BARRIER)<br>
+@@ -17157,6 +17176,7 @@ arm_final_prescan_insn (rtx insn)<br>
+           {<br>
+             reverse = TRUE;<br>
+             seeking_return = 1;<br>
++            return_code = GET_CODE (body);<br>
+           }<br>
+         else<br>
+           return;<br>
+@@ -17197,11 +17217,15 @@ arm_final_prescan_insn (rtx insn)<br>
+         label = XEXP (XEXP (SET_SRC (body), 2), 0);<br>
+         then_not_else = FALSE;<br>
+       }<br>
+-      else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)<br>
+-      seeking_return = 1;<br>
+-      else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)<br>
++      else if (ANY_RETURN_P (XEXP (SET_SRC (body), 1)))<br>
++      {<br>
++        seeking_return = 1;<br>
++        return_code = GET_CODE (XEXP (SET_SRC (body), 1));<br>
++      }<br>
++      else if (ANY_RETURN_P (XEXP (SET_SRC (body), 2)))<br>
+         {<br>
+         seeking_return = 1;<br>
++        return_code = GET_CODE (XEXP (SET_SRC (body), 2));<br>
+         then_not_else = FALSE;<br>
+         }<br>
+       else<br>
+@@ -17302,8 +17326,7 @@ arm_final_prescan_insn (rtx insn)<br>
+                      &amp;&amp; !use_return_insn (TRUE, NULL)<br>
+                      &amp;&amp; !optimize_size)<br>
+               fail = TRUE;<br>
+-            else if (GET_CODE (scanbody) == RETURN<br>
+-                     &amp;&amp; seeking_return)<br>
++            else if (GET_CODE (scanbody) == return_code)<br>
+               {<br>
+                 arm_ccfsm_state = 2;<br>
+                 succeed = TRUE;<br>
+Index: gcc-4_5-branch/gcc/config/arm/arm.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/arm.h<br>
++++ gcc-4_5-branch/gcc/config/arm/arm.h<br>
+@@ -2622,6 +2622,8 @@ extern int making_const_table;<br>
+ #define RETURN_ADDR_RTX(COUNT, FRAME) \<br>
+   arm_return_addr (COUNT, FRAME)<br>
+<br>
++#define RETURN_ADDR_REGNUM LR_REGNUM<br>
++<br>
+ /* Mask of the bits in the PC that contain the real return address<br>
+    when running in 26-bit mode.  */<br>
+ #define RETURN_ADDR_MASK26 (0x03fffffc)<br>
+Index: gcc-4_5-branch/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a><br>
++++ gcc-4_5-branch/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a><br>
+@@ -8882,66 +8882,72 @@<br>
+   [(set_attr &quot;type&quot; &quot;call&quot;)]<br>
+ )<br>
+<br>
+-(define_expand &quot;return&quot;<br>
+-  [(return)]<br>
+-  &quot;TARGET_32BIT &amp;&amp; USE_RETURN_INSN (FALSE)&quot;<br>
++;; Both kinds of return insn.<br>
++(define_code_iterator returns [return simple_return])<br>
++(define_code_attr return_str [(return &quot;&quot;) (simple_return &quot;simple_&quot;)])<br>
++(define_code_attr return_simple_p [(return &quot;false&quot;) (simple_return &quot;true&quot;)])<br>
++(define_code_attr return_cond [(return &quot; &amp;&amp; USE_RETURN_INSN (FALSE)&quot;)<br>
++                             (simple_return &quot; &amp;&amp; use_simple_return_p ()&quot;)])<br>
++<br>
++(define_expand &quot;&lt;return_str&gt;return&quot;<br>
++  [(returns)]<br>
++  &quot;TARGET_32BIT&lt;return_cond&gt;&quot;<br>
+   &quot;&quot;)<br>
+<br>
+-;; Often the return insn will be the same as loading from memory, so set attr<br>
+-(define_insn &quot;*arm_return&quot;<br>
+-  [(return)]<br>
+-  &quot;TARGET_ARM &amp;&amp; USE_RETURN_INSN (FALSE)&quot;<br>
+-  &quot;*<br>
+-  {<br>
+-    if (arm_ccfsm_state == 2)<br>
+-      {<br>
+-        arm_ccfsm_state += 2;<br>
+-        return \&quot;\&quot;;<br>
+-      }<br>
+-    return output_return_instruction (const_true_rtx, TRUE, FALSE);<br>
+-  }&quot;<br>
++(define_insn &quot;*arm_&lt;return_str&gt;return&quot;<br>
++  [(returns)]<br>
++  &quot;TARGET_ARM&lt;return_cond&gt;&quot;<br>
++{<br>
++  if (arm_ccfsm_state == 2)<br>
++    {<br>
++      arm_ccfsm_state += 2;<br>
++      return &quot;&quot;;<br>
++    }<br>
++  return output_return_instruction (const_true_rtx, true, false,<br>
++                                  &lt;return_simple_p&gt;);<br>
++}<br>
+   [(set_attr &quot;type&quot; &quot;load1&quot;)<br>
+    (set_attr &quot;length&quot; &quot;12&quot;)<br>
+    (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
+ )<br>
+<br>
+-(define_insn &quot;*cond_return&quot;<br>
++(define_insn &quot;*cond_&lt;return_str&gt;return&quot;<br>
+   [(set (pc)<br>
+         (if_then_else (match_operator 0 &quot;arm_comparison_operator&quot;<br>
+                      [(match_operand 1 &quot;cc_register&quot; &quot;&quot;) (const_int 0)])<br>
+-                      (return)<br>
++                      (returns)<br>
+                       (pc)))]<br>
+-  &quot;TARGET_ARM &amp;&amp; USE_RETURN_INSN (TRUE)&quot;<br>
+-  &quot;*<br>
+-  {<br>
+-    if (arm_ccfsm_state == 2)<br>
+-      {<br>
+-        arm_ccfsm_state += 2;<br>
+-        return \&quot;\&quot;;<br>
+-      }<br>
+-    return output_return_instruction (operands[0], TRUE, FALSE);<br>
+-  }&quot;<br>
++  &quot;TARGET_ARM&lt;return_cond&gt;&quot;<br>
++{<br>
++  if (arm_ccfsm_state == 2)<br>
++    {<br>
++      arm_ccfsm_state += 2;<br>
++      return &quot;&quot;;<br>
++    }<br>
++  return output_return_instruction (operands[0], true, false,<br>
++                                  &lt;return_simple_p&gt;);<br>
++}<br>
+   [(set_attr &quot;conds&quot; &quot;use&quot;)<br>
+    (set_attr &quot;length&quot; &quot;12&quot;)<br>
+    (set_attr &quot;type&quot; &quot;load1&quot;)]<br>
+ )<br>
+<br>
+-(define_insn &quot;*cond_return_inverted&quot;<br>
++(define_insn &quot;*cond_&lt;return_str&gt;return_inverted&quot;<br>
+   [(set (pc)<br>
+         (if_then_else (match_operator 0 &quot;arm_comparison_operator&quot;<br>
+                      [(match_operand 1 &quot;cc_register&quot; &quot;&quot;) (const_int 0)])<br>
+                       (pc)<br>
+-                    (return)))]<br>
+-  &quot;TARGET_ARM &amp;&amp; USE_RETURN_INSN (TRUE)&quot;<br>
+-  &quot;*<br>
+-  {<br>
+-    if (arm_ccfsm_state == 2)<br>
+-      {<br>
+-        arm_ccfsm_state += 2;<br>
+-        return \&quot;\&quot;;<br>
+-      }<br>
+-    return output_return_instruction (operands[0], TRUE, TRUE);<br>
+-  }&quot;<br>
++                    (returns)))]<br>
++  &quot;TARGET_ARM&lt;return_cond&gt;&quot;<br>
++{<br>
++  if (arm_ccfsm_state == 2)<br>
++    {<br>
++      arm_ccfsm_state += 2;<br>
++      return &quot;&quot;;<br>
++    }<br>
++  return output_return_instruction (operands[0], true, true,<br>
++                                  &lt;return_simple_p&gt;);<br>
++}<br>
+   [(set_attr &quot;conds&quot; &quot;use&quot;)<br>
+    (set_attr &quot;length&quot; &quot;12&quot;)<br>
+    (set_attr &quot;type&quot; &quot;load1&quot;)]<br>
+@@ -10809,8 +10815,7 @@<br>
+       DONE;<br>
+     }<br>
+   emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,<br>
+-      gen_rtvec (1,<br>
+-              gen_rtx_RETURN (VOIDmode)),<br>
++      gen_rtvec (1, ret_rtx),<br>
+       VUNSPEC_EPILOGUE));<br>
+   DONE;<br>
+   &quot;<br>
+@@ -10827,7 +10832,7 @@<br>
+   &quot;TARGET_32BIT&quot;<br>
+   &quot;*<br>
+   if (use_return_insn (FALSE, next_nonnote_insn (insn)))<br>
+-    return output_return_instruction (const_true_rtx, FALSE, FALSE);<br>
++    return output_return_instruction (const_true_rtx, false, false, false);<br>
+   return arm_output_epilogue (next_nonnote_insn (insn));<br>
+   &quot;<br>
+ ;; Length is absolute worst case<br>
+Index: gcc-4_5-branch/gcc/config/arm/<a href="http://thumb2.md" target="_blank">thumb2.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/<a href="http://thumb2.md" target="_blank">thumb2.md</a><br>
++++ gcc-4_5-branch/gcc/config/arm/<a href="http://thumb2.md" target="_blank">thumb2.md</a><br>
+@@ -1020,16 +1020,15 @@<br>
+<br>
+ ;; Note: this is not predicable, to avoid issues with linker-generated<br>
+ ;; interworking stubs.<br>
+-(define_insn &quot;*thumb2_return&quot;<br>
+-  [(return)]<br>
+-  &quot;TARGET_THUMB2 &amp;&amp; USE_RETURN_INSN (FALSE)&quot;<br>
+-  &quot;*<br>
+-  {<br>
+-    return output_return_instruction (const_true_rtx, TRUE, FALSE);<br>
+-  }&quot;<br>
++(define_insn &quot;*thumb2_&lt;return_str&gt;return&quot;<br>
++  [(returns)]<br>
++  &quot;TARGET_THUMB2&lt;return_cond&gt;&quot;<br>
++{<br>
++  return output_return_instruction (const_true_rtx, true, false,<br>
++                                  &lt;return_simple_p&gt;);<br>
++}<br>
+   [(set_attr &quot;type&quot; &quot;load1&quot;)<br>
+-   (set_attr &quot;length&quot; &quot;12&quot;)]<br>
+-)<br>
++   (set_attr &quot;length&quot; &quot;12&quot;)])<br>
+<br>
+ (define_insn_and_split &quot;thumb2_eh_return&quot;<br>
+   [(unspec_volatile [(match_operand:SI 0 &quot;s_register_operand&quot; &quot;r&quot;)]<br>
+Index: gcc-4_5-branch/gcc/config/bfin/bfin.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/bfin/bfin.c<br>
++++ gcc-4_5-branch/gcc/config/bfin/bfin.c<br>
+@@ -2359,7 +2359,7 @@ bfin_expand_call (rtx retval, rtx fnaddr<br>
+     XVECEXP (pat, 0, n++) = gen_rtx_USE (VOIDmode, picreg);<br>
+   XVECEXP (pat, 0, n++) = gen_rtx_USE (VOIDmode, cookie);<br>
+   if (sibcall)<br>
+-    XVECEXP (pat, 0, n++) = gen_rtx_RETURN (VOIDmode);<br>
++    XVECEXP (pat, 0, n++) = ret_rtx;<br>
+   else<br>
+     XVECEXP (pat, 0, n++) = gen_rtx_CLOBBER (VOIDmode, retsreg);<br>
+   call = emit_call_insn (pat);<br>
+Index: gcc-4_5-branch/gcc/config/cris/cris.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/cris/cris.c<br>
++++ gcc-4_5-branch/gcc/config/cris/cris.c<br>
+@@ -1771,7 +1771,7 @@ cris_expand_return (bool on_stack)<br>
+      we do that until they&#39;re fixed.  Currently, all return insns in a<br>
+      function must be the same (not really a limiting factor) so we need<br>
+      to check that it doesn&#39;t change half-way through.  */<br>
+-  emit_jump_insn (gen_rtx_RETURN (VOIDmode));<br>
++  emit_jump_insn (ret_rtx);<br>
+<br>
+   CRIS_ASSERT (cfun-&gt;machine-&gt;return_type != CRIS_RETINSN_RET || !on_stack);<br>
+   CRIS_ASSERT (cfun-&gt;machine-&gt;return_type != CRIS_RETINSN_JUMP || on_stack);<br>
+Index: gcc-4_5-branch/gcc/config/h8300/h8300.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/h8300/h8300.c<br>
++++ gcc-4_5-branch/gcc/config/h8300/h8300.c<br>
+@@ -691,7 +691,7 @@ h8300_push_pop (int regno, int nregs, bo<br>
+   /* Add the return instruction.  */<br>
+   if (return_p)<br>
+     {<br>
+-      RTVEC_ELT (vec, i) = gen_rtx_RETURN (VOIDmode);<br>
++      RTVEC_ELT (vec, i) = ret_rtx;<br>
+       i++;<br>
+     }<br>
+<br>
+@@ -975,7 +975,7 @@ h8300_expand_epilogue (void)<br>
+     }<br>
+<br>
+   if (!returned_p)<br>
+-    emit_jump_insn (gen_rtx_RETURN (VOIDmode));<br>
++    emit_jump_insn (ret_rtx);<br>
+ }<br>
+<br>
+ /* Return nonzero if the current function is an interrupt<br>
+Index: gcc-4_5-branch/gcc/config/i386/i386.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/i386/i386.c<br>
++++ gcc-4_5-branch/gcc/config/i386/i386.c<br>
+@@ -9308,13 +9308,13 @@ ix86_expand_epilogue (int style)<br>
+<br>
+         pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,<br>
+                                    popc, -1, true);<br>
+-        emit_jump_insn (gen_return_indirect_internal (ecx));<br>
++        emit_jump_insn (gen_simple_return_indirect_internal (ecx));<br>
+       }<br>
+       else<br>
+-      emit_jump_insn (gen_return_pop_internal (popc));<br>
++      emit_jump_insn (gen_simple_return_pop_internal (popc));<br>
+     }<br>
+   else<br>
+-    emit_jump_insn (gen_return_internal ());<br>
++    emit_jump_insn (gen_simple_return_internal ());<br>
+<br>
+   /* Restore the state back to the state from the prologue,<br>
+      so that it&#39;s correct for the next epilogue.  */<br>
+@@ -26615,7 +26615,7 @@ ix86_pad_returns (void)<br>
+       rtx prev;<br>
+       bool replace = false;<br>
+<br>
+-      if (!JUMP_P (ret) || GET_CODE (PATTERN (ret)) != RETURN<br>
++      if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))<br>
+         || optimize_bb_for_size_p (bb))<br>
+       continue;<br>
+       for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))<br>
+@@ -26645,7 +26645,10 @@ ix86_pad_returns (void)<br>
+       }<br>
+       if (replace)<br>
+       {<br>
+-        emit_jump_insn_before (gen_return_internal_long (), ret);<br>
++        if (PATTERN (ret) == ret_rtx)<br>
++          emit_jump_insn_before (gen_return_internal_long (), ret);<br>
++        else<br>
++          emit_jump_insn_before (gen_simple_return_internal_long (), ret);<br>
+         delete_insn (ret);<br>
+       }<br>
+     }<br>
+Index: gcc-4_5-branch/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a><br>
++++ gcc-4_5-branch/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a><br>
+@@ -13798,24 +13798,29 @@<br>
+   &quot;&quot;<br>
+   [(set_attr &quot;length&quot; &quot;0&quot;)])<br>
+<br>
++(define_code_iterator returns [return simple_return])<br>
++(define_code_attr return_str [(return &quot;&quot;) (simple_return &quot;simple_&quot;)])<br>
++(define_code_attr return_cond [(return &quot;ix86_can_use_return_insn_p ()&quot;)<br>
++                             (simple_return &quot;&quot;)])<br>
++<br>
+ ;; Insn emitted into the body of a function to return from a function.<br>
+ ;; This is only done if the function&#39;s epilogue is known to be simple.<br>
+ ;; See comments for ix86_can_use_return_insn_p in i386.c.<br>
+<br>
+-(define_expand &quot;return&quot;<br>
+-  [(return)]<br>
+-  &quot;ix86_can_use_return_insn_p ()&quot;<br>
++(define_expand &quot;&lt;return_str&gt;return&quot;<br>
++  [(returns)]<br>
++  &quot;&lt;return_cond&gt;&quot;<br>
+ {<br>
+   if (crtl-&gt;args.pops_args)<br>
+     {<br>
+       rtx popc = GEN_INT (crtl-&gt;args.pops_args);<br>
+-      emit_jump_insn (gen_return_pop_internal (popc));<br>
++      emit_jump_insn (gen_&lt;return_str&gt;return_pop_internal (popc));<br>
+       DONE;<br>
+     }<br>
+ })<br>
+<br>
+-(define_insn &quot;return_internal&quot;<br>
+-  [(return)]<br>
++(define_insn &quot;&lt;return_str&gt;return_internal&quot;<br>
++  [(returns)]<br>
+   &quot;reload_completed&quot;<br>
+   &quot;ret&quot;<br>
+   [(set_attr &quot;length&quot; &quot;1&quot;)<br>
+@@ -13826,8 +13831,8 @@<br>
+ ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET<br>
+ ;; instruction Athlon and K8 have.<br>
+<br>
+-(define_insn &quot;return_internal_long&quot;<br>
+-  [(return)<br>
++(define_insn &quot;&lt;return_str&gt;return_internal_long&quot;<br>
++  [(returns)<br>
+    (unspec [(const_int 0)] UNSPEC_REP)]<br>
+   &quot;reload_completed&quot;<br>
+   &quot;rep\;ret&quot;<br>
+@@ -13837,8 +13842,8 @@<br>
+    (set_attr &quot;prefix_rep&quot; &quot;1&quot;)<br>
+    (set_attr &quot;modrm&quot; &quot;0&quot;)])<br>
+<br>
+-(define_insn &quot;return_pop_internal&quot;<br>
+-  [(return)<br>
++(define_insn &quot;&lt;return_str&gt;return_pop_internal&quot;<br>
++  [(returns)<br>
+    (use (match_operand:SI 0 &quot;const_int_operand&quot; &quot;&quot;))]<br>
+   &quot;reload_completed&quot;<br>
+   &quot;ret\t%0&quot;<br>
+@@ -13847,8 +13852,8 @@<br>
+    (set_attr &quot;length_immediate&quot; &quot;2&quot;)<br>
+    (set_attr &quot;modrm&quot; &quot;0&quot;)])<br>
+<br>
+-(define_insn &quot;return_indirect_internal&quot;<br>
+-  [(return)<br>
++(define_insn &quot;&lt;return_str&gt;return_indirect_internal&quot;<br>
++  [(returns)<br>
+    (use (match_operand:SI 0 &quot;register_operand&quot; &quot;r&quot;))]<br>
+   &quot;reload_completed&quot;<br>
+   &quot;jmp\t%A0&quot;<br>
+Index: gcc-4_5-branch/gcc/config/m68hc11/<a href="http://m68hc11.md" target="_blank">m68hc11.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/m68hc11/<a href="http://m68hc11.md" target="_blank">m68hc11.md</a><br>
++++ gcc-4_5-branch/gcc/config/m68hc11/<a href="http://m68hc11.md" target="_blank">m68hc11.md</a><br>
+@@ -6576,7 +6576,7 @@<br>
+   if (ret_size &amp;&amp; ret_size &lt;= 2)<br>
+     {<br>
+       emit_jump_insn (gen_rtx_PARALLEL (VOIDmode,<br>
+-                    gen_rtvec (2, gen_rtx_RETURN (VOIDmode),<br>
++                    gen_rtvec (2, ret_rtx,<br>
+                                gen_rtx_USE (VOIDmode,<br>
+                                             gen_rtx_REG (HImode, 1)))));<br>
+       DONE;<br>
+@@ -6584,7 +6584,7 @@<br>
+   if (ret_size)<br>
+     {<br>
+       emit_jump_insn (gen_rtx_PARALLEL (VOIDmode,<br>
+-                    gen_rtvec (2, gen_rtx_RETURN (VOIDmode),<br>
++                    gen_rtvec (2, ret_rtx,<br>
+                                gen_rtx_USE (VOIDmode,<br>
+                                             gen_rtx_REG (SImode, 0)))));<br>
+       DONE;<br>
+Index: gcc-4_5-branch/gcc/config/m68k/m68k.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/m68k/m68k.c<br>
++++ gcc-4_5-branch/gcc/config/m68k/m68k.c<br>
+@@ -1366,7 +1366,7 @@ m68k_expand_epilogue (bool sibcall_p)<br>
+                          EH_RETURN_STACKADJ_RTX));<br>
+<br>
+   if (!sibcall_p)<br>
+-    emit_jump_insn (gen_rtx_RETURN (VOIDmode));<br>
++    emit_jump_insn (ret_rtx);<br>
+ }<br>
+<br>
+ /* Return true if X is a valid comparison operator for the dbcc<br>
+Index: gcc-4_5-branch/gcc/config/mips/mips.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/mips/mips.c<br>
++++ gcc-4_5-branch/gcc/config/mips/mips.c<br>
+@@ -10497,7 +10497,8 @@ mips_expand_epilogue (bool sibcall_p)<br>
+           regno = GP_REG_FIRST + 7;<br>
+         else<br>
+           regno = RETURN_ADDR_REGNUM;<br>
+-        emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode, regno)));<br>
++        emit_jump_insn (gen_simple_return_internal (gen_rtx_REG (Pmode,<br>
++                                                                 regno)));<br>
+       }<br>
+     }<br>
+<br>
+Index: gcc-4_5-branch/gcc/config/mips/<a href="http://mips.md" target="_blank">mips.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/mips/<a href="http://mips.md" target="_blank">mips.md</a><br>
++++ gcc-4_5-branch/gcc/config/mips/<a href="http://mips.md" target="_blank">mips.md</a><br>
+@@ -5815,6 +5815,18 @@<br>
+   [(set_attr &quot;type&quot;   &quot;jump&quot;)<br>
+    (set_attr &quot;mode&quot;   &quot;none&quot;)])<br>
+<br>
++(define_expand &quot;simple_return&quot;<br>
++  [(simple_return)]<br>
++  &quot;!mips_can_use_return_insn ()&quot;<br>
++  { mips_expand_before_return (); })<br>
++<br>
++(define_insn &quot;*simple_return&quot;<br>
++  [(simple_return)]<br>
++  &quot;!mips_can_use_return_insn ()&quot;<br>
++  &quot;%*j\t$31%/&quot;<br>
++  [(set_attr &quot;type&quot;   &quot;jump&quot;)<br>
++   (set_attr &quot;mode&quot;   &quot;none&quot;)])<br>
++<br>
+ ;; Normal return.<br>
+<br>
+ (define_insn &quot;return_internal&quot;<br>
+@@ -5825,6 +5837,14 @@<br>
+   [(set_attr &quot;type&quot;   &quot;jump&quot;)<br>
+    (set_attr &quot;mode&quot;   &quot;none&quot;)])<br>
+<br>
++(define_insn &quot;simple_return_internal&quot;<br>
++  [(simple_return)<br>
++   (use (match_operand 0 &quot;pmode_register_operand&quot; &quot;&quot;))]<br>
++  &quot;&quot;<br>
++  &quot;%*j\t%0%/&quot;<br>
++  [(set_attr &quot;type&quot;   &quot;jump&quot;)<br>
++   (set_attr &quot;mode&quot;   &quot;none&quot;)])<br>
++<br>
+ ;; Exception return.<br>
+ (define_insn &quot;mips_eret&quot;<br>
+   [(return)<br>
+Index: gcc-4_5-branch/gcc/config/picochip/picochip.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/picochip/picochip.c<br>
++++ gcc-4_5-branch/gcc/config/picochip/picochip.c<br>
+@@ -1996,7 +1996,7 @@ picochip_expand_epilogue (int is_sibling<br>
+     rtvec p;<br>
+     p = rtvec_alloc (2);<br>
+<br>
+-    RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);<br>
++    RTVEC_ELT (p, 0) = ret_rtx;<br>
+     RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,<br>
+                                   gen_rtx_REG (Pmode, LINK_REGNUM));<br>
+     emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));<br>
+Index: gcc-4_5-branch/gcc/config/rs6000/rs6000.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/rs6000/rs6000.c<br>
++++ gcc-4_5-branch/gcc/config/rs6000/rs6000.c<br>
+@@ -18563,7 +18563,7 @@ rs6000_make_savres_rtx (rs6000_stack_t *<br>
+   p = rtvec_alloc ((lr ? 4 : 3) + n_regs);<br>
+<br>
+   if (!savep &amp;&amp; lr)<br>
+-    RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);<br>
++    RTVEC_ELT (p, offset++) = ret_rtx;<br>
+<br>
+   RTVEC_ELT (p, offset++)<br>
+     = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));<br>
+@@ -19638,7 +19638,7 @@ rs6000_emit_epilogue (int sibcall)<br>
+       alloc_rname = ggc_strdup (rname);<br>
+<br>
+       j = 0;<br>
+-      RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);<br>
++      RTVEC_ELT (p, j++) = ret_rtx;<br>
+       RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,<br>
+                                       gen_rtx_REG (Pmode,<br>
+                                                    LR_REGNO));<br>
+@@ -20254,7 +20254,7 @@ rs6000_emit_epilogue (int sibcall)<br>
+       else<br>
+       p = rtvec_alloc (2);<br>
+<br>
+-      RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);<br>
++      RTVEC_ELT (p, 0) = ret_rtx;<br>
+       RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)<br>
+                         ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))<br>
+                         : gen_rtx_CLOBBER (VOIDmode,<br>
+@@ -20695,7 +20695,7 @@ rs6000_output_mi_thunk (FILE *file, tree<br>
+                       gen_rtx_USE (VOIDmode,<br>
+                                    gen_rtx_REG (SImode,<br>
+                                                 LR_REGNO)),<br>
+-                      gen_rtx_RETURN (VOIDmode))));<br>
++                      ret_rtx)));<br>
+   SIBLING_CALL_P (insn) = 1;<br>
+   emit_barrier ();<br>
+<br>
+Index: gcc-4_5-branch/gcc/config/rx/rx.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/rx/rx.c<br>
++++ gcc-4_5-branch/gcc/config/rx/rx.c<br>
+@@ -1562,7 +1562,7 @@ gen_rx_rtsd_vector (unsigned int adjust,<br>
+                               : plus_constant (stack_pointer_rtx,<br>
+                                                i * UNITS_PER_WORD)));<br>
+<br>
+-  XVECEXP (vector, 0, count - 1) = gen_rtx_RETURN (VOIDmode);<br>
++  XVECEXP (vector, 0, count - 1) = ret_rtx;<br>
+<br>
+   return vector;<br>
+ }<br>
+Index: gcc-4_5-branch/gcc/config/s390/s390.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/s390/s390.c<br>
++++ gcc-4_5-branch/gcc/config/s390/s390.c<br>
+@@ -8170,7 +8170,7 @@ s390_emit_epilogue (bool sibcall)<br>
+<br>
+       p = rtvec_alloc (2);<br>
+<br>
+-      RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);<br>
++      RTVEC_ELT (p, 0) = ret_rtx;<br>
+       RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);<br>
+       emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));<br>
+     }<br>
+Index: gcc-4_5-branch/gcc/config/sh/sh.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/sh/sh.c<br>
++++ gcc-4_5-branch/gcc/config/sh/sh.c<br>
+@@ -5252,7 +5252,8 @@ barrier_align (rtx barrier_or_label)<br>
+       }<br>
+       if (prev<br>
+         &amp;&amp; JUMP_P (prev)<br>
+-        &amp;&amp; JUMP_LABEL (prev))<br>
++        &amp;&amp; JUMP_LABEL (prev)<br>
++        &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (prev)))<br>
+       {<br>
+         rtx x;<br>
+         if (jump_to_next<br>
+@@ -5951,7 +5952,7 @@ split_branches (rtx first)<br>
+                       JUMP_LABEL (insn) = far_label;<br>
+                       LABEL_NUSES (far_label)++;<br>
+                     }<br>
+-                  redirect_jump (insn, NULL_RTX, 1);<br>
++                  redirect_jump (insn, ret_rtx, 1);<br>
+                   far_label = 0;<br>
+                 }<br>
+             }<br>
+Index: gcc-4_5-branch/gcc/config/v850/v850.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/v850/v850.c<br>
++++ gcc-4_5-branch/gcc/config/v850/v850.c<br>
+@@ -1832,7 +1832,7 @@ expand_epilogue (void)<br>
+       {<br>
+         restore_all = gen_rtx_PARALLEL (VOIDmode,<br>
+                                         rtvec_alloc (num_restore + 2));<br>
+-        XVECEXP (restore_all, 0, 0) = gen_rtx_RETURN (VOIDmode);<br>
++        XVECEXP (restore_all, 0, 0) = ret_rtx;<br>
+         XVECEXP (restore_all, 0, 1)<br>
+           = gen_rtx_SET (VOIDmode, stack_pointer_rtx,<br>
+                           gen_rtx_PLUS (Pmode,<br>
+Index: gcc-4_5-branch/gcc/df-scan.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/df-scan.c<br>
++++ gcc-4_5-branch/gcc/df-scan.c<br>
+@@ -3296,6 +3296,7 @@ df_uses_record (enum df_ref_class cl, st<br>
+       }<br>
+<br>
+     case RETURN:<br>
++    case SIMPLE_RETURN:<br>
+       break;<br>
+<br>
+     case ASM_OPERANDS:<br>
+Index: gcc-4_5-branch/gcc/doc/invoke.texi<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/doc/invoke.texi<br>
++++ gcc-4_5-branch/gcc/doc/invoke.texi<br>
+@@ -5751,6 +5751,7 @@ compilation time.<br>
+ -fipa-pure-const @gol<br>
+ -fipa-reference @gol<br>
+ -fmerge-constants<br>
++-fshrink-wrap @gol<br>
+ -fsplit-wide-types @gol<br>
+ -ftree-builtin-call-dce @gol<br>
+ -ftree-ccp @gol<br>
+@@ -6506,6 +6507,12 @@ This option has no effect until one of @<br>
+ When pipelining loops during selective scheduling, also pipeline outer loops.<br>
+ This option has no effect until @option{-fsel-sched-pipelining} is turned on.<br>
+<br>
++@item -fshrink-wrap<br>
++@opindex fshrink-wrap<br>
++Emit function prologues only before parts of the function that need it,<br>
++rather than at the top of the function.  This flag is enabled by default at<br>
++@option{-O} and higher.<br>
++<br>
+ @item -fcaller-saves<br>
+ @opindex fcaller-saves<br>
+ Enable values to be allocated in registers that will be clobbered by<br>
+Index: gcc-4_5-branch/gcc/doc/md.texi<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/doc/md.texi<br>
++++ gcc-4_5-branch/gcc/doc/md.texi<br>
+@@ -4801,7 +4801,19 @@ RTL generation phase.  In this case it i<br>
+ multiple instructions are usually needed to return from a function, but<br>
+ some class of functions only requires one instruction to implement a<br>
+ return.  Normally, the applicable functions are those which do not need<br>
+-to save any registers or allocate stack space.<br>
++to save any registers or allocate stack space, although some targets<br>
++have instructions that can perform both the epilogue and function return<br>
++in one instruction.<br>
++<br>
++@cindex @code{simple_return} instruction pattern<br>
++@item @samp{simple_return}<br>
++Subroutine return instruction.  This instruction pattern name should be<br>
++defined only if a single instruction can do all the work of returning<br>
++from a function on a path where no epilogue is required.  This pattern<br>
++is very similar to the @code{return} instruction pattern, but it is emitted<br>
++only by the shrink-wrapping optimization on paths where the function<br>
++prologue has not been executed, and a function return should occur without<br>
++any of the effects of the epilogue.<br>
+<br>
+ @findex reload_completed<br>
+ @findex leaf_function_p<br>
+Index: gcc-4_5-branch/gcc/doc/rtl.texi<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/doc/rtl.texi<br>
++++ gcc-4_5-branch/gcc/doc/rtl.texi<br>
+@@ -2888,6 +2888,13 @@ placed in @code{pc} to return to the cal<br>
+ Note that an insn pattern of @code{(return)} is logically equivalent to<br>
+ @code{(set (pc) (return))}, but the latter form is never used.<br>
+<br>
++@findex simple_return<br>
++@item (simple_return)<br>
++Like @code{(return)}, but truly represents only a function return, while<br>
++@code{(return)} may represent an insn that also performs other functions<br>
++of the function epilogue.  Like @code{(return)}, this may also occur in<br>
++conditional jumps.<br>
++<br>
+ @findex call<br>
+ @item (call @var{function} @var{nargs})<br>
+ Represents a function call.  @var{function} is a @code{mem} expression<br>
+@@ -3017,7 +3024,7 @@ Represents several side effects performe<br>
+ brackets stand for a vector; the operand of @code{parallel} is a<br>
+ vector of expressions.  @var{x0}, @var{x1} and so on are individual<br>
+ side effect expressions---expressions of code @code{set}, @code{call},<br>
+-@code{return}, @code{clobber} or @code{use}.<br>
++@code{return}, @code{simple_return}, @code{clobber} or @code{use}.<br>
+<br>
+ ``In parallel&#39;&#39; means that first all the values used in the individual<br>
+ side-effects are computed, and second all the actual side-effects are<br>
+@@ -3656,14 +3663,16 @@ and @code{call_insn} insns:<br>
+ @table @code<br>
+ @findex PATTERN<br>
+ @item PATTERN (@var{i})<br>
+-An expression for the side effect performed by this insn.  This must be<br>
+-one of the following codes: @code{set}, @code{call}, @code{use},<br>
+-@code{clobber}, @code{return}, @code{asm_input}, @code{asm_output},<br>
+-@code{addr_vec}, @code{addr_diff_vec}, @code{trap_if}, @code{unspec},<br>
+-@code{unspec_volatile}, @code{parallel}, @code{cond_exec}, or @code{sequence}.  If it is a @code{parallel},<br>
+-each element of the @code{parallel} must be one these codes, except that<br>
+-@code{parallel} expressions cannot be nested and @code{addr_vec} and<br>
+-@code{addr_diff_vec} are not permitted inside a @code{parallel} expression.<br>
++An expression for the side effect performed by this insn.  This must<br>
++be one of the following codes: @code{set}, @code{call}, @code{use},<br>
++@code{clobber}, @code{return}, @code{simple_return}, @code{asm_input},<br>
++@code{asm_output}, @code{addr_vec}, @code{addr_diff_vec},<br>
++@code{trap_if}, @code{unspec}, @code{unspec_volatile},<br>
++@code{parallel}, @code{cond_exec}, or @code{sequence}.  If it is a<br>
++@code{parallel}, each element of the @code{parallel} must be one these<br>
++codes, except that @code{parallel} expressions cannot be nested and<br>
++@code{addr_vec} and @code{addr_diff_vec} are not permitted inside a<br>
++@code{parallel} expression.<br>
+<br>
+ @findex INSN_CODE<br>
+ @item INSN_CODE (@var{i})<br>
+Index: gcc-4_5-branch/gcc/doc/tm.texi<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/doc/tm.texi<br>
++++ gcc-4_5-branch/gcc/doc/tm.texi<br>
+@@ -3287,6 +3287,12 @@ Define this if the return address of a p<br>
+ from the frame pointer of the previous stack frame.<br>
+ @end defmac<br>
+<br>
++@defmac RETURN_ADDR_REGNUM<br>
++If defined, a C expression whose value is the register number of the return<br>
++address for the current function.  Targets that pass the return address on<br>
++the stack should not define this macro.<br>
++@end defmac<br>
++<br>
+ @defmac INCOMING_RETURN_ADDR_RTX<br>
+ A C expression whose value is RTL representing the location of the<br>
+ incoming return address at the beginning of any function, before the<br>
+Index: gcc-4_5-branch/gcc/dwarf2out.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/dwarf2out.c<br>
++++ gcc-4_5-branch/gcc/dwarf2out.c<br>
+@@ -1396,7 +1396,7 @@ compute_barrier_args_size_1 (rtx insn, H<br>
+     {<br>
+       rtx dest = JUMP_LABEL (insn);<br>
+<br>
+-      if (dest)<br>
++      if (dest &amp;&amp; !ANY_RETURN_P (dest))<br>
+       {<br>
+         if (barrier_args_size [INSN_UID (dest)] &lt; 0)<br>
+           {<br>
+Index: gcc-4_5-branch/gcc/emit-rtl.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/emit-rtl.c<br>
++++ gcc-4_5-branch/gcc/emit-rtl.c<br>
+@@ -2432,6 +2432,8 @@ verify_rtx_sharing (rtx orig, rtx insn)<br>
+     case CODE_LABEL:<br>
+     case PC:<br>
+     case CC0:<br>
++    case RETURN:<br>
++    case SIMPLE_RETURN:<br>
+     case SCRATCH:<br>
+       return;<br>
+       /* SCRATCH must be shared because they represent distinct values.  */<br>
+@@ -3323,14 +3325,17 @@ prev_label (rtx insn)<br>
+   return insn;<br>
+ }<br>
+<br>
+-/* Return the last label to mark the same position as LABEL.  Return null<br>
+-   if LABEL itself is null.  */<br>
++/* Return the last label to mark the same position as LABEL.  Return LABEL<br>
++   itself if it is null or any return rtx.  */<br>
+<br>
+ rtx<br>
+ skip_consecutive_labels (rtx label)<br>
+ {<br>
+   rtx insn;<br>
+<br>
++  if (label &amp;&amp; ANY_RETURN_P (label))<br>
++    return label;<br>
++<br>
+   for (insn = label; insn != 0 &amp;&amp; !INSN_P (insn); insn = NEXT_INSN (insn))<br>
+     if (LABEL_P (insn))<br>
+       label = insn;<br>
+@@ -5209,7 +5214,7 @@ classify_insn (rtx x)<br>
+     return CODE_LABEL;<br>
+   if (GET_CODE (x) == CALL)<br>
+     return CALL_INSN;<br>
+-  if (GET_CODE (x) == RETURN)<br>
++  if (GET_CODE (x) == RETURN || GET_CODE (x) == SIMPLE_RETURN)<br>
+     return JUMP_INSN;<br>
+   if (GET_CODE (x) == SET)<br>
+     {<br>
+@@ -5715,8 +5720,10 @@ init_emit_regs (void)<br>
+   init_reg_modes_target ();<br>
+<br>
+   /* Assign register numbers to the globally defined register rtx.  */<br>
+-  pc_rtx = gen_rtx_PC (VOIDmode);<br>
+-  cc0_rtx = gen_rtx_CC0 (VOIDmode);<br>
++  pc_rtx = gen_rtx_fmt_ (PC, VOIDmode);<br>
++  ret_rtx = gen_rtx_fmt_ (RETURN, VOIDmode);<br>
++  simple_return_rtx = gen_rtx_fmt_ (SIMPLE_RETURN, VOIDmode);<br>
++  cc0_rtx = gen_rtx_fmt_ (CC0, VOIDmode);<br>
+   stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);<br>
+   frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);<br>
+   hard_frame_pointer_rtx = gen_raw_REG (Pmode, HARD_FRAME_POINTER_REGNUM);<br>
+Index: gcc-4_5-branch/gcc/final.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/final.c<br>
++++ gcc-4_5-branch/gcc/final.c<br>
+@@ -2428,7 +2428,7 @@ final_scan_insn (rtx insn, FILE *file, i<br>
+               delete_insn (insn);<br>
+               break;<br>
+             }<br>
+-          else if (GET_CODE (SET_SRC (body)) == RETURN)<br>
++          else if (ANY_RETURN_P (SET_SRC (body)))<br>
+             /* Replace (set (pc) (return)) with (return).  */<br>
+             PATTERN (insn) = body = SET_SRC (body);<br>
+<br>
+Index: gcc-4_5-branch/gcc/function.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/function.c<br>
++++ gcc-4_5-branch/gcc/function.c<br>
+@@ -147,9 +147,6 @@ extern tree debug_find_var_in_block_tree<br>
+    can always export `prologue_epilogue_contains&#39;.  */<br>
+ static void record_insns (rtx, rtx, htab_t *) ATTRIBUTE_UNUSED;<br>
+ static bool contains (const_rtx, htab_t);<br>
+-#ifdef HAVE_return<br>
+-static void emit_return_into_block (basic_block);<br>
+-#endif<br>
+ static void prepare_function_start (void);<br>
+ static void do_clobber_return_reg (rtx, void *);<br>
+ static void do_use_return_reg (rtx, void *);<br>
+@@ -4987,35 +4984,190 @@ prologue_epilogue_contains (const_rtx in<br>
+   return 0;<br>
+ }<br>
+<br>
++#ifdef HAVE_simple_return<br>
++/* This collects sets and clobbers of hard registers in a HARD_REG_SET,<br>
++   which is pointed to by DATA.  */<br>
++static void<br>
++record_hard_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)<br>
++{<br>
++  HARD_REG_SET *pset = (HARD_REG_SET *)data;<br>
++  if (REG_P (x) &amp;&amp; REGNO (x) &lt; FIRST_PSEUDO_REGISTER)<br>
++    {<br>
++      int nregs = hard_regno_nregs[REGNO (x)][GET_MODE (x)];<br>
++      while (nregs-- &gt; 0)<br>
++      SET_HARD_REG_BIT (*pset, REGNO (x) + nregs);<br>
++    }<br>
++}<br>
++<br>
++/* A subroutine of requires_stack_frame_p, called via for_each_rtx.<br>
++   If any change is made, set CHANGED<br>
++   to true.  */<br>
++<br>
++static int<br>
++frame_required_for_rtx (rtx *loc, void *data ATTRIBUTE_UNUSED)<br>
++{<br>
++  rtx x = *loc;<br>
++  if (x == stack_pointer_rtx || x == hard_frame_pointer_rtx<br>
++      || x == arg_pointer_rtx || x == pic_offset_table_rtx<br>
++#ifdef RETURN_ADDR_REGNUM<br>
++      || (REG_P (x) &amp;&amp; REGNO (x) == RETURN_ADDR_REGNUM)<br>
++#endif<br>
++      )<br>
++    return 1;<br>
++  return 0;<br>
++}<br>
++<br>
++static bool<br>
++requires_stack_frame_p (rtx insn)<br>
++{<br>
++  HARD_REG_SET hardregs;<br>
++  unsigned regno;<br>
++<br>
++  if (!INSN_P (insn) || DEBUG_INSN_P (insn))<br>
++    return false;<br>
++  if (CALL_P (insn))<br>
++    return !SIBLING_CALL_P (insn);<br>
++  if (for_each_rtx (&amp;PATTERN (insn), frame_required_for_rtx, NULL))<br>
++    return true;<br>
++  CLEAR_HARD_REG_SET (hardregs);<br>
++  note_stores (PATTERN (insn), record_hard_reg_sets, &amp;hardregs);<br>
++  AND_COMPL_HARD_REG_SET (hardregs, call_used_reg_set);<br>
++  for (regno = 0; regno &lt; FIRST_PSEUDO_REGISTER; regno++)<br>
++    if (TEST_HARD_REG_BIT (hardregs, regno)<br>
++      &amp;&amp; df_regs_ever_live_p (regno))<br>
++      return true;<br>
++  return false;<br>
++}<br>
++#endif<br>
++<br>
+ #ifdef HAVE_return<br>
+-/* Insert gen_return at the end of block BB.  This also means updating<br>
+-   block_for_insn appropriately.  */<br>
++<br>
++static rtx<br>
++gen_return_pattern (bool simple_p)<br>
++{<br>
++#ifdef HAVE_simple_return<br>
++  return simple_p ? gen_simple_return () : gen_return ();<br>
++#else<br>
++  gcc_assert (!simple_p);<br>
++  return gen_return ();<br>
++#endif<br>
++}<br>
++<br>
++/* Insert an appropriate return pattern at the end of block BB.  This<br>
++   also means updating block_for_insn appropriately.  */<br>
+<br>
+ static void<br>
+-emit_return_into_block (basic_block bb)<br>
++emit_return_into_block (bool simple_p, basic_block bb)<br>
+ {<br>
+-  emit_jump_insn_after (gen_return (), BB_END (bb));<br>
++  rtx jump;<br>
++  jump = emit_jump_insn_after (gen_return_pattern (simple_p), BB_END (bb));<br>
++  JUMP_LABEL (jump) = simple_p ? simple_return_rtx : ret_rtx;<br>
+ }<br>
+-#endif /* HAVE_return */<br>
++#endif<br>
+<br>
+ /* Generate the prologue and epilogue RTL if the machine supports it.  Thread<br>
+    this into place with notes indicating where the prologue ends and where<br>
+-   the epilogue begins.  Update the basic block information when possible.  */<br>
++   the epilogue begins.  Update the basic block information when possible.<br>
++<br>
++   Notes on epilogue placement:<br>
++   There are several kinds of edges to the exit block:<br>
++   * a single fallthru edge from LAST_BB<br>
++   * possibly, edges from blocks containing sibcalls<br>
++   * possibly, fake edges from infinite loops<br>
++<br>
++   The epilogue is always emitted on the fallthru edge from the last basic<br>
++   block in the function, LAST_BB, into the exit block.<br>
++<br>
++   If LAST_BB is empty except for a label, it is the target of every<br>
++   other basic block in the function that ends in a return.  If a<br>
++   target has a return or simple_return pattern (possibly with<br>
++   conditional variants), these basic blocks can be changed so that a<br>
++   return insn is emitted into them, and their target is adjusted to<br>
++   the real exit block.<br>
++<br>
++   Notes on shrink wrapping: We implement a fairly conservative<br>
++   version of shrink-wrapping rather than the textbook one.  We only<br>
++   generate a single prologue and a single epilogue.  This is<br>
++   sufficient to catch a number of interesting cases involving early<br>
++   exits.<br>
++<br>
++   First, we identify the blocks that require the prologue to occur before<br>
++   them.  These are the ones that modify a call-saved register, or reference<br>
++   any of the stack or frame pointer registers.  To simplify things, we then<br>
++   mark everything reachable from these blocks as also requiring a prologue.<br>
++   This takes care of loops automatically, and avoids the need to examine<br>
++   whether MEMs reference the frame, since it is sufficient to check for<br>
++   occurrences of the stack or frame pointer.<br>
++<br>
++   We then compute the set of blocks for which the need for a prologue<br>
++   is anticipatable (borrowing terminology from the shrink-wrapping<br>
++   description in Muchnick&#39;s book).  These are the blocks which either<br>
++   require a prologue themselves, or those that have only successors<br>
++   where the prologue is anticipatable.  The prologue needs to be<br>
++   inserted on all edges from BB1-&gt;BB2 where BB2 is in ANTIC and BB1<br>
++   is not.  For the moment, we ensure that only one such edge exists.<br>
++<br>
++   The epilogue is placed as described above, but we make a<br>
++   distinction between inserting return and simple_return patterns<br>
++   when modifying other blocks that end in a return.  Blocks that end<br>
++   in a sibcall omit the sibcall_epilogue if the block is not in<br>
++   ANTIC.  */<br>
+<br>
+ static void<br>
+ thread_prologue_and_epilogue_insns (void)<br>
+ {<br>
+   int inserted = 0;<br>
++  basic_block last_bb;<br>
++  bool last_bb_active;<br>
++#ifdef HAVE_simple_return<br>
++  bool unconverted_simple_returns = false;<br>
++  basic_block simple_return_block = NULL;<br>
++#endif<br>
++  rtx returnjump ATTRIBUTE_UNUSED;<br>
++  rtx seq ATTRIBUTE_UNUSED, epilogue_end ATTRIBUTE_UNUSED;<br>
++  rtx prologue_seq ATTRIBUTE_UNUSED, split_prologue_seq ATTRIBUTE_UNUSED;<br>
++  edge entry_edge, orig_entry_edge, exit_fallthru_edge;<br>
+   edge e;<br>
+-#if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) || defined (HAVE_return) || defined (HAVE_prologue)<br>
+-  rtx seq;<br>
+-#endif<br>
+-#if defined (HAVE_epilogue) || defined(HAVE_return)<br>
+-  rtx epilogue_end = NULL_RTX;<br>
+-#endif<br>
+   edge_iterator ei;<br>
++  bitmap_head bb_flags;<br>
++<br>
++  df_analyze ();<br>
+<br>
+   rtl_profile_for_bb (ENTRY_BLOCK_PTR);<br>
++<br>
++  epilogue_end = NULL_RTX;<br>
++  returnjump = NULL_RTX;<br>
++<br>
++  /* Can&#39;t deal with multiple successors of the entry block at the<br>
++     moment.  Function should always have at least one entry<br>
++     point.  */<br>
++  gcc_assert (single_succ_p (ENTRY_BLOCK_PTR));<br>
++  entry_edge = single_succ_edge (ENTRY_BLOCK_PTR);<br>
++  orig_entry_edge = entry_edge;<br>
++<br>
++  exit_fallthru_edge = find_fallthru_edge (EXIT_BLOCK_PTR-&gt;preds);<br>
++  if (exit_fallthru_edge != NULL)<br>
++    {<br>
++      rtx label;<br>
++<br>
++      last_bb = exit_fallthru_edge-&gt;src;<br>
++      /* Test whether there are active instructions in the last block.  */<br>
++      label = BB_END (last_bb);<br>
++      while (label &amp;&amp; !LABEL_P (label))<br>
++      {<br>
++        if (active_insn_p (label))<br>
++          break;<br>
++        label = PREV_INSN (label);<br>
++      }<br>
++<br>
++      last_bb_active = BB_HEAD (last_bb) != label || !LABEL_P (label);<br>
++    }<br>
++  else<br>
++    {<br>
++      last_bb = NULL;<br>
++      last_bb_active = false;<br>
++    }<br>
++<br>
+ #ifdef HAVE_prologue<br>
+   if (HAVE_prologue)<br>
+     {<br>
+@@ -5040,20 +5192,169 @@ thread_prologue_and_epilogue_insns (void<br>
+         emit_insn (gen_blockage ());<br>
+ #endif<br>
+<br>
+-      seq = get_insns ();<br>
++      prologue_seq = get_insns ();<br>
+       end_sequence ();<br>
+       set_insn_locators (seq, prologue_locator);<br>
++    }<br>
++#endif<br>
+<br>
+-      /* Can&#39;t deal with multiple successors of the entry block<br>
+-         at the moment.  Function should always have at least one<br>
+-         entry point.  */<br>
+-      gcc_assert (single_succ_p (ENTRY_BLOCK_PTR));<br>
++  bitmap_initialize (&amp;bb_flags, &amp;bitmap_default_obstack);<br>
+<br>
+-      insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));<br>
+-      inserted = 1;<br>
++#ifdef HAVE_simple_return<br>
++  /* Try to perform a kind of shrink-wrapping, making sure the<br>
++     prologue/epilogue is emitted only around those parts of the<br>
++     function that require it.  */<br>
++<br>
++  if (flag_shrink_wrap &amp;&amp; HAVE_simple_return &amp;&amp; !flag_non_call_exceptions<br>
++      &amp;&amp; HAVE_prologue &amp;&amp; !crtl-&gt;calls_eh_return)<br>
++    {<br>
++      HARD_REG_SET prologue_clobbered, live_on_edge;<br>
++      rtx p_insn;<br>
++      VEC(basic_block, heap) *vec;<br>
++      basic_block bb;<br>
++      bitmap_head bb_antic_flags;<br>
++      bitmap_head bb_on_list;<br>
++<br>
++      bitmap_initialize (&amp;bb_antic_flags, &amp;bitmap_default_obstack);<br>
++      bitmap_initialize (&amp;bb_on_list, &amp;bitmap_default_obstack);<br>
++<br>
++      vec = VEC_alloc (basic_block, heap, n_basic_blocks);<br>
++<br>
++      FOR_EACH_BB (bb)<br>
++      {<br>
++        rtx insn;<br>
++        FOR_BB_INSNS (bb, insn)<br>
++          {<br>
++            if (requires_stack_frame_p (insn))<br>
++              {<br>
++                bitmap_set_bit (&amp;bb_flags, bb-&gt;index);<br>
++                VEC_quick_push (basic_block, vec, bb);<br>
++                break;<br>
++              }<br>
++          }<br>
++      }<br>
++<br>
++      /* For every basic block that needs a prologue, mark all blocks<br>
++       reachable from it, so as to ensure they are also seen as<br>
++       requiring a prologue.  */<br>
++      while (!VEC_empty (basic_block, vec))<br>
++      {<br>
++        basic_block tmp_bb = VEC_pop (basic_block, vec);<br>
++        edge e;<br>
++        edge_iterator ei;<br>
++        FOR_EACH_EDGE (e, ei, tmp_bb-&gt;succs)<br>
++          {<br>
++            if (e-&gt;dest == EXIT_BLOCK_PTR<br>
++                || bitmap_bit_p (&amp;bb_flags, e-&gt;dest-&gt;index))<br>
++              continue;<br>
++            bitmap_set_bit (&amp;bb_flags, e-&gt;dest-&gt;index);<br>
++            VEC_quick_push (basic_block, vec, e-&gt;dest);<br>
++          }<br>
++      }<br>
++      /* If the last basic block contains only a label, we&#39;ll be able<br>
++       to convert jumps to it to (potentially conditional) return<br>
++       insns later.  This means we don&#39;t necessarily need a prologue<br>
++       for paths reaching it.  */<br>
++      if (last_bb)<br>
++      {<br>
++        if (!last_bb_active)<br>
++          bitmap_clear_bit (&amp;bb_flags, last_bb-&gt;index);<br>
++        else if (!bitmap_bit_p (&amp;bb_flags, last_bb-&gt;index))<br>
++          goto fail_shrinkwrap;<br>
++      }<br>
++<br>
++      /* Now walk backwards from every block that is marked as needing<br>
++       a prologue to compute the bb_antic_flags bitmap.  */<br>
++      bitmap_copy (&amp;bb_antic_flags, &amp;bb_flags);<br>
++      FOR_EACH_BB (bb)<br>
++      {<br>
++        edge e;<br>
++        edge_iterator ei;<br>
++        if (!bitmap_bit_p (&amp;bb_flags, bb-&gt;index))<br>
++          continue;<br>
++        FOR_EACH_EDGE (e, ei, bb-&gt;preds)<br>
++          if (!bitmap_bit_p (&amp;bb_antic_flags, e-&gt;src-&gt;index))<br>
++            {<br>
++              VEC_quick_push (basic_block, vec, e-&gt;src);<br>
++              bitmap_set_bit (&amp;bb_on_list, e-&gt;src-&gt;index);<br>
++            }<br>
++      }<br>
++      while (!VEC_empty (basic_block, vec))<br>
++      {<br>
++        basic_block tmp_bb = VEC_pop (basic_block, vec);<br>
++        edge e;<br>
++        edge_iterator ei;<br>
++        bool all_set = true;<br>
++<br>
++        bitmap_clear_bit (&amp;bb_on_list, tmp_bb-&gt;index);<br>
++        FOR_EACH_EDGE (e, ei, tmp_bb-&gt;succs)<br>
++          {<br>
++            if (!bitmap_bit_p (&amp;bb_antic_flags, e-&gt;dest-&gt;index))<br>
++              {<br>
++                all_set = false;<br>
++                break;<br>
++              }<br>
++          }<br>
++        if (all_set)<br>
++          {<br>
++            bitmap_set_bit (&amp;bb_antic_flags, tmp_bb-&gt;index);<br>
++            FOR_EACH_EDGE (e, ei, tmp_bb-&gt;preds)<br>
++              if (!bitmap_bit_p (&amp;bb_antic_flags, e-&gt;src-&gt;index))<br>
++                {<br>
++                  VEC_quick_push (basic_block, vec, e-&gt;src);<br>
++                  bitmap_set_bit (&amp;bb_on_list, e-&gt;src-&gt;index);<br>
++                }<br>
++          }<br>
++      }<br>
++      /* Find exactly one edge that leads to a block in ANTIC from<br>
++       a block that isn&#39;t.  */<br>
++      if (!bitmap_bit_p (&amp;bb_antic_flags, entry_edge-&gt;dest-&gt;index))<br>
++      FOR_EACH_BB (bb)<br>
++        {<br>
++          if (!bitmap_bit_p (&amp;bb_antic_flags, bb-&gt;index))<br>
++            continue;<br>
++          FOR_EACH_EDGE (e, ei, bb-&gt;preds)<br>
++            if (!bitmap_bit_p (&amp;bb_antic_flags, e-&gt;src-&gt;index))<br>
++              {<br>
++                if (entry_edge != orig_entry_edge)<br>
++                  {<br>
++                    entry_edge = orig_entry_edge;<br>
++                    goto fail_shrinkwrap;<br>
++                  }<br>
++                entry_edge = e;<br>
++              }<br>
++        }<br>
++<br>
++      /* Test whether the prologue is known to clobber any register<br>
++       (other than FP or SP) which are live on the edge.  */<br>
++      CLEAR_HARD_REG_SET (prologue_clobbered);<br>
++      for (p_insn = prologue_seq; p_insn; p_insn = NEXT_INSN (p_insn))<br>
++      if (NONDEBUG_INSN_P (p_insn))<br>
++        note_stores (PATTERN (p_insn), record_hard_reg_sets,<br>
++                     &amp;prologue_clobbered);<br>
++      CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM);<br>
++      if (frame_pointer_needed)<br>
++      CLEAR_HARD_REG_BIT (prologue_clobbered, HARD_FRAME_POINTER_REGNUM);<br>
++<br>
++      CLEAR_HARD_REG_SET (live_on_edge);<br>
++      reg_set_to_hard_reg_set (&amp;live_on_edge,<br>
++                             df_get_live_in (entry_edge-&gt;dest));<br>
++      if (hard_reg_set_intersect_p (live_on_edge, prologue_clobbered))<br>
++      entry_edge = orig_entry_edge;<br>
++<br>
++    fail_shrinkwrap:<br>
++      bitmap_clear (&amp;bb_antic_flags);<br>
++      bitmap_clear (&amp;bb_on_list);<br>
++      VEC_free (basic_block, heap, vec);<br>
+     }<br>
+ #endif<br>
+<br>
++  if (prologue_seq != NULL_RTX)<br>
++    {<br>
++      insert_insn_on_edge (prologue_seq, entry_edge);<br>
++      inserted = true;<br>
++    }<br>
++<br>
+   /* If the exit block has no non-fake predecessors, we don&#39;t need<br>
+      an epilogue.  */<br>
+   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR-&gt;preds)<br>
+@@ -5063,100 +5364,130 @@ thread_prologue_and_epilogue_insns (void<br>
+     goto epilogue_done;<br>
+<br>
+   rtl_profile_for_bb (EXIT_BLOCK_PTR);<br>
++<br>
+ #ifdef HAVE_return<br>
+-  if (optimize &amp;&amp; HAVE_return)<br>
++  /* If we&#39;re allowed to generate a simple return instruction, then by<br>
++     definition we don&#39;t need a full epilogue.  If the last basic<br>
++     block before the exit block does not contain active instructions,<br>
++     examine its predecessors and try to emit (conditional) return<br>
++     instructions.  */<br>
++  if (optimize &amp;&amp; !last_bb_active<br>
++      &amp;&amp; (HAVE_return || entry_edge != orig_entry_edge))<br>
+     {<br>
+-      /* If we&#39;re allowed to generate a simple return instruction,<br>
+-       then by definition we don&#39;t need a full epilogue.  Examine<br>
+-       the block that falls through to EXIT.   If it does not<br>
+-       contain any code, examine its predecessors and try to<br>
+-       emit (conditional) return instructions.  */<br>
+-<br>
+-      basic_block last;<br>
++      edge_iterator ei2;<br>
++      int i;<br>
++      basic_block bb;<br>
+       rtx label;<br>
++      VEC(basic_block,heap) *src_bbs;<br>
+<br>
+-      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR-&gt;preds)<br>
+-      if (e-&gt;flags &amp; EDGE_FALLTHRU)<br>
+-        break;<br>
+-      if (e == NULL)<br>
++      if (exit_fallthru_edge == NULL)<br>
+       goto epilogue_done;<br>
+-      last = e-&gt;src;<br>
++      label = BB_HEAD (last_bb);<br>
+<br>
+-      /* Verify that there are no active instructions in the last block.  */<br>
+-      label = BB_END (last);<br>
+-      while (label &amp;&amp; !LABEL_P (label))<br>
+-      {<br>
+-        if (active_insn_p (label))<br>
+-          break;<br>
+-        label = PREV_INSN (label);<br>
+-      }<br>
++      src_bbs = VEC_alloc (basic_block, heap, EDGE_COUNT (last_bb-&gt;preds));<br>
++      FOR_EACH_EDGE (e, ei2, last_bb-&gt;preds)<br>
++      if (e-&gt;src != ENTRY_BLOCK_PTR)<br>
++        VEC_quick_push (basic_block, src_bbs, e-&gt;src);<br>
+<br>
+-      if (BB_HEAD (last) == label &amp;&amp; LABEL_P (label))<br>
++      FOR_EACH_VEC_ELT (basic_block, src_bbs, i, bb)<br>
+       {<br>
+-        edge_iterator ei2;<br>
++        bool simple_p;<br>
++        rtx jump;<br>
++        e = find_edge (bb, last_bb);<br>
+<br>
+-        for (ei2 = ei_start (last-&gt;preds); (e = ei_safe_edge (ei2)); )<br>
+-          {<br>
+-            basic_block bb = e-&gt;src;<br>
+-            rtx jump;<br>
++        jump = BB_END (bb);<br>
+<br>
+-            if (bb == ENTRY_BLOCK_PTR)<br>
+-              {<br>
+-                ei_next (&amp;ei2);<br>
+-                continue;<br>
+-              }<br>
++#ifdef HAVE_simple_return<br>
++        simple_p = (entry_edge != orig_entry_edge<br>
++                    ? !bitmap_bit_p (&amp;bb_flags, bb-&gt;index) : false);<br>
++#else<br>
++        simple_p = false;<br>
++#endif<br>
+<br>
+-            jump = BB_END (bb);<br>
+-            if (!JUMP_P (jump) || JUMP_LABEL (jump) != label)<br>
+-              {<br>
+-                ei_next (&amp;ei2);<br>
+-                continue;<br>
+-              }<br>
++        if (!simple_p<br>
++            &amp;&amp; (!HAVE_return || !JUMP_P (jump)<br>
++                || JUMP_LABEL (jump) != label))<br>
++          continue;<br>
+<br>
+-            /* If we have an unconditional jump, we can replace that<br>
+-               with a simple return instruction.  */<br>
+-            if (simplejump_p (jump))<br>
+-              {<br>
+-                emit_return_into_block (bb);<br>
+-                delete_insn (jump);<br>
+-              }<br>
++        /* If we have an unconditional jump, we can replace that<br>
++           with a simple return instruction.  */<br>
++        if (!JUMP_P (jump))<br>
++          {<br>
++            emit_barrier_after (BB_END (bb));<br>
++            emit_return_into_block (simple_p, bb);<br>
++          }<br>
++        else if (simplejump_p (jump))<br>
++          {<br>
++            emit_return_into_block (simple_p, bb);<br>
++            delete_insn (jump);<br>
++          }<br>
++        else if (condjump_p (jump) &amp;&amp; JUMP_LABEL (jump) != label)<br>
++          {<br>
++            basic_block new_bb;<br>
++            edge new_e;<br>
+<br>
+-            /* If we have a conditional jump, we can try to replace<br>
+-               that with a conditional return instruction.  */<br>
+-            else if (condjump_p (jump))<br>
+-              {<br>
+-                if (! redirect_jump (jump, 0, 0))<br>
+-                  {<br>
+-                    ei_next (&amp;ei2);<br>
+-                    continue;<br>
+-                  }<br>
++            gcc_assert (simple_p);<br>
++            new_bb = split_edge (e);<br>
++            emit_barrier_after (BB_END (new_bb));<br>
++            emit_return_into_block (simple_p, new_bb);<br>
++#ifdef HAVE_simple_return<br>
++            simple_return_block = new_bb;<br>
++#endif<br>
++            new_e = single_succ_edge (new_bb);<br>
++            redirect_edge_succ (new_e, EXIT_BLOCK_PTR);<br>
+<br>
+-                /* If this block has only one successor, it both jumps<br>
+-                   and falls through to the fallthru block, so we can&#39;t<br>
+-                   delete the edge.  */<br>
+-                if (single_succ_p (bb))<br>
+-                  {<br>
+-                    ei_next (&amp;ei2);<br>
+-                    continue;<br>
+-                  }<br>
+-              }<br>
++            continue;<br>
++          }<br>
++        /* If we have a conditional jump branching to the last<br>
++           block, we can try to replace that with a conditional<br>
++           return instruction.  */<br>
++        else if (condjump_p (jump))<br>
++          {<br>
++            rtx dest;<br>
++            if (simple_p)<br>
++              dest = simple_return_rtx;<br>
+             else<br>
++              dest = ret_rtx;<br>
++            if (! redirect_jump (jump, dest, 0))<br>
+               {<br>
+-                ei_next (&amp;ei2);<br>
++#ifdef HAVE_simple_return<br>
++                if (simple_p)<br>
++                  unconverted_simple_returns = true;<br>
++#endif<br>
+                 continue;<br>
+               }<br>
+<br>
+-            /* Fix up the CFG for the successful change we just made.  */<br>
+-            redirect_edge_succ (e, EXIT_BLOCK_PTR);<br>
++            /* If this block has only one successor, it both jumps<br>
++               and falls through to the fallthru block, so we can&#39;t<br>
++               delete the edge.  */<br>
++            if (single_succ_p (bb))<br>
++              continue;<br>
++          }<br>
++        else<br>
++          {<br>
++#ifdef HAVE_simple_return<br>
++            if (simple_p)<br>
++              unconverted_simple_returns = true;<br>
++#endif<br>
++            continue;<br>
+           }<br>
+<br>
++        /* Fix up the CFG for the successful change we just made.  */<br>
++        redirect_edge_succ (e, EXIT_BLOCK_PTR);<br>
++      }<br>
++      VEC_free (basic_block, heap, src_bbs);<br>
++<br>
++      if (HAVE_return)<br>
++      {<br>
+         /* Emit a return insn for the exit fallthru block.  Whether<br>
+            this is still reachable will be determined later.  */<br>
+<br>
+-        emit_barrier_after (BB_END (last));<br>
+-        emit_return_into_block (last);<br>
+-        epilogue_end = BB_END (last);<br>
+-        single_succ_edge (last)-&gt;flags &amp;= ~EDGE_FALLTHRU;<br>
++        emit_barrier_after (BB_END (last_bb));<br>
++        emit_return_into_block (false, last_bb);<br>
++        epilogue_end = BB_END (last_bb);<br>
++        if (JUMP_P (epilogue_end))<br>
++          JUMP_LABEL (epilogue_end) = ret_rtx;<br>
++        single_succ_edge (last_bb)-&gt;flags &amp;= ~EDGE_FALLTHRU;<br>
+         goto epilogue_done;<br>
+       }<br>
+     }<br>
+@@ -5193,15 +5524,10 @@ thread_prologue_and_epilogue_insns (void<br>
+     }<br>
+ #endif<br>
+<br>
+-  /* Find the edge that falls through to EXIT.  Other edges may exist<br>
+-     due to RETURN instructions, but those don&#39;t need epilogues.<br>
+-     There really shouldn&#39;t be a mixture -- either all should have<br>
+-     been converted or none, however...  */<br>
++  /* If nothing falls through into the exit block, we don&#39;t need an<br>
++     epilogue.  */<br>
+<br>
+-  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR-&gt;preds)<br>
+-    if (e-&gt;flags &amp; EDGE_FALLTHRU)<br>
+-      break;<br>
+-  if (e == NULL)<br>
++  if (exit_fallthru_edge == NULL)<br>
+     goto epilogue_done;<br>
+<br>
+ #ifdef HAVE_epilogue<br>
+@@ -5217,25 +5543,36 @@ thread_prologue_and_epilogue_insns (void<br>
+       set_insn_locators (seq, epilogue_locator);<br>
+<br>
+       seq = get_insns ();<br>
++      returnjump = get_last_insn ();<br>
+       end_sequence ();<br>
+<br>
+-      insert_insn_on_edge (seq, e);<br>
++      insert_insn_on_edge (seq, exit_fallthru_edge);<br>
+       inserted = 1;<br>
++      if (JUMP_P (returnjump))<br>
++      {<br>
++        rtx pat = PATTERN (returnjump);<br>
++        if (GET_CODE (pat) == PARALLEL)<br>
++          pat = XVECEXP (pat, 0, 0);<br>
++        if (ANY_RETURN_P (pat))<br>
++          JUMP_LABEL (returnjump) = pat;<br>
++        else<br>
++          JUMP_LABEL (returnjump) = ret_rtx;<br>
++      }<br>
+     }<br>
+   else<br>
+ #endif<br>
+     {<br>
+       basic_block cur_bb;<br>
+<br>
+-      if (! next_active_insn (BB_END (e-&gt;src)))<br>
++      if (! next_active_insn (BB_END (exit_fallthru_edge-&gt;src)))<br>
+       goto epilogue_done;<br>
+       /* We have a fall-through edge to the exit block, the source is not<br>
+-         at the end of the function, and there will be an assembler epilogue<br>
+-         at the end of the function.<br>
+-         We can&#39;t use force_nonfallthru here, because that would try to<br>
+-         use return.  Inserting a jump &#39;by hand&#39; is extremely messy, so<br>
++       at the end of the function, and there will be an assembler epilogue<br>
++       at the end of the function.<br>
++       We can&#39;t use force_nonfallthru here, because that would try to<br>
++       use return.  Inserting a jump &#39;by hand&#39; is extremely messy, so<br>
+        we take advantage of cfg_layout_finalize using<br>
+-      fixup_fallthru_exit_predecessor.  */<br>
++       fixup_fallthru_exit_predecessor.  */<br>
+       cfg_layout_initialize (0);<br>
+       FOR_EACH_BB (cur_bb)<br>
+       if (cur_bb-&gt;index &gt;= NUM_FIXED_BLOCKS<br>
+@@ -5244,6 +5581,7 @@ thread_prologue_and_epilogue_insns (void<br>
+       cfg_layout_finalize ();<br>
+     }<br>
+ epilogue_done:<br>
++<br>
+   default_rtl_profile ();<br>
+<br>
+   if (inserted)<br>
+@@ -5260,33 +5598,93 @@ epilogue_done:<br>
+       }<br>
+     }<br>
+<br>
++#ifdef HAVE_simple_return<br>
++  /* If there were branches to an empty LAST_BB which we tried to<br>
++     convert to conditional simple_returns, but couldn&#39;t for some<br>
++     reason, create a block to hold a simple_return insn and redirect<br>
++     those remaining edges.  */<br>
++  if (unconverted_simple_returns)<br>
++    {<br>
++      edge_iterator ei2;<br>
++      basic_block exit_pred = EXIT_BLOCK_PTR-&gt;prev_bb;<br>
++<br>
++      gcc_assert (entry_edge != orig_entry_edge);<br>
++<br>
++#ifdef HAVE_epilogue<br>
++      if (simple_return_block == NULL &amp;&amp; returnjump != NULL_RTX<br>
++        &amp;&amp; JUMP_LABEL (returnjump) == simple_return_rtx)<br>
++      {<br>
++        edge e = split_block (exit_fallthru_edge-&gt;src,<br>
++                              PREV_INSN (returnjump));<br>
++        simple_return_block = e-&gt;dest;<br>
++      }<br>
++#endif<br>
++      if (simple_return_block == NULL)<br>
++      {<br>
++        basic_block bb;<br>
++        rtx start;<br>
++<br>
++        bb = create_basic_block (NULL, NULL, exit_pred);<br>
++        start = emit_jump_insn_after (gen_simple_return (),<br>
++                                      BB_END (bb));<br>
++        JUMP_LABEL (start) = simple_return_rtx;<br>
++        emit_barrier_after (start);<br>
++<br>
++        simple_return_block = bb;<br>
++        make_edge (bb, EXIT_BLOCK_PTR, 0);<br>
++      }<br>
++<br>
++    restart_scan:<br>
++      for (ei2 = ei_start (last_bb-&gt;preds); (e = ei_safe_edge (ei2)); )<br>
++      {<br>
++        basic_block bb = e-&gt;src;<br>
++<br>
++        if (bb != ENTRY_BLOCK_PTR<br>
++            &amp;&amp; !bitmap_bit_p (&amp;bb_flags, bb-&gt;index))<br>
++          {<br>
++            redirect_edge_and_branch_force (e, simple_return_block);<br>
++            goto restart_scan;<br>
++          }<br>
++        ei_next (&amp;ei2);<br>
++<br>
++      }<br>
++    }<br>
++#endif<br>
++<br>
+ #ifdef HAVE_sibcall_epilogue<br>
+   /* Emit sibling epilogues before any sibling call sites.  */<br>
+   for (ei = ei_start (EXIT_BLOCK_PTR-&gt;preds); (e = ei_safe_edge (ei)); )<br>
+     {<br>
+       basic_block bb = e-&gt;src;<br>
+       rtx insn = BB_END (bb);<br>
++      rtx ep_seq;<br>
+<br>
+       if (!CALL_P (insn)<br>
+-        || ! SIBLING_CALL_P (insn))<br>
++        || ! SIBLING_CALL_P (insn)<br>
++        || (entry_edge != orig_entry_edge<br>
++            &amp;&amp; !bitmap_bit_p (&amp;bb_flags, bb-&gt;index)))<br>
+       {<br>
+         ei_next (&amp;ei);<br>
+         continue;<br>
+       }<br>
+<br>
+-      start_sequence ();<br>
+-      emit_note (NOTE_INSN_EPILOGUE_BEG);<br>
+-      emit_insn (gen_sibcall_epilogue ());<br>
+-      seq = get_insns ();<br>
+-      end_sequence ();<br>
++      ep_seq = gen_sibcall_epilogue ();<br>
++      if (ep_seq)<br>
++      {<br>
++        start_sequence ();<br>
++        emit_note (NOTE_INSN_EPILOGUE_BEG);<br>
++        emit_insn (ep_seq);<br>
++        seq = get_insns ();<br>
++        end_sequence ();<br>
+<br>
+-      /* Retain a map of the epilogue insns.  Used in life analysis to<br>
+-       avoid getting rid of sibcall epilogue insns.  Do this before we<br>
+-       actually emit the sequence.  */<br>
+-      record_insns (seq, NULL, &amp;epilogue_insn_hash);<br>
+-      set_insn_locators (seq, epilogue_locator);<br>
++        /* Retain a map of the epilogue insns.  Used in life analysis to<br>
++           avoid getting rid of sibcall epilogue insns.  Do this before we<br>
++           actually emit the sequence.  */<br>
++        record_insns (seq, NULL, &amp;epilogue_insn_hash);<br>
++        set_insn_locators (seq, epilogue_locator);<br>
+<br>
+-      emit_insn_before (seq, insn);<br>
++        emit_insn_before (seq, insn);<br>
++      }<br>
+       ei_next (&amp;ei);<br>
+     }<br>
+ #endif<br>
+@@ -5311,6 +5709,8 @@ epilogue_done:<br>
+     }<br>
+ #endif<br>
+<br>
++  bitmap_clear (&amp;bb_flags);<br>
++<br>
+   /* Threading the prologue and epilogue changes the artificial refs<br>
+      in the entry and exit blocks.  */<br>
+   epilogue_completed = 1;<br>
+Index: gcc-4_5-branch/gcc/genemit.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/genemit.c<br>
++++ gcc-4_5-branch/gcc/genemit.c<br>
+@@ -222,6 +222,12 @@ gen_exp (rtx x, enum rtx_code subroutine<br>
+     case PC:<br>
+       printf (&quot;pc_rtx&quot;);<br>
+       return;<br>
++    case RETURN:<br>
++      printf (&quot;ret_rtx&quot;);<br>
++      return;<br>
++    case SIMPLE_RETURN:<br>
++      printf (&quot;simple_return_rtx&quot;);<br>
++      return;<br>
+     case CLOBBER:<br>
+       if (REG_P (XEXP (x, 0)))<br>
+       {<br>
+@@ -544,8 +550,8 @@ gen_expand (rtx expand)<br>
+         || (GET_CODE (next) == PARALLEL<br>
+             &amp;&amp; ((GET_CODE (XVECEXP (next, 0, 0)) == SET<br>
+                  &amp;&amp; GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)<br>
+-                || GET_CODE (XVECEXP (next, 0, 0)) == RETURN))<br>
+-        || GET_CODE (next) == RETURN)<br>
++                || ANY_RETURN_P (XVECEXP (next, 0, 0))))<br>
++        || ANY_RETURN_P (next))<br>
+       printf (&quot;  emit_jump_insn (&quot;);<br>
+       else if ((GET_CODE (next) == SET &amp;&amp; GET_CODE (SET_SRC (next)) == CALL)<br>
+              || GET_CODE (next) == CALL<br>
+@@ -660,7 +666,7 @@ gen_split (rtx split)<br>
+         || (GET_CODE (next) == PARALLEL<br>
+             &amp;&amp; GET_CODE (XVECEXP (next, 0, 0)) == SET<br>
+             &amp;&amp; GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)<br>
+-        || GET_CODE (next) == RETURN)<br>
++        || ANY_RETURN_P (next))<br>
+       printf (&quot;  emit_jump_insn (&quot;);<br>
+       else if ((GET_CODE (next) == SET &amp;&amp; GET_CODE (SET_SRC (next)) == CALL)<br>
+              || GET_CODE (next) == CALL<br>
+Index: gcc-4_5-branch/gcc/gengenrtl.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/gengenrtl.c<br>
++++ gcc-4_5-branch/gcc/gengenrtl.c<br>
+@@ -146,6 +146,10 @@ special_rtx (int idx)<br>
+         || strcmp (defs[idx].enumname, &quot;REG&quot;) == 0<br>
+         || strcmp (defs[idx].enumname, &quot;SUBREG&quot;) == 0<br>
+         || strcmp (defs[idx].enumname, &quot;MEM&quot;) == 0<br>
++        || strcmp (defs[idx].enumname, &quot;PC&quot;) == 0<br>
++        || strcmp (defs[idx].enumname, &quot;CC0&quot;) == 0<br>
++        || strcmp (defs[idx].enumname, &quot;RETURN&quot;) == 0<br>
++        || strcmp (defs[idx].enumname, &quot;SIMPLE_RETURN&quot;) == 0<br>
+         || strcmp (defs[idx].enumname, &quot;CONST_VECTOR&quot;) == 0);<br>
+ }<br>
+<br>
+Index: gcc-4_5-branch/gcc/haifa-sched.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/haifa-sched.c<br>
++++ gcc-4_5-branch/gcc/haifa-sched.c<br>
+@@ -4231,7 +4231,7 @@ xrecalloc (void *p, size_t new_nmemb, si<br>
+ /* Helper function.<br>
+    Find fallthru edge from PRED.  */<br>
+ edge<br>
+-find_fallthru_edge (basic_block pred)<br>
++find_fallthru_edge_from (basic_block pred)<br>
+ {<br>
+   edge e;<br>
+   edge_iterator ei;<br>
+@@ -4298,7 +4298,7 @@ init_before_recovery (basic_block *befor<br>
+   edge e;<br>
+<br>
+   last = EXIT_BLOCK_PTR-&gt;prev_bb;<br>
+-  e = find_fallthru_edge (last);<br>
++  e = find_fallthru_edge_from (last);<br>
+<br>
+   if (e)<br>
+     {<br>
+@@ -5234,6 +5234,11 @@ check_cfg (rtx head, rtx tail)<br>
+                   gcc_assert (/* Usual case.  */<br>
+                                 (EDGE_COUNT (bb-&gt;succs) &gt; 1<br>
+                                  &amp;&amp; !BARRIER_P (NEXT_INSN (head)))<br>
++                              /* Special cases, see cfglayout.c:<br>
++                                 fixup_reorder_chain.  */<br>
++                              || (EDGE_COUNT (bb-&gt;succs) == 1<br>
++                                  &amp;&amp; (!onlyjump_p (head)<br>
++                                      || returnjump_p (head)))<br>
+                                 /* Or jump to the next instruction.  */<br>
+                                 || (EDGE_COUNT (bb-&gt;succs) == 1<br>
+                                     &amp;&amp; (BB_HEAD (EDGE_I (bb-&gt;succs, 0)-&gt;dest)<br>
+Index: gcc-4_5-branch/gcc/ifcvt.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/ifcvt.c<br>
++++ gcc-4_5-branch/gcc/ifcvt.c<br>
+@@ -105,7 +105,7 @@ static int find_if_case_1 (basic_block,<br>
+ static int find_if_case_2 (basic_block, edge, edge);<br>
+ static int find_memory (rtx *, void *);<br>
+ static int dead_or_predicable (basic_block, basic_block, basic_block,<br>
+-                             basic_block, int);<br>
++                             edge, int);<br>
+ static void noce_emit_move_insn (rtx, rtx);<br>
+ static rtx block_has_only_trap (basic_block);<br>
+<br>
+@@ -3791,6 +3791,7 @@ find_if_case_1 (basic_block test_bb, edg<br>
+   basic_block then_bb = then_edge-&gt;dest;<br>
+   basic_block else_bb = else_edge-&gt;dest;<br>
+   basic_block new_bb;<br>
++  rtx else_target = NULL_RTX;<br>
+   int then_bb_index;<br>
+<br>
+   /* If we are partitioning hot/cold basic blocks, we don&#39;t want to<br>
+@@ -3840,9 +3841,16 @@ find_if_case_1 (basic_block test_bb, edg<br>
+                                   predictable_edge_p (then_edge)))))<br>
+     return FALSE;<br>
+<br>
++  if (else_bb == EXIT_BLOCK_PTR)<br>
++    {<br>
++      rtx jump = BB_END (else_edge-&gt;src);<br>
++      gcc_assert (JUMP_P (jump));<br>
++      else_target = JUMP_LABEL (jump);<br>
++    }<br>
++<br>
+   /* Registers set are dead, or are predicable.  */<br>
+   if (! dead_or_predicable (test_bb, then_bb, else_bb,<br>
+-                          single_succ (then_bb), 1))<br>
++                          single_succ_edge (then_bb), 1))<br>
+     return FALSE;<br>
+<br>
+   /* Conversion went ok, including moving the insns and fixing up the<br>
+@@ -3859,6 +3867,9 @@ find_if_case_1 (basic_block test_bb, edg<br>
+       redirect_edge_succ (FALLTHRU_EDGE (test_bb), else_bb);<br>
+       new_bb = 0;<br>
+     }<br>
++  else if (else_bb == EXIT_BLOCK_PTR)<br>
++    new_bb = force_nonfallthru_and_redirect (FALLTHRU_EDGE (test_bb),<br>
++                                           else_bb, else_target);<br>
+   else<br>
+     new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb),<br>
+                                            else_bb);<br>
+@@ -3957,7 +3968,7 @@ find_if_case_2 (basic_block test_bb, edg<br>
+     return FALSE;<br>
+<br>
+   /* Registers set are dead, or are predicable.  */<br>
+-  if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ-&gt;dest, 0))<br>
++  if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, 0))<br>
+     return FALSE;<br>
+<br>
+   /* Conversion went ok, including moving the insns and fixing up the<br>
+@@ -3995,12 +4006,34 @@ find_memory (rtx *px, void *data ATTRIBU<br>
+<br>
+ static int<br>
+ dead_or_predicable (basic_block test_bb, basic_block merge_bb,<br>
+-                  basic_block other_bb, basic_block new_dest, int reversep)<br>
++                  basic_block other_bb, edge dest_edge, int reversep)<br>
+ {<br>
+-  rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;<br>
++  basic_block new_dest = dest_edge-&gt;dest;<br>
++  rtx head, end, jump, earliest = NULL_RTX, old_dest;<br>
+   bitmap merge_set = NULL;<br>
+   /* Number of pending changes.  */<br>
+   int n_validated_changes = 0;<br>
++  rtx new_dest_label;<br>
++<br>
++  jump = BB_END (dest_edge-&gt;src);<br>
++  if (JUMP_P (jump))<br>
++    {<br>
++      new_dest_label = JUMP_LABEL (jump);<br>
++      if (new_dest_label == NULL_RTX)<br>
++      {<br>
++        new_dest_label = PATTERN (jump);<br>
++        gcc_assert (ANY_RETURN_P (new_dest_label));<br>
++      }<br>
++    }<br>
++  else if (other_bb != new_dest)<br>
++    {<br>
++      if (new_dest == EXIT_BLOCK_PTR)<br>
++      new_dest_label = ret_rtx;<br>
++      else<br>
++      new_dest_label = block_label (new_dest);<br>
++    }<br>
++  else<br>
++    new_dest_label = NULL_RTX;<br>
+<br>
+   jump = BB_END (test_bb);<br>
+<br>
+@@ -4220,10 +4253,9 @@ dead_or_predicable (basic_block test_bb,<br>
+   old_dest = JUMP_LABEL (jump);<br>
+   if (other_bb != new_dest)<br>
+     {<br>
+-      new_label = block_label (new_dest);<br>
+       if (reversep<br>
+-        ? ! invert_jump_1 (jump, new_label)<br>
+-        : ! redirect_jump_1 (jump, new_label))<br>
++        ? ! invert_jump_1 (jump, new_dest_label)<br>
++        : ! redirect_jump_1 (jump, new_dest_label))<br>
+       goto cancel;<br>
+     }<br>
+<br>
+@@ -4234,7 +4266,7 @@ dead_or_predicable (basic_block test_bb,<br>
+<br>
+   if (other_bb != new_dest)<br>
+     {<br>
+-      redirect_jump_2 (jump, old_dest, new_label, 0, reversep);<br>
++      redirect_jump_2 (jump, old_dest, new_dest_label, 0, reversep);<br>
+<br>
+       redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);<br>
+       if (reversep)<br>
+Index: gcc-4_5-branch/gcc/jump.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/jump.c<br>
++++ gcc-4_5-branch/gcc/jump.c<br>
+@@ -29,7 +29,8 @@ along with GCC; see the file COPYING3.<br>
+    JUMP_LABEL internal field.  With this we can detect labels that<br>
+    become unused because of the deletion of all the jumps that<br>
+    formerly used them.  The JUMP_LABEL info is sometimes looked<br>
+-   at by later passes.<br>
++   at by later passes.  For return insns, it contains either a<br>
++   RETURN or a SIMPLE_RETURN rtx.<br>
+<br>
+    The subroutines redirect_jump and invert_jump are used<br>
+    from other passes as well.  */<br>
+@@ -742,10 +743,10 @@ condjump_p (const_rtx insn)<br>
+     return (GET_CODE (x) == IF_THEN_ELSE<br>
+           &amp;&amp; ((GET_CODE (XEXP (x, 2)) == PC<br>
+                &amp;&amp; (GET_CODE (XEXP (x, 1)) == LABEL_REF<br>
+-                   || GET_CODE (XEXP (x, 1)) == RETURN))<br>
++                   || ANY_RETURN_P (XEXP (x, 1))))<br>
+               || (GET_CODE (XEXP (x, 1)) == PC<br>
+                   &amp;&amp; (GET_CODE (XEXP (x, 2)) == LABEL_REF<br>
+-                      || GET_CODE (XEXP (x, 2)) == RETURN))));<br>
++                      || ANY_RETURN_P (XEXP (x, 2))))));<br>
+ }<br>
+<br>
+ /* Return nonzero if INSN is a (possibly) conditional jump inside a<br>
+@@ -774,11 +775,11 @@ condjump_in_parallel_p (const_rtx insn)<br>
+     return 0;<br>
+   if (XEXP (SET_SRC (x), 2) == pc_rtx<br>
+       &amp;&amp; (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF<br>
+-        || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))<br>
++        || ANY_RETURN_P (XEXP (SET_SRC (x), 1)) == RETURN))<br>
+     return 1;<br>
+   if (XEXP (SET_SRC (x), 1) == pc_rtx<br>
+       &amp;&amp; (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF<br>
+-        || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))<br>
++        || ANY_RETURN_P (XEXP (SET_SRC (x), 2))))<br>
+     return 1;<br>
+   return 0;<br>
+ }<br>
+@@ -840,8 +841,9 @@ any_condjump_p (const_rtx insn)<br>
+   a = GET_CODE (XEXP (SET_SRC (x), 1));<br>
+   b = GET_CODE (XEXP (SET_SRC (x), 2));<br>
+<br>
+-  return ((b == PC &amp;&amp; (a == LABEL_REF || a == RETURN))<br>
+-        || (a == PC &amp;&amp; (b == LABEL_REF || b == RETURN)));<br>
++  return ((b == PC &amp;&amp; (a == LABEL_REF || a == RETURN || a == SIMPLE_RETURN))<br>
++        || (a == PC<br>
++            &amp;&amp; (b == LABEL_REF || b == RETURN || b == SIMPLE_RETURN)));<br>
+ }<br>
+<br>
+ /* Return the label of a conditional jump.  */<br>
+@@ -878,6 +880,7 @@ returnjump_p_1 (rtx *loc, void *data ATT<br>
+   switch (GET_CODE (x))<br>
+     {<br>
+     case RETURN:<br>
++    case SIMPLE_RETURN:<br>
+     case EH_RETURN:<br>
+       return true;<br>
+<br>
+@@ -1200,7 +1203,7 @@ delete_related_insns (rtx insn)<br>
+   /* If deleting a jump, decrement the count of the label,<br>
+      and delete the label if it is now unused.  */<br>
+<br>
+-  if (JUMP_P (insn) &amp;&amp; JUMP_LABEL (insn))<br>
++  if (JUMP_P (insn) &amp;&amp; JUMP_LABEL (insn) &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (insn)))<br>
+     {<br>
+       rtx lab = JUMP_LABEL (insn), lab_next;<br>
+<br>
+@@ -1331,6 +1334,18 @@ delete_for_peephole (rtx from, rtx to)<br>
+      is also an unconditional jump in that case.  */<br>
+ }<br>
+<br>
++/* A helper function for redirect_exp_1; examines its input X and returns<br>
++   either a LABEL_REF around a label, or a RETURN if X was NULL.  */<br>
++static rtx<br>
++redirect_target (rtx x)<br>
++{<br>
++  if (x == NULL_RTX)<br>
++    return ret_rtx;<br>
++  if (!ANY_RETURN_P (x))<br>
++    return gen_rtx_LABEL_REF (Pmode, x);<br>
++  return x;<br>
++}<br>
++<br>
+ /* Throughout LOC, redirect OLABEL to NLABEL.  Treat null OLABEL or<br>
+    NLABEL as a return.  Accrue modifications into the change group.  */<br>
+<br>
+@@ -1342,37 +1357,19 @@ redirect_exp_1 (rtx *loc, rtx olabel, rt<br>
+   int i;<br>
+   const char *fmt;<br>
+<br>
+-  if (code == LABEL_REF)<br>
+-    {<br>
+-      if (XEXP (x, 0) == olabel)<br>
+-      {<br>
+-        rtx n;<br>
+-        if (nlabel)<br>
+-          n = gen_rtx_LABEL_REF (Pmode, nlabel);<br>
+-        else<br>
+-          n = gen_rtx_RETURN (VOIDmode);<br>
+-<br>
+-        validate_change (insn, loc, n, 1);<br>
+-        return;<br>
+-      }<br>
+-    }<br>
+-  else if (code == RETURN &amp;&amp; olabel == 0)<br>
++  if ((code == LABEL_REF &amp;&amp; XEXP (x, 0) == olabel)<br>
++      || x == olabel)<br>
+     {<br>
+-      if (nlabel)<br>
+-      x = gen_rtx_LABEL_REF (Pmode, nlabel);<br>
+-      else<br>
+-      x = gen_rtx_RETURN (VOIDmode);<br>
+-      if (loc == &amp;PATTERN (insn))<br>
+-      x = gen_rtx_SET (VOIDmode, pc_rtx, x);<br>
+-      validate_change (insn, loc, x, 1);<br>
++      validate_change (insn, loc, redirect_target (nlabel), 1);<br>
+       return;<br>
+     }<br>
+<br>
+-  if (code == SET &amp;&amp; nlabel == 0 &amp;&amp; SET_DEST (x) == pc_rtx<br>
++  if (code == SET &amp;&amp; SET_DEST (x) == pc_rtx<br>
++      &amp;&amp; ANY_RETURN_P (nlabel)<br>
+       &amp;&amp; GET_CODE (SET_SRC (x)) == LABEL_REF<br>
+       &amp;&amp; XEXP (SET_SRC (x), 0) == olabel)<br>
+     {<br>
+-      validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);<br>
++      validate_change (insn, loc, nlabel, 1);<br>
+       return;<br>
+     }<br>
+<br>
+@@ -1409,6 +1406,7 @@ redirect_jump_1 (rtx jump, rtx nlabel)<br>
+   int ochanges = num_validated_changes ();<br>
+   rtx *loc, asmop;<br>
+<br>
++  gcc_assert (nlabel);<br>
+   asmop = extract_asm_operands (PATTERN (jump));<br>
+   if (asmop)<br>
+     {<br>
+@@ -1430,17 +1428,20 @@ redirect_jump_1 (rtx jump, rtx nlabel)<br>
+    jump target label is unused as a result, it and the code following<br>
+    it may be deleted.<br>
+<br>
+-   If NLABEL is zero, we are to turn the jump into a (possibly conditional)<br>
+-   RETURN insn.<br>
++   Normally, NLABEL will be a label, but it may also be a RETURN or<br>
++   SIMPLE_RETURN rtx; in that case we are to turn the jump into a<br>
++   (possibly conditional) return insn.<br>
+<br>
+    The return value will be 1 if the change was made, 0 if it wasn&#39;t<br>
+-   (this can only occur for NLABEL == 0).  */<br>
++   (this can only occur when trying to produce return insns).  */<br>
+<br>
+ int<br>
+ redirect_jump (rtx jump, rtx nlabel, int delete_unused)<br>
+ {<br>
+   rtx olabel = JUMP_LABEL (jump);<br>
+<br>
++  gcc_assert (nlabel != NULL_RTX);<br>
++<br>
+   if (nlabel == olabel)<br>
+     return 1;<br>
+<br>
+@@ -1452,7 +1453,7 @@ redirect_jump (rtx jump, rtx nlabel, int<br>
+ }<br>
+<br>
+ /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with<br>
+-   NLABEL in JUMP.<br>
++   NEW_DEST in JUMP.<br>
+    If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref<br>
+    count has dropped to zero.  */<br>
+ void<br>
+@@ -1468,13 +1469,14 @@ redirect_jump_2 (rtx jump, rtx olabel, r<br>
+      about this.  */<br>
+   gcc_assert (delete_unused &gt;= 0);<br>
+   JUMP_LABEL (jump) = nlabel;<br>
+-  if (nlabel)<br>
++  if (nlabel &amp;&amp; !ANY_RETURN_P (nlabel))<br>
+     ++LABEL_NUSES (nlabel);<br>
+<br>
+   /* Update labels in any REG_EQUAL note.  */<br>
+   if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)<br>
+     {<br>
+-      if (!nlabel || (invert &amp;&amp; !invert_exp_1 (XEXP (note, 0), jump)))<br>
++      if (ANY_RETURN_P (nlabel)<br>
++        || (invert &amp;&amp; !invert_exp_1 (XEXP (note, 0), jump)))<br>
+       remove_note (jump, note);<br>
+       else<br>
+       {<br>
+@@ -1483,7 +1485,8 @@ redirect_jump_2 (rtx jump, rtx olabel, r<br>
+       }<br>
+     }<br>
+<br>
+-  if (olabel &amp;&amp; --LABEL_NUSES (olabel) == 0 &amp;&amp; delete_unused &gt; 0<br>
++  if (olabel &amp;&amp; !ANY_RETURN_P (olabel)<br>
++      &amp;&amp; --LABEL_NUSES (olabel) == 0 &amp;&amp; delete_unused &gt; 0<br>
+       /* Undefined labels will remain outside the insn stream.  */<br>
+       &amp;&amp; INSN_UID (olabel))<br>
+     delete_related_insns (olabel);<br>
+Index: gcc-4_5-branch/gcc/opts.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/opts.c<br>
++++ gcc-4_5-branch/gcc/opts.c<br>
+@@ -909,6 +909,7 @@ decode_options (unsigned int argc, const<br>
+   flag_ipa_cp = opt2;<br>
+   flag_ipa_sra = opt2;<br>
+   flag_ee = opt2;<br>
++  flag_shrink_wrap = opt2;<br>
+<br>
+   /* Track fields in field-sensitive alias analysis.  */<br>
+   set_param_value (&quot;max-fields-for-field-sensitive&quot;,<br>
+Index: gcc-4_5-branch/gcc/print-rtl.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/print-rtl.c<br>
++++ gcc-4_5-branch/gcc/print-rtl.c<br>
+@@ -308,9 +308,16 @@ print_rtx (const_rtx in_rtx)<br>
+             }<br>
+         }<br>
+       else if (i == 8 &amp;&amp; JUMP_P (in_rtx) &amp;&amp; JUMP_LABEL (in_rtx) != NULL)<br>
+-        /* Output the JUMP_LABEL reference.  */<br>
+-        fprintf (outfile, &quot;\n%s%*s -&gt; %d&quot;, print_rtx_head, indent * 2, &quot;&quot;,<br>
+-                 INSN_UID (JUMP_LABEL (in_rtx)));<br>
++        {<br>
++          /* Output the JUMP_LABEL reference.  */<br>
++          fprintf (outfile, &quot;\n%s%*s -&gt; &quot;, print_rtx_head, indent * 2, &quot;&quot;);<br>
++          if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)<br>
++            fprintf (outfile, &quot;return&quot;);<br>
++          else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)<br>
++            fprintf (outfile, &quot;simple_return&quot;);<br>
++          else<br>
++            fprintf (outfile, &quot;%d&quot;, INSN_UID (JUMP_LABEL (in_rtx)));<br>
++        }<br>
+       else if (i == 0 &amp;&amp; GET_CODE (in_rtx) == VALUE)<br>
+         {<br>
+ #ifndef GENERATOR_FILE<br>
+Index: gcc-4_5-branch/gcc/reorg.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/reorg.c<br>
++++ gcc-4_5-branch/gcc/reorg.c<br>
+@@ -161,8 +161,11 @@ static rtx *unfilled_firstobj;<br>
+ #define unfilled_slots_next   \<br>
+   ((rtx *) obstack_next_free (&amp;unfilled_slots_obstack))<br>
+<br>
+-/* Points to the label before the end of the function.  */<br>
+-static rtx end_of_function_label;<br>
++/* Points to the label before the end of the function, or before a<br>
++   return insn.  */<br>
++static rtx function_return_label;<br>
++/* Likewise for a simple_return.  */<br>
++static rtx function_simple_return_label;<br>
+<br>
+ /* Mapping between INSN_UID&#39;s and position in the code since INSN_UID&#39;s do<br>
+    not always monotonically increase.  */<br>
+@@ -175,7 +178,7 @@ static int stop_search_p (rtx, int);<br>
+ static int resource_conflicts_p (struct resources *, struct resources *);<br>
+ static int insn_references_resource_p (rtx, struct resources *, bool);<br>
+ static int insn_sets_resource_p (rtx, struct resources *, bool);<br>
+-static rtx find_end_label (void);<br>
++static rtx find_end_label (rtx);<br>
+ static rtx emit_delay_sequence (rtx, rtx, int);<br>
+ static rtx add_to_delay_list (rtx, rtx);<br>
+ static rtx delete_from_delay_slot (rtx);<br>
+@@ -220,6 +223,15 @@ static void relax_delay_slots (rtx);<br>
+ static void make_return_insns (rtx);<br>
+ #endif<br>
+<br>
++/* Return true iff INSN is a simplejump, or any kind of return insn.  */<br>
++<br>
++static bool<br>
++simplejump_or_return_p (rtx insn)<br>
++{<br>
++  return (JUMP_P (insn)<br>
++        &amp;&amp; (simplejump_p (insn) || ANY_RETURN_P (PATTERN (insn))));<br>
++}<br>
++ <br>
+ /* Return TRUE if this insn should stop the search for insn to fill delay<br>
+    slots.  LABELS_P indicates that labels should terminate the search.<br>
+    In all cases, jumps terminate the search.  */<br>
+@@ -335,23 +347,29 @@ insn_sets_resource_p (rtx insn, struct r<br>
+<br>
+    ??? There may be a problem with the current implementation.  Suppose<br>
+    we start with a bare RETURN insn and call find_end_label.  It may set<br>
+-   end_of_function_label just before the RETURN.  Suppose the machinery<br>
++   function_return_label just before the RETURN.  Suppose the machinery<br>
+    is able to fill the delay slot of the RETURN insn afterwards.  Then<br>
+-   end_of_function_label is no longer valid according to the property<br>
++   function_return_label is no longer valid according to the property<br>
+    described above and find_end_label will still return it unmodified.<br>
+    Note that this is probably mitigated by the following observation:<br>
+-   once end_of_function_label is made, it is very likely the target of<br>
++   once function_return_label is made, it is very likely the target of<br>
+    a jump, so filling the delay slot of the RETURN will be much more<br>
+    difficult.  */<br>
+<br>
+ static rtx<br>
+-find_end_label (void)<br>
++find_end_label (rtx kind)<br>
+ {<br>
+   rtx insn;<br>
++  rtx *plabel;<br>
++<br>
++  if (kind == ret_rtx)<br>
++    plabel = &amp;function_return_label;<br>
++  else<br>
++    plabel = &amp;function_simple_return_label;<br>
+<br>
+   /* If we found one previously, return it.  */<br>
+-  if (end_of_function_label)<br>
+-    return end_of_function_label;<br>
++  if (*plabel)<br>
++    return *plabel;<br>
+<br>
+   /* Otherwise, see if there is a label at the end of the function.  If there<br>
+      is, it must be that RETURN insns aren&#39;t needed, so that is our return<br>
+@@ -366,44 +384,44 @@ find_end_label (void)<br>
+<br>
+   /* When a target threads its epilogue we might already have a<br>
+      suitable return insn.  If so put a label before it for the<br>
+-     end_of_function_label.  */<br>
++     function_return_label.  */<br>
+   if (BARRIER_P (insn)<br>
+       &amp;&amp; JUMP_P (PREV_INSN (insn))<br>
+-      &amp;&amp; GET_CODE (PATTERN (PREV_INSN (insn))) == RETURN)<br>
++      &amp;&amp; PATTERN (PREV_INSN (insn)) == kind)<br>
+     {<br>
+       rtx temp = PREV_INSN (PREV_INSN (insn));<br>
+-      end_of_function_label = gen_label_rtx ();<br>
+-      LABEL_NUSES (end_of_function_label) = 0;<br>
++      rtx label = gen_label_rtx ();<br>
++      LABEL_NUSES (label) = 0;<br>
+<br>
+       /* Put the label before an USE insns that may precede the RETURN insn.  */<br>
+       while (GET_CODE (temp) == USE)<br>
+       temp = PREV_INSN (temp);<br>
+<br>
+-      emit_label_after (end_of_function_label, temp);<br>
++      emit_label_after (label, temp);<br>
++      *plabel = label;<br>
+     }<br>
+<br>
+   else if (LABEL_P (insn))<br>
+-    end_of_function_label = insn;<br>
++    *plabel = insn;<br>
+   else<br>
+     {<br>
+-      end_of_function_label = gen_label_rtx ();<br>
+-      LABEL_NUSES (end_of_function_label) = 0;<br>
++      rtx label = gen_label_rtx ();<br>
++      LABEL_NUSES (label) = 0;<br>
+       /* If the basic block reorder pass moves the return insn to<br>
+        some other place try to locate it again and put our<br>
+-       end_of_function_label there.  */<br>
+-      while (insn &amp;&amp; ! (JUMP_P (insn)<br>
+-                      &amp;&amp; (GET_CODE (PATTERN (insn)) == RETURN)))<br>
++       function_return_label there.  */<br>
++      while (insn &amp;&amp; ! (JUMP_P (insn) &amp;&amp; (PATTERN (insn) == kind)))<br>
+       insn = PREV_INSN (insn);<br>
+       if (insn)<br>
+       {<br>
+         insn = PREV_INSN (insn);<br>
+<br>
+-        /* Put the label before an USE insns that may proceed the<br>
++        /* Put the label before an USE insns that may precede the<br>
+            RETURN insn.  */<br>
+         while (GET_CODE (insn) == USE)<br>
+           insn = PREV_INSN (insn);<br>
+<br>
+-        emit_label_after (end_of_function_label, insn);<br>
++        emit_label_after (label, insn);<br>
+       }<br>
+       else<br>
+       {<br>
+@@ -413,19 +431,16 @@ find_end_label (void)<br>
+             &amp;&amp; ! HAVE_return<br>
+ #endif<br>
+             )<br>
+-          {<br>
+-            /* The RETURN insn has its delay slot filled so we cannot<br>
+-               emit the label just before it.  Since we already have<br>
+-               an epilogue and cannot emit a new RETURN, we cannot<br>
+-               emit the label at all.  */<br>
+-            end_of_function_label = NULL_RTX;<br>
+-            return end_of_function_label;<br>
+-          }<br>
++          /* The RETURN insn has its delay slot filled so we cannot<br>
++             emit the label just before it.  Since we already have<br>
++             an epilogue and cannot emit a new RETURN, we cannot<br>
++             emit the label at all.  */<br>
++          return NULL_RTX;<br>
+ #endif /* HAVE_epilogue */<br>
+<br>
+         /* Otherwise, make a new label and emit a RETURN and BARRIER,<br>
+            if needed.  */<br>
+-        emit_label (end_of_function_label);<br>
++        emit_label (label);<br>
+ #ifdef HAVE_return<br>
+         /* We don&#39;t bother trying to create a return insn if the<br>
+            epilogue has filled delay-slots; we would have to try and<br>
+@@ -437,19 +452,21 @@ find_end_label (void)<br>
+             /* The return we make may have delay slots too.  */<br>
+             rtx insn = gen_return ();<br>
+             insn = emit_jump_insn (insn);<br>
++            JUMP_LABEL (insn) = ret_rtx;<br>
+             emit_barrier ();<br>
+             if (num_delay_slots (insn) &gt; 0)<br>
+               obstack_ptr_grow (&amp;unfilled_slots_obstack, insn);<br>
+           }<br>
+ #endif<br>
+       }<br>
++      *plabel = label;<br>
+     }<br>
+<br>
+   /* Show one additional use for this label so it won&#39;t go away until<br>
+      we are done.  */<br>
+-  ++LABEL_NUSES (end_of_function_label);<br>
++  ++LABEL_NUSES (*plabel);<br>
+<br>
+-  return end_of_function_label;<br>
++  return *plabel;<br>
+ }<br>
+<br>
+ /* Put INSN and LIST together in a SEQUENCE rtx of LENGTH, and replace<br>
+@@ -797,10 +814,8 @@ optimize_skip (rtx insn)<br>
+   if ((next_trial == next_active_insn (JUMP_LABEL (insn))<br>
+        &amp;&amp; ! (next_trial == 0 &amp;&amp; crtl-&gt;epilogue_delay_list != 0))<br>
+       || (next_trial != 0<br>
+-        &amp;&amp; JUMP_P (next_trial)<br>
+-        &amp;&amp; JUMP_LABEL (insn) == JUMP_LABEL (next_trial)<br>
+-        &amp;&amp; (simplejump_p (next_trial)<br>
+-            || GET_CODE (PATTERN (next_trial)) == RETURN)))<br>
++        &amp;&amp; simplejump_or_return_p (next_trial)<br>
++        &amp;&amp; JUMP_LABEL (insn) == JUMP_LABEL (next_trial)))<br>
+     {<br>
+       if (eligible_for_annul_false (insn, 0, trial, flags))<br>
+       {<br>
+@@ -819,13 +834,11 @@ optimize_skip (rtx insn)<br>
+        branch, thread our jump to the target of that branch.  Don&#39;t<br>
+        change this into a RETURN here, because it may not accept what<br>
+        we have in the delay slot.  We&#39;ll fix this up later.  */<br>
+-      if (next_trial &amp;&amp; JUMP_P (next_trial)<br>
+-        &amp;&amp; (simplejump_p (next_trial)<br>
+-            || GET_CODE (PATTERN (next_trial)) == RETURN))<br>
++      if (next_trial &amp;&amp; simplejump_or_return_p (next_trial))<br>
+       {<br>
+         rtx target_label = JUMP_LABEL (next_trial);<br>
+-        if (target_label == 0)<br>
+-          target_label = find_end_label ();<br>
++        if (ANY_RETURN_P (target_label))<br>
++          target_label = find_end_label (target_label);<br>
+<br>
+         if (target_label)<br>
+           {<br>
+@@ -866,7 +879,7 @@ get_jump_flags (rtx insn, rtx label)<br>
+   if (JUMP_P (insn)<br>
+       &amp;&amp; (condjump_p (insn) || condjump_in_parallel_p (insn))<br>
+       &amp;&amp; INSN_UID (insn) &lt;= max_uid<br>
+-      &amp;&amp; label != 0<br>
++      &amp;&amp; label != 0 &amp;&amp; !ANY_RETURN_P (label)<br>
+       &amp;&amp; INSN_UID (label) &lt;= max_uid)<br>
+     flags<br>
+       = (uid_to_ruid[INSN_UID (label)] &gt; uid_to_ruid[INSN_UID (insn)])<br>
+@@ -1038,7 +1051,7 @@ get_branch_condition (rtx insn, rtx targ<br>
+     pat = XVECEXP (pat, 0, 0);<br>
+<br>
+   if (GET_CODE (pat) == RETURN)<br>
+-    return target == 0 ? const_true_rtx : 0;<br>
++    return ANY_RETURN_P (target) ? const_true_rtx : 0;<br>
+<br>
+   else if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)<br>
+     return 0;<br>
+@@ -1318,7 +1331,11 @@ steal_delay_list_from_target (rtx insn,<br>
+     }<br>
+<br>
+   /* Show the place to which we will be branching.  */<br>
+-  *pnew_thread = next_active_insn (JUMP_LABEL (XVECEXP (seq, 0, 0)));<br>
++  temp = JUMP_LABEL (XVECEXP (seq, 0, 0));<br>
++  if (ANY_RETURN_P (temp))<br>
++    *pnew_thread = temp;<br>
++  else<br>
++    *pnew_thread = next_active_insn (temp);<br>
+<br>
+   /* Add any new insns to the delay list and update the count of the<br>
+      number of slots filled.  */<br>
+@@ -1358,8 +1375,7 @@ steal_delay_list_from_fallthrough (rtx i<br>
+   /* We can&#39;t do anything if SEQ&#39;s delay insn isn&#39;t an<br>
+      unconditional branch.  */<br>
+<br>
+-  if (! simplejump_p (XVECEXP (seq, 0, 0))<br>
+-      &amp;&amp; GET_CODE (PATTERN (XVECEXP (seq, 0, 0))) != RETURN)<br>
++  if (! simplejump_or_return_p (XVECEXP (seq, 0, 0)))<br>
+     return delay_list;<br>
+<br>
+   for (i = 1; i &lt; XVECLEN (seq, 0); i++)<br>
+@@ -1827,7 +1843,7 @@ own_thread_p (rtx thread, rtx label, int<br>
+   rtx insn;<br>
+<br>
+   /* We don&#39;t own the function end.  */<br>
+-  if (thread == 0)<br>
++  if (ANY_RETURN_P (thread))<br>
+     return 0;<br>
+<br>
+   /* Get the first active insn, or THREAD, if it is an active insn.  */<br>
+@@ -2245,7 +2261,8 @@ fill_simple_delay_slots (int non_jumps_p<br>
+         &amp;&amp; (!JUMP_P (insn)<br>
+             || ((condjump_p (insn) || condjump_in_parallel_p (insn))<br>
+                 &amp;&amp; ! simplejump_p (insn)<br>
+-                &amp;&amp; JUMP_LABEL (insn) != 0)))<br>
++                &amp;&amp; JUMP_LABEL (insn) != 0<br>
++                &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (insn)))))<br>
+       {<br>
+         /* Invariant: If insn is a JUMP_INSN, the insn&#39;s jump<br>
+            label.  Otherwise, zero.  */<br>
+@@ -2270,7 +2287,7 @@ fill_simple_delay_slots (int non_jumps_p<br>
+               target = JUMP_LABEL (insn);<br>
+           }<br>
+<br>
+-        if (target == 0)<br>
++        if (target == 0 || ANY_RETURN_P (target))<br>
+           for (trial = next_nonnote_insn (insn); trial; trial = next_trial)<br>
+             {<br>
+               next_trial = next_nonnote_insn (trial);<br>
+@@ -2349,6 +2366,7 @@ fill_simple_delay_slots (int non_jumps_p<br>
+             &amp;&amp; JUMP_P (trial)<br>
+             &amp;&amp; simplejump_p (trial)<br>
+             &amp;&amp; (target == 0 || JUMP_LABEL (trial) == target)<br>
++            &amp;&amp; !ANY_RETURN_P (JUMP_LABEL (trial))<br>
+             &amp;&amp; (next_trial = next_active_insn (JUMP_LABEL (trial))) != 0<br>
+             &amp;&amp; ! (NONJUMP_INSN_P (next_trial)<br>
+                   &amp;&amp; GET_CODE (PATTERN (next_trial)) == SEQUENCE)<br>
+@@ -2371,7 +2389,7 @@ fill_simple_delay_slots (int non_jumps_p<br>
+             if (new_label != 0)<br>
+               new_label = get_label_before (new_label);<br>
+             else<br>
+-              new_label = find_end_label ();<br>
++              new_label = find_end_label (simple_return_rtx);<br>
+<br>
+             if (new_label)<br>
+               {<br>
+@@ -2503,7 +2521,8 @@ fill_simple_delay_slots (int non_jumps_p<br>
+<br>
+ /* Follow any unconditional jump at LABEL;<br>
+    return the ultimate label reached by any such chain of jumps.<br>
+-   Return null if the chain ultimately leads to a return instruction.<br>
++   Return a suitable return rtx if the chain ultimately leads to a<br>
++   return instruction.<br>
+    If LABEL is not followed by a jump, return LABEL.<br>
+    If the chain loops or we can&#39;t find end, return LABEL,<br>
+    since that tells caller to avoid changing the insn.  */<br>
+@@ -2518,6 +2537,7 @@ follow_jumps (rtx label)<br>
+<br>
+   for (depth = 0;<br>
+        (depth &lt; 10<br>
++      &amp;&amp; !ANY_RETURN_P (value)<br>
+       &amp;&amp; (insn = next_active_insn (value)) != 0<br>
+       &amp;&amp; JUMP_P (insn)<br>
+       &amp;&amp; ((JUMP_LABEL (insn) != 0 &amp;&amp; any_uncondjump_p (insn)<br>
+@@ -2527,18 +2547,22 @@ follow_jumps (rtx label)<br>
+       &amp;&amp; BARRIER_P (next));<br>
+        depth++)<br>
+     {<br>
+-      rtx tem;<br>
++      rtx this_label = JUMP_LABEL (insn);<br>
+<br>
+       /* If we have found a cycle, make the insn jump to itself.  */<br>
+-      if (JUMP_LABEL (insn) == label)<br>
++      if (this_label == label)<br>
+       return label;<br>
+<br>
+-      tem = next_active_insn (JUMP_LABEL (insn));<br>
+-      if (tem &amp;&amp; (GET_CODE (PATTERN (tem)) == ADDR_VEC<br>
++      if (!ANY_RETURN_P (this_label))<br>
++      {<br>
++        rtx tem = next_active_insn (this_label);<br>
++        if (tem<br>
++            &amp;&amp; (GET_CODE (PATTERN (tem)) == ADDR_VEC<br>
+                 || GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))<br>
+-      break;<br>
++          break;<br>
++      }<br>
+<br>
+-      value = JUMP_LABEL (insn);<br>
++      value = this_label;<br>
+     }<br>
+   if (depth == 10)<br>
+     return label;<br>
+@@ -2901,6 +2925,7 @@ fill_slots_from_thread (rtx insn, rtx co<br>
+      arithmetic insn after the jump insn and put the arithmetic insn in the<br>
+      delay slot.  If we can&#39;t do this, return.  */<br>
+   if (delay_list == 0 &amp;&amp; likely &amp;&amp; new_thread<br>
++      &amp;&amp; !ANY_RETURN_P (new_thread)<br>
+       &amp;&amp; NONJUMP_INSN_P (new_thread)<br>
+       &amp;&amp; GET_CODE (PATTERN (new_thread)) != ASM_INPUT<br>
+       &amp;&amp; asm_noperands (PATTERN (new_thread)) &lt; 0)<br>
+@@ -2985,16 +3010,14 @@ fill_slots_from_thread (rtx insn, rtx co<br>
+<br>
+       gcc_assert (thread_if_true);<br>
+<br>
+-      if (new_thread &amp;&amp; JUMP_P (new_thread)<br>
+-        &amp;&amp; (simplejump_p (new_thread)<br>
+-            || GET_CODE (PATTERN (new_thread)) == RETURN)<br>
++      if (new_thread &amp;&amp; simplejump_or_return_p (new_thread)<br>
+         &amp;&amp; redirect_with_delay_list_safe_p (insn,<br>
+                                             JUMP_LABEL (new_thread),<br>
+                                             delay_list))<br>
+       new_thread = follow_jumps (JUMP_LABEL (new_thread));<br>
+<br>
+-      if (new_thread == 0)<br>
+-      label = find_end_label ();<br>
++      if (ANY_RETURN_P (new_thread))<br>
++      label = find_end_label (new_thread);<br>
+       else if (LABEL_P (new_thread))<br>
+       label = new_thread;<br>
+       else<br>
+@@ -3340,11 +3363,12 @@ relax_delay_slots (rtx first)<br>
+        group of consecutive labels.  */<br>
+       if (JUMP_P (insn)<br>
+         &amp;&amp; (condjump_p (insn) || condjump_in_parallel_p (insn))<br>
+-        &amp;&amp; (target_label = JUMP_LABEL (insn)) != 0)<br>
++        &amp;&amp; (target_label = JUMP_LABEL (insn)) != 0<br>
++        &amp;&amp; !ANY_RETURN_P (target_label))<br>
+       {<br>
+         target_label = skip_consecutive_labels (follow_jumps (target_label));<br>
+-        if (target_label == 0)<br>
+-          target_label = find_end_label ();<br>
++        if (ANY_RETURN_P (target_label))<br>
++          target_label = find_end_label (target_label);<br>
+<br>
+         if (target_label &amp;&amp; next_active_insn (target_label) == next<br>
+             &amp;&amp; ! condjump_in_parallel_p (insn))<br>
+@@ -3359,9 +3383,8 @@ relax_delay_slots (rtx first)<br>
+         /* See if this jump conditionally branches around an unconditional<br>
+            jump.  If so, invert this jump and point it to the target of the<br>
+            second jump.  */<br>
+-        if (next &amp;&amp; JUMP_P (next)<br>
++        if (next &amp;&amp; simplejump_or_return_p (next)<br>
+             &amp;&amp; any_condjump_p (insn)<br>
+-            &amp;&amp; (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN)<br>
+             &amp;&amp; target_label<br>
+             &amp;&amp; next_active_insn (target_label) == next_active_insn (next)<br>
+             &amp;&amp; no_labels_between_p (insn, next))<br>
+@@ -3403,8 +3426,7 @@ relax_delay_slots (rtx first)<br>
+        Don&#39;t do this if we expect the conditional branch to be true, because<br>
+        we would then be making the more common case longer.  */<br>
+<br>
+-      if (JUMP_P (insn)<br>
+-        &amp;&amp; (simplejump_p (insn) || GET_CODE (PATTERN (insn)) == RETURN)<br>
++      if (simplejump_or_return_p (insn)<br>
+         &amp;&amp; (other = prev_active_insn (insn)) != 0<br>
+         &amp;&amp; any_condjump_p (other)<br>
+         &amp;&amp; no_labels_between_p (other, insn)<br>
+@@ -3445,10 +3467,10 @@ relax_delay_slots (rtx first)<br>
+        Only do so if optimizing for size since this results in slower, but<br>
+        smaller code.  */<br>
+       if (optimize_function_for_size_p (cfun)<br>
+-        &amp;&amp; GET_CODE (PATTERN (delay_insn)) == RETURN<br>
++        &amp;&amp; ANY_RETURN_P (PATTERN (delay_insn))<br>
+         &amp;&amp; next<br>
+         &amp;&amp; JUMP_P (next)<br>
+-        &amp;&amp; GET_CODE (PATTERN (next)) == RETURN)<br>
++        &amp;&amp; PATTERN (next) == PATTERN (delay_insn))<br>
+       {<br>
+         rtx after;<br>
+         int i;<br>
+@@ -3487,14 +3509,16 @@ relax_delay_slots (rtx first)<br>
+       continue;<br>
+<br>
+       target_label = JUMP_LABEL (delay_insn);<br>
++      if (target_label &amp;&amp; ANY_RETURN_P (target_label))<br>
++      continue;<br>
+<br>
+       if (target_label)<br>
+       {<br>
+         /* If this jump goes to another unconditional jump, thread it, but<br>
+            don&#39;t convert a jump into a RETURN here.  */<br>
+         trial = skip_consecutive_labels (follow_jumps (target_label));<br>
+-        if (trial == 0)<br>
+-          trial = find_end_label ();<br>
++        if (ANY_RETURN_P (trial))<br>
++          trial = find_end_label (trial);<br>
+<br>
+         if (trial &amp;&amp; trial != target_label<br>
+             &amp;&amp; redirect_with_delay_slots_safe_p (delay_insn, trial, insn))<br>
+@@ -3517,7 +3541,7 @@ relax_delay_slots (rtx first)<br>
+                later incorrectly compute register live/death info.  */<br>
+             rtx tmp = next_active_insn (trial);<br>
+             if (tmp == 0)<br>
+-              tmp = find_end_label ();<br>
++              tmp = find_end_label (simple_return_rtx);<br>
+<br>
+             if (tmp)<br>
+               {<br>
+@@ -3537,14 +3561,12 @@ relax_delay_slots (rtx first)<br>
+            delay list and that insn is redundant, thread the jump.  */<br>
+         if (trial &amp;&amp; GET_CODE (PATTERN (trial)) == SEQUENCE<br>
+             &amp;&amp; XVECLEN (PATTERN (trial), 0) == 2<br>
+-            &amp;&amp; JUMP_P (XVECEXP (PATTERN (trial), 0, 0))<br>
+-            &amp;&amp; (simplejump_p (XVECEXP (PATTERN (trial), 0, 0))<br>
+-                || GET_CODE (PATTERN (XVECEXP (PATTERN (trial), 0, 0))) == RETURN)<br>
++            &amp;&amp; simplejump_or_return_p (XVECEXP (PATTERN (trial), 0, 0))<br>
+             &amp;&amp; redundant_insn (XVECEXP (PATTERN (trial), 0, 1), insn, 0))<br>
+           {<br>
+             target_label = JUMP_LABEL (XVECEXP (PATTERN (trial), 0, 0));<br>
+-            if (target_label == 0)<br>
+-              target_label = find_end_label ();<br>
++            if (ANY_RETURN_P (target_label))<br>
++              target_label = find_end_label (target_label);<br>
+<br>
+             if (target_label<br>
+                 &amp;&amp; redirect_with_delay_slots_safe_p (delay_insn, target_label,<br>
+@@ -3622,16 +3644,15 @@ relax_delay_slots (rtx first)<br>
+        a RETURN here.  */<br>
+       if (! INSN_ANNULLED_BRANCH_P (delay_insn)<br>
+         &amp;&amp; any_condjump_p (delay_insn)<br>
+-        &amp;&amp; next &amp;&amp; JUMP_P (next)<br>
+-        &amp;&amp; (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN)<br>
++        &amp;&amp; next &amp;&amp; simplejump_or_return_p (next)<br>
+         &amp;&amp; next_active_insn (target_label) == next_active_insn (next)<br>
+         &amp;&amp; no_labels_between_p (insn, next))<br>
+       {<br>
+         rtx label = JUMP_LABEL (next);<br>
+         rtx old_label = JUMP_LABEL (delay_insn);<br>
+<br>
+-        if (label == 0)<br>
+-          label = find_end_label ();<br>
++        if (ANY_RETURN_P (label))<br>
++          label = find_end_label (label);<br>
+<br>
+         /* find_end_label can generate a new label. Check this first.  */<br>
+         if (label<br>
+@@ -3692,7 +3713,8 @@ static void<br>
+ make_return_insns (rtx first)<br>
+ {<br>
+   rtx insn, jump_insn, pat;<br>
+-  rtx real_return_label = end_of_function_label;<br>
++  rtx real_return_label = function_return_label;<br>
++  rtx real_simple_return_label = function_simple_return_label;<br>
+   int slots, i;<br>
+<br>
+ #ifdef DELAY_SLOTS_FOR_EPILOGUE<br>
+@@ -3707,18 +3729,25 @@ make_return_insns (rtx first)<br>
+ #endif<br>
+<br>
+   /* See if there is a RETURN insn in the function other than the one we<br>
+-     made for END_OF_FUNCTION_LABEL.  If so, set up anything we can&#39;t change<br>
++     made for FUNCTION_RETURN_LABEL.  If so, set up anything we can&#39;t change<br>
+      into a RETURN to jump to it.  */<br>
+   for (insn = first; insn; insn = NEXT_INSN (insn))<br>
+-    if (JUMP_P (insn) &amp;&amp; GET_CODE (PATTERN (insn)) == RETURN)<br>
++    if (JUMP_P (insn) &amp;&amp; ANY_RETURN_P (PATTERN (insn)))<br>
+       {<br>
+-      real_return_label = get_label_before (insn);<br>
++      rtx t = get_label_before (insn);<br>
++      if (PATTERN (insn) == ret_rtx)<br>
++        real_return_label = t;<br>
++      else<br>
++        real_simple_return_label = t;<br>
+       break;<br>
+       }<br>
+<br>
+   /* Show an extra usage of REAL_RETURN_LABEL so it won&#39;t go away if it<br>
+-     was equal to END_OF_FUNCTION_LABEL.  */<br>
+-  LABEL_NUSES (real_return_label)++;<br>
++     was equal to FUNCTION_RETURN_LABEL.  */<br>
++  if (real_return_label)<br>
++    LABEL_NUSES (real_return_label)++;<br>
++  if (real_simple_return_label)<br>
++    LABEL_NUSES (real_simple_return_label)++;<br>
+<br>
+   /* Clear the list of insns to fill so we can use it.  */<br>
+   obstack_free (&amp;unfilled_slots_obstack, unfilled_firstobj);<br>
+@@ -3726,13 +3755,27 @@ make_return_insns (rtx first)<br>
+   for (insn = first; insn; insn = NEXT_INSN (insn))<br>
+     {<br>
+       int flags;<br>
++      rtx kind, real_label;<br>
+<br>
+       /* Only look at filled JUMP_INSNs that go to the end of function<br>
+        label.  */<br>
+       if (!NONJUMP_INSN_P (insn)<br>
+         || GET_CODE (PATTERN (insn)) != SEQUENCE<br>
+-        || !JUMP_P (XVECEXP (PATTERN (insn), 0, 0))<br>
+-        || JUMP_LABEL (XVECEXP (PATTERN (insn), 0, 0)) != end_of_function_label)<br>
++        || !JUMP_P (XVECEXP (PATTERN (insn), 0, 0)))<br>
++      continue;<br>
++<br>
++      if (JUMP_LABEL (XVECEXP (PATTERN (insn), 0, 0)) == function_return_label)<br>
++      {<br>
++        kind = ret_rtx;<br>
++        real_label = real_return_label;<br>
++      }<br>
++      else if (JUMP_LABEL (XVECEXP (PATTERN (insn), 0, 0))<br>
++             == function_simple_return_label)<br>
++      {<br>
++        kind = simple_return_rtx;<br>
++        real_label = real_simple_return_label;<br>
++      }<br>
++      else<br>
+       continue;<br>
+<br>
+       pat = PATTERN (insn);<br>
+@@ -3740,14 +3783,12 @@ make_return_insns (rtx first)<br>
+<br>
+       /* If we can&#39;t make the jump into a RETURN, try to redirect it to the best<br>
+        RETURN and go on to the next insn.  */<br>
+-      if (! reorg_redirect_jump (jump_insn, NULL_RTX))<br>
++      if (! reorg_redirect_jump (jump_insn, kind))<br>
+       {<br>
+         /* Make sure redirecting the jump will not invalidate the delay<br>
+            slot insns.  */<br>
+-        if (redirect_with_delay_slots_safe_p (jump_insn,<br>
+-                                              real_return_label,<br>
+-                                              insn))<br>
+-          reorg_redirect_jump (jump_insn, real_return_label);<br>
++        if (redirect_with_delay_slots_safe_p (jump_insn, real_label, insn))<br>
++          reorg_redirect_jump (jump_insn, real_label);<br>
+         continue;<br>
+       }<br>
+<br>
+@@ -3787,7 +3828,7 @@ make_return_insns (rtx first)<br>
+        RETURN, delete the SEQUENCE and output the individual insns,<br>
+        followed by the RETURN.  Then set things up so we try to find<br>
+        insns for its delay slots, if it needs some.  */<br>
+-      if (GET_CODE (PATTERN (jump_insn)) == RETURN)<br>
++      if (ANY_RETURN_P (PATTERN (jump_insn)))<br>
+       {<br>
+         rtx prev = PREV_INSN (insn);<br>
+<br>
+@@ -3804,13 +3845,16 @@ make_return_insns (rtx first)<br>
+       else<br>
+       /* It is probably more efficient to keep this with its current<br>
+          delay slot as a branch to a RETURN.  */<br>
+-      reorg_redirect_jump (jump_insn, real_return_label);<br>
++      reorg_redirect_jump (jump_insn, real_label);<br>
+     }<br>
+<br>
+   /* Now delete REAL_RETURN_LABEL if we never used it.  Then try to fill any<br>
+      new delay slots we have created.  */<br>
+-  if (--LABEL_NUSES (real_return_label) == 0)<br>
++  if (real_return_label != NULL_RTX &amp;&amp; --LABEL_NUSES (real_return_label) == 0)<br>
+     delete_related_insns (real_return_label);<br>
++  if (real_simple_return_label != NULL_RTX<br>
++      &amp;&amp; --LABEL_NUSES (real_simple_return_label) == 0)<br>
++    delete_related_insns (real_simple_return_label);<br>
+<br>
+   fill_simple_delay_slots (1);<br>
+   fill_simple_delay_slots (0);<br>
+@@ -3878,7 +3922,7 @@ dbr_schedule (rtx first)<br>
+   init_resource_info (epilogue_insn);<br>
+<br>
+   /* Show we haven&#39;t computed an end-of-function label yet.  */<br>
+-  end_of_function_label = 0;<br>
++  function_return_label = function_simple_return_label = NULL_RTX;<br>
+<br>
+   /* Initialize the statistics for this function.  */<br>
+   memset (num_insns_needing_delays, 0, sizeof num_insns_needing_delays);<br>
+@@ -3900,11 +3944,23 @@ dbr_schedule (rtx first)<br>
+   /* If we made an end of function label, indicate that it is now<br>
+      safe to delete it by undoing our prior adjustment to LABEL_NUSES.<br>
+      If it is now unused, delete it.  */<br>
+-  if (end_of_function_label &amp;&amp; --LABEL_NUSES (end_of_function_label) == 0)<br>
+-    delete_related_insns (end_of_function_label);<br>
++  if (function_return_label &amp;&amp; --LABEL_NUSES (function_return_label) == 0)<br>
++    delete_related_insns (function_return_label);<br>
++  if (function_simple_return_label<br>
++      &amp;&amp; --LABEL_NUSES (function_simple_return_label) == 0)<br>
++    delete_related_insns (function_simple_return_label);<br>
+<br>
++#if defined HAVE_return || defined HAVE_simple_return<br>
++  if (<br>
+ #ifdef HAVE_return<br>
+-  if (HAVE_return &amp;&amp; end_of_function_label != 0)<br>
++      (HAVE_return &amp;&amp; function_return_label != 0)<br>
++#else<br>
++      0<br>
++#endif<br>
++#ifdef HAVE_simple_return<br>
++      || (HAVE_simple_return &amp;&amp; function_simple_return_label != 0)<br>
++#endif<br>
++      )<br>
+     make_return_insns (first);<br>
+ #endif<br>
+<br>
+Index: gcc-4_5-branch/gcc/resource.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/resource.c<br>
++++ gcc-4_5-branch/gcc/resource.c<br>
+@@ -495,6 +495,8 @@ find_dead_or_set_registers (rtx target,<br>
+                 || GET_CODE (PATTERN (this_jump_insn)) == RETURN)<br>
+               {<br>
+                 next = JUMP_LABEL (this_jump_insn);<br>
++                if (next &amp;&amp; ANY_RETURN_P (next))<br>
++                  next = NULL_RTX;<br>
+                 if (jump_insn == 0)<br>
+                   {<br>
+                     jump_insn = insn;<br>
+@@ -562,9 +564,10 @@ find_dead_or_set_registers (rtx target,<br>
+                 AND_COMPL_HARD_REG_SET (scratch, needed.regs);<br>
+                 AND_COMPL_HARD_REG_SET (fallthrough_res.regs, scratch);<br>
+<br>
+-                find_dead_or_set_registers (JUMP_LABEL (this_jump_insn),<br>
+-                                            &amp;target_res, 0, jump_count,<br>
+-                                            target_set, needed);<br>
++                if (!ANY_RETURN_P (JUMP_LABEL (this_jump_insn)))<br>
++                  find_dead_or_set_registers (JUMP_LABEL (this_jump_insn),<br>
++                                              &amp;target_res, 0, jump_count,<br>
++                                              target_set, needed);<br>
+                 find_dead_or_set_registers (next,<br>
+                                             &amp;fallthrough_res, 0, jump_count,<br>
+                                             set, needed);<br>
+@@ -1097,6 +1100,8 @@ mark_target_live_regs (rtx insns, rtx ta<br>
+       struct resources new_resources;<br>
+       rtx stop_insn = next_active_insn (jump_insn);<br>
+<br>
++      if (jump_target &amp;&amp; ANY_RETURN_P (jump_target))<br>
++      jump_target = NULL_RTX;<br>
+       mark_target_live_regs (insns, next_active_insn (jump_target),<br>
+                            &amp;new_resources);<br>
+       CLEAR_RESOURCE (&amp;set);<br>
+Index: gcc-4_5-branch/gcc/rtl.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/rtl.c<br>
++++ gcc-4_5-branch/gcc/rtl.c<br>
+@@ -256,6 +256,8 @@ copy_rtx (rtx orig)<br>
+     case CODE_LABEL:<br>
+     case PC:<br>
+     case CC0:<br>
++    case RETURN:<br>
++    case SIMPLE_RETURN:<br>
+     case SCRATCH:<br>
+       /* SCRATCH must be shared because they represent distinct values.  */<br>
+       return orig;<br>
+Index: gcc-4_5-branch/gcc/rtl.def<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/rtl.def<br>
++++ gcc-4_5-branch/gcc/rtl.def<br>
+@@ -296,6 +296,10 @@ DEF_RTL_EXPR(CALL, &quot;call&quot;, &quot;ee&quot;, RTX_EXT<br>
+<br>
+ DEF_RTL_EXPR(RETURN, &quot;return&quot;, &quot;&quot;, RTX_EXTRA)<br>
+<br>
++/* A plain return, to be used on paths that are reached without going<br>
++   through the function prologue.  */<br>
++DEF_RTL_EXPR(SIMPLE_RETURN, &quot;simple_return&quot;, &quot;&quot;, RTX_EXTRA)<br>
++<br>
+ /* Special for EH return from subroutine.  */<br>
+<br>
+ DEF_RTL_EXPR(EH_RETURN, &quot;eh_return&quot;, &quot;&quot;, RTX_EXTRA)<br>
+Index: gcc-4_5-branch/gcc/rtl.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/rtl.h<br>
++++ gcc-4_5-branch/gcc/rtl.h<br>
+@@ -411,6 +411,10 @@ struct GTY(()) rtvec_def {<br>
+   (JUMP_P (INSN) &amp;&amp; (GET_CODE (PATTERN (INSN)) == ADDR_VEC || \<br>
+                    GET_CODE (PATTERN (INSN)) == ADDR_DIFF_VEC))<br>
+<br>
++/* Predicate yielding nonzero iff X is a return or simple_preturn.  */<br>
++#define ANY_RETURN_P(X) \<br>
++  (GET_CODE (X) == RETURN || GET_CODE (X) == SIMPLE_RETURN)<br>
++<br>
+ /* 1 if X is a unary operator.  */<br>
+<br>
+ #define UNARY_P(X)   \<br>
+@@ -1998,6 +2002,8 @@ enum global_rtl_index<br>
+ {<br>
+   GR_PC,<br>
+   GR_CC0,<br>
++  GR_RETURN,<br>
++  GR_SIMPLE_RETURN,<br>
+   GR_STACK_POINTER,<br>
+   GR_FRAME_POINTER,<br>
+ /* For register elimination to work properly these hard_frame_pointer_rtx,<br>
+@@ -2032,6 +2038,8 @@ extern GTY(()) rtx global_rtl[GR_MAX];<br>
+<br>
+ /* Standard pieces of rtx, to be substituted directly into things.  */<br>
+ #define pc_rtx                  (global_rtl[GR_PC])<br>
++#define ret_rtx                 (global_rtl[GR_RETURN])<br>
++#define simple_return_rtx       (global_rtl[GR_SIMPLE_RETURN])<br>
+ #define cc0_rtx                 (global_rtl[GR_CC0])<br>
+<br>
+ /* All references to certain hard regs, except those created<br>
+Index: gcc-4_5-branch/gcc/rtlanal.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/rtlanal.c<br>
++++ gcc-4_5-branch/gcc/rtlanal.c<br>
+@@ -2673,6 +2673,7 @@ tablejump_p (const_rtx insn, rtx *labelp<br>
+<br>
+   if (JUMP_P (insn)<br>
+       &amp;&amp; (label = JUMP_LABEL (insn)) != NULL_RTX<br>
++      &amp;&amp; !ANY_RETURN_P (label)<br>
+       &amp;&amp; (table = next_active_insn (label)) != NULL_RTX<br>
+       &amp;&amp; JUMP_TABLE_DATA_P (table))<br>
+     {<br>
+Index: gcc-4_5-branch/gcc/sched-int.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/sched-int.h<br>
++++ gcc-4_5-branch/gcc/sched-int.h<br>
+@@ -199,7 +199,7 @@ extern int max_issue (struct ready_list<br>
+<br>
+ extern void ebb_compute_jump_reg_dependencies (rtx, regset, regset, regset);<br>
+<br>
+-extern edge find_fallthru_edge (basic_block);<br>
++extern edge find_fallthru_edge_from (basic_block);<br>
+<br>
+ extern void (* sched_init_only_bb) (basic_block, basic_block);<br>
+ extern basic_block (* sched_split_block) (basic_block, rtx);<br>
+Index: gcc-4_5-branch/gcc/sched-vis.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/sched-vis.c<br>
++++ gcc-4_5-branch/gcc/sched-vis.c<br>
+@@ -549,6 +549,9 @@ print_pattern (char *buf, const_rtx x, i<br>
+     case RETURN:<br>
+       sprintf (buf, &quot;return&quot;);<br>
+       break;<br>
++    case SIMPLE_RETURN:<br>
++      sprintf (buf, &quot;simple_return&quot;);<br>
++      break;<br>
+     case CALL:<br>
+       print_exp (buf, x, verbose);<br>
+       break;<br>
+Index: gcc-4_5-branch/gcc/sel-sched-ir.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/sel-sched-ir.c<br>
++++ gcc-4_5-branch/gcc/sel-sched-ir.c<br>
+@@ -686,7 +686,7 @@ merge_fences (fence_t f, insn_t insn,<br>
+<br>
+       /* Find fallthrough edge.  */<br>
+       gcc_assert (BLOCK_FOR_INSN (insn)-&gt;prev_bb);<br>
+-      candidate = find_fallthru_edge (BLOCK_FOR_INSN (insn)-&gt;prev_bb);<br>
++      candidate = find_fallthru_edge_from (BLOCK_FOR_INSN (insn)-&gt;prev_bb);<br>
+<br>
+       if (!candidate<br>
+           || (candidate-&gt;src != BLOCK_FOR_INSN (last_scheduled_insn)<br>
+Index: gcc-4_5-branch/gcc/sel-sched.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/sel-sched.c<br>
++++ gcc-4_5-branch/gcc/sel-sched.c<br>
+@@ -617,8 +617,8 @@ in_fallthru_bb_p (rtx insn, rtx succ)<br>
+   if (bb == BLOCK_FOR_INSN (succ))<br>
+     return true;<br>
+<br>
+-  if (find_fallthru_edge (bb))<br>
+-    bb = find_fallthru_edge (bb)-&gt;dest;<br>
++  if (find_fallthru_edge_from (bb))<br>
++    bb = find_fallthru_edge_from (bb)-&gt;dest;<br>
+   else<br>
+     return false;<br>
+<br>
+@@ -4911,7 +4911,7 @@ move_cond_jump (rtx insn, bnd_t bnd)<br>
+   next = PREV_INSN (insn);<br>
+   BND_TO (bnd) = insn;<br>
+<br>
+-  ft_edge = find_fallthru_edge (block_from);<br>
++  ft_edge = find_fallthru_edge_from (block_from);<br>
+   block_next = ft_edge-&gt;dest;<br>
+   /* There must be a fallthrough block (or where should go<br>
+   control flow in case of false jump predicate otherwise?).  */<br>
+Index: gcc-4_5-branch/gcc/vec.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/vec.h<br>
++++ gcc-4_5-branch/gcc/vec.h<br>
+@@ -188,6 +188,18 @@ along with GCC; see the file COPYING3.<br>
+<br>
+ #define VEC_iterate(T,V,I,P)  (VEC_OP(T,base,iterate)(VEC_BASE(V),I,&amp;(P)))<br>
+<br>
++/* Convenience macro for forward iteration.  */<br>
++<br>
++#define FOR_EACH_VEC_ELT(T, V, I, P)          \<br>
++  for (I = 0; VEC_iterate (T, (V), (I), (P)); ++(I))<br>
++<br>
++/* Convenience macro for reverse iteration.  */<br>
++<br>
++#define FOR_EACH_VEC_ELT_REVERSE(T,V,I,P) \<br>
++  for (I = VEC_length (T, (V)) - 1;           \<br>
++       VEC_iterate (T, (V), (I), (P));          \<br>
++       (I)--)<br>
++<br>
+ /* Allocate new vector.<br>
+    VEC(T,A) *VEC_T_A_alloc(int reserve);<br>
+<br>
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99475.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99475.patch<br>
new file mode 100644<br>
index 0000000..aa9d6aa<br>
--- /dev/null<br>
+++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99475.patch<br>
@@ -0,0 +1,4217 @@<br>
+2011-02-08  Andrew Stubbs  &lt;<a href="mailto:ams@codesourcery.com">ams@codesourcery.com</a>&gt;<br>
+<br>
+       Backport from FSF mainline:<br>
+<br>
+       2010-06-30  H.J. Lu  &lt;<a href="http://hongjiu.lu" target="_blank">hongjiu.lu</a>@<a href="http://intel.com" target="_blank">intel.com</a>&gt;<br>
+<br>
+       PR target/44721<br>
+       * config/i386/<a href="http://i386.md" target="_blank">i386.md</a> (peephole2 for arithmetic ops with memory):<br>
+       Fix last commit.<br>
+<br>
+       2010-06-30  Richard Guenther  &lt;<a href="mailto:rguenther@suse.de">rguenther@suse.de</a>&gt;<br>
+<br>
+       PR target/44722<br>
+       * config/i386/<a href="http://i386.md" target="_blank">i386.md</a> (peephole2 for fix:SSEMODEI24): Guard<br>
+       against oscillation with reverse peephole2.<br>
+<br>
+       2010-07-01  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
+<br>
+       PR target/44727<br>
+       * config/i386/<a href="http://i386.md" target="_blank">i386.md</a> (peephole2 for arithmetic ops with memory):<br>
+       Make sure operand 0 dies.<br>
+<br>
+2010-12-03  Yao Qi  &lt;<a href="mailto:yao@codesourcery.com">yao@codesourcery.com</a>&gt;<br>
+<br>
+       * config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>: Rewrite ldm/stm RTL patterns to fix<br>
+       regressions.<br>
+       * config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>: Regenreate.<br>
+<br>
+2010-12-03  Yao Qi  &lt;<a href="mailto:yao@codesourcery.com">yao@codesourcery.com</a>&gt;<br>
+<br>
+       Backport from FSF mainline:<br>
+<br>
+       2010-08-02  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
+<br>
+       PR target/40457<br>
+       * config/arm/arm.h (arm_regs_in_sequence): Declare.<br>
+       * config/arm/arm-protos.h (emit_ldm_seq, emit_stm_seq,<br>
+       load_multiple_sequence, store_multiple_sequence): Delete<br>
+       declarations.<br>
+       (arm_gen_load_multiple, arm_gen_store_multiple): Adjust<br>
+       declarations.<br>
+       * config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>: New file.<br>
+       * config/arm/arm.c (arm_regs_in_sequence): New array.<br>
+       (load_multiple_sequence): Now static.  New args SAVED_ORDER,<br>
+       CHECK_REGS.  All callers changed.<br>
+       If SAVED_ORDER is nonnull, copy the computed order into it.<br>
+       If CHECK_REGS is false, don&#39;t sort REGS.  Handle Thumb mode.<br>
+       (store_multiple_sequence): Now static.  New args NOPS_TOTAL,<br>
+       SAVED_ORDER, REG_RTXS and CHECK_REGS.  All callers changed.<br>
+       If SAVED_ORDER is nonnull, copy the computed order into it.<br>
+       If CHECK_REGS is false, don&#39;t sort REGS.  Set up REG_RTXS just<br>
+       like REGS.  Handle Thumb mode.<br>
+       (arm_gen_load_multiple_1): New function, broken out of<br>
+       arm_gen_load_multiple.<br>
+       (arm_gen_store_multiple_1): New function, broken out of<br>
+       arm_gen_store_multiple.<br>
+       (arm_gen_multiple_op): New function, with code from<br>
+       arm_gen_load_multiple and arm_gen_store_multiple moved here.<br>
+       (arm_gen_load_multiple, arm_gen_store_multiple): Now just<br>
+       wrappers around arm_gen_multiple_op.  Remove argument UP, all callers<br>
+       changed.<br>
+       (gen_ldm_seq, gen_stm_seq, gen_const_stm_seq): New functions.<br>
+       * config/arm/<a href="http://predicates.md" target="_blank">predicates.md</a> (commutative_binary_operator): New.<br>
+       (load_multiple_operation, store_multiple_operation): Handle more<br>
+       variants of these patterns with different starting offsets.  Handle<br>
+       Thumb-1.<br>
+       * config/arm/<a href="http://arm.md" target="_blank">arm.md</a>: Include &quot;<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>&quot;.<br>
+       (ldmsi_postinc4, ldmsi_postinc4_thumb1, ldmsi_postinc3, ldmsi_postinc2,<br>
+       ldmsi4, ldmsi3, ldmsi2, stmsi_postinc4, stmsi_postinc4_thumb1,<br>
+       stmsi_postinc3, stmsi_postinc2, stmsi4, stmsi3, stmsi2 and related<br>
+       peepholes): Delete.<br>
+       * config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>: New file.<br>
+       * config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>: New file.<br>
+<br>
+       * config/arm/arm.c (arm_rtx_costs_1): Remove second clause from the<br>
+       if statement which adds extra costs to frame-related expressions.<br>
+<br>
+       2010-05-06  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
+<br>
+       * config/arm/arm.h (MAX_LDM_STM_OPS): New macro.<br>
+       * config/arm/arm.c (multiple_operation_profitable_p,<br>
+       compute_offset_order): New static functions.<br>
+       (load_multiple_sequence, store_multiple_sequence): Use them.<br>
+       Replace constant 4 with MAX_LDM_STM_OPS.  Compute order[0] from<br>
+       memory offsets, not register numbers.<br>
+       (emit_ldm_seq, emit_stm_seq): Replace constant 4 with MAX_LDM_STM_OPS.<br>
+<br>
+       2010-04-16  Bernd Schmidt  &lt;<a href="mailto:bernds@codesourcery.com">bernds@codesourcery.com</a>&gt;<br>
+<br>
+       * recog.h (struct recog_data): New field is_operator.<br>
+       (struct insn_operand_data): New field is_operator.<br>
+       * recog.c (extract_insn): Set recog_data.is_operator.<br>
+       * genoutput.c (output_operand_data): Emit code to set the<br>
+       is_operator field.<br>
+       * reload.c (find_reloads): Use it rather than testing for an<br>
+       empty constraint string.<br>
+<br>
+=== added file &#39;gcc/config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>&#39;<br>
+Index: gcc-4_5-branch/gcc/config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a><br>
+===================================================================<br>
+--- /dev/null<br>
++++ gcc-4_5-branch/gcc/config/arm/<a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a><br>
+@@ -0,0 +1,333 @@<br>
++(* Auto-generate ARM ldm/stm patterns<br>
++   Copyright (C) 2010 Free Software Foundation, Inc.<br>
++   Contributed by CodeSourcery.<br>
++<br>
++   This file is part of GCC.<br>
++<br>
++   GCC is free software; you can redistribute it and/or modify it under<br>
++   the terms of the GNU General Public License as published by the Free<br>
++   Software Foundation; either version 3, or (at your option) any later<br>
++   version.<br>
++<br>
++   GCC is distributed in the hope that it will be useful, but WITHOUT ANY<br>
++   WARRANTY; without even the implied warranty of MERCHANTABILITY or<br>
++   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License<br>
++   for more details.<br>
++<br>
++   You should have received a copy of the GNU General Public License<br>
++   along with GCC; see the file COPYING3.  If not see<br>
++   &lt;<a href="http://www.gnu.org/licenses/" target="_blank">http://www.gnu.org/licenses/</a>&gt;.<br>
++<br>
++   This is an O&#39;Caml program.  The O&#39;Caml compiler is available from:<br>
++<br>
++     <a href="http://caml.inria.fr/" target="_blank">http://caml.inria.fr/</a><br>
++<br>
++   Or from your favourite OS&#39;s friendly packaging system. Tested with version<br>
++   3.09.2, though other versions will probably work too.<br>
++<br>
++   Run with:<br>
++     ocaml <a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a> &gt;/path/to/gcc/config/arm/<a href="http://ldmstm.ml" target="_blank">ldmstm.ml</a><br>
++*)<br>
++<br>
++type amode = IA | IB | DA | DB<br>
++<br>
++type optype = IN | OUT | INOUT<br>
++<br>
++let rec string_of_addrmode addrmode =<br>
++  match addrmode with<br>
++    IA -&gt; &quot;ia&quot; | IB -&gt; &quot;ib&quot; | DA -&gt; &quot;da&quot; | DB -&gt; &quot;db&quot;<br>
++<br>
++let rec initial_offset addrmode nregs =<br>
++  match addrmode with<br>
++    IA -&gt; 0<br>
++  | IB -&gt; 4<br>
++  | DA -&gt; -4 * nregs + 4<br>
++  | DB -&gt; -4 * nregs<br>
++<br>
++let rec final_offset addrmode nregs =<br>
++  match addrmode with<br>
++    IA -&gt; nregs * 4<br>
++  | IB -&gt; nregs * 4<br>
++  | DA -&gt; -4 * nregs<br>
++  | DB -&gt; -4 * nregs<br>
++<br>
++let constr thumb =<br>
++  if thumb then &quot;l&quot; else &quot;rk&quot;<br>
++<br>
++let inout_constr op_type =<br>
++  match op_type with<br>
++  OUT -&gt; &quot;=&quot;<br>
++  | INOUT -&gt; &quot;+&amp;&quot;<br>
++  | IN -&gt; &quot;&quot;<br>
++<br>
++let destreg nregs first op_type thumb =<br>
++  if not first then<br>
++    Printf.sprintf &quot;(match_dup %d)&quot; (nregs)<br>
++  else<br>
++    Printf.sprintf (&quot;(match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;%s%s\&quot;)&quot;)<br>
++    (nregs) (inout_constr op_type) (constr thumb)<br>
++<br>
++let write_ldm_set thumb nregs offset opnr first =<br>
++  let indent = &quot;     &quot; in<br>
++  Printf.printf &quot;%s&quot; (if first then &quot;    [&quot; else indent);<br>
++  Printf.printf &quot;(set (match_operand:SI %d \&quot;arm_hard_register_operand\&quot; \&quot;\&quot;)\n&quot; opnr;<br>
++  Printf.printf &quot;%s     (mem:SI &quot; indent;<br>
++  begin if offset != 0 then Printf.printf &quot;(plus:SI &quot; end;<br>
++  Printf.printf &quot;%s&quot; (destreg nregs first IN thumb);<br>
++  begin if offset != 0 then Printf.printf &quot;\n%s             (const_int %d))&quot; indent offset end;<br>
++  Printf.printf &quot;))&quot;<br>
++<br>
++let write_stm_set thumb nregs offset opnr first =<br>
++  let indent = &quot;     &quot; in<br>
++  Printf.printf &quot;%s&quot; (if first then &quot;    [&quot; else indent);<br>
++  Printf.printf &quot;(set (mem:SI &quot;;<br>
++  begin if offset != 0 then Printf.printf &quot;(plus:SI &quot; end;<br>
++  Printf.printf &quot;%s&quot; (destreg nregs first IN thumb);<br>
++  begin if offset != 0 then Printf.printf &quot; (const_int %d))&quot; offset end;<br>
++  Printf.printf &quot;)\n%s     (match_operand:SI %d \&quot;arm_hard_register_operand\&quot; \&quot;\&quot;))&quot; indent opnr<br>
++<br>
++let write_ldm_peep_set extra_indent nregs opnr first =<br>
++  let indent = &quot;   &quot; ^ extra_indent in<br>
++  Printf.printf &quot;%s&quot; (if first then extra_indent ^ &quot;  [&quot; else indent);<br>
++  Printf.printf &quot;(set (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; opnr;<br>
++  Printf.printf &quot;%s     (match_operand:SI %d \&quot;memory_operand\&quot; \&quot;\&quot;))&quot; indent (nregs + opnr)<br>
++<br>
++let write_stm_peep_set extra_indent nregs opnr first =<br>
++  let indent = &quot;   &quot; ^ extra_indent in<br>
++  Printf.printf &quot;%s&quot; (if first then extra_indent ^ &quot;  [&quot; else indent);<br>
++  Printf.printf &quot;(set (match_operand:SI %d \&quot;memory_operand\&quot; \&quot;\&quot;)\n&quot; (nregs + opnr);<br>
++  Printf.printf &quot;%s     (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;))&quot; indent opnr<br>
++<br>
++let write_any_load optype nregs opnr first =<br>
++  let indent = &quot;   &quot; in<br>
++  Printf.printf &quot;%s&quot; (if first then &quot;  [&quot; else indent);<br>
++  Printf.printf &quot;(set (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; opnr;<br>
++  Printf.printf &quot;%s     (match_operand:SI %d \&quot;%s\&quot; \&quot;\&quot;))&quot; indent (nregs * 2 + opnr) optype<br>
++<br>
++let write_const_store nregs opnr first =<br>
++  let indent = &quot;   &quot; in<br>
++  Printf.printf &quot;%s(set (match_operand:SI %d \&quot;memory_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs + opnr);<br>
++  Printf.printf &quot;%s     (match_dup %d))&quot; indent opnr<br>
++<br>
++let write_const_stm_peep_set nregs opnr first =<br>
++  write_any_load &quot;const_int_operand&quot; nregs opnr first;<br>
++  Printf.printf &quot;\n&quot;;<br>
++  write_const_store nregs opnr false<br>
++<br>
++<br>
++let rec write_pat_sets func opnr offset first n_left =<br>
++  func offset opnr first;<br>
++  begin<br>
++    if n_left &gt; 1 then begin<br>
++      Printf.printf &quot;\n&quot;;<br>
++      write_pat_sets func (opnr + 1) (offset + 4) false (n_left - 1);<br>
++    end else<br>
++      Printf.printf &quot;]&quot;<br>
++  end<br>
++<br>
++let rec write_peep_sets func opnr first n_left =<br>
++  func opnr first;<br>
++  begin<br>
++    if n_left &gt; 1 then begin<br>
++      Printf.printf &quot;\n&quot;;<br>
++      write_peep_sets func (opnr + 1) false (n_left - 1);<br>
++    end<br>
++  end<br>
++<br>
++let can_thumb addrmode update is_store =<br>
++  match addrmode, update, is_store with<br>
++    (* Thumb1 mode only supports IA with update.  However, for LDMIA,<br>
++       if the address register also appears in the list of loaded<br>
++       registers, the loaded value is stored, hence the RTL pattern<br>
++       to describe such an insn does not have an update.  We check<br>
++       in the match_parallel predicate that the condition described<br>
++       above is met.  *)<br>
++    IA, _, false -&gt; true<br>
++  | IA, true, true -&gt; true<br>
++  | _ -&gt; false<br>
++<br>
++let target addrmode thumb =<br>
++  match addrmode, thumb with<br>
++    IA, true -&gt; &quot;TARGET_THUMB1&quot;<br>
++  | IA, false -&gt; &quot;TARGET_32BIT&quot;<br>
++  | DB, false -&gt; &quot;TARGET_32BIT&quot;<br>
++  | _, false -&gt; &quot;TARGET_ARM&quot;<br>
++<br>
++let write_pattern_1 name ls addrmode nregs write_set_fn update thumb =<br>
++  let astr = string_of_addrmode addrmode in<br>
++  Printf.printf &quot;(define_insn \&quot;*%s%s%d_%s%s\&quot;\n&quot;<br>
++    (if thumb then &quot;thumb_&quot; else &quot;&quot;) name nregs astr<br>
++    (if update then &quot;_update&quot; else &quot;&quot;);<br>
++  Printf.printf &quot;  [(match_parallel 0 \&quot;%s_multiple_operation\&quot;\n&quot; ls;<br>
++  begin<br>
++    if update then begin<br>
++      Printf.printf &quot;    [(set %s\n          (plus:SI &quot;<br>
++      (destreg 1 true OUT thumb); (*destreg 2 true IN thumb*)<br>
++      Printf.printf &quot;(match_operand:SI 2 \&quot;s_register_operand\&quot; \&quot;1\&quot;)&quot;;<br>
++      Printf.printf &quot; (const_int %d)))\n&quot;<br>
++      (final_offset addrmode nregs)<br>
++    end<br>
++  end;<br>
++  write_pat_sets<br>
++    (write_set_fn thumb (if update then 2 else 1)) (if update then 3 else 2)<br>
++    (initial_offset addrmode nregs)<br>
++    (not update) nregs;<br>
++  Printf.printf &quot;)]\n  \&quot;%s &amp;&amp; XVECLEN (operands[0], 0) == %d\&quot;\n&quot;<br>
++    (target addrmode thumb)<br>
++    (if update then nregs + 1 else nregs);<br>
++  Printf.printf &quot;  \&quot;%s%%(%s%%)\\t%%%d%s, {&quot;<br>
++    name astr (1) (if update then &quot;!&quot; else &quot;&quot;);<br>
++  for n = 1 to nregs; do<br>
++    Printf.printf &quot;%%%d%s&quot; (n+(if update then 2 else 1)) (if n &lt; nregs then &quot;, &quot; else &quot;&quot;)<br>
++  done;<br>
++  Printf.printf &quot;}\&quot;\n&quot;;<br>
++  Printf.printf &quot;  [(set_attr \&quot;type\&quot; \&quot;%s%d\&quot;)&quot; ls nregs;<br>
++  begin if not thumb then<br>
++    Printf.printf &quot;\n   (set_attr \&quot;predicable\&quot; \&quot;yes\&quot;)&quot;;<br>
++  end;<br>
++  Printf.printf &quot;])\n\n&quot;<br>
++<br>
++let write_ldm_pattern addrmode nregs update =<br>
++  write_pattern_1 &quot;ldm&quot; &quot;load&quot; addrmode nregs write_ldm_set update false;<br>
++  begin if can_thumb addrmode update false then<br>
++    write_pattern_1 &quot;ldm&quot; &quot;load&quot; addrmode nregs write_ldm_set update true;<br>
++  end<br>
++<br>
++let write_stm_pattern addrmode nregs update =<br>
++  write_pattern_1 &quot;stm&quot; &quot;store&quot; addrmode nregs write_stm_set update false;<br>
++  begin if can_thumb addrmode update true then<br>
++    write_pattern_1 &quot;stm&quot; &quot;store&quot; addrmode nregs write_stm_set update true;<br>
++  end<br>
++<br>
++let write_ldm_commutative_peephole thumb =<br>
++  let nregs = 2 in<br>
++  Printf.printf &quot;(define_peephole2\n&quot;;<br>
++  write_peep_sets (write_ldm_peep_set &quot;&quot; nregs) 0 true nregs;<br>
++  let indent = &quot;   &quot; in<br>
++  if thumb then begin<br>
++    Printf.printf &quot;\n%s(set (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs * 2);<br>
++    Printf.printf &quot;%s     (match_operator:SI %d \&quot;commutative_binary_operator\&quot;\n&quot; indent (nregs * 2 + 1);<br>
++    Printf.printf &quot;%s      [(match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs * 2 + 2);<br>
++    Printf.printf &quot;%s       (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)]))]\n&quot; indent (nregs * 2 + 3)<br>
++  end else begin<br>
++    Printf.printf &quot;\n%s(parallel\n&quot; indent;<br>
++    Printf.printf &quot;%s  [(set (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs * 2);<br>
++    Printf.printf &quot;%s        (match_operator:SI %d \&quot;commutative_binary_operator\&quot;\n&quot; indent (nregs * 2 + 1);<br>
++    Printf.printf &quot;%s         [(match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)\n&quot; indent (nregs * 2 + 2);<br>
++    Printf.printf &quot;%s          (match_operand:SI %d \&quot;s_register_operand\&quot; \&quot;\&quot;)]))\n&quot; indent (nregs * 2 + 3);<br>
++    Printf.printf &quot;%s   (clobber (reg:CC CC_REGNUM))])]\n&quot; indent<br>
++  end;<br>
++  Printf.printf &quot;  \&quot;(((operands[%d] == operands[0] &amp;&amp; operands[%d] == operands[1])\n&quot; (nregs * 2 + 2) (nregs * 2 + 3);<br>
++  Printf.printf &quot;     || (operands[%d] == operands[0] &amp;&amp; operands[%d] == operands[1]))\n&quot; (nregs * 2 + 3) (nregs * 2 + 2);<br>
++  Printf.printf &quot;    &amp;&amp; peep2_reg_dead_p (%d, operands[0]) &amp;&amp; peep2_reg_dead_p (%d, operands[1]))\&quot;\n&quot; (nregs + 1) (nregs + 1);<br>
++  begin<br>
++    if thumb then<br>
++      Printf.printf &quot;  [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))]\n&quot;<br>
++      (nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3)<br>
++    else begin<br>
++      Printf.printf &quot;  [(parallel\n&quot;;<br>
++      Printf.printf &quot;    [(set (match_dup %d) (match_op_dup %d [(match_dup %d) (match_dup %d)]))\n&quot;<br>
++      (nregs * 2) (nregs * 2 + 1) (nregs * 2 + 2) (nregs * 2 + 3);<br>
++      Printf.printf &quot;     (clobber (reg:CC CC_REGNUM))])]\n&quot;<br>
++    end<br>
++  end;<br>
++  Printf.printf &quot;{\n  if (!gen_ldm_seq (operands, %d, true))\n    FAIL;\n&quot; nregs;<br>
++  Printf.printf &quot;})\n\n&quot;<br>
++<br>
++let write_ldm_peephole nregs =<br>
++  Printf.printf &quot;(define_peephole2\n&quot;;<br>
++  write_peep_sets (write_ldm_peep_set &quot;&quot; nregs) 0 true nregs;<br>
++  Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
++  Printf.printf &quot;  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
++<br>
++let write_ldm_peephole_b nregs =<br>
++  if nregs &gt; 2 then begin<br>
++    Printf.printf &quot;(define_peephole2\n&quot;;<br>
++    write_ldm_peep_set &quot;&quot; nregs 0 true;<br>
++    Printf.printf &quot;\n   (parallel\n&quot;;<br>
++    write_peep_sets (write_ldm_peep_set &quot;  &quot; nregs) 1 true (nregs - 1);<br>
++    Printf.printf &quot;])]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
++    Printf.printf &quot;  if (gen_ldm_seq (operands, %d, false))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
++  end<br>
++<br>
++let write_stm_peephole nregs =<br>
++  Printf.printf &quot;(define_peephole2\n&quot;;<br>
++  write_peep_sets (write_stm_peep_set &quot;&quot; nregs) 0 true nregs;<br>
++  Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
++  Printf.printf &quot;  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
++<br>
++let write_stm_peephole_b nregs =<br>
++  if nregs &gt; 2 then begin<br>
++    Printf.printf &quot;(define_peephole2\n&quot;;<br>
++    write_stm_peep_set &quot;&quot; nregs 0 true;<br>
++    Printf.printf &quot;\n   (parallel\n&quot;;<br>
++    write_peep_sets (write_stm_peep_set &quot;&quot; nregs) 1 true (nregs - 1);<br>
++    Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
++    Printf.printf &quot;  if (gen_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
++  end<br>
++<br>
++let write_const_stm_peephole_a nregs =<br>
++  Printf.printf &quot;(define_peephole2\n&quot;;<br>
++  write_peep_sets (write_const_stm_peep_set nregs) 0 true nregs;<br>
++  Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
++  Printf.printf &quot;  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
++<br>
++let write_const_stm_peephole_b nregs =<br>
++  Printf.printf &quot;(define_peephole2\n&quot;;<br>
++  write_peep_sets (write_any_load &quot;const_int_operand&quot; nregs) 0 true nregs;<br>
++  Printf.printf &quot;\n&quot;;<br>
++  write_peep_sets (write_const_store nregs) 0 false nregs;<br>
++  Printf.printf &quot;]\n  \&quot;\&quot;\n  [(const_int 0)]\n{\n&quot;;<br>
++  Printf.printf &quot;  if (gen_const_stm_seq (operands, %d))\n    DONE;\n  else\n    FAIL;\n})\n\n&quot; nregs<br>
++<br>
++let patterns () =<br>
++  let addrmodes = [ IA; IB; DA; DB ]  in<br>
++  let sizes = [ 4; 3; 2] in<br>
++  List.iter<br>
++    (fun n -&gt;<br>
++      List.iter<br>
++      (fun addrmode -&gt;<br>
++        write_ldm_pattern addrmode n false;<br>
++        write_ldm_pattern addrmode n true;<br>
++        write_stm_pattern addrmode n false;<br>
++        write_stm_pattern addrmode n true)<br>
++      addrmodes;<br>
++      write_ldm_peephole n;<br>
++      write_ldm_peephole_b n;<br>
++      write_const_stm_peephole_a n;<br>
++      write_const_stm_peephole_b n;<br>
++      write_stm_peephole n;)<br>
++    sizes;<br>
++  write_ldm_commutative_peephole false;<br>
++  write_ldm_commutative_peephole true<br>
++<br>
++let print_lines = List.iter (fun s -&gt; Format.printf &quot;%s@\n&quot; s)<br>
++<br>
++(* Do it.  *)<br>
++<br>
++let _ =<br>
++  print_lines [<br>
++&quot;/* ARM ldm/stm instruction patterns.  This file was automatically generated&quot;;<br>
++&quot;   using <a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>.  Please do not edit manually.&quot;;<br>
++&quot;&quot;;<br>
++&quot;   Copyright (C) 2010 Free Software Foundation, Inc.&quot;;<br>
++&quot;   Contributed by CodeSourcery.&quot;;<br>
++&quot;&quot;;<br>
++&quot;   This file is part of GCC.&quot;;<br>
++&quot;&quot;;<br>
++&quot;   GCC is free software; you can redistribute it and/or modify it&quot;;<br>
++&quot;   under the terms of the GNU General Public License as published&quot;;<br>
++&quot;   by the Free Software Foundation; either version 3, or (at your&quot;;<br>
++&quot;   option) any later version.&quot;;<br>
++&quot;&quot;;<br>
++&quot;   GCC is distributed in the hope that it will be useful, but WITHOUT&quot;;<br>
++&quot;   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY&quot;;<br>
++&quot;   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public&quot;;<br>
++&quot;   License for more details.&quot;;<br>
++&quot;&quot;;<br>
++&quot;   You should have received a copy of the GNU General Public License and&quot;;<br>
++&quot;   a copy of the GCC Runtime Library Exception along with this program;&quot;;<br>
++&quot;   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see&quot;;<br>
++&quot;   &lt;<a href="http://www.gnu.org/licenses/" target="_blank">http://www.gnu.org/licenses/</a>&gt;.  */&quot;;<br>
++&quot;&quot;];<br>
++  patterns ();<br>
+Index: gcc-4_5-branch/gcc/config/arm/arm-protos.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/arm-protos.h<br>
++++ gcc-4_5-branch/gcc/config/arm/arm-protos.h<br>
+@@ -100,14 +100,11 @@ extern int symbol_mentioned_p (rtx);<br>
+ extern int label_mentioned_p (rtx);<br>
+ extern RTX_CODE minmax_code (rtx);<br>
+ extern int adjacent_mem_locations (rtx, rtx);<br>
+-extern int load_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);<br>
+-extern const char *emit_ldm_seq (rtx *, int);<br>
+-extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);<br>
+-extern const char * emit_stm_seq (rtx *, int);<br>
+-extern rtx arm_gen_load_multiple (int, int, rtx, int, int,<br>
+-                                rtx, HOST_WIDE_INT *);<br>
+-extern rtx arm_gen_store_multiple (int, int, rtx, int, int,<br>
+-                                 rtx, HOST_WIDE_INT *);<br>
++extern bool gen_ldm_seq (rtx *, int, bool);<br>
++extern bool gen_stm_seq (rtx *, int);<br>
++extern bool gen_const_stm_seq (rtx *, int);<br>
++extern rtx arm_gen_load_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *);<br>
++extern rtx arm_gen_store_multiple (int *, int, rtx, int, rtx, HOST_WIDE_INT *);<br>
+ extern int arm_gen_movmemqi (rtx *);<br>
+ extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);<br>
+ extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx,<br>
+Index: gcc-4_5-branch/gcc/config/arm/arm.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/arm.c<br>
++++ gcc-4_5-branch/gcc/config/arm/arm.c<br>
+@@ -753,6 +753,12 @@ static const char * const arm_condition_<br>
+   &quot;hi&quot;, &quot;ls&quot;, &quot;ge&quot;, &quot;lt&quot;, &quot;gt&quot;, &quot;le&quot;, &quot;al&quot;, &quot;nv&quot;<br>
+ };<br>
+<br>
++/* The register numbers in sequence, for passing to arm_gen_load_multiple.  */<br>
++int arm_regs_in_sequence[] =<br>
++{<br>
++  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15<br>
++};<br>
++<br>
+ #define ARM_LSL_NAME (TARGET_UNIFIED_ASM ? &quot;lsl&quot; : &quot;asl&quot;)<br>
+ #define streq(string1, string2) (strcmp (string1, string2) == 0)<br>
+<br>
+@@ -9680,24 +9686,125 @@ adjacent_mem_locations (rtx a, rtx b)<br>
+   return 0;<br>
+ }<br>
+<br>
+-int<br>
+-load_multiple_sequence (rtx *operands, int nops, int *regs, int *base,<br>
+-                      HOST_WIDE_INT *load_offset)<br>
++<br>
++/* Return true iff it would be profitable to turn a sequence of NOPS loads<br>
++   or stores (depending on IS_STORE) into a load-multiple or store-multiple<br>
++   instruction.  ADD_OFFSET is nonzero if the base address register needs<br>
++   to be modified with an add instruction before we can use it.  */<br>
++<br>
++static bool<br>
++multiple_operation_profitable_p (bool is_store ATTRIBUTE_UNUSED,<br>
++                               int nops, HOST_WIDE_INT add_offset)<br>
++ {<br>
++  /* For ARM8,9 &amp; StrongARM, 2 ldr instructions are faster than an ldm<br>
++     if the offset isn&#39;t small enough.  The reason 2 ldrs are faster<br>
++     is because these ARMs are able to do more than one cache access<br>
++     in a single cycle.  The ARM9 and StrongARM have Harvard caches,<br>
++     whilst the ARM8 has a double bandwidth cache.  This means that<br>
++     these cores can do both an instruction fetch and a data fetch in<br>
++     a single cycle, so the trick of calculating the address into a<br>
++     scratch register (one of the result regs) and then doing a load<br>
++     multiple actually becomes slower (and no smaller in code size).<br>
++     That is the transformation<br>
++<br>
++      ldr     rd1, [rbase + offset]<br>
++      ldr     rd2, [rbase + offset + 4]<br>
++<br>
++     to<br>
++<br>
++      add     rd1, rbase, offset<br>
++      ldmia   rd1, {rd1, rd2}<br>
++<br>
++     produces worse code -- &#39;3 cycles + any stalls on rd2&#39; instead of<br>
++     &#39;2 cycles + any stalls on rd2&#39;.  On ARMs with only one cache<br>
++     access per cycle, the first sequence could never complete in less<br>
++     than 6 cycles, whereas the ldm sequence would only take 5 and<br>
++     would make better use of sequential accesses if not hitting the<br>
++     cache.<br>
++<br>
++     We cheat here and test &#39;arm_ld_sched&#39; which we currently know to<br>
++     only be true for the ARM8, ARM9 and StrongARM.  If this ever<br>
++     changes, then the test below needs to be reworked.  */<br>
++  if (nops == 2 &amp;&amp; arm_ld_sched &amp;&amp; add_offset != 0)<br>
++    return false;<br>
++<br>
++  return true;<br>
++}<br>
++<br>
++/* Subroutine of load_multiple_sequence and store_multiple_sequence.<br>
++   Given an array of UNSORTED_OFFSETS, of which there are NOPS, compute<br>
++   an array ORDER which describes the sequence to use when accessing the<br>
++   offsets that produces an ascending order.  In this sequence, each<br>
++   offset must be larger by exactly 4 than the previous one.  ORDER[0]<br>
++   must have been filled in with the lowest offset by the caller.<br>
++   If UNSORTED_REGS is nonnull, it is an array of register numbers that<br>
++   we use to verify that ORDER produces an ascending order of registers.<br>
++   Return true if it was possible to construct such an order, false if<br>
++   not.  */<br>
++<br>
++static bool<br>
++compute_offset_order (int nops, HOST_WIDE_INT *unsorted_offsets, int *order,<br>
++                    int *unsorted_regs)<br>
+ {<br>
+-  int unsorted_regs[4];<br>
+-  HOST_WIDE_INT unsorted_offsets[4];<br>
+-  int order[4];<br>
+-  int base_reg = -1;<br>
+   int i;<br>
++  for (i = 1; i &lt; nops; i++)<br>
++    {<br>
++      int j;<br>
++<br>
++      order[i] = order[i - 1];<br>
++      for (j = 0; j &lt; nops; j++)<br>
++      if (unsorted_offsets[j] == unsorted_offsets[order[i - 1]] + 4)<br>
++        {<br>
++          /* We must find exactly one offset that is higher than the<br>
++             previous one by 4.  */<br>
++          if (order[i] != order[i - 1])<br>
++            return false;<br>
++          order[i] = j;<br>
++        }<br>
++      if (order[i] == order[i - 1])<br>
++      return false;<br>
++      /* The register numbers must be ascending.  */<br>
++      if (unsorted_regs != NULL<br>
++        &amp;&amp; unsorted_regs[order[i]] &lt;= unsorted_regs[order[i - 1]])<br>
++      return false;<br>
++    }<br>
++  return true;<br>
++}<br>
++<br>
++/* Used to determine in a peephole whether a sequence of load<br>
++   instructions can be changed into a load-multiple instruction.<br>
++   NOPS is the number of separate load instructions we are examining.  The<br>
++   first NOPS entries in OPERANDS are the destination registers, the<br>
++   next NOPS entries are memory operands.  If this function is<br>
++   successful, *BASE is set to the common base register of the memory<br>
++   accesses; *LOAD_OFFSET is set to the first memory location&#39;s offset<br>
++   from that base register.<br>
++   REGS is an array filled in with the destination register numbers.<br>
++   SAVED_ORDER (if nonnull), is an array filled in with an order that maps<br>
++   insn numbers to to an ascending order of stores.  If CHECK_REGS is true,<br>
++   the sequence of registers in REGS matches the loads from ascending memory<br>
++   locations, and the function verifies that the register numbers are<br>
++   themselves ascending.  If CHECK_REGS is false, the register numbers<br>
++   are stored in the order they are found in the operands.  */<br>
++static int<br>
++load_multiple_sequence (rtx *operands, int nops, int *regs, int *saved_order,<br>
++                      int *base, HOST_WIDE_INT *load_offset, bool check_regs)<br>
++{<br>
++  int unsorted_regs[MAX_LDM_STM_OPS];<br>
++  HOST_WIDE_INT unsorted_offsets[MAX_LDM_STM_OPS];<br>
++  int order[MAX_LDM_STM_OPS];<br>
++  rtx base_reg_rtx = NULL;<br>
++  int base_reg = -1;<br>
++  int i, ldm_case;<br>
+<br>
+   if (low_irq_latency)<br>
+     return 0;<br>
+<br>
+-  /* Can only handle 2, 3, or 4 insns at present,<br>
+-     though could be easily extended if required.  */<br>
+-  gcc_assert (nops &gt;= 2 &amp;&amp; nops &lt;= 4);<br>
++  /* Can only handle up to MAX_LDM_STM_OPS insns at present, though could be<br>
++     easily extended if required.  */<br>
++  gcc_assert (nops &gt;= 2 &amp;&amp; nops &lt;= MAX_LDM_STM_OPS);<br>
+<br>
+-  memset (order, 0, 4 * sizeof (int));<br>
++  memset (order, 0, MAX_LDM_STM_OPS * sizeof (int));<br>
+<br>
+   /* Loop over the operands and check that the memory references are<br>
+      suitable (i.e. immediate offsets from the same base register).  At<br>
+@@ -9735,32 +9842,30 @@ load_multiple_sequence (rtx *operands, i<br>
+         if (i == 0)<br>
+           {<br>
+             base_reg = REGNO (reg);<br>
+-            unsorted_regs[0] = (GET_CODE (operands[i]) == REG<br>
+-                                ? REGNO (operands[i])<br>
+-                                : REGNO (SUBREG_REG (operands[i])));<br>
+-            order[0] = 0;<br>
+-          }<br>
+-        else<br>
+-          {<br>
+-            if (base_reg != (int) REGNO (reg))<br>
+-              /* Not addressed from the same base register.  */<br>
++            base_reg_rtx = reg;<br>
++            if (TARGET_THUMB1 &amp;&amp; base_reg &gt; LAST_LO_REGNUM)<br>
+               return 0;<br>
+-<br>
+-            unsorted_regs[i] = (GET_CODE (operands[i]) == REG<br>
+-                                ? REGNO (operands[i])<br>
+-                                : REGNO (SUBREG_REG (operands[i])));<br>
+-            if (unsorted_regs[i] &lt; unsorted_regs[order[0]])<br>
+-              order[0] = i;<br>
+           }<br>
++        else if (base_reg != (int) REGNO (reg))<br>
++          /* Not addressed from the same base register.  */<br>
++          return 0;<br>
++<br>
++        unsorted_regs[i] = (GET_CODE (operands[i]) == REG<br>
++                            ? REGNO (operands[i])<br>
++                            : REGNO (SUBREG_REG (operands[i])));<br>
+<br>
+         /* If it isn&#39;t an integer register, or if it overwrites the<br>
+            base register but isn&#39;t the last insn in the list, then<br>
+            we can&#39;t do this.  */<br>
+-        if (unsorted_regs[i] &lt; 0 || unsorted_regs[i] &gt; 14<br>
++        if (unsorted_regs[i] &lt; 0<br>
++            || (TARGET_THUMB1 &amp;&amp; unsorted_regs[i] &gt; LAST_LO_REGNUM)<br>
++            || unsorted_regs[i] &gt; 14<br>
+             || (i != nops - 1 &amp;&amp; unsorted_regs[i] == base_reg))<br>
+           return 0;<br>
+<br>
+         unsorted_offsets[i] = INTVAL (offset);<br>
++        if (i == 0 || unsorted_offsets[i] &lt; unsorted_offsets[order[0]])<br>
++          order[0] = i;<br>
+       }<br>
+       else<br>
+       /* Not a suitable memory address.  */<br>
+@@ -9769,167 +9874,90 @@ load_multiple_sequence (rtx *operands, i<br>
+<br>
+   /* All the useful information has now been extracted from the<br>
+      operands into unsorted_regs and unsorted_offsets; additionally,<br>
+-     order[0] has been set to the lowest numbered register in the<br>
+-     list.  Sort the registers into order, and check that the memory<br>
+-     offsets are ascending and adjacent.  */<br>
+-<br>
+-  for (i = 1; i &lt; nops; i++)<br>
+-    {<br>
+-      int j;<br>
+-<br>
+-      order[i] = order[i - 1];<br>
+-      for (j = 0; j &lt; nops; j++)<br>
+-      if (unsorted_regs[j] &gt; unsorted_regs[order[i - 1]]<br>
+-          &amp;&amp; (order[i] == order[i - 1]<br>
+-              || unsorted_regs[j] &lt; unsorted_regs[order[i]]))<br>
+-        order[i] = j;<br>
+-<br>
+-      /* Have we found a suitable register? if not, one must be used more<br>
+-       than once.  */<br>
+-      if (order[i] == order[i - 1])<br>
+-      return 0;<br>
++     order[0] has been set to the lowest offset in the list.  Sort<br>
++     the offsets into order, verifying that they are adjacent, and<br>
++     check that the register numbers are ascending.  */<br>
++  if (!compute_offset_order (nops, unsorted_offsets, order,<br>
++                           check_regs ? unsorted_regs : NULL))<br>
++    return 0;<br>
+<br>
+-      /* Is the memory address adjacent and ascending? */<br>
+-      if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)<br>
+-      return 0;<br>
+-    }<br>
++  if (saved_order)<br>
++    memcpy (saved_order, order, sizeof order);<br>
+<br>
+   if (base)<br>
+     {<br>
+       *base = base_reg;<br>
+<br>
+       for (i = 0; i &lt; nops; i++)<br>
+-      regs[i] = unsorted_regs[order[i]];<br>
++      regs[i] = unsorted_regs[check_regs ? order[i] : i];<br>
+<br>
+       *load_offset = unsorted_offsets[order[0]];<br>
+     }<br>
+<br>
+-  if (unsorted_offsets[order[0]] == 0)<br>
+-    return 1; /* ldmia */<br>
+-<br>
+-  if (TARGET_ARM &amp;&amp; unsorted_offsets[order[0]] == 4)<br>
+-    return 2; /* ldmib */<br>
+-<br>
+-  if (TARGET_ARM &amp;&amp; unsorted_offsets[order[nops - 1]] == 0)<br>
+-    return 3; /* ldmda */<br>
+-<br>
+-  if (unsorted_offsets[order[nops - 1]] == -4)<br>
+-    return 4; /* ldmdb */<br>
+-<br>
+-  /* For ARM8,9 &amp; StrongARM, 2 ldr instructions are faster than an ldm<br>
+-     if the offset isn&#39;t small enough.  The reason 2 ldrs are faster<br>
+-     is because these ARMs are able to do more than one cache access<br>
+-     in a single cycle.  The ARM9 and StrongARM have Harvard caches,<br>
+-     whilst the ARM8 has a double bandwidth cache.  This means that<br>
+-     these cores can do both an instruction fetch and a data fetch in<br>
+-     a single cycle, so the trick of calculating the address into a<br>
+-     scratch register (one of the result regs) and then doing a load<br>
+-     multiple actually becomes slower (and no smaller in code size).<br>
+-     That is the transformation<br>
+-<br>
+-      ldr     rd1, [rbase + offset]<br>
+-      ldr     rd2, [rbase + offset + 4]<br>
+-<br>
+-     to<br>
+-<br>
+-      add     rd1, rbase, offset<br>
+-      ldmia   rd1, {rd1, rd2}<br>
+-<br>
+-     produces worse code -- &#39;3 cycles + any stalls on rd2&#39; instead of<br>
+-     &#39;2 cycles + any stalls on rd2&#39;.  On ARMs with only one cache<br>
+-     access per cycle, the first sequence could never complete in less<br>
+-     than 6 cycles, whereas the ldm sequence would only take 5 and<br>
+-     would make better use of sequential accesses if not hitting the<br>
+-     cache.<br>
+-<br>
+-     We cheat here and test &#39;arm_ld_sched&#39; which we currently know to<br>
+-     only be true for the ARM8, ARM9 and StrongARM.  If this ever<br>
+-     changes, then the test below needs to be reworked.  */<br>
+-  if (nops == 2 &amp;&amp; arm_ld_sched)<br>
++  if (TARGET_THUMB1<br>
++      &amp;&amp; !peep2_reg_dead_p (nops, base_reg_rtx))<br>
+     return 0;<br>
+<br>
+-  /* Can&#39;t do it without setting up the offset, only do this if it takes<br>
+-     no more than one insn.  */<br>
+-  return (const_ok_for_arm (unsorted_offsets[order[0]])<br>
+-        || const_ok_for_arm (-unsorted_offsets[order[0]])) ? 5 : 0;<br>
+-}<br>
+-<br>
+-const char *<br>
+-emit_ldm_seq (rtx *operands, int nops)<br>
+-{<br>
+-  int regs[4];<br>
+-  int base_reg;<br>
+-  HOST_WIDE_INT offset;<br>
+-  char buf[100];<br>
+-  int i;<br>
+-<br>
+-  switch (load_multiple_sequence (operands, nops, regs, &amp;base_reg, &amp;offset))<br>
+-    {<br>
+-    case 1:<br>
+-      strcpy (buf, &quot;ldm%(ia%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    case 2:<br>
+-      strcpy (buf, &quot;ldm%(ib%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    case 3:<br>
+-      strcpy (buf, &quot;ldm%(da%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    case 4:<br>
+-      strcpy (buf, &quot;ldm%(db%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    case 5:<br>
+-      if (offset &gt;= 0)<br>
+-      sprintf (buf, &quot;add%%?\t%s%s, %s%s, #%ld&quot;, REGISTER_PREFIX,<br>
+-               reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],<br>
+-               (long) offset);<br>
+-      else<br>
+-      sprintf (buf, &quot;sub%%?\t%s%s, %s%s, #%ld&quot;, REGISTER_PREFIX,<br>
+-               reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],<br>
+-               (long) -offset);<br>
+-      output_asm_insn (buf, operands);<br>
+-      base_reg = regs[0];<br>
+-      strcpy (buf, &quot;ldm%(ia%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    default:<br>
+-      gcc_unreachable ();<br>
+-    }<br>
+-<br>
+-  sprintf (buf + strlen (buf), &quot;%s%s, {%s%s&quot;, REGISTER_PREFIX,<br>
+-         reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);<br>
+-<br>
+-  for (i = 1; i &lt; nops; i++)<br>
+-    sprintf (buf + strlen (buf), &quot;, %s%s&quot;, REGISTER_PREFIX,<br>
+-           reg_names[regs[i]]);<br>
++  if (unsorted_offsets[order[0]] == 0)<br>
++    ldm_case = 1; /* ldmia */<br>
++  else if (TARGET_ARM &amp;&amp; unsorted_offsets[order[0]] == 4)<br>
++    ldm_case = 2; /* ldmib */<br>
++  else if (TARGET_ARM &amp;&amp; unsorted_offsets[order[nops - 1]] == 0)<br>
++    ldm_case = 3; /* ldmda */<br>
++  else if (TARGET_32BIT &amp;&amp; unsorted_offsets[order[nops - 1]] == -4)<br>
++    ldm_case = 4; /* ldmdb */<br>
++  else if (const_ok_for_arm (unsorted_offsets[order[0]])<br>
++         || const_ok_for_arm (-unsorted_offsets[order[0]]))<br>
++    ldm_case = 5;<br>
++  else<br>
++    return 0;<br>
+<br>
+-  strcat (buf, &quot;}\t%@ phole ldm&quot;);<br>
++  if (!multiple_operation_profitable_p (false, nops,<br>
++                                      ldm_case == 5<br>
++                                      ? unsorted_offsets[order[0]] : 0))<br>
++    return 0;<br>
+<br>
+-  output_asm_insn (buf, operands);<br>
+-  return &quot;&quot;;<br>
++  return ldm_case;<br>
+ }<br>
+<br>
+-int<br>
+-store_multiple_sequence (rtx *operands, int nops, int *regs, int *base,<br>
+-                       HOST_WIDE_INT * load_offset)<br>
+-{<br>
+-  int unsorted_regs[4];<br>
+-  HOST_WIDE_INT unsorted_offsets[4];<br>
+-  int order[4];<br>
++/* Used to determine in a peephole whether a sequence of store instructions can<br>
++   be changed into a store-multiple instruction.<br>
++   NOPS is the number of separate store instructions we are examining.<br>
++   NOPS_TOTAL is the total number of instructions recognized by the peephole<br>
++   pattern.<br>
++   The first NOPS entries in OPERANDS are the source registers, the next<br>
++   NOPS entries are memory operands.  If this function is successful, *BASE is<br>
++   set to the common base register of the memory accesses; *LOAD_OFFSET is set<br>
++   to the first memory location&#39;s offset from that base register.  REGS is an<br>
++   array filled in with the source register numbers, REG_RTXS (if nonnull) is<br>
++   likewise filled with the corresponding rtx&#39;s.<br>
++   SAVED_ORDER (if nonnull), is an array filled in with an order that maps insn<br>
++   numbers to to an ascending order of stores.<br>
++   If CHECK_REGS is true, the sequence of registers in *REGS matches the stores<br>
++   from ascending memory locations, and the function verifies that the register<br>
++   numbers are themselves ascending.  If CHECK_REGS is false, the register<br>
++   numbers are stored in the order they are found in the operands.  */<br>
++static int<br>
++store_multiple_sequence (rtx *operands, int nops, int nops_total,<br>
++                       int *regs, rtx *reg_rtxs, int *saved_order, int *base,<br>
++                       HOST_WIDE_INT *load_offset, bool check_regs)<br>
++{<br>
++  int unsorted_regs[MAX_LDM_STM_OPS];<br>
++  rtx unsorted_reg_rtxs[MAX_LDM_STM_OPS];<br>
++  HOST_WIDE_INT unsorted_offsets[MAX_LDM_STM_OPS];<br>
++  int order[MAX_LDM_STM_OPS];<br>
+   int base_reg = -1;<br>
+-  int i;<br>
++  rtx base_reg_rtx = NULL;<br>
++  int i, stm_case;<br>
+<br>
+   if (low_irq_latency)<br>
+     return 0;<br>
+<br>
+-  /* Can only handle 2, 3, or 4 insns at present, though could be easily<br>
+-     extended if required.  */<br>
+-  gcc_assert (nops &gt;= 2 &amp;&amp; nops &lt;= 4);<br>
++  /* Can only handle up to MAX_LDM_STM_OPS insns at present, though could be<br>
++     easily extended if required.  */<br>
++  gcc_assert (nops &gt;= 2 &amp;&amp; nops &lt;= MAX_LDM_STM_OPS);<br>
+<br>
+-  memset (order, 0, 4 * sizeof (int));<br>
++  memset (order, 0, MAX_LDM_STM_OPS * sizeof (int));<br>
+<br>
+   /* Loop over the operands and check that the memory references are<br>
+      suitable (i.e. immediate offsets from the same base register).  At<br>
+@@ -9964,32 +9992,32 @@ store_multiple_sequence (rtx *operands,<br>
+             &amp;&amp; (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))<br>
+                 == CONST_INT)))<br>
+       {<br>
++        unsorted_reg_rtxs[i] = (GET_CODE (operands[i]) == REG<br>
++                                ? operands[i] : SUBREG_REG (operands[i]));<br>
++        unsorted_regs[i] = REGNO (unsorted_reg_rtxs[i]);<br>
++<br>
+         if (i == 0)<br>
+           {<br>
+             base_reg = REGNO (reg);<br>
+-            unsorted_regs[0] = (GET_CODE (operands[i]) == REG<br>
+-                                ? REGNO (operands[i])<br>
+-                                : REGNO (SUBREG_REG (operands[i])));<br>
+-            order[0] = 0;<br>
+-          }<br>
+-        else<br>
+-          {<br>
+-            if (base_reg != (int) REGNO (reg))<br>
+-              /* Not addressed from the same base register.  */<br>
++            base_reg_rtx = reg;<br>
++            if (TARGET_THUMB1 &amp;&amp; base_reg &gt; LAST_LO_REGNUM)<br>
+               return 0;<br>
+-<br>
+-            unsorted_regs[i] = (GET_CODE (operands[i]) == REG<br>
+-                                ? REGNO (operands[i])<br>
+-                                : REGNO (SUBREG_REG (operands[i])));<br>
+-            if (unsorted_regs[i] &lt; unsorted_regs[order[0]])<br>
+-              order[0] = i;<br>
+           }<br>
++        else if (base_reg != (int) REGNO (reg))<br>
++          /* Not addressed from the same base register.  */<br>
++          return 0;<br>
+<br>
+         /* If it isn&#39;t an integer register, then we can&#39;t do this.  */<br>
+-        if (unsorted_regs[i] &lt; 0 || unsorted_regs[i] &gt; 14)<br>
++        if (unsorted_regs[i] &lt; 0<br>
++            || (TARGET_THUMB1 &amp;&amp; unsorted_regs[i] &gt; LAST_LO_REGNUM)<br>
++            || (TARGET_THUMB2 &amp;&amp; unsorted_regs[i] == base_reg)<br>
++            || (TARGET_THUMB2 &amp;&amp; unsorted_regs[i] == SP_REGNUM)<br>
++            || unsorted_regs[i] &gt; 14)<br>
+           return 0;<br>
+<br>
+         unsorted_offsets[i] = INTVAL (offset);<br>
++        if (i == 0 || unsorted_offsets[i] &lt; unsorted_offsets[order[0]])<br>
++          order[0] = i;<br>
+       }<br>
+       else<br>
+       /* Not a suitable memory address.  */<br>
+@@ -9998,111 +10026,65 @@ store_multiple_sequence (rtx *operands,<br>
+<br>
+   /* All the useful information has now been extracted from the<br>
+      operands into unsorted_regs and unsorted_offsets; additionally,<br>
+-     order[0] has been set to the lowest numbered register in the<br>
+-     list.  Sort the registers into order, and check that the memory<br>
+-     offsets are ascending and adjacent.  */<br>
+-<br>
+-  for (i = 1; i &lt; nops; i++)<br>
+-    {<br>
+-      int j;<br>
+-<br>
+-      order[i] = order[i - 1];<br>
+-      for (j = 0; j &lt; nops; j++)<br>
+-      if (unsorted_regs[j] &gt; unsorted_regs[order[i - 1]]<br>
+-          &amp;&amp; (order[i] == order[i - 1]<br>
+-              || unsorted_regs[j] &lt; unsorted_regs[order[i]]))<br>
+-        order[i] = j;<br>
+-<br>
+-      /* Have we found a suitable register? if not, one must be used more<br>
+-       than once.  */<br>
+-      if (order[i] == order[i - 1])<br>
+-      return 0;<br>
++     order[0] has been set to the lowest offset in the list.  Sort<br>
++     the offsets into order, verifying that they are adjacent, and<br>
++     check that the register numbers are ascending.  */<br>
++  if (!compute_offset_order (nops, unsorted_offsets, order,<br>
++                           check_regs ? unsorted_regs : NULL))<br>
++    return 0;<br>
+<br>
+-      /* Is the memory address adjacent and ascending? */<br>
+-      if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)<br>
+-      return 0;<br>
+-    }<br>
++  if (saved_order)<br>
++    memcpy (saved_order, order, sizeof order);<br>
+<br>
+   if (base)<br>
+     {<br>
+       *base = base_reg;<br>
+<br>
+       for (i = 0; i &lt; nops; i++)<br>
+-      regs[i] = unsorted_regs[order[i]];<br>
++      {<br>
++        regs[i] = unsorted_regs[check_regs ? order[i] : i];<br>
++        if (reg_rtxs)<br>
++          reg_rtxs[i] = unsorted_reg_rtxs[check_regs ? order[i] : i];<br>
++      }<br>
+<br>
+       *load_offset = unsorted_offsets[order[0]];<br>
+     }<br>
+<br>
+-  if (unsorted_offsets[order[0]] == 0)<br>
+-    return 1; /* stmia */<br>
+-<br>
+-  if (unsorted_offsets[order[0]] == 4)<br>
+-    return 2; /* stmib */<br>
+-<br>
+-  if (unsorted_offsets[order[nops - 1]] == 0)<br>
+-    return 3; /* stmda */<br>
+-<br>
+-  if (unsorted_offsets[order[nops - 1]] == -4)<br>
+-    return 4; /* stmdb */<br>
+-<br>
+-  return 0;<br>
+-}<br>
+-<br>
+-const char *<br>
+-emit_stm_seq (rtx *operands, int nops)<br>
+-{<br>
+-  int regs[4];<br>
+-  int base_reg;<br>
+-  HOST_WIDE_INT offset;<br>
+-  char buf[100];<br>
+-  int i;<br>
+-<br>
+-  switch (store_multiple_sequence (operands, nops, regs, &amp;base_reg, &amp;offset))<br>
+-    {<br>
+-    case 1:<br>
+-      strcpy (buf, &quot;stm%(ia%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    case 2:<br>
+-      strcpy (buf, &quot;stm%(ib%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    case 3:<br>
+-      strcpy (buf, &quot;stm%(da%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    case 4:<br>
+-      strcpy (buf, &quot;stm%(db%)\t&quot;);<br>
+-      break;<br>
+-<br>
+-    default:<br>
+-      gcc_unreachable ();<br>
+-    }<br>
+-<br>
+-  sprintf (buf + strlen (buf), &quot;%s%s, {%s%s&quot;, REGISTER_PREFIX,<br>
+-         reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);<br>
++  if (TARGET_THUMB1<br>
++      &amp;&amp; !peep2_reg_dead_p (nops_total, base_reg_rtx))<br>
++    return 0;<br>
+<br>
+-  for (i = 1; i &lt; nops; i++)<br>
+-    sprintf (buf + strlen (buf), &quot;, %s%s&quot;, REGISTER_PREFIX,<br>
+-           reg_names[regs[i]]);<br>
++  if (unsorted_offsets[order[0]] == 0)<br>
++    stm_case = 1; /* stmia */<br>
++  else if (TARGET_ARM &amp;&amp; unsorted_offsets[order[0]] == 4)<br>
++    stm_case = 2; /* stmib */<br>
++  else if (TARGET_ARM &amp;&amp; unsorted_offsets[order[nops - 1]] == 0)<br>
++    stm_case = 3; /* stmda */<br>
++  else if (TARGET_32BIT &amp;&amp; unsorted_offsets[order[nops - 1]] == -4)<br>
++    stm_case = 4; /* stmdb */<br>
++  else<br>
++    return 0;<br>
+<br>
+-  strcat (buf, &quot;}\t%@ phole stm&quot;);<br>
++  if (!multiple_operation_profitable_p (false, nops, 0))<br>
++    return 0;<br>
+<br>
+-  output_asm_insn (buf, operands);<br>
+-  return &quot;&quot;;<br>
++  return stm_case;<br>
+ }<br>
+<br>
+ /* Routines for use in generating RTL.  */<br>
+<br>
+-rtx<br>
+-arm_gen_load_multiple (int base_regno, int count, rtx from, int up,<br>
+-                     int write_back, rtx basemem, HOST_WIDE_INT *offsetp)<br>
++/* Generate a load-multiple instruction.  COUNT is the number of loads in<br>
++   the instruction; REGS and MEMS are arrays containing the operands.<br>
++   BASEREG is the base register to be used in addressing the memory operands.<br>
++   WBACK_OFFSET is nonzero if the instruction should update the base<br>
++   register.  */<br>
++<br>
++static rtx<br>
++arm_gen_load_multiple_1 (int count, int *regs, rtx *mems, rtx basereg,<br>
++                       HOST_WIDE_INT wback_offset)<br>
+ {<br>
+-  HOST_WIDE_INT offset = *offsetp;<br>
+   int i = 0, j;<br>
+   rtx result;<br>
+-  int sign = up ? 1 : -1;<br>
+-  rtx mem, addr;<br>
+<br>
+   /* XScale has load-store double instructions, but they have stricter<br>
+      alignment requirements than load-store multiple, so we cannot<br>
+@@ -10139,18 +10121,10 @@ arm_gen_load_multiple (int base_regno, i<br>
+       start_sequence ();<br>
+<br>
+       for (i = 0; i &lt; count; i++)<br>
+-      {<br>
+-        addr = plus_constant (from, i * 4 * sign);<br>
+-        mem = adjust_automodify_address (basemem, SImode, addr, offset);<br>
+-        emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);<br>
+-        offset += 4 * sign;<br>
+-      }<br>
++      emit_move_insn (gen_rtx_REG (SImode, regs[i]), mems[i]);<br>
+<br>
+-      if (write_back)<br>
+-      {<br>
+-        emit_move_insn (from, plus_constant (from, count * 4 * sign));<br>
+-        *offsetp = offset;<br>
+-      }<br>
++      if (wback_offset != 0)<br>
++      emit_move_insn (basereg, plus_constant (basereg, wback_offset));<br>
+<br>
+       seq = get_insns ();<br>
+       end_sequence ();<br>
+@@ -10159,41 +10133,40 @@ arm_gen_load_multiple (int base_regno, i<br>
+     }<br>
+<br>
+   result = gen_rtx_PARALLEL (VOIDmode,<br>
+-                           rtvec_alloc (count + (write_back ? 1 : 0)));<br>
+-  if (write_back)<br>
++                           rtvec_alloc (count + (wback_offset != 0 ? 1 : 0)));<br>
++  if (wback_offset != 0)<br>
+     {<br>
+       XVECEXP (result, 0, 0)<br>
+-      = gen_rtx_SET (VOIDmode, from, plus_constant (from, count * 4 * sign));<br>
++      = gen_rtx_SET (VOIDmode, basereg,<br>
++                     plus_constant (basereg, wback_offset));<br>
+       i = 1;<br>
+       count++;<br>
+     }<br>
+<br>
+   for (j = 0; i &lt; count; i++, j++)<br>
+-    {<br>
+-      addr = plus_constant (from, j * 4 * sign);<br>
+-      mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);<br>
+-      XVECEXP (result, 0, i)<br>
+-      = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);<br>
+-      offset += 4 * sign;<br>
+-    }<br>
+-<br>
+-  if (write_back)<br>
+-    *offsetp = offset;<br>
++    XVECEXP (result, 0, i)<br>
++      = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regs[j]), mems[j]);<br>
+<br>
+   return result;<br>
+ }<br>
+<br>
+-rtx<br>
+-arm_gen_store_multiple (int base_regno, int count, rtx to, int up,<br>
+-                      int write_back, rtx basemem, HOST_WIDE_INT *offsetp)<br>
++/* Generate a store-multiple instruction.  COUNT is the number of stores in<br>
++   the instruction; REGS and MEMS are arrays containing the operands.<br>
++   BASEREG is the base register to be used in addressing the memory operands.<br>
++   WBACK_OFFSET is nonzero if the instruction should update the base<br>
++   register.  */<br>
++<br>
++static rtx<br>
++arm_gen_store_multiple_1 (int count, int *regs, rtx *mems, rtx basereg,<br>
++                        HOST_WIDE_INT wback_offset)<br>
+ {<br>
+-  HOST_WIDE_INT offset = *offsetp;<br>
+   int i = 0, j;<br>
+   rtx result;<br>
+-  int sign = up ? 1 : -1;<br>
+-  rtx mem, addr;<br>
+<br>
+-  /* See arm_gen_load_multiple for discussion of<br>
++  if (GET_CODE (basereg) == PLUS)<br>
++    basereg = XEXP (basereg, 0);<br>
++<br>
++  /* See arm_gen_load_multiple_1 for discussion of<br>
+      the pros/cons of ldm/stm usage for XScale.  */<br>
+   if (low_irq_latency || (arm_tune_xscale &amp;&amp; count &lt;= 2 &amp;&amp; ! optimize_size))<br>
+     {<br>
+@@ -10202,18 +10175,10 @@ arm_gen_store_multiple (int base_regno,<br>
+       start_sequence ();<br>
+<br>
+       for (i = 0; i &lt; count; i++)<br>
+-      {<br>
+-        addr = plus_constant (to, i * 4 * sign);<br>
+-        mem = adjust_automodify_address (basemem, SImode, addr, offset);<br>
+-        emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));<br>
+-        offset += 4 * sign;<br>
+-      }<br>
++      emit_move_insn (mems[i], gen_rtx_REG (SImode, regs[i]));<br>
+<br>
+-      if (write_back)<br>
+-      {<br>
+-        emit_move_insn (to, plus_constant (to, count * 4 * sign));<br>
+-        *offsetp = offset;<br>
+-      }<br>
++      if (wback_offset != 0)<br>
++      emit_move_insn (basereg, plus_constant (basereg, wback_offset));<br>
+<br>
+       seq = get_insns ();<br>
+       end_sequence ();<br>
+@@ -10222,29 +10187,319 @@ arm_gen_store_multiple (int base_regno,<br>
+     }<br>
+<br>
+   result = gen_rtx_PARALLEL (VOIDmode,<br>
+-                           rtvec_alloc (count + (write_back ? 1 : 0)));<br>
+-  if (write_back)<br>
++                           rtvec_alloc (count + (wback_offset != 0 ? 1 : 0)));<br>
++  if (wback_offset != 0)<br>
+     {<br>
+       XVECEXP (result, 0, 0)<br>
+-      = gen_rtx_SET (VOIDmode, to,<br>
+-                     plus_constant (to, count * 4 * sign));<br>
++      = gen_rtx_SET (VOIDmode, basereg,<br>
++                     plus_constant (basereg, wback_offset));<br>
+       i = 1;<br>
+       count++;<br>
+     }<br>
+<br>
+   for (j = 0; i &lt; count; i++, j++)<br>
++    XVECEXP (result, 0, i)<br>
++      = gen_rtx_SET (VOIDmode, mems[j], gen_rtx_REG (SImode, regs[j]));<br>
++<br>
++  return result;<br>
++}<br>
++<br>
++/* Generate either a load-multiple or a store-multiple instruction.  This<br>
++   function can be used in situations where we can start with a single MEM<br>
++   rtx and adjust its address upwards.<br>
++   COUNT is the number of operations in the instruction, not counting a<br>
++   possible update of the base register.  REGS is an array containing the<br>
++   register operands.<br>
++   BASEREG is the base register to be used in addressing the memory operands,<br>
++   which are constructed from BASEMEM.<br>
++   WRITE_BACK specifies whether the generated instruction should include an<br>
++   update of the base register.<br>
++   OFFSETP is used to pass an offset to and from this function; this offset<br>
++   is not used when constructing the address (instead BASEMEM should have an<br>
++   appropriate offset in its address), it is used only for setting<br>
++   MEM_OFFSET.  It is updated only if WRITE_BACK is true.*/<br>
++<br>
++static rtx<br>
++arm_gen_multiple_op (bool is_load, int *regs, int count, rtx basereg,<br>
++                   bool write_back, rtx basemem, HOST_WIDE_INT *offsetp)<br>
++{<br>
++  rtx mems[MAX_LDM_STM_OPS];<br>
++  HOST_WIDE_INT offset = *offsetp;<br>
++  int i;<br>
++<br>
++  gcc_assert (count &lt;= MAX_LDM_STM_OPS);<br>
++<br>
++  if (GET_CODE (basereg) == PLUS)<br>
++    basereg = XEXP (basereg, 0);<br>
++<br>
++  for (i = 0; i &lt; count; i++)<br>
+     {<br>
+-      addr = plus_constant (to, j * 4 * sign);<br>
+-      mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);<br>
+-      XVECEXP (result, 0, i)<br>
+-      = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));<br>
+-      offset += 4 * sign;<br>
++      rtx addr = plus_constant (basereg, i * 4);<br>
++      mems[i] = adjust_automodify_address_nv (basemem, SImode, addr, offset);<br>
++      offset += 4;<br>
+     }<br>
+<br>
+   if (write_back)<br>
+     *offsetp = offset;<br>
+<br>
+-  return result;<br>
++  if (is_load)<br>
++    return arm_gen_load_multiple_1 (count, regs, mems, basereg,<br>
++                                  write_back ? 4 * count : 0);<br>
++  else<br>
++    return arm_gen_store_multiple_1 (count, regs, mems, basereg,<br>
++                                   write_back ? 4 * count : 0);<br>
++}<br>
++<br>
++rtx<br>
++arm_gen_load_multiple (int *regs, int count, rtx basereg, int write_back,<br>
++                     rtx basemem, HOST_WIDE_INT *offsetp)<br>
++{<br>
++  return arm_gen_multiple_op (TRUE, regs, count, basereg, write_back, basemem,<br>
++                            offsetp);<br>
++}<br>
++<br>
++rtx<br>
++arm_gen_store_multiple (int *regs, int count, rtx basereg, int write_back,<br>
++                      rtx basemem, HOST_WIDE_INT *offsetp)<br>
++{<br>
++  return arm_gen_multiple_op (FALSE, regs, count, basereg, write_back, basemem,<br>
++                            offsetp);<br>
++}<br>
++<br>
++/* Called from a peephole2 expander to turn a sequence of loads into an<br>
++   LDM instruction.  OPERANDS are the operands found by the peephole matcher;<br>
++   NOPS indicates how many separate loads we are trying to combine.  SORT_REGS<br>
++   is true if we can reorder the registers because they are used commutatively<br>
++   subsequently.<br>
++   Returns true iff we could generate a new instruction.  */<br>
++<br>
++bool<br>
++gen_ldm_seq (rtx *operands, int nops, bool sort_regs)<br>
++{<br>
++  int regs[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];<br>
++  rtx mems[MAX_LDM_STM_OPS];<br>
++  int i, j, base_reg;<br>
++  rtx base_reg_rtx;<br>
++  HOST_WIDE_INT offset;<br>
++  int write_back = FALSE;<br>
++  int ldm_case;<br>
++  rtx addr;<br>
++<br>
++  ldm_case = load_multiple_sequence (operands, nops, regs, mem_order,<br>
++                                   &amp;base_reg, &amp;offset, !sort_regs);<br>
++<br>
++  if (ldm_case == 0)<br>
++    return false;<br>
++<br>
++  if (sort_regs)<br>
++    for (i = 0; i &lt; nops - 1; i++)<br>
++      for (j = i + 1; j &lt; nops; j++)<br>
++      if (regs[i] &gt; regs[j])<br>
++        {<br>
++          int t = regs[i];<br>
++          regs[i] = regs[j];<br>
++          regs[j] = t;<br>
++        }<br>
++  base_reg_rtx = gen_rtx_REG (Pmode, base_reg);<br>
++<br>
++  if (TARGET_THUMB1)<br>
++    {<br>
++      gcc_assert (peep2_reg_dead_p (nops, base_reg_rtx));<br>
++      gcc_assert (ldm_case == 1 || ldm_case == 5);<br>
++      write_back = TRUE;<br>
++    }<br>
++<br>
++  if (ldm_case == 5)<br>
++    {<br>
++      rtx newbase = TARGET_THUMB1 ? base_reg_rtx : gen_rtx_REG (SImode, regs[0]);<br>
++      emit_insn (gen_addsi3 (newbase, base_reg_rtx, GEN_INT (offset)));<br>
++      offset = 0;<br>
++      if (!TARGET_THUMB1)<br>
++      {<br>
++        base_reg = regs[0];<br>
++        base_reg_rtx = newbase;<br>
++      }<br>
++    }<br>
++<br>
++  for (i = 0; i &lt; nops; i++)<br>
++    {<br>
++      addr = plus_constant (base_reg_rtx, offset + i * 4);<br>
++      mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],<br>
++                                            SImode, addr, 0);<br>
++    }<br>
++  emit_insn (arm_gen_load_multiple_1 (nops, regs, mems, base_reg_rtx,<br>
++                                    write_back ? offset + i * 4 : 0));<br>
++  return true;<br>
++}<br>
++<br>
++/* Called from a peephole2 expander to turn a sequence of stores into an<br>
++   STM instruction.  OPERANDS are the operands found by the peephole matcher;<br>
++   NOPS indicates how many separate stores we are trying to combine.<br>
++   Returns true iff we could generate a new instruction.  */<br>
++<br>
++bool<br>
++gen_stm_seq (rtx *operands, int nops)<br>
++{<br>
++  int i;<br>
++  int regs[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];<br>
++  rtx mems[MAX_LDM_STM_OPS];<br>
++  int base_reg;<br>
++  rtx base_reg_rtx;<br>
++  HOST_WIDE_INT offset;<br>
++  int write_back = FALSE;<br>
++  int stm_case;<br>
++  rtx addr;<br>
++  bool base_reg_dies;<br>
++<br>
++  stm_case = store_multiple_sequence (operands, nops, nops, regs, NULL,<br>
++                                    mem_order, &amp;base_reg, &amp;offset, true);<br>
++<br>
++  if (stm_case == 0)<br>
++    return false;<br>
++<br>
++  base_reg_rtx = gen_rtx_REG (Pmode, base_reg);<br>
++<br>
++  base_reg_dies = peep2_reg_dead_p (nops, base_reg_rtx);<br>
++  if (TARGET_THUMB1)<br>
++    {<br>
++      gcc_assert (base_reg_dies);<br>
++      write_back = TRUE;<br>
++    }<br>
++<br>
++  if (stm_case == 5)<br>
++    {<br>
++      gcc_assert (base_reg_dies);<br>
++      emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, GEN_INT (offset)));<br>
++      offset = 0;<br>
++    }<br>
++<br>
++  addr = plus_constant (base_reg_rtx, offset);<br>
++<br>
++  for (i = 0; i &lt; nops; i++)<br>
++    {<br>
++      addr = plus_constant (base_reg_rtx, offset + i * 4);<br>
++      mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],<br>
++                                            SImode, addr, 0);<br>
++    }<br>
++  emit_insn (arm_gen_store_multiple_1 (nops, regs, mems, base_reg_rtx,<br>
++                                     write_back ? offset + i * 4 : 0));<br>
++  return true;<br>
++}<br>
++<br>
++/* Called from a peephole2 expander to turn a sequence of stores that are<br>
++   preceded by constant loads into an STM instruction.  OPERANDS are the<br>
++   operands found by the peephole matcher; NOPS indicates how many<br>
++   separate stores we are trying to combine; there are 2 * NOPS<br>
++   instructions in the peephole.<br>
++   Returns true iff we could generate a new instruction.  */<br>
++<br>
++bool<br>
++gen_const_stm_seq (rtx *operands, int nops)<br>
++{<br>
++  int regs[MAX_LDM_STM_OPS], sorted_regs[MAX_LDM_STM_OPS];<br>
++  int reg_order[MAX_LDM_STM_OPS], mem_order[MAX_LDM_STM_OPS];<br>
++  rtx reg_rtxs[MAX_LDM_STM_OPS], orig_reg_rtxs[MAX_LDM_STM_OPS];<br>
++  rtx mems[MAX_LDM_STM_OPS];<br>
++  int base_reg;<br>
++  rtx base_reg_rtx;<br>
++  HOST_WIDE_INT offset;<br>
++  int write_back = FALSE;<br>
++  int stm_case;<br>
++  rtx addr;<br>
++  bool base_reg_dies;<br>
++  int i, j;<br>
++  HARD_REG_SET allocated;<br>
++<br>
++  stm_case = store_multiple_sequence (operands, nops, 2 * nops, regs, reg_rtxs,<br>
++                                    mem_order, &amp;base_reg, &amp;offset, false);<br>
++<br>
++  if (stm_case == 0)<br>
++    return false;<br>
++<br>
++  memcpy (orig_reg_rtxs, reg_rtxs, sizeof orig_reg_rtxs);<br>
++<br>
++  /* If the same register is used more than once, try to find a free<br>
++     register.  */<br>
++  CLEAR_HARD_REG_SET (allocated);<br>
++  for (i = 0; i &lt; nops; i++)<br>
++    {<br>
++      for (j = i + 1; j &lt; nops; j++)<br>
++      if (regs[i] == regs[j])<br>
++        {<br>
++          rtx t = peep2_find_free_register (0, nops * 2,<br>
++                                            TARGET_THUMB1 ? &quot;l&quot; : &quot;r&quot;,<br>
++                                            SImode, &amp;allocated);<br>
++          if (t == NULL_RTX)<br>
++            return false;<br>
++          reg_rtxs[i] = t;<br>
++          regs[i] = REGNO (t);<br>
++        }<br>
++    }<br>
++<br>
++  /* Compute an ordering that maps the register numbers to an ascending<br>
++     sequence.  */<br>
++  reg_order[0] = 0;<br>
++  for (i = 0; i &lt; nops; i++)<br>
++    if (regs[i] &lt; regs[reg_order[0]])<br>
++      reg_order[0] = i;<br>
++<br>
++  for (i = 1; i &lt; nops; i++)<br>
++    {<br>
++      int this_order = reg_order[i - 1];<br>
++      for (j = 0; j &lt; nops; j++)<br>
++      if (regs[j] &gt; regs[reg_order[i - 1]]<br>
++          &amp;&amp; (this_order == reg_order[i - 1]<br>
++              || regs[j] &lt; regs[this_order]))<br>
++        this_order = j;<br>
++      reg_order[i] = this_order;<br>
++    }<br>
++<br>
++  /* Ensure that registers that must be live after the instruction end<br>
++     up with the correct value.  */<br>
++  for (i = 0; i &lt; nops; i++)<br>
++    {<br>
++      int this_order = reg_order[i];<br>
++      if ((this_order != mem_order[i]<br>
++         || orig_reg_rtxs[this_order] != reg_rtxs[this_order])<br>
++        &amp;&amp; !peep2_reg_dead_p (nops * 2, orig_reg_rtxs[this_order]))<br>
++      return false;<br>
++    }<br>
++<br>
++  /* Load the constants.  */<br>
++  for (i = 0; i &lt; nops; i++)<br>
++    {<br>
++      rtx op = operands[2 * nops + mem_order[i]];<br>
++      sorted_regs[i] = regs[reg_order[i]];<br>
++      emit_move_insn (reg_rtxs[reg_order[i]], op);<br>
++    }<br>
++<br>
++  base_reg_rtx = gen_rtx_REG (Pmode, base_reg);<br>
++<br>
++  base_reg_dies = peep2_reg_dead_p (nops * 2, base_reg_rtx);<br>
++  if (TARGET_THUMB1)<br>
++    {<br>
++      gcc_assert (base_reg_dies);<br>
++      write_back = TRUE;<br>
++    }<br>
++<br>
++  if (stm_case == 5)<br>
++    {<br>
++      gcc_assert (base_reg_dies);<br>
++      emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, GEN_INT (offset)));<br>
++      offset = 0;<br>
++    }<br>
++<br>
++  addr = plus_constant (base_reg_rtx, offset);<br>
++<br>
++  for (i = 0; i &lt; nops; i++)<br>
++    {<br>
++      addr = plus_constant (base_reg_rtx, offset + i * 4);<br>
++      mems[i] = adjust_automodify_address_nv (operands[nops + mem_order[i]],<br>
++                                            SImode, addr, 0);<br>
++    }<br>
++  emit_insn (arm_gen_store_multiple_1 (nops, sorted_regs, mems, base_reg_rtx,<br>
++                                     write_back ? offset + i * 4 : 0));<br>
++  return true;<br>
+ }<br>
+<br>
+ int<br>
+@@ -10280,20 +10535,21 @@ arm_gen_movmemqi (rtx *operands)<br>
+   for (i = 0; in_words_to_go &gt;= 2; i+=4)<br>
+     {<br>
+       if (in_words_to_go &gt; 4)<br>
+-      emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,<br>
+-                                        srcbase, &amp;srcoffset));<br>
++      emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, src,<br>
++                                        TRUE, srcbase, &amp;srcoffset));<br>
+       else<br>
+-      emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE,<br>
+-                                        FALSE, srcbase, &amp;srcoffset));<br>
++      emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, in_words_to_go,<br>
++                                        src, FALSE, srcbase,<br>
++                                        &amp;srcoffset));<br>
+<br>
+       if (out_words_to_go)<br>
+       {<br>
+         if (out_words_to_go &gt; 4)<br>
+-          emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,<br>
+-                                             dstbase, &amp;dstoffset));<br>
++          emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, dst,<br>
++                                             TRUE, dstbase, &amp;dstoffset));<br>
+         else if (out_words_to_go != 1)<br>
+-          emit_insn (arm_gen_store_multiple (0, out_words_to_go,<br>
+-                                             dst, TRUE,<br>
++          emit_insn (arm_gen_store_multiple (arm_regs_in_sequence,<br>
++                                             out_words_to_go, dst,<br>
+                                              (last_bytes == 0<br>
+                                               ? FALSE : TRUE),<br>
+                                              dstbase, &amp;dstoffset));<br>
+Index: gcc-4_5-branch/gcc/config/arm/arm.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/arm.h<br>
++++ gcc-4_5-branch/gcc/config/arm/arm.h<br>
+@@ -1143,6 +1143,9 @@ extern int arm_structure_size_boundary;<br>
+   ((MODE) == TImode || (MODE) == EImode || (MODE) == OImode \<br>
+    || (MODE) == CImode || (MODE) == XImode)<br>
+<br>
++/* The register numbers in sequence, for passing to arm_gen_load_multiple.  */<br>
++extern int arm_regs_in_sequence[];<br>
++<br>
+ /* The order in which register should be allocated.  It is good to use ip<br>
+    since no saving is required (though calls clobber it) and it never contains<br>
+    function parameters.  It is quite good to use lr since other calls may<br>
+@@ -2823,4 +2826,8 @@ enum arm_builtins<br>
+ #define NEED_INDICATE_EXEC_STACK      0<br>
+ #endif<br>
+<br>
++/* The maximum number of parallel loads or stores we support in an ldm/stm<br>
++   instruction.  */<br>
++#define MAX_LDM_STM_OPS 4<br>
++<br>
+ #endif /* ! GCC_ARM_H */<br>
+Index: gcc-4_5-branch/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a><br>
++++ gcc-4_5-branch/gcc/config/arm/<a href="http://arm.md" target="_blank">arm.md</a><br>
+@@ -6282,7 +6282,7 @@<br>
+<br>
+ ;; load- and store-multiple insns<br>
+ ;; The arm can load/store any set of registers, provided that they are in<br>
+-;; ascending order; but that is beyond GCC so stick with what it knows.<br>
++;; ascending order, but these expanders assume a contiguous set.<br>
+<br>
+ (define_expand &quot;load_multiple&quot;<br>
+   [(match_par_dup 3 [(set (match_operand:SI 0 &quot;&quot; &quot;&quot;)<br>
+@@ -6303,126 +6303,12 @@<br>
+     FAIL;<br>
+<br>
+   operands[3]<br>
+-    = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),<br>
++    = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),<br>
++                           INTVAL (operands[2]),<br>
+                            force_reg (SImode, XEXP (operands[1], 0)),<br>
+-                           TRUE, FALSE, operands[1], &amp;offset);<br>
++                           FALSE, operands[1], &amp;offset);<br>
+ })<br>
+<br>
+-;; Load multiple with write-back<br>
+-<br>
+-(define_insn &quot;*ldmsi_postinc4&quot;<br>
+-  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
+-        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
+-                 (const_int 16)))<br>
+-     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (match_dup 2)))<br>
+-     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 4))))<br>
+-     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 8))))<br>
+-     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
+-  &quot;ldm%(ia%)\\t%1!, {%3, %4, %5, %6}&quot;<br>
+-  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
+-   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*ldmsi_postinc4_thumb1&quot;<br>
+-  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
+-        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
+-                 (const_int 16)))<br>
+-     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (match_dup 2)))<br>
+-     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 4))))<br>
+-     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 8))))<br>
+-     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 12))))])]<br>
+-  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
+-  &quot;ldmia\\t%1!, {%3, %4, %5, %6}&quot;<br>
+-  [(set_attr &quot;type&quot; &quot;load4&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*ldmsi_postinc3&quot;<br>
+-  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
+-        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
+-                 (const_int 12)))<br>
+-     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (match_dup 2)))<br>
+-     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 4))))<br>
+-     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 8))))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
+-  &quot;ldm%(ia%)\\t%1!, {%3, %4, %5}&quot;<br>
+-  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
+-   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*ldmsi_postinc2&quot;<br>
+-  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
+-        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
+-                 (const_int 8)))<br>
+-     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (match_dup 2)))<br>
+-     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 2) (const_int 4))))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
+-  &quot;ldm%(ia%)\\t%1!, {%3, %4}&quot;<br>
+-  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
+-   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
+-)<br>
+-<br>
+-;; Ordinary load multiple<br>
+-<br>
+-(define_insn &quot;*ldmsi4&quot;<br>
+-  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;)))<br>
+-     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 1) (const_int 4))))<br>
+-     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 1) (const_int 8))))<br>
+-     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
+-  &quot;ldm%(ia%)\\t%1, {%2, %3, %4, %5}&quot;<br>
+-  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
+-   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*ldmsi3&quot;<br>
+-  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;)))<br>
+-     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 1) (const_int 4))))<br>
+-     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
+-  &quot;ldm%(ia%)\\t%1, {%2, %3, %4}&quot;<br>
+-  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
+-   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*ldmsi2&quot;<br>
+-  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;)))<br>
+-     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
+-        (mem:SI (plus:SI (match_dup 1) (const_int 4))))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
+-  &quot;ldm%(ia%)\\t%1, {%2, %3}&quot;<br>
+-  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
+-   (set_attr &quot;predicable&quot; &quot;yes&quot;)]<br>
+-)<br>
+-<br>
+ (define_expand &quot;store_multiple&quot;<br>
+   [(match_par_dup 3 [(set (match_operand:SI 0 &quot;&quot; &quot;&quot;)<br>
+                           (match_operand:SI 1 &quot;&quot; &quot;&quot;))<br>
+@@ -6442,125 +6328,12 @@<br>
+     FAIL;<br>
+<br>
+   operands[3]<br>
+-    = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),<br>
++    = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),<br>
++                            INTVAL (operands[2]),<br>
+                             force_reg (SImode, XEXP (operands[0], 0)),<br>
+-                            TRUE, FALSE, operands[0], &amp;offset);<br>
++                            FALSE, operands[0], &amp;offset);<br>
+ })<br>
+<br>
+-;; Store multiple with write-back<br>
+-<br>
+-(define_insn &quot;*stmsi_postinc4&quot;<br>
+-  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
+-        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
+-                 (const_int 16)))<br>
+-     (set (mem:SI (match_dup 2))<br>
+-        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
+-        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
+-        (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
+-        (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
+-  &quot;stm%(ia%)\\t%1!, {%3, %4, %5, %6}&quot;<br>
+-  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
+-   (set_attr &quot;type&quot; &quot;store4&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*stmsi_postinc4_thumb1&quot;<br>
+-  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
+-        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
+-                 (const_int 16)))<br>
+-     (set (mem:SI (match_dup 2))<br>
+-        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
+-        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
+-        (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
+-        (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
+-  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
+-  &quot;stmia\\t%1!, {%3, %4, %5, %6}&quot;<br>
+-  [(set_attr &quot;type&quot; &quot;store4&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*stmsi_postinc3&quot;<br>
+-  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
+-        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
+-                 (const_int 12)))<br>
+-     (set (mem:SI (match_dup 2))<br>
+-        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
+-        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
+-        (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
+-  &quot;stm%(ia%)\\t%1!, {%3, %4, %5}&quot;<br>
+-  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
+-   (set_attr &quot;type&quot; &quot;store3&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*stmsi_postinc2&quot;<br>
+-  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
+-    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=r&quot;)<br>
+-        (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;)<br>
+-                 (const_int 8)))<br>
+-     (set (mem:SI (match_dup 2))<br>
+-        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
+-        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
+-  &quot;stm%(ia%)\\t%1!, {%3, %4}&quot;<br>
+-  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
+-   (set_attr &quot;type&quot; &quot;store2&quot;)]<br>
+-)<br>
+-<br>
+-;; Ordinary store multiple<br>
+-<br>
+-(define_insn &quot;*stmsi4&quot;<br>
+-  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
+-    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;))<br>
+-        (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
+-        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
+-        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))<br>
+-        (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
+-  &quot;stm%(ia%)\\t%1, {%2, %3, %4, %5}&quot;<br>
+-  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
+-   (set_attr &quot;type&quot; &quot;store4&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*stmsi3&quot;<br>
+-  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
+-    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;))<br>
+-        (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
+-        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
+-        (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
+-  &quot;stm%(ia%)\\t%1, {%2, %3, %4}&quot;<br>
+-  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
+-   (set_attr &quot;type&quot; &quot;store3&quot;)]<br>
+-)<br>
+-<br>
+-(define_insn &quot;*stmsi2&quot;<br>
+-  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
+-    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;r&quot;))<br>
+-        (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
+-     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
+-        (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
+-  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
+-  &quot;stm%(ia%)\\t%1, {%2, %3}&quot;<br>
+-  [(set_attr &quot;predicable&quot; &quot;yes&quot;)<br>
+-   (set_attr &quot;type&quot; &quot;store2&quot;)]<br>
+-)<br>
+<br>
+ ;; Move a block of memory if it is word aligned and MORE than 2 words long.<br>
+ ;; We could let this apply for blocks of less than this, but it clobbers so<br>
+@@ -9031,8 +8804,8 @@<br>
+       if (REGNO (reg) == R0_REGNUM)<br>
+         {<br>
+           /* On thumb we have to use a write-back instruction.  */<br>
+-          emit_insn (arm_gen_store_multiple (R0_REGNUM, 4, addr, TRUE,<br>
+-                      TARGET_THUMB ? TRUE : FALSE, mem, &amp;offset));<br>
++          emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,<br>
++                     TARGET_THUMB ? TRUE : FALSE, mem, &amp;offset));<br>
+           size = TARGET_ARM ? 16 : 0;<br>
+         }<br>
+       else<br>
+@@ -9078,8 +8851,8 @@<br>
+       if (REGNO (reg) == R0_REGNUM)<br>
+         {<br>
+           /* On thumb we have to use a write-back instruction.  */<br>
+-          emit_insn (arm_gen_load_multiple (R0_REGNUM, 4, addr, TRUE,<br>
+-                      TARGET_THUMB ? TRUE : FALSE, mem, &amp;offset));<br>
++          emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,<br>
++                     TARGET_THUMB ? TRUE : FALSE, mem, &amp;offset));<br>
+           size = TARGET_ARM ? 16 : 0;<br>
+         }<br>
+       else<br>
+@@ -10672,87 +10445,6 @@<br>
+   &quot;&quot;<br>
+ )<br>
+<br>
+-; Peepholes to spot possible load- and store-multiples, if the ordering is<br>
+-; reversed, check that the memory references aren&#39;t volatile.<br>
+-<br>
+-(define_peephole<br>
+-  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 4 &quot;memory_operand&quot; &quot;m&quot;))<br>
+-   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 5 &quot;memory_operand&quot; &quot;m&quot;))<br>
+-   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 6 &quot;memory_operand&quot; &quot;m&quot;))<br>
+-   (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 7 &quot;memory_operand&quot; &quot;m&quot;))]<br>
+-  &quot;TARGET_ARM &amp;&amp; load_multiple_sequence (operands, 4, NULL, NULL, NULL)&quot;<br>
+-  &quot;*<br>
+-  return emit_ldm_seq (operands, 4);<br>
+-  &quot;<br>
+-)<br>
+-<br>
+-(define_peephole<br>
+-  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 3 &quot;memory_operand&quot; &quot;m&quot;))<br>
+-   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 4 &quot;memory_operand&quot; &quot;m&quot;))<br>
+-   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 5 &quot;memory_operand&quot; &quot;m&quot;))]<br>
+-  &quot;TARGET_ARM &amp;&amp; load_multiple_sequence (operands, 3, NULL, NULL, NULL)&quot;<br>
+-  &quot;*<br>
+-  return emit_ldm_seq (operands, 3);<br>
+-  &quot;<br>
+-)<br>
+-<br>
+-(define_peephole<br>
+-  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 2 &quot;memory_operand&quot; &quot;m&quot;))<br>
+-   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
+-        (match_operand:SI 3 &quot;memory_operand&quot; &quot;m&quot;))]<br>
+-  &quot;TARGET_ARM &amp;&amp; load_multiple_sequence (operands, 2, NULL, NULL, NULL)&quot;<br>
+-  &quot;*<br>
+-  return emit_ldm_seq (operands, 2);<br>
+-  &quot;<br>
+-)<br>
+-<br>
+-(define_peephole<br>
+-  [(set (match_operand:SI 4 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
+-   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
+-   (set (match_operand:SI 6 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 2 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
+-   (set (match_operand:SI 7 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 3 &quot;s_register_operand&quot; &quot;rk&quot;))]<br>
+-  &quot;TARGET_ARM &amp;&amp; store_multiple_sequence (operands, 4, NULL, NULL, NULL)&quot;<br>
+-  &quot;*<br>
+-  return emit_stm_seq (operands, 4);<br>
+-  &quot;<br>
+-)<br>
+-<br>
+-(define_peephole<br>
+-  [(set (match_operand:SI 3 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
+-   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
+-   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 2 &quot;s_register_operand&quot; &quot;rk&quot;))]<br>
+-  &quot;TARGET_ARM &amp;&amp; store_multiple_sequence (operands, 3, NULL, NULL, NULL)&quot;<br>
+-  &quot;*<br>
+-  return emit_stm_seq (operands, 3);<br>
+-  &quot;<br>
+-)<br>
+-<br>
+-(define_peephole<br>
+-  [(set (match_operand:SI 2 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
+-   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;=m&quot;)<br>
+-        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))]<br>
+-  &quot;TARGET_ARM &amp;&amp; store_multiple_sequence (operands, 2, NULL, NULL, NULL)&quot;<br>
+-  &quot;*<br>
+-  return emit_stm_seq (operands, 2);<br>
+-  &quot;<br>
+-)<br>
+-<br>
+ (define_split<br>
+   [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
+       (and:SI (ge:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
+@@ -11554,6 +11246,8 @@<br>
+   &quot;<br>
+ )<br>
+<br>
++;; Load the load/store multiple patterns<br>
++(include &quot;<a href="http://ldmstm.md" target="_blank">ldmstm.md</a>&quot;)<br>
+ ;; Load the FPA co-processor patterns<br>
+ (include &quot;<a href="http://fpa.md" target="_blank">fpa.md</a>&quot;)<br>
+ ;; Load the Maverick co-processor patterns<br>
+Index: gcc-4_5-branch/gcc/config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a><br>
+===================================================================<br>
+--- /dev/null<br>
++++ gcc-4_5-branch/gcc/config/arm/<a href="http://ldmstm.md" target="_blank">ldmstm.md</a><br>
+@@ -0,0 +1,1191 @@<br>
++/* ARM ldm/stm instruction patterns.  This file was automatically generated<br>
++   using <a href="http://arm-ldmstm.ml" target="_blank">arm-ldmstm.ml</a>.  Please do not edit manually.<br>
++<br>
++   Copyright (C) 2010 Free Software Foundation, Inc.<br>
++   Contributed by CodeSourcery.<br>
++<br>
++   This file is part of GCC.<br>
++<br>
++   GCC is free software; you can redistribute it and/or modify it<br>
++   under the terms of the GNU General Public License as published<br>
++   by the Free Software Foundation; either version 3, or (at your<br>
++   option) any later version.<br>
++<br>
++   GCC is distributed in the hope that it will be useful, but WITHOUT<br>
++   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY<br>
++   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public<br>
++   License for more details.<br>
++<br>
++   You should have received a copy of the GNU General Public License and<br>
++   a copy of the GCC Runtime Library Exception along with this program;<br>
++   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see<br>
++   &lt;<a href="http://www.gnu.org/licenses/" target="_blank">http://www.gnu.org/licenses/</a>&gt;.  */<br>
++<br>
++(define_insn &quot;*ldm4_ia&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 8))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 12))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(ia%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_ldm4_ia&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;l&quot;)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 8))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 12))))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(ia%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)])<br>
++<br>
++(define_insn &quot;*ldm4_ia_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 8))))<br>
++     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 12))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;ldm%(ia%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_ldm4_ia_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 8))))<br>
++     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 12))))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;ldm%(ia%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)])<br>
++<br>
++(define_insn &quot;*stm4_ia&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(ia%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm4_ia_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
++          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;stm%(ia%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_stm4_ia_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
++          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;stm%(ia%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)])<br>
++<br>
++(define_insn &quot;*ldm4_ib&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 8))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 12))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 16))))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(ib%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm4_ib_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 8))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 12))))<br>
++     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 16))))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;ldm%(ib%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm4_ib&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int 4)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(ib%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm4_ib_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 16)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 16)))<br>
++          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;stm%(ib%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm4_da&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int -12))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -4))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 1)))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(da%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm4_da_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -16)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -12))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -4))))<br>
++     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;ldm%(da%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm4_da&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -12)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -8)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (match_dup 1))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(da%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm4_da_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -16)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -12)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;stm%(da%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm4_db&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int -16))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -12))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -4))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(db%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm4_db_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -16)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -16))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -12))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -4))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;ldm%(db%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm4_db&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -16)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -12)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -8)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(db%)\t%1, {%2, %3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm4_db_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -16)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -16)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -12)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
++          (match_operand:SI 6 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 5&quot;<br>
++  &quot;stm%(db%)\t%1!, {%3, %4, %5, %6}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store4&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_ldm_seq (operands, 4, false))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (parallel<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++          (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;))<br>
++     (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
++          (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;))<br>
++     (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;)<br>
++          (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;))])]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_ldm_seq (operands, 4, false))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 8 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 0))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 9 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 1))<br>
++   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 10 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 2))<br>
++   (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 11 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 3))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_const_stm_seq (operands, 4))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 8 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 9 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 10 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 11 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 0))<br>
++   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 1))<br>
++   (set (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 2))<br>
++   (set (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 3))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_const_stm_seq (operands, 4))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 6 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 7 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 3 &quot;s_register_operand&quot; &quot;&quot;))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_stm_seq (operands, 4))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_insn &quot;*ldm3_ia&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 8))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(ia%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_ldm3_ia&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;l&quot;)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 8))))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(ia%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)])<br>
++<br>
++(define_insn &quot;*ldm3_ia_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 8))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(ia%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_ldm3_ia_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 8))))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(ia%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)])<br>
++<br>
++(define_insn &quot;*stm3_ia&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(ia%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm3_ia_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(ia%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_stm3_ia_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(ia%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)])<br>
++<br>
++(define_insn &quot;*ldm3_ib&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 8))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 12))))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(ib%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm3_ib_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 8))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 12))))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(ib%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm3_ib&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int 4)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(ib%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm3_ib_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 12)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 12)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(ib%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm3_da&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 1)))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(da%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm3_da_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -12)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -4))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(da%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm3_da&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -8)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (match_dup 1))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(da%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm3_da_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -12)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(da%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm3_db&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int -12))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -4))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(db%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm3_db_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -12)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -12))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -4))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;ldm%(db%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm3_db&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -12)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -8)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(db%)\t%1, {%2, %3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm3_db_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -12)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -12)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
++          (match_operand:SI 5 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 4&quot;<br>
++  &quot;stm%(db%)\t%1!, {%3, %4, %5}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store3&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_ldm_seq (operands, 3, false))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (parallel<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++          (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;))<br>
++     (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
++          (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;))])]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_ldm_seq (operands, 3, false))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 6 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 0))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 7 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 1))<br>
++   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 8 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 2))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_const_stm_seq (operands, 3))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 6 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 7 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 8 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 0))<br>
++   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 1))<br>
++   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 2))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_const_stm_seq (operands, 3))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 4 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 5 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 2 &quot;s_register_operand&quot; &quot;&quot;))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_stm_seq (operands, 3))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_insn &quot;*ldm2_ia&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 4))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;ldm%(ia%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_ldm2_ia&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;l&quot;)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 4))))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;ldm%(ia%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)])<br>
++<br>
++(define_insn &quot;*ldm2_ia_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(ia%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_ldm2_ia_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(ia%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)])<br>
++<br>
++(define_insn &quot;*stm2_ia&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;stm%(ia%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm2_ia_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(ia%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*thumb_stm2_ia_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=l&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_THUMB1 &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(ia%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)])<br>
++<br>
++(define_insn &quot;*ldm2_ib&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int 8))))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;ldm%(ib%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm2_ib_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int 8))))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(ib%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm2_ib&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int 4)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;stm%(ib%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm2_ib_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int 8)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(ib%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm2_da&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int -4))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 1)))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;ldm%(da%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm2_da_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -8)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -4))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (match_dup 2)))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(da%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm2_da&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -4)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (match_dup 1))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;stm%(da%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm2_da_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -8)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (match_dup 2))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_ARM &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(da%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm2_db&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 1)<br>
++                  (const_int -4))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;ldm%(db%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*ldm2_db_update&quot;<br>
++  [(match_parallel 0 &quot;load_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -8)))<br>
++     (set (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -8))))<br>
++     (set (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;)<br>
++          (mem:SI (plus:SI (match_dup 2)<br>
++                  (const_int -4))))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;ldm%(db%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;load2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm2_db&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (mem:SI (plus:SI (match_operand:SI 1 &quot;s_register_operand&quot; &quot;rk&quot;) (const_int -8)))<br>
++          (match_operand:SI 2 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 1) (const_int -4)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 2&quot;<br>
++  &quot;stm%(db%)\t%1, {%2, %3}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_insn &quot;*stm2_db_update&quot;<br>
++  [(match_parallel 0 &quot;store_multiple_operation&quot;<br>
++    [(set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;=rk&quot;)<br>
++          (plus:SI (match_operand:SI 2 &quot;s_register_operand&quot; &quot;1&quot;) (const_int -8)))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -8)))<br>
++          (match_operand:SI 3 &quot;arm_hard_register_operand&quot; &quot;&quot;))<br>
++     (set (mem:SI (plus:SI (match_dup 2) (const_int -4)))<br>
++          (match_operand:SI 4 &quot;arm_hard_register_operand&quot; &quot;&quot;))])]<br>
++  &quot;TARGET_32BIT &amp;&amp; XVECLEN (operands[0], 0) == 3&quot;<br>
++  &quot;stm%(db%)\t%1!, {%3, %4}&quot;<br>
++  [(set_attr &quot;type&quot; &quot;store2&quot;)<br>
++   (set_attr &quot;predicable&quot; &quot;yes&quot;)])<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_ldm_seq (operands, 2, false))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 4 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 0))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 5 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 1))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_const_stm_seq (operands, 2))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 4 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 5 &quot;const_int_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 0))<br>
++   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_dup 1))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_const_stm_seq (operands, 2))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;))]<br>
++  &quot;&quot;<br>
++  [(const_int 0)]<br>
++{<br>
++  if (gen_stm_seq (operands, 2))<br>
++    DONE;<br>
++  else<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (parallel<br>
++     [(set (match_operand:SI 4 &quot;s_register_operand&quot; &quot;&quot;)<br>
++           (match_operator:SI 5 &quot;commutative_binary_operator&quot;<br>
++            [(match_operand:SI 6 &quot;s_register_operand&quot; &quot;&quot;)<br>
++             (match_operand:SI 7 &quot;s_register_operand&quot; &quot;&quot;)]))<br>
++      (clobber (reg:CC CC_REGNUM))])]<br>
++  &quot;(((operands[6] == operands[0] &amp;&amp; operands[7] == operands[1])<br>
++     || (operands[7] == operands[0] &amp;&amp; operands[6] == operands[1]))<br>
++    &amp;&amp; peep2_reg_dead_p (3, operands[0]) &amp;&amp; peep2_reg_dead_p (3, operands[1]))&quot;<br>
++  [(parallel<br>
++    [(set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))<br>
++     (clobber (reg:CC CC_REGNUM))])]<br>
++{<br>
++  if (!gen_ldm_seq (operands, 2, true))<br>
++    FAIL;<br>
++})<br>
++<br>
++(define_peephole2<br>
++  [(set (match_operand:SI 0 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 2 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 1 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operand:SI 3 &quot;memory_operand&quot; &quot;&quot;))<br>
++   (set (match_operand:SI 4 &quot;s_register_operand&quot; &quot;&quot;)<br>
++        (match_operator:SI 5 &quot;commutative_binary_operator&quot;<br>
++         [(match_operand:SI 6 &quot;s_register_operand&quot; &quot;&quot;)<br>
++          (match_operand:SI 7 &quot;s_register_operand&quot; &quot;&quot;)]))]<br>
++  &quot;(((operands[6] == operands[0] &amp;&amp; operands[7] == operands[1])<br>
++     || (operands[7] == operands[0] &amp;&amp; operands[6] == operands[1]))<br>
++    &amp;&amp; peep2_reg_dead_p (3, operands[0]) &amp;&amp; peep2_reg_dead_p (3, operands[1]))&quot;<br>
++  [(set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))]<br>
++{<br>
++  if (!gen_ldm_seq (operands, 2, true))<br>
++    FAIL;<br>
++})<br>
++<br>
+Index: gcc-4_5-branch/gcc/config/arm/<a href="http://predicates.md" target="_blank">predicates.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/arm/<a href="http://predicates.md" target="_blank">predicates.md</a><br>
++++ gcc-4_5-branch/gcc/config/arm/<a href="http://predicates.md" target="_blank">predicates.md</a><br>
+@@ -211,6 +211,11 @@<br>
+   (and (match_code &quot;ior,xor,and&quot;)<br>
+        (match_test &quot;mode == GET_MODE (op)&quot;)))<br>
+<br>
++;; True for commutative operators<br>
++(define_special_predicate &quot;commutative_binary_operator&quot;<br>
++  (and (match_code &quot;ior,xor,and,plus&quot;)<br>
++       (match_test &quot;mode == GET_MODE (op)&quot;)))<br>
++<br>
+ ;; True for shift operators.<br>
+ (define_special_predicate &quot;shift_operator&quot;<br>
+   (and (ior (ior (and (match_code &quot;mult&quot;)<br>
+@@ -334,16 +339,20 @@<br>
+   (match_code &quot;parallel&quot;)<br>
+ {<br>
+   HOST_WIDE_INT count = XVECLEN (op, 0);<br>
+-  int dest_regno;<br>
++  unsigned dest_regno;<br>
+   rtx src_addr;<br>
+   HOST_WIDE_INT i = 1, base = 0;<br>
++  HOST_WIDE_INT offset = 0;<br>
+   rtx elt;<br>
++  bool addr_reg_loaded = false;<br>
++  bool update = false;<br>
+<br>
+   if (low_irq_latency)<br>
+     return false;<br>
+<br>
+   if (count &lt;= 1<br>
+-      || GET_CODE (XVECEXP (op, 0, 0)) != SET)<br>
++      || GET_CODE (XVECEXP (op, 0, 0)) != SET<br>
++      || !REG_P (SET_DEST (XVECEXP (op, 0, 0))))<br>
+     return false;<br>
+<br>
+   /* Check to see if this might be a write-back.  */<br>
+@@ -351,6 +360,7 @@<br>
+     {<br>
+       i++;<br>
+       base = 1;<br>
++      update = true;<br>
+<br>
+       /* Now check it more carefully.  */<br>
+       if (GET_CODE (SET_DEST (elt)) != REG<br>
+@@ -369,6 +379,15 @@<br>
+<br>
+   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));<br>
+   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);<br>
++  if (GET_CODE (src_addr) == PLUS)<br>
++    {<br>
++      if (GET_CODE (XEXP (src_addr, 1)) != CONST_INT)<br>
++      return false;<br>
++      offset = INTVAL (XEXP (src_addr, 1));<br>
++      src_addr = XEXP (src_addr, 0);<br>
++    }<br>
++  if (!REG_P (src_addr))<br>
++    return false;<br>
+<br>
+   for (; i &lt; count; i++)<br>
+     {<br>
+@@ -377,16 +396,28 @@<br>
+       if (GET_CODE (elt) != SET<br>
+           || GET_CODE (SET_DEST (elt)) != REG<br>
+           || GET_MODE (SET_DEST (elt)) != SImode<br>
+-          || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)<br>
++          || REGNO (SET_DEST (elt)) &lt;= dest_regno<br>
+           || GET_CODE (SET_SRC (elt)) != MEM<br>
+           || GET_MODE (SET_SRC (elt)) != SImode<br>
+-          || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS<br>
+-          || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)<br>
+-          || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT<br>
+-          || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)<br>
++          || ((GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS<br>
++             || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)<br>
++             || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT<br>
++             || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != offset + (i - base) * 4)<br>
++            &amp;&amp; (!REG_P (XEXP (SET_SRC (elt), 0))<br>
++                || offset + (i - base) * 4 != 0)))<br>
+         return false;<br>
++      dest_regno = REGNO (SET_DEST (elt));<br>
++      if (dest_regno == REGNO (src_addr))<br>
++        addr_reg_loaded = true;<br>
+     }<br>
+-<br>
++  /* For Thumb, we only have updating instructions.  If the pattern does<br>
++     not describe an update, it must be because the address register is<br>
++     in the list of loaded registers - on the hardware, this has the effect<br>
++     of overriding the update.  */<br>
++  if (update &amp;&amp; addr_reg_loaded)<br>
++    return false;<br>
++  if (TARGET_THUMB1)<br>
++    return update || addr_reg_loaded;<br>
+   return true;<br>
+ })<br>
+<br>
+@@ -394,9 +425,9 @@<br>
+   (match_code &quot;parallel&quot;)<br>
+ {<br>
+   HOST_WIDE_INT count = XVECLEN (op, 0);<br>
+-  int src_regno;<br>
++  unsigned src_regno;<br>
+   rtx dest_addr;<br>
+-  HOST_WIDE_INT i = 1, base = 0;<br>
++  HOST_WIDE_INT i = 1, base = 0, offset = 0;<br>
+   rtx elt;<br>
+<br>
+   if (low_irq_latency)<br>
+@@ -430,6 +461,16 @@<br>
+   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));<br>
+   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);<br>
+<br>
++  if (GET_CODE (dest_addr) == PLUS)<br>
++    {<br>
++      if (GET_CODE (XEXP (dest_addr, 1)) != CONST_INT)<br>
++      return false;<br>
++      offset = INTVAL (XEXP (dest_addr, 1));<br>
++      dest_addr = XEXP (dest_addr, 0);<br>
++    }<br>
++  if (!REG_P (dest_addr))<br>
++    return false;<br>
++<br>
+   for (; i &lt; count; i++)<br>
+     {<br>
+       elt = XVECEXP (op, 0, i);<br>
+@@ -437,14 +478,17 @@<br>
+       if (GET_CODE (elt) != SET<br>
+           || GET_CODE (SET_SRC (elt)) != REG<br>
+           || GET_MODE (SET_SRC (elt)) != SImode<br>
+-          || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)<br>
++          || REGNO (SET_SRC (elt)) &lt;= src_regno<br>
+           || GET_CODE (SET_DEST (elt)) != MEM<br>
+           || GET_MODE (SET_DEST (elt)) != SImode<br>
+-          || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS<br>
+-          || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)<br>
+-          || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT<br>
+-          || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)<br>
++          || ((GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS<br>
++             || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)<br>
++             || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT<br>
++               || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != offset + (i - base) * 4)<br>
++            &amp;&amp; (!REG_P (XEXP (SET_DEST (elt), 0))<br>
++                || offset + (i - base) * 4 != 0)))<br>
+         return false;<br>
++      src_regno = REGNO (SET_SRC (elt));<br>
+     }<br>
+<br>
+   return true;<br>
+Index: gcc-4_5-branch/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a><br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a><br>
++++ gcc-4_5-branch/gcc/config/i386/<a href="http://i386.md" target="_blank">i386.md</a><br>
+@@ -4934,6 +4934,7 @@<br>
+    (set (match_operand:SSEMODEI24 2 &quot;register_operand&quot; &quot;&quot;)<br>
+       (fix:SSEMODEI24 (match_dup 0)))]<br>
+   &quot;TARGET_SHORTEN_X87_SSE<br>
++   &amp;&amp; !(TARGET_AVOID_VECTOR_DECODE &amp;&amp; optimize_insn_for_speed_p ())<br>
+    &amp;&amp; peep2_reg_dead_p (2, operands[0])&quot;<br>
+   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]<br>
+   &quot;&quot;)<br>
+@@ -20036,15 +20037,14 @@<br>
+ ;;  leal    (%edx,%eax,4), %eax<br>
+<br>
+ (define_peephole2<br>
+-  [(parallel [(set (match_operand 0 &quot;register_operand&quot; &quot;&quot;)<br>
++  [(match_scratch:P 5 &quot;r&quot;)<br>
++   (parallel [(set (match_operand 0 &quot;register_operand&quot; &quot;&quot;)<br>
+                  (ashift (match_operand 1 &quot;register_operand&quot; &quot;&quot;)<br>
+                          (match_operand 2 &quot;const_int_operand&quot; &quot;&quot;)))<br>
+              (clobber (reg:CC FLAGS_REG))])<br>
+-   (set (match_operand 3 &quot;register_operand&quot;)<br>
+-        (match_operand 4 &quot;x86_64_general_operand&quot; &quot;&quot;))<br>
+-   (parallel [(set (match_operand 5 &quot;register_operand&quot; &quot;&quot;)<br>
+-                 (plus (match_operand 6 &quot;register_operand&quot; &quot;&quot;)<br>
+-                       (match_operand 7 &quot;register_operand&quot; &quot;&quot;)))<br>
++   (parallel [(set (match_operand 3 &quot;register_operand&quot; &quot;&quot;)<br>
++                 (plus (match_dup 0)<br>
++                       (match_operand 4 &quot;x86_64_general_operand&quot; &quot;&quot;)))<br>
+                  (clobber (reg:CC FLAGS_REG))])]<br>
+   &quot;INTVAL (operands[2]) &gt;= 0 &amp;&amp; INTVAL (operands[2]) &lt;= 3<br>
+    /* Validate MODE for lea.  */<br>
+@@ -20053,31 +20053,27 @@<br>
+           || GET_MODE (operands[0]) == HImode))<br>
+        || GET_MODE (operands[0]) == SImode<br>
+        || (TARGET_64BIT &amp;&amp; GET_MODE (operands[0]) == DImode))<br>
++   &amp;&amp; (rtx_equal_p (operands[0], operands[3])<br>
++       || peep2_reg_dead_p (2, operands[0]))<br>
+    /* We reorder load and the shift.  */<br>
+-   &amp;&amp; !rtx_equal_p (operands[1], operands[3])<br>
+-   &amp;&amp; !reg_overlap_mentioned_p (operands[0], operands[4])<br>
+-   /* Last PLUS must consist of operand 0 and 3.  */<br>
+-   &amp;&amp; !rtx_equal_p (operands[0], operands[3])<br>
+-   &amp;&amp; (rtx_equal_p (operands[3], operands[6])<br>
+-       || rtx_equal_p (operands[3], operands[7]))<br>
+-   &amp;&amp; (rtx_equal_p (operands[0], operands[6])<br>
+-       || rtx_equal_p (operands[0], operands[7]))<br>
+-   /* The intermediate operand 0 must die or be same as output.  */<br>
+-   &amp;&amp; (rtx_equal_p (operands[0], operands[5])<br>
+-       || peep2_reg_dead_p (3, operands[0]))&quot;<br>
+-  [(set (match_dup 3) (match_dup 4))<br>
++   &amp;&amp; !reg_overlap_mentioned_p (operands[0], operands[4])&quot;<br>
++  [(set (match_dup 5) (match_dup 4))<br>
+    (set (match_dup 0) (match_dup 1))]<br>
+ {<br>
+-  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;<br>
++  enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;<br>
+   int scale = 1 &lt;&lt; INTVAL (operands[2]);<br>
+   rtx index = gen_lowpart (Pmode, operands[1]);<br>
+-  rtx base = gen_lowpart (Pmode, operands[3]);<br>
+-  rtx dest = gen_lowpart (mode, operands[5]);<br>
++  rtx base = gen_lowpart (Pmode, operands[5]);<br>
++  rtx dest = gen_lowpart (mode, operands[3]);<br>
+<br>
+   operands[1] = gen_rtx_PLUS (Pmode, base,<br>
+                             gen_rtx_MULT (Pmode, index, GEN_INT (scale)));<br>
++  operands[5] = base;<br>
+   if (mode != Pmode)<br>
+-    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);<br>
++    {<br>
++      operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);<br>
++      operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);<br>
++    }<br>
+   operands[0] = dest;<br>
+ })<br>
+<br>
+Index: gcc-4_5-branch/gcc/df-problems.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/df-problems.c<br>
++++ gcc-4_5-branch/gcc/df-problems.c<br>
+@@ -3748,9 +3748,22 @@ df_simulate_find_defs (rtx insn, bitmap<br>
+   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)<br>
+     {<br>
+       df_ref def = *def_rec;<br>
+-      /* If the def is to only part of the reg, it does<br>
+-       not kill the other defs that reach here.  */<br>
+-      if (!(DF_REF_FLAGS (def) &amp; (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))<br>
++      bitmap_set_bit (defs, DF_REF_REGNO (def));<br>
++    }<br>
++}<br>
++<br>
++/* Find the set of real DEFs, which are not clobbers, for INSN.  */<br>
++<br>
++void<br>
++df_simulate_find_noclobber_defs (rtx insn, bitmap defs)<br>
++{<br>
++  df_ref *def_rec;<br>
++  unsigned int uid = INSN_UID (insn);<br>
++<br>
++  for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)<br>
++    {<br>
++      df_ref def = *def_rec;<br>
++      if (!(DF_REF_FLAGS (def) &amp; (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))<br>
+       bitmap_set_bit (defs, DF_REF_REGNO (def));<br>
+     }<br>
+ }<br>
+@@ -3921,7 +3934,7 @@ df_simulate_initialize_forwards (basic_b<br>
+     {<br>
+       df_ref def = *def_rec;<br>
+       if (DF_REF_FLAGS (def) &amp; DF_REF_AT_TOP)<br>
+-      bitmap_clear_bit (live, DF_REF_REGNO (def));<br>
++      bitmap_set_bit (live, DF_REF_REGNO (def));<br>
+     }<br>
+ }<br>
+<br>
+@@ -3942,7 +3955,7 @@ df_simulate_one_insn_forwards (basic_blo<br>
+      while here the scan is performed forwards!  So, first assume that the<br>
+      def is live, and if this is not true REG_UNUSED notes will rectify the<br>
+      situation.  */<br>
+-  df_simulate_find_defs (insn, live);<br>
++  df_simulate_find_noclobber_defs (insn, live);<br>
+<br>
+   /* Clear all of the registers that go dead.  */<br>
+   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))<br>
+Index: gcc-4_5-branch/gcc/df.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/df.h<br>
++++ gcc-4_5-branch/gcc/df.h<br>
+@@ -978,6 +978,7 @@ extern void df_note_add_problem (void);<br>
+ extern void df_md_add_problem (void);<br>
+ extern void df_md_simulate_artificial_defs_at_top (basic_block, bitmap);<br>
+ extern void df_md_simulate_one_insn (basic_block, rtx, bitmap);<br>
++extern void df_simulate_find_noclobber_defs (rtx, bitmap);<br>
+ extern void df_simulate_find_defs (rtx, bitmap);<br>
+ extern void df_simulate_defs (rtx, bitmap);<br>
+ extern void df_simulate_uses (rtx, bitmap);<br>
+Index: gcc-4_5-branch/gcc/fwprop.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/fwprop.c<br>
++++ gcc-4_5-branch/gcc/fwprop.c<br>
+@@ -228,7 +228,10 @@ single_def_use_enter_block (struct dom_w<br>
+<br>
+   process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP);<br>
+   process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP);<br>
+-  df_simulate_initialize_forwards (bb, local_lr);<br>
++<br>
++  /* We don&#39;t call df_simulate_initialize_forwards, as it may overestimate<br>
++     the live registers if there are unused artificial defs.  We prefer<br>
++     liveness to be underestimated.  */<br>
+<br>
+   FOR_BB_INSNS (bb, insn)<br>
+     if (INSN_P (insn))<br>
+Index: gcc-4_5-branch/gcc/genoutput.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/genoutput.c<br>
++++ gcc-4_5-branch/gcc/genoutput.c<br>
+@@ -266,6 +266,8 @@ output_operand_data (void)<br>
+<br>
+       printf (&quot;    %d,\n&quot;, d-&gt;strict_low);<br>
+<br>
++      printf (&quot;    %d,\n&quot;, d-&gt;constraint == NULL ? 1 : 0);<br>
++<br>
+       printf (&quot;    %d\n&quot;, d-&gt;eliminable);<br>
+<br>
+       printf(&quot;  },\n&quot;);<br>
+Index: gcc-4_5-branch/gcc/genrecog.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/genrecog.c<br>
++++ gcc-4_5-branch/gcc/genrecog.c<br>
+@@ -1782,20 +1782,11 @@ change_state (const char *oldpos, const<br>
+   int odepth = strlen (oldpos);<br>
+   int ndepth = strlen (newpos);<br>
+   int depth;<br>
+-  int old_has_insn, new_has_insn;<br>
+<br>
+   /* Pop up as many levels as necessary.  */<br>
+   for (depth = odepth; strncmp (oldpos, newpos, depth) != 0; --depth)<br>
+     continue;<br>
+<br>
+-  /* Hunt for the last [A-Z] in both strings.  */<br>
+-  for (old_has_insn = odepth - 1; old_has_insn &gt;= 0; --old_has_insn)<br>
+-    if (ISUPPER (oldpos[old_has_insn]))<br>
+-      break;<br>
+-  for (new_has_insn = ndepth - 1; new_has_insn &gt;= 0; --new_has_insn)<br>
+-    if (ISUPPER (newpos[new_has_insn]))<br>
+-      break;<br>
+-<br>
+   /* Go down to desired level.  */<br>
+   while (depth &lt; ndepth)<br>
+     {<br>
+Index: gcc-4_5-branch/gcc/ifcvt.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/ifcvt.c<br>
++++ gcc-4_5-branch/gcc/ifcvt.c<br>
+@@ -4011,6 +4011,7 @@ dead_or_predicable (basic_block test_bb,<br>
+   basic_block new_dest = dest_edge-&gt;dest;<br>
+   rtx head, end, jump, earliest = NULL_RTX, old_dest;<br>
+   bitmap merge_set = NULL;<br>
++  bitmap merge_set_noclobber  = NULL;<br>
+   /* Number of pending changes.  */<br>
+   int n_validated_changes = 0;<br>
+   rtx new_dest_label;<br>
+@@ -4169,6 +4170,7 @@ dead_or_predicable (basic_block test_bb,<br>
+                      end of the block.  */<br>
+<br>
+       merge_set = BITMAP_ALLOC (&amp;reg_obstack);<br>
++      merge_set_noclobber = BITMAP_ALLOC (&amp;reg_obstack);<br>
+<br>
+       /* If we allocated new pseudos (e.g. in the conditional move<br>
+        expander called from noce_emit_cmove), we must resize the<br>
+@@ -4187,6 +4189,7 @@ dead_or_predicable (basic_block test_bb,<br>
+                 df_ref def = *def_rec;<br>
+                 bitmap_set_bit (merge_set, DF_REF_REGNO (def));<br>
+               }<br>
++              df_simulate_find_noclobber_defs (insn, merge_set_noclobber);<br>
+           }<br>
+       }<br>
+<br>
+@@ -4197,7 +4200,7 @@ dead_or_predicable (basic_block test_bb,<br>
+         unsigned i;<br>
+         bitmap_iterator bi;<br>
+<br>
+-          EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)<br>
++          EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)<br>
+           {<br>
+             if (i &lt; FIRST_PSEUDO_REGISTER<br>
+                 &amp;&amp; ! fixed_regs[i]<br>
+@@ -4233,7 +4236,7 @@ dead_or_predicable (basic_block test_bb,<br>
+          TEST_SET &amp; DF_LIVE_IN (merge_bb)<br>
+        are empty.  */<br>
+<br>
+-      if (bitmap_intersect_p (merge_set, test_set)<br>
++      if (bitmap_intersect_p (merge_set_noclobber, test_set)<br>
+         || bitmap_intersect_p (merge_set, test_live)<br>
+         || bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))<br>
+       intersect = true;<br>
+@@ -4320,6 +4323,7 @@ dead_or_predicable (basic_block test_bb,<br>
+           remove_reg_equal_equiv_notes_for_regno (i);<br>
+<br>
+         BITMAP_FREE (merge_set);<br>
++          BITMAP_FREE (merge_set_noclobber);<br>
+       }<br>
+<br>
+       reorder_insns (head, end, PREV_INSN (earliest));<br>
+@@ -4340,7 +4344,10 @@ dead_or_predicable (basic_block test_bb,<br>
+   cancel_changes (0);<br>
+  fail:<br>
+   if (merge_set)<br>
+-    BITMAP_FREE (merge_set);<br>
++    {<br>
++      BITMAP_FREE (merge_set);<br>
++      BITMAP_FREE (merge_set_noclobber);<br>
++    }<br>
+   return FALSE;<br>
+ }<br>
+<br>
+Index: gcc-4_5-branch/gcc/recog.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/recog.c<br>
++++ gcc-4_5-branch/gcc/recog.c<br>
+@@ -2082,6 +2082,7 @@ extract_insn (rtx insn)<br>
+                              recog_data.operand_loc,<br>
+                              recog_data.constraints,<br>
+                              recog_data.operand_mode, NULL);<br>
++        memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);<br>
+         if (noperands &gt; 0)<br>
+           {<br>
+             const char *p =  recog_data.constraints[0];<br>
+@@ -2111,6 +2112,7 @@ extract_insn (rtx insn)<br>
+       for (i = 0; i &lt; noperands; i++)<br>
+       {<br>
+         recog_data.constraints[i] = insn_data[icode].operand[i].constraint;<br>
++        recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;<br>
+         recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;<br>
+         /* VOIDmode match_operands gets mode from their real operand.  */<br>
+         if (recog_data.operand_mode[i] == VOIDmode)<br>
+@@ -2909,6 +2911,10 @@ struct peep2_insn_data<br>
+<br>
+ static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];<br>
+ static int peep2_current;<br>
++<br>
++static bool peep2_do_rebuild_jump_labels;<br>
++static bool peep2_do_cleanup_cfg;<br>
++<br>
+ /* The number of instructions available to match a peep2.  */<br>
+ int peep2_current_count;<br>
+<br>
+@@ -2917,6 +2923,16 @@ int peep2_current_count;<br>
+    DF_LIVE_OUT for the block.  */<br>
+ #define PEEP2_EOB     pc_rtx<br>
+<br>
++/* Wrap N to fit into the peep2_insn_data buffer.  */<br>
++<br>
++static int<br>
++peep2_buf_position (int n)<br>
++{<br>
++  if (n &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
++    n -= MAX_INSNS_PER_PEEP2 + 1;<br>
++  return n;<br>
++}<br>
++<br>
+ /* Return the Nth non-note insn after `current&#39;, or return NULL_RTX if it<br>
+    does not exist.  Used by the recognizer to find the next insn to match<br>
+    in a multi-insn pattern.  */<br>
+@@ -2926,9 +2942,7 @@ peep2_next_insn (int n)<br>
+ {<br>
+   gcc_assert (n &lt;= peep2_current_count);<br>
+<br>
+-  n += peep2_current;<br>
+-  if (n &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-    n -= MAX_INSNS_PER_PEEP2 + 1;<br>
++  n = peep2_buf_position (peep2_current + n);<br>
+<br>
+   return peep2_insn_data[n].insn;<br>
+ }<br>
+@@ -2941,9 +2955,7 @@ peep2_regno_dead_p (int ofs, int regno)<br>
+ {<br>
+   gcc_assert (ofs &lt; MAX_INSNS_PER_PEEP2 + 1);<br>
+<br>
+-  ofs += peep2_current;<br>
+-  if (ofs &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-    ofs -= MAX_INSNS_PER_PEEP2 + 1;<br>
++  ofs = peep2_buf_position (peep2_current + ofs);<br>
+<br>
+   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);<br>
+<br>
+@@ -2959,9 +2971,7 @@ peep2_reg_dead_p (int ofs, rtx reg)<br>
+<br>
+   gcc_assert (ofs &lt; MAX_INSNS_PER_PEEP2 + 1);<br>
+<br>
+-  ofs += peep2_current;<br>
+-  if (ofs &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-    ofs -= MAX_INSNS_PER_PEEP2 + 1;<br>
++  ofs = peep2_buf_position (peep2_current + ofs);<br>
+<br>
+   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);<br>
+<br>
+@@ -2996,12 +3006,8 @@ peep2_find_free_register (int from, int<br>
+   gcc_assert (from &lt; MAX_INSNS_PER_PEEP2 + 1);<br>
+   gcc_assert (to &lt; MAX_INSNS_PER_PEEP2 + 1);<br>
+<br>
+-  from += peep2_current;<br>
+-  if (from &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-    from -= MAX_INSNS_PER_PEEP2 + 1;<br>
+-  to += peep2_current;<br>
+-  if (to &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-    to -= MAX_INSNS_PER_PEEP2 + 1;<br>
++  from = peep2_buf_position (peep2_current + from);<br>
++  to = peep2_buf_position (peep2_current + to);<br>
+<br>
+   gcc_assert (peep2_insn_data[from].insn != NULL_RTX);<br>
+   REG_SET_TO_HARD_REG_SET (live, peep2_insn_data[from].live_before);<br>
+@@ -3010,8 +3016,7 @@ peep2_find_free_register (int from, int<br>
+     {<br>
+       HARD_REG_SET this_live;<br>
+<br>
+-      if (++from &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-      from = 0;<br>
++      from = peep2_buf_position (from + 1);<br>
+       gcc_assert (peep2_insn_data[from].insn != NULL_RTX);<br>
+       REG_SET_TO_HARD_REG_SET (this_live, peep2_insn_data[from].live_before);<br>
+       IOR_HARD_REG_SET (live, this_live);<br>
+@@ -3104,19 +3109,234 @@ peep2_reinit_state (regset live)<br>
+   COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);<br>
+ }<br>
+<br>
++/* While scanning basic block BB, we found a match of length MATCH_LEN,<br>
++   starting at INSN.  Perform the replacement, removing the old insns and<br>
++   replacing them with ATTEMPT.  Returns the last insn emitted.  */<br>
++<br>
++static rtx<br>
++peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)<br>
++{<br>
++  int i;<br>
++  rtx last, note, before_try, x;<br>
++  bool was_call = false;<br>
++<br>
++  /* If we are splitting a CALL_INSN, look for the CALL_INSN<br>
++     in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other<br>
++     cfg-related call notes.  */<br>
++  for (i = 0; i &lt;= match_len; ++i)<br>
++    {<br>
++      int j;<br>
++      rtx old_insn, new_insn, note;<br>
++<br>
++      j = peep2_buf_position (peep2_current + i);<br>
++      old_insn = peep2_insn_data[j].insn;<br>
++      if (!CALL_P (old_insn))<br>
++      continue;<br>
++      was_call = true;<br>
++<br>
++      new_insn = attempt;<br>
++      while (new_insn != NULL_RTX)<br>
++      {<br>
++        if (CALL_P (new_insn))<br>
++          break;<br>
++        new_insn = NEXT_INSN (new_insn);<br>
++      }<br>
++<br>
++      gcc_assert (new_insn != NULL_RTX);<br>
++<br>
++      CALL_INSN_FUNCTION_USAGE (new_insn)<br>
++      = CALL_INSN_FUNCTION_USAGE (old_insn);<br>
++<br>
++      for (note = REG_NOTES (old_insn);<br>
++         note;<br>
++         note = XEXP (note, 1))<br>
++      switch (REG_NOTE_KIND (note))<br>
++        {<br>
++        case REG_NORETURN:<br>
++        case REG_SETJMP:<br>
++          add_reg_note (new_insn, REG_NOTE_KIND (note),<br>
++                        XEXP (note, 0));<br>
++          break;<br>
++        default:<br>
++          /* Discard all other reg notes.  */<br>
++          break;<br>
++        }<br>
++<br>
++      /* Croak if there is another call in the sequence.  */<br>
++      while (++i &lt;= match_len)<br>
++      {<br>
++        j = peep2_buf_position (peep2_current + i);<br>
++        old_insn = peep2_insn_data[j].insn;<br>
++        gcc_assert (!CALL_P (old_insn));<br>
++      }<br>
++      break;<br>
++    }<br>
++<br>
++  i = peep2_buf_position (peep2_current + match_len);<br>
++<br>
++  note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);<br>
++<br>
++  /* Replace the old sequence with the new.  */<br>
++  last = emit_insn_after_setloc (attempt,<br>
++                               peep2_insn_data[i].insn,<br>
++                               INSN_LOCATOR (peep2_insn_data[i].insn));<br>
++  before_try = PREV_INSN (insn);<br>
++  delete_insn_chain (insn, peep2_insn_data[i].insn, false);<br>
++<br>
++  /* Re-insert the EH_REGION notes.  */<br>
++  if (note || (was_call &amp;&amp; nonlocal_goto_handler_labels))<br>
++    {<br>
++      edge eh_edge;<br>
++      edge_iterator ei;<br>
++<br>
++      FOR_EACH_EDGE (eh_edge, ei, bb-&gt;succs)<br>
++      if (eh_edge-&gt;flags &amp; (EDGE_EH | EDGE_ABNORMAL_CALL))<br>
++        break;<br>
++<br>
++      if (note)<br>
++      copy_reg_eh_region_note_backward (note, last, before_try);<br>
++<br>
++      if (eh_edge)<br>
++      for (x = last; x != before_try; x = PREV_INSN (x))<br>
++        if (x != BB_END (bb)<br>
++            &amp;&amp; (can_throw_internal (x)<br>
++                || can_nonlocal_goto (x)))<br>
++          {<br>
++            edge nfte, nehe;<br>
++            int flags;<br>
++<br>
++            nfte = split_block (bb, x);<br>
++            flags = (eh_edge-&gt;flags<br>
++                     &amp; (EDGE_EH | EDGE_ABNORMAL));<br>
++            if (CALL_P (x))<br>
++              flags |= EDGE_ABNORMAL_CALL;<br>
++            nehe = make_edge (nfte-&gt;src, eh_edge-&gt;dest,<br>
++                              flags);<br>
++<br>
++            nehe-&gt;probability = eh_edge-&gt;probability;<br>
++            nfte-&gt;probability<br>
++              = REG_BR_PROB_BASE - nehe-&gt;probability;<br>
++<br>
++            peep2_do_cleanup_cfg |= purge_dead_edges (nfte-&gt;dest);<br>
++            bb = nfte-&gt;src;<br>
++            eh_edge = nehe;<br>
++          }<br>
++<br>
++      /* Converting possibly trapping insn to non-trapping is<br>
++       possible.  Zap dummy outgoing edges.  */<br>
++      peep2_do_cleanup_cfg |= purge_dead_edges (bb);<br>
++    }<br>
++<br>
++  /* If we generated a jump instruction, it won&#39;t have<br>
++     JUMP_LABEL set.  Recompute after we&#39;re done.  */<br>
++  for (x = last; x != before_try; x = PREV_INSN (x))<br>
++    if (JUMP_P (x))<br>
++      {<br>
++      peep2_do_rebuild_jump_labels = true;<br>
++      break;<br>
++      }<br>
++<br>
++  return last;<br>
++}<br>
++<br>
++/* After performing a replacement in basic block BB, fix up the life<br>
++   information in our buffer.  LAST is the last of the insns that we<br>
++   emitted as a replacement.  PREV is the insn before the start of<br>
++   the replacement.  MATCH_LEN is the number of instructions that were<br>
++   matched, and which now need to be replaced in the buffer.  */<br>
++<br>
++static void<br>
++peep2_update_life (basic_block bb, int match_len, rtx last, rtx prev)<br>
++{<br>
++  int i = peep2_buf_position (peep2_current + match_len + 1);<br>
++  rtx x;<br>
++  regset_head live;<br>
++<br>
++  INIT_REG_SET (&amp;live);<br>
++  COPY_REG_SET (&amp;live, peep2_insn_data[i].live_before);<br>
++<br>
++  gcc_assert (peep2_current_count &gt;= match_len + 1);<br>
++  peep2_current_count -= match_len + 1;<br>
++<br>
++  x = last;<br>
++  do<br>
++    {<br>
++      if (INSN_P (x))<br>
++      {<br>
++        df_insn_rescan (x);<br>
++        if (peep2_current_count &lt; MAX_INSNS_PER_PEEP2)<br>
++          {<br>
++            peep2_current_count++;<br>
++            if (--i &lt; 0)<br>
++              i = MAX_INSNS_PER_PEEP2;<br>
++            peep2_insn_data[i].insn = x;<br>
++            df_simulate_one_insn_backwards (bb, x, &amp;live);<br>
++            COPY_REG_SET (peep2_insn_data[i].live_before, &amp;live);<br>
++          }<br>
++      }<br>
++      x = PREV_INSN (x);<br>
++    }<br>
++  while (x != prev);<br>
++  CLEAR_REG_SET (&amp;live);<br>
++<br>
++  peep2_current = i;<br>
++}<br>
++<br>
++/* Add INSN, which is in BB, at the end of the peep2 insn buffer if possible.<br>
++   Return true if we added it, false otherwise.  The caller will try to match<br>
++   peepholes against the buffer if we return false; otherwise it will try to<br>
++   add more instructions to the buffer.  */<br>
++<br>
++static bool<br>
++peep2_fill_buffer (basic_block bb, rtx insn, regset live)<br>
++{<br>
++  int pos;<br>
++<br>
++  /* Once we have filled the maximum number of insns the buffer can hold,<br>
++     allow the caller to match the insns against peepholes.  We wait until<br>
++     the buffer is full in case the target has similar peepholes of different<br>
++     length; we always want to match the longest if possible.  */<br>
++  if (peep2_current_count == MAX_INSNS_PER_PEEP2)<br>
++    return false;<br>
++<br>
++  /* If an insn has RTX_FRAME_RELATED_P set, peephole substitution would lose<br>
++     the REG_FRAME_RELATED_EXPR that is attached.  */<br>
++  if (RTX_FRAME_RELATED_P (insn))<br>
++    {<br>
++      /* Let the buffer drain first.  */<br>
++      if (peep2_current_count &gt; 0)<br>
++      return false;<br>
++      /* Step over the insn then return true without adding the insn<br>
++       to the buffer; this will cause us to process the next<br>
++       insn.  */<br>
++      df_simulate_one_insn_forwards (bb, insn, live);<br>
++      return true;<br>
++    }<br>
++<br>
++  pos = peep2_buf_position (peep2_current + peep2_current_count);<br>
++  peep2_insn_data[pos].insn = insn;<br>
++  COPY_REG_SET (peep2_insn_data[pos].live_before, live);<br>
++  peep2_current_count++;<br>
++<br>
++  df_simulate_one_insn_forwards (bb, insn, live);<br>
++  return true;<br>
++}<br>
++<br>
+ /* Perform the peephole2 optimization pass.  */<br>
+<br>
+ static void<br>
+ peephole2_optimize (void)<br>
+ {<br>
+-  rtx insn, prev;<br>
++  rtx insn;<br>
+   bitmap live;<br>
+   int i;<br>
+   basic_block bb;<br>
+-  bool do_cleanup_cfg = false;<br>
+-  bool do_rebuild_jump_labels = false;<br>
++<br>
++  peep2_do_cleanup_cfg = false;<br>
++  peep2_do_rebuild_jump_labels = false;<br>
+<br>
+   df_set_flags (DF_LR_RUN_DCE);<br>
++  df_note_add_problem ();<br>
+   df_analyze ();<br>
+<br>
+   /* Initialize the regsets we&#39;re going to use.  */<br>
+@@ -3126,214 +3346,59 @@ peephole2_optimize (void)<br>
+<br>
+   FOR_EACH_BB_REVERSE (bb)<br>
+     {<br>
++      bool past_end = false;<br>
++      int pos;<br>
++<br>
+       rtl_profile_for_bb (bb);<br>
+<br>
+       /* Start up propagation.  */<br>
+-      bitmap_copy (live, DF_LR_OUT (bb));<br>
+-      df_simulate_initialize_backwards (bb, live);<br>
++      bitmap_copy (live, DF_LR_IN (bb));<br>
++      df_simulate_initialize_forwards (bb, live);<br>
+       peep2_reinit_state (live);<br>
+<br>
+-      for (insn = BB_END (bb); ; insn = prev)<br>
++      insn = BB_HEAD (bb);<br>
++      for (;;)<br>
+       {<br>
+-        prev = PREV_INSN (insn);<br>
+-        if (NONDEBUG_INSN_P (insn))<br>
+-          {<br>
+-            rtx attempt, before_try, x;<br>
+-            int match_len;<br>
+-            rtx note;<br>
+-            bool was_call = false;<br>
+-<br>
+-            /* Record this insn.  */<br>
+-            if (--peep2_current &lt; 0)<br>
+-              peep2_current = MAX_INSNS_PER_PEEP2;<br>
+-            if (peep2_current_count &lt; MAX_INSNS_PER_PEEP2<br>
+-                &amp;&amp; peep2_insn_data[peep2_current].insn == NULL_RTX)<br>
+-              peep2_current_count++;<br>
+-            peep2_insn_data[peep2_current].insn = insn;<br>
+-            df_simulate_one_insn_backwards (bb, insn, live);<br>
+-            COPY_REG_SET (peep2_insn_data[peep2_current].live_before, live);<br>
+-<br>
+-            if (RTX_FRAME_RELATED_P (insn))<br>
+-              {<br>
+-                /* If an insn has RTX_FRAME_RELATED_P set, peephole<br>
+-                   substitution would lose the<br>
+-                   REG_FRAME_RELATED_EXPR that is attached.  */<br>
+-                peep2_reinit_state (live);<br>
+-                attempt = NULL;<br>
+-              }<br>
+-            else<br>
+-              /* Match the peephole.  */<br>
+-              attempt = peephole2_insns (PATTERN (insn), insn, &amp;match_len);<br>
+-<br>
+-            if (attempt != NULL)<br>
+-              {<br>
+-                /* If we are splitting a CALL_INSN, look for the CALL_INSN<br>
+-                   in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other<br>
+-                   cfg-related call notes.  */<br>
+-                for (i = 0; i &lt;= match_len; ++i)<br>
+-                  {<br>
+-                    int j;<br>
+-                    rtx old_insn, new_insn, note;<br>
++        rtx attempt, head;<br>
++        int match_len;<br>
+<br>
+-                    j = i + peep2_current;<br>
+-                    if (j &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-                      j -= MAX_INSNS_PER_PEEP2 + 1;<br>
+-                    old_insn = peep2_insn_data[j].insn;<br>
+-                    if (!CALL_P (old_insn))<br>
+-                      continue;<br>
+-                    was_call = true;<br>
+-<br>
+-                    new_insn = attempt;<br>
+-                    while (new_insn != NULL_RTX)<br>
+-                      {<br>
+-                        if (CALL_P (new_insn))<br>
+-                          break;<br>
+-                        new_insn = NEXT_INSN (new_insn);<br>
+-                      }<br>
+-<br>
+-                    gcc_assert (new_insn != NULL_RTX);<br>
+-<br>
+-                    CALL_INSN_FUNCTION_USAGE (new_insn)<br>
+-                      = CALL_INSN_FUNCTION_USAGE (old_insn);<br>
+-<br>
+-                    for (note = REG_NOTES (old_insn);<br>
+-                         note;<br>
+-                         note = XEXP (note, 1))<br>
+-                      switch (REG_NOTE_KIND (note))<br>
+-                        {<br>
+-                        case REG_NORETURN:<br>
+-                        case REG_SETJMP:<br>
+-                          add_reg_note (new_insn, REG_NOTE_KIND (note),<br>
+-                                        XEXP (note, 0));<br>
+-                          break;<br>
+-                        default:<br>
+-                          /* Discard all other reg notes.  */<br>
+-                          break;<br>
+-                        }<br>
+-<br>
+-                    /* Croak if there is another call in the sequence.  */<br>
+-                    while (++i &lt;= match_len)<br>
+-                      {<br>
+-                        j = i + peep2_current;<br>
+-                        if (j &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-                          j -= MAX_INSNS_PER_PEEP2 + 1;<br>
+-                        old_insn = peep2_insn_data[j].insn;<br>
+-                        gcc_assert (!CALL_P (old_insn));<br>
+-                      }<br>
+-                    break;<br>
+-                  }<br>
+-<br>
+-                i = match_len + peep2_current;<br>
+-                if (i &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-                  i -= MAX_INSNS_PER_PEEP2 + 1;<br>
+-<br>
+-                note = find_reg_note (peep2_insn_data[i].insn,<br>
+-                                      REG_EH_REGION, NULL_RTX);<br>
+-<br>
+-                /* Replace the old sequence with the new.  */<br>
+-                attempt = emit_insn_after_setloc (attempt,<br>
+-                                                  peep2_insn_data[i].insn,<br>
+-                                     INSN_LOCATOR (peep2_insn_data[i].insn));<br>
+-                before_try = PREV_INSN (insn);<br>
+-                delete_insn_chain (insn, peep2_insn_data[i].insn, false);<br>
+-<br>
+-                /* Re-insert the EH_REGION notes.  */<br>
+-                if (note || (was_call &amp;&amp; nonlocal_goto_handler_labels))<br>
+-                  {<br>
+-                    edge eh_edge;<br>
+-                    edge_iterator ei;<br>
+-<br>
+-                    FOR_EACH_EDGE (eh_edge, ei, bb-&gt;succs)<br>
+-                      if (eh_edge-&gt;flags &amp; (EDGE_EH | EDGE_ABNORMAL_CALL))<br>
+-                        break;<br>
+-<br>
+-                    if (note)<br>
+-                      copy_reg_eh_region_note_backward (note, attempt,<br>
+-                                                        before_try);<br>
+-<br>
+-                    if (eh_edge)<br>
+-                      for (x = attempt ; x != before_try ; x = PREV_INSN (x))<br>
+-                        if (x != BB_END (bb)<br>
+-                            &amp;&amp; (can_throw_internal (x)<br>
+-                                || can_nonlocal_goto (x)))<br>
+-                          {<br>
+-                            edge nfte, nehe;<br>
+-                            int flags;<br>
+-<br>
+-                            nfte = split_block (bb, x);<br>
+-                            flags = (eh_edge-&gt;flags<br>
+-                                     &amp; (EDGE_EH | EDGE_ABNORMAL));<br>
+-                            if (CALL_P (x))<br>
+-                              flags |= EDGE_ABNORMAL_CALL;<br>
+-                            nehe = make_edge (nfte-&gt;src, eh_edge-&gt;dest,<br>
+-                                              flags);<br>
+-<br>
+-                            nehe-&gt;probability = eh_edge-&gt;probability;<br>
+-                            nfte-&gt;probability<br>
+-                              = REG_BR_PROB_BASE - nehe-&gt;probability;<br>
+-<br>
+-                            do_cleanup_cfg |= purge_dead_edges (nfte-&gt;dest);<br>
+-                            bb = nfte-&gt;src;<br>
+-                            eh_edge = nehe;<br>
+-                          }<br>
+-<br>
+-                    /* Converting possibly trapping insn to non-trapping is<br>
+-                       possible.  Zap dummy outgoing edges.  */<br>
+-                    do_cleanup_cfg |= purge_dead_edges (bb);<br>
+-                  }<br>
++        if (!past_end &amp;&amp; !NONDEBUG_INSN_P (insn))<br>
++          {<br>
++          next_insn:<br>
++            insn = NEXT_INSN (insn);<br>
++            if (insn == NEXT_INSN (BB_END (bb)))<br>
++              past_end = true;<br>
++            continue;<br>
++          }<br>
++        if (!past_end &amp;&amp; peep2_fill_buffer (bb, insn, live))<br>
++          goto next_insn;<br>
+<br>
+-                if (targetm.have_conditional_execution ())<br>
+-                  {<br>
+-                    for (i = 0; i &lt; MAX_INSNS_PER_PEEP2 + 1; ++i)<br>
+-                      peep2_insn_data[i].insn = NULL_RTX;<br>
+-                    peep2_insn_data[peep2_current].insn = PEEP2_EOB;<br>
+-                    peep2_current_count = 0;<br>
+-                  }<br>
+-                else<br>
+-                  {<br>
+-                    /* Back up lifetime information past the end of the<br>
+-                       newly created sequence.  */<br>
+-                    if (++i &gt;= MAX_INSNS_PER_PEEP2 + 1)<br>
+-                      i = 0;<br>
+-                    bitmap_copy (live, peep2_insn_data[i].live_before);<br>
+-<br>
+-                    /* Update life information for the new sequence.  */<br>
+-                    x = attempt;<br>
+-                    do<br>
+-                      {<br>
+-                        if (INSN_P (x))<br>
+-                          {<br>
+-                            if (--i &lt; 0)<br>
+-                              i = MAX_INSNS_PER_PEEP2;<br>
+-                            if (peep2_current_count &lt; MAX_INSNS_PER_PEEP2<br>
+-                                &amp;&amp; peep2_insn_data[i].insn == NULL_RTX)<br>
+-                              peep2_current_count++;<br>
+-                            peep2_insn_data[i].insn = x;<br>
+-                            df_insn_rescan (x);<br>
+-                            df_simulate_one_insn_backwards (bb, x, live);<br>
+-                            bitmap_copy (peep2_insn_data[i].live_before,<br>
+-                                         live);<br>
+-                          }<br>
+-                        x = PREV_INSN (x);<br>
+-                      }<br>
+-                    while (x != prev);<br>
++        /* If we did not fill an empty buffer, it signals the end of the<br>
++           block.  */<br>
++        if (peep2_current_count == 0)<br>
++          break;<br>
+<br>
+-                    peep2_current = i;<br>
+-                  }<br>
++        /* The buffer filled to the current maximum, so try to match.  */<br>
+<br>
+-                /* If we generated a jump instruction, it won&#39;t have<br>
+-                   JUMP_LABEL set.  Recompute after we&#39;re done.  */<br>
+-                for (x = attempt; x != before_try; x = PREV_INSN (x))<br>
+-                  if (JUMP_P (x))<br>
+-                    {<br>
+-                      do_rebuild_jump_labels = true;<br>
+-                      break;<br>
+-                    }<br>
+-              }<br>
++        pos = peep2_buf_position (peep2_current + peep2_current_count);<br>
++        peep2_insn_data[pos].insn = PEEP2_EOB;<br>
++        COPY_REG_SET (peep2_insn_data[pos].live_before, live);<br>
++<br>
++        /* Match the peephole.  */<br>
++        head = peep2_insn_data[peep2_current].insn;<br>
++        attempt = peephole2_insns (PATTERN (head), head, &amp;match_len);<br>
++        if (attempt != NULL)<br>
++          {<br>
++            rtx last;<br>
++            last = peep2_attempt (bb, head, match_len, attempt);<br>
++            peep2_update_life (bb, match_len, last, PREV_INSN (attempt));<br>
++          }<br>
++        else<br>
++          {<br>
++            /* If no match, advance the buffer by one insn.  */<br>
++            peep2_current = peep2_buf_position (peep2_current + 1);<br>
++            peep2_current_count--;<br>
+           }<br>
+-<br>
+-        if (insn == BB_HEAD (bb))<br>
+-          break;<br>
+       }<br>
+     }<br>
+<br>
+@@ -3341,7 +3406,7 @@ peephole2_optimize (void)<br>
+   for (i = 0; i &lt; MAX_INSNS_PER_PEEP2 + 1; ++i)<br>
+     BITMAP_FREE (peep2_insn_data[i].live_before);<br>
+   BITMAP_FREE (live);<br>
+-  if (do_rebuild_jump_labels)<br>
++  if (peep2_do_rebuild_jump_labels)<br>
+     rebuild_jump_labels (get_insns ());<br>
+ }<br>
+ #endif /* HAVE_peephole2 */<br>
+Index: gcc-4_5-branch/gcc/recog.h<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/recog.h<br>
++++ gcc-4_5-branch/gcc/recog.h<br>
+@@ -194,6 +194,9 @@ struct recog_data<br>
+   /* Gives the constraint string for operand N.  */<br>
+   const char *constraints[MAX_RECOG_OPERANDS];<br>
+<br>
++  /* Nonzero if operand N is a match_operator or a match_parallel.  */<br>
++  char is_operator[MAX_RECOG_OPERANDS];<br>
++<br>
+   /* Gives the mode of operand N.  */<br>
+   enum machine_mode operand_mode[MAX_RECOG_OPERANDS];<br>
+<br>
+@@ -260,6 +263,8 @@ struct insn_operand_data<br>
+<br>
+   const char strict_low;<br>
+<br>
++  const char is_operator;<br>
++<br>
+   const char eliminable;<br>
+ };<br>
+<br>
+Index: gcc-4_5-branch/gcc/reload.c<br>
+===================================================================<br>
+--- gcc-4_5-branch.orig/gcc/reload.c<br>
++++ gcc-4_5-branch/gcc/reload.c<br>
+@@ -3631,7 +3631,7 @@ find_reloads (rtx insn, int replace, int<br>
+                  || modified[j] != RELOAD_WRITE)<br>
+                 &amp;&amp; j != i<br>
+                 /* Ignore things like match_operator operands.  */<br>
+-                &amp;&amp; *recog_data.constraints[j] != 0<br>
++                &amp;&amp; !recog_data.is_operator[j]<br>
+                 /* Don&#39;t count an input operand that is constrained to match<br>
+                    the early clobber operand.  */<br>
+                 &amp;&amp; ! (this_alternative_matches[j] == i<br>
<font color="#888888">--<br>
1.7.0.4<br>
<br>
<br>
_______________________________________________<br>
Openembedded-core mailing list<br>
<a href="mailto:Openembedded-core@lists.linuxtogo.org">Openembedded-core@lists.linuxtogo.org</a><br>
<a href="http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core" target="_blank">http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core</a><br>
</font></blockquote></div><br>