OSDN Git Service

* reload1.c (eliminate_regs, case MINUS): Canonicalize
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Jan 1997 17:15:54 +0000 (17:15 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Jan 1997 17:15:54 +0000 (17:15 +0000)
(minus (plus reg const) reg) to (plus (minus reg reg) const).
* reload.c (find_reloads_address): Treat (plus (minus reg reg) const)
the same as (plus (plus reg reg) const).

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

gcc/reload.c
gcc/reload1.c

index 5bb39dc..e1f5f91 100644 (file)
@@ -4368,7 +4368,9 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
   /* If we have an indexed stack slot, there are three possible reasons why
      it might be invalid: The index might need to be reloaded, the address
      might have been made by frame pointer elimination and hence have a
-     constant out of range, or both reasons might apply.  
+     constant out of range, or the address is the result of register
+     elimination and (plus (plus reg reg) const), which has been
+     canonicalized from (plus (plus reg const) reg), isn't a valid address.
 
      We can easily check for an index needing reload, but even if that is the
      case, we might also have an invalid constant.  To avoid making the
@@ -4395,7 +4397,11 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
      innermost PLUS.  */
 
   else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
-          && GET_CODE (XEXP (ad, 0)) == PLUS
+          && (GET_CODE (XEXP (ad, 0)) == PLUS
+              /* MINUS can happen as a result of register elimination of
+                 (minus eliminable reg) which gets canonicalized as
+                 (plus (minus reg reg) const).  */
+              || GET_CODE (XEXP (ad, 0)) == MINUS)
           && (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
               || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
@@ -4406,7 +4412,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
               || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
           && ! memory_address_p (mode, ad))
     {
-      *loc = ad = gen_rtx (PLUS, GET_MODE (ad),
+      *loc = ad = gen_rtx (GET_CODE (XEXP (ad, 0)), GET_MODE (ad),
                           plus_constant (XEXP (XEXP (ad, 0), 0),
                                          INTVAL (XEXP (ad, 1))),
                           XEXP (XEXP (ad, 0), 1));
index b5e9394..d4f2140 100644 (file)
@@ -2853,7 +2853,7 @@ eliminate_regs (x, mem_mode, insn)
         context.
 
         If we have (plus (eliminable) (reg)), we want to produce
-        (plus (plus (replacement) (reg) (const))).  If this was part of a
+        (plus (plus (replacement) (reg)) (const)).  If this was part of a
         normal add insn, (plus (replacement) (reg)) will be pushed as a
         reload.  This is the desired action.  */
 
@@ -2892,6 +2892,28 @@ eliminate_regs (x, mem_mode, insn)
       }
       return x;
 
+    case MINUS:
+      /* If we have (minus (eliminable) (reg)), we want to produce
+        (plus (minus (replacement) (reg)) (const)).  The main reason being
+        to be consistent with what is done for PLUS.  find_reloads_address
+        assumes that we do this.  */
+      {
+       rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
+       rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn);
+
+       if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
+         {
+           if (GET_CODE (new0) == PLUS)
+             return gen_rtx (PLUS, GET_MODE (x),
+                             gen_rtx (MINUS, GET_MODE (x),
+                                      XEXP (new0, 0), new1),
+                             XEXP (new0, 1));
+           else
+             return gen_rtx (MINUS, GET_MODE (x), new0, new1);
+         }
+      }
+      return x;
+
     case MULT:
       /* If this is the product of an eliminable register and a 
         constant, apply the distribute law and move the constant out
@@ -2920,7 +2942,6 @@ eliminate_regs (x, mem_mode, insn)
 
     case CALL:
     case COMPARE:
-    case MINUS:
     case DIV:      case UDIV:
     case MOD:      case UMOD:
     case AND:      case IOR:      case XOR: