]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/final.c
2012-10-23 Vladimir Makarov <vmakarov@redhat.com>
[thirdparty/gcc.git] / gcc / final.c
index bffc1a9c46099f44c5c4c2040998c1d945442519..ceb688e5e312e256269bcc82bc890ab640081ef2 100644 (file)
@@ -2560,7 +2560,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
              {
                rtx src1, src2;
                if (GET_CODE (SET_SRC (set)) == SUBREG)
-                 SET_SRC (set) = alter_subreg (&SET_SRC (set));
+                 SET_SRC (set) = alter_subreg (&SET_SRC (set), true);
 
                src1 = SET_SRC (set);
                src2 = NULL_RTX;
@@ -2568,10 +2568,10 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
                  {
                    if (GET_CODE (XEXP (SET_SRC (set), 0)) == SUBREG)
                      XEXP (SET_SRC (set), 0)
-                       = alter_subreg (&XEXP (SET_SRC (set), 0));
+                       = alter_subreg (&XEXP (SET_SRC (set), 0), true);
                    if (GET_CODE (XEXP (SET_SRC (set), 1)) == SUBREG)
                      XEXP (SET_SRC (set), 1)
-                       = alter_subreg (&XEXP (SET_SRC (set), 1));
+                       = alter_subreg (&XEXP (SET_SRC (set), 1), true);
                    if (XEXP (SET_SRC (set), 1)
                        == CONST0_RTX (GET_MODE (XEXP (SET_SRC (set), 0))))
                      src2 = XEXP (SET_SRC (set), 0);
@@ -2974,7 +2974,7 @@ cleanup_subreg_operands (rtx insn)
         expression directly.  */
       if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
        {
-         recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i]);
+         recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i], true);
          changed = true;
        }
       else if (GET_CODE (recog_data.operand[i]) == PLUS
@@ -2987,7 +2987,7 @@ cleanup_subreg_operands (rtx insn)
     {
       if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
        {
-         *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i]);
+         *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i], true);
          changed = true;
        }
       else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
@@ -2999,11 +2999,11 @@ cleanup_subreg_operands (rtx insn)
     df_insn_rescan (insn);
 }
 
-/* If X is a SUBREG, replace it with a REG or a MEM,
-   based on the thing it is a subreg of.  */
+/* If X is a SUBREG, try to replace it with a REG or a MEM, based on
+   the thing it is a subreg of.  Do it anyway if FINAL_P.  */
 
 rtx
-alter_subreg (rtx *xp)
+alter_subreg (rtx *xp, bool final_p)
 {
   rtx x = *xp;
   rtx y = SUBREG_REG (x);
@@ -3027,16 +3027,19 @@ alter_subreg (rtx *xp)
             offset += difference % UNITS_PER_WORD;
         }
 
-      *xp = adjust_address (y, GET_MODE (x), offset);
+      if (final_p)
+       *xp = adjust_address (y, GET_MODE (x), offset);
+      else
+       *xp = adjust_address_nv (y, GET_MODE (x), offset);
     }
   else
     {
       rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
-                                SUBREG_BYTE (x));
+                                    SUBREG_BYTE (x));
 
       if (new_rtx != 0)
        *xp = new_rtx;
-      else if (REG_P (y))
+      else if (final_p && REG_P (y))
        {
          /* Simplify_subreg can't handle some REG cases, but we have to.  */
          unsigned int regno;
@@ -3076,7 +3079,7 @@ walk_alter_subreg (rtx *xp, bool *changed)
 
     case SUBREG:
       *changed = true;
-      return alter_subreg (xp);
+      return alter_subreg (xp, true);
 
     default:
       break;
@@ -3682,7 +3685,7 @@ void
 output_operand (rtx x, int code ATTRIBUTE_UNUSED)
 {
   if (x && GET_CODE (x) == SUBREG)
-    x = alter_subreg (&x);
+    x = alter_subreg (&x, true);
 
   /* X must not be a pseudo reg.  */
   gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);