reload.c (find_reloads_address): Make return value tri-state.
authorUlrich Weigand <uweigand@de.ibm.com>
Sun, 22 Aug 2004 22:09:12 +0000 (22:09 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Sun, 22 Aug 2004 22:09:12 +0000 (22:09 +0000)
* reload.c (find_reloads_address): Make return value tri-state.
Return -1 if LEGITIMIZE_RELOAD_ADDRESS succeeded.
(find_reloads): Assume that reloaded addresses match 'o' or
EXTRA_MEMORY_CONSTRAINT constraints only if find_reloads_address
returned 1 (not -1).  Omit optional reloads for address operands
only if find_reloads_address returned 1 (not -1).

* config/s390/s390.c (legitimize_reload_address): New function.
* config/s390/s390-protos.h (legitimize_reload_address): Declare.
* config/s390/s390.h (LEGITIMIZE_RELOAD_ADDRESS): Define.  Call
legitimize_reload_address.

From-SVN: r86388

gcc/ChangeLog
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/reload.c

index af7e4d471fddd005f5b05b4061b4b4845ee7fbac..11d177860fd255bfdc8b9fd736aa6238fa0a4689 100644 (file)
@@ -1,3 +1,17 @@
+2004-08-22  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * reload.c (find_reloads_address): Make return value tri-state.
+       Return -1 if LEGITIMIZE_RELOAD_ADDRESS succeeded.
+       (find_reloads): Assume that reloaded addresses match 'o' or
+       EXTRA_MEMORY_CONSTRAINT constraints only if find_reloads_address
+       returned 1 (not -1).  Omit optional reloads for address operands
+       only if find_reloads_address returned 1 (not -1).
+
+       * config/s390/s390.c (legitimize_reload_address): New function.
+       * config/s390/s390-protos.h (legitimize_reload_address): Declare.
+       * config/s390/s390.h (LEGITIMIZE_RELOAD_ADDRESS): Define.  Call
+       legitimize_reload_address.
+
 2004-08-22  Richard Hendersion  <rth@redhat.com>
 
        * tree.h (SAVE_EXPR_RESOLVED_P): New.
index b099122b63f40ba8af86a14b03e982f1d86449c3..6f05d80d545ba8516144b7a98ea64600923e838c 100644 (file)
@@ -65,6 +65,7 @@ extern int legitimate_reload_constant_p (rtx);
 extern int legitimate_address_p (enum machine_mode, rtx, int);
 extern rtx legitimize_pic_address (rtx, rtx);
 extern rtx legitimize_address (rtx, rtx, enum machine_mode);
+extern rtx legitimize_reload_address (rtx, enum machine_mode, int, int);
 extern enum reg_class s390_preferred_reload_class (rtx, enum reg_class);
 extern enum reg_class s390_secondary_input_reload_class (enum reg_class,
                                                         enum machine_mode,
index f68879c59963448954cd19301ba90e665029cb01..06953ae776f809ee7e22aa00074d8c7bceb54676 100644 (file)
@@ -3210,6 +3210,52 @@ legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
   return x;
 }
 
+/* Try a machine-dependent way of reloading an illegitimate address AD
+   operand.  If we find one, push the reload and and return the new address.
+
+   MODE is the mode of the enclosing MEM.  OPNUM is the operand number
+   and TYPE is the reload type of the current reload.  */
+
+rtx 
+legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
+                          int opnum, int type)
+{
+  if (!optimize || TARGET_LONG_DISPLACEMENT)
+    return NULL_RTX;
+
+  if (GET_CODE (ad) == PLUS)
+    {
+      rtx tem = simplify_binary_operation (PLUS, Pmode,
+                                          XEXP (ad, 0), XEXP (ad, 1));
+      if (tem)
+       ad = tem;
+    }
+
+  if (GET_CODE (ad) == PLUS
+      && GET_CODE (XEXP (ad, 0)) == REG
+      && GET_CODE (XEXP (ad, 1)) == CONST_INT
+      && !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
+    {
+      HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
+      HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
+      rtx cst, tem, new;
+
+      cst = GEN_INT (upper);
+      if (!legitimate_reload_constant_p (cst))
+       cst = force_const_mem (Pmode, cst);
+
+      tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
+      new = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
+
+      push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
+                  BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, 
+                  opnum, (enum reload_type) type);
+      return new;
+    }
+
+  return NULL_RTX;
+}
+
 /* Emit code to move LEN bytes from DST to SRC.  */
 
 void
index 7dec84f454fad85b0f9eafade51391fdf67589bc..f361ce4d37409e060f50e341ef865f103bb6af0b 100644 (file)
@@ -819,6 +819,19 @@ CUMULATIVE_ARGS;
     goto WIN;                                                           \
 }
 
+/* Try a machine-dependent way of reloading an illegitimate address
+   operand.  If we find one, push the reload and jump to WIN.  This
+   macro is used in only one place: `find_reloads_address' in reload.c.  */
+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN)     \
+do {                                                                   \
+  rtx new = legitimize_reload_address (AD, MODE, OPNUM, (int)(TYPE));  \
+  if (new)                                                             \
+    {                                                                  \
+      (AD) = new;                                                      \
+      goto WIN;                                                                \
+    }                                                                  \
+} while (0)
+
 /* Nonzero if the constant value X is a legitimate general operand.
    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
 #define LEGITIMATE_CONSTANT_P(X) \
index b3f7db80f9f31b814f27834893217c0c6dc59f24..260e4b7a3aaa7a94b9f25e3196fa7356082103ca 100644 (file)
@@ -2485,9 +2485,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
      a register.  */
   enum reg_class preferred_class[MAX_RECOG_OPERANDS];
   char pref_or_nothing[MAX_RECOG_OPERANDS];
-  /* Nonzero for a MEM operand whose entire address needs a reload.  */
+  /* Nonzero for a MEM operand whose entire address needs a reload. 
+     May be -1 to indicate the entire address may or may not need a reload.  */
   int address_reloaded[MAX_RECOG_OPERANDS];
-  /* Nonzero for an address operand that needs to be completely reloaded.  */
+  /* Nonzero for an address operand that needs to be completely reloaded.
+     May be -1 to indicate the entire operand may or may not need a reload.  */
   int address_operand_reloaded[MAX_RECOG_OPERANDS];
   /* Value of enum reload_type to use for operand.  */
   enum reload_type operand_type[MAX_RECOG_OPERANDS];
@@ -3180,7 +3182,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                          : offsettable_nonstrict_memref_p (operand))
                         /* A reloaded address is offsettable because it is now
                            just a simple register indirect.  */
-                        || address_reloaded[i]))
+                        || address_reloaded[i] == 1))
                    || (REG_P (operand)
                        && REGNO (operand) >= FIRST_PSEUDO_REGISTER
                        && reg_renumber[REGNO (operand)] < 0
@@ -3291,7 +3293,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                        /* If the address was already reloaded,
                           we win as well.  */
                        else if (MEM_P (operand)
-                                && address_reloaded[i])
+                                && address_reloaded[i] == 1)
                          win = 1;
                        /* Likewise if the address will be reloaded because
                           reg_equiv_address is nonzero.  For reg_equiv_mem
@@ -3891,7 +3893,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
       }
     else if (goal_alternative_matched[i] < 0
             && goal_alternative_matches[i] < 0
-            && !address_operand_reloaded[i]
+            && address_operand_reloaded[i] != 1
             && optimize)
       {
        /* For each non-matching operand that's a MEM or a pseudo-register
@@ -4631,8 +4633,9 @@ maybe_memory_address_p (enum machine_mode mode, rtx ad, rtx *part)
    to determine if we may generate output reloads, and where to put USEs
    for pseudos that we have to replace with stack slots.
 
-   Value is nonzero if this address is reloaded or replaced as a whole.
-   This is interesting to the caller if the address is an autoincrement.
+   Value is one if this address is reloaded or replaced as a whole; it is
+   zero if the top level of this address was not reloaded or replaced, and
+   it is -1 if it may or may not have been reloaded or replaced.
 
    Note that there is no verification that the address will be valid after
    this routine does its work.  Instead, we rely on the fact that the address
@@ -4771,7 +4774,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
       *memrefloc = copy_rtx (*memrefloc);
       XEXP (*memrefloc, 0) = ad;
       move_replacements (&ad, &XEXP (*memrefloc, 0));
-      return 1;
+      return -1;
     }
   while (0);
 #endif