OSDN Git Service

PR target/42321
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 21 Mar 2010 20:27:00 +0000 (20:27 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 21 Mar 2010 20:27:00 +0000 (20:27 +0000)
* arm.c (arm_output_epilogue): Correctly match VFP pop instructions
with their corresponding prologue pushes.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157609 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c

index d098df7..06e2ffd 100644 (file)
@@ -1,3 +1,9 @@
+2010-03-21  Richard Earnshaw  <rearnsha@arm.com>
+
+       PR target/42321
+       * arm.c (arm_output_epilogue): Correctly match VFP pop instructions
+       with their corresponding prologue pushes.
+
 2010-03-20  Andrew Pinski  <pinskia@gmail.com>
 
        PR target/43156
index cc023c1..6f42dd0 100644 (file)
@@ -13731,24 +13731,29 @@ arm_output_epilogue (rtx sibling)
 
       if (TARGET_HARD_FLOAT && TARGET_VFP)
        {
-         start_reg = FIRST_VFP_REGNUM;
-         for (reg = FIRST_VFP_REGNUM; reg < LAST_VFP_REGNUM; reg += 2)
+         int end_reg = LAST_VFP_REGNUM + 1;
+
+         /* Scan the registers in reverse order.  We need to match
+            any groupings made in the prologue and generate matching
+            pop operations.  */
+         for (reg = LAST_VFP_REGNUM - 1; reg >= FIRST_VFP_REGNUM; reg -= 2)
            {
              if ((!df_regs_ever_live_p (reg) || call_used_regs[reg])
-                 && (!df_regs_ever_live_p (reg + 1) || call_used_regs[reg + 1]))
+                 && (!df_regs_ever_live_p (reg + 1)
+                     || call_used_regs[reg + 1]))
                {
-                 if (start_reg != reg)
+                 if (end_reg > reg + 2)
                    vfp_output_fldmd (f, SP_REGNUM,
-                                     (start_reg - FIRST_VFP_REGNUM) / 2,
-                                     (reg - start_reg) / 2);
-                 start_reg = reg + 2;
+                                     (reg + 2 - FIRST_VFP_REGNUM) / 2,
+                                     (end_reg - (reg + 2)) / 2);
+                 end_reg = reg;
                }
            }
-         if (start_reg != reg)
-           vfp_output_fldmd (f, SP_REGNUM,
-                             (start_reg - FIRST_VFP_REGNUM) / 2,
-                             (reg - start_reg) / 2);
+         if (end_reg > reg + 2)
+           vfp_output_fldmd (f, SP_REGNUM, 0,
+                             (end_reg - (reg + 2)) / 2);
        }
+
       if (TARGET_IWMMXT)
        for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
          if (df_regs_ever_live_p (reg) && !call_used_regs[reg])