OSDN Git Service

(sparc_builtin_saveregs): New function.
[pf3gnuchains/gcc-fork.git] / gcc / reload.c
index e15a5e6..c75f158 100644 (file)
@@ -207,6 +207,17 @@ static int n_replacements;
 static rtx memlocs[MAX_RECOG_OPERANDS * ((MAX_REGS_PER_ADDRESS * 2) + 1)];
 static int n_memlocs;
 
+#ifdef SECONDARY_MEMORY_NEEDED
+
+/* Save MEMs needed to copy from one class of registers to another.  One MEM
+   is used per mode, but normally only one or two modes are ever used.  
+
+   We keep two versions, before and after register elimination.  */
+
+static rtx secondary_memlocs[NUM_MACHINE_MODES];
+static rtx secondary_memlocs_elim[NUM_MACHINE_MODES];
+#endif
+
 /* The instruction we are doing reloads for;
    so we can test whether a register dies in it.  */
 static rtx this_insn;
@@ -242,6 +253,7 @@ static int hard_reg_set_here_p ();
 /* static rtx forget_volatility (); */
 static rtx subst_reg_equivs ();
 static rtx subst_indexed_address ();
+void copy_replacements ();
 rtx find_equiv_reg ();
 static int find_inc_amount ();
 \f
@@ -369,6 +381,78 @@ find_secondary_reload (x, reload_class, reload_mode, in_p, picode, pmode,
 }
 #endif /* HAVE_SECONDARY_RELOADS */
 \f
+#ifdef SECONDARY_MEMORY_NEEDED
+
+/* Return a memory location that will be used to copy X in mode MODE.  
+   If we haven't already made a location for this mode in this insn,
+   call find_reloads_address on the location being returned.  */
+
+rtx
+get_secondary_mem (x, mode)
+     rtx x;
+     enum machine_mode mode;
+{
+  rtx loc;
+  int mem_valid;
+
+  /* If MODE is narrower than a word, widen it.  This is required because
+     most machines that require these memory locations do not support
+     short load and stores from all registers (e.g., FP registers).  We could
+     possibly conditionalize this, but we lose nothing by doing the wider
+     mode.  */
+
+  if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
+    mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0);
+
+  /* If we already have made a MEM for this insn, return it.  */
+  if (secondary_memlocs_elim[(int) mode] != 0)
+    return secondary_memlocs_elim[(int) mode];
+
+  /* If this is the first time we've tried to get a MEM for this mode, 
+     allocate a new one.  `something_changed' in reload will get set
+     by noticing that the frame size has changed.  */
+
+  if (secondary_memlocs[(int) mode] == 0)
+    secondary_memlocs[(int) mode]
+      = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
+
+  /* Get a version of the address doing any eliminations needed.  If that
+     didn't give us a new MEM, make a new one if it isn't valid.  */
+
+  loc = eliminate_regs (secondary_memlocs[(int) mode], 0, NULL_RTX);
+  mem_valid = strict_memory_address_p (mode, XEXP (loc, 0));
+
+  if (! mem_valid && loc == secondary_memlocs[(int) mode])
+    loc = copy_rtx (loc);
+
+  /* The only time the call below will do anything is if the stack
+     offset is too large.  In that case IND_LEVELS doesn't matter, so we
+     can just pass a zero.  */
+  if (! mem_valid)
+    find_reloads_address (mode, NULL_PTR, XEXP (loc, 0), &XEXP (loc, 0), x, 0);
+
+  /* If the address was not valid to begin with, we can not save it, because
+     there is no guarantee that the reloads needed to make it valid will
+     occur before every use of this address.  */
+
+  else
+    secondary_memlocs_elim[(int) mode] = loc;
+
+  return loc;
+}
+
+/* Clear any secondary memory locations we've made.  */
+
+void
+clear_secondary_mem ()
+{
+  int i;
+
+  for (i = 0; i < NUM_MACHINE_MODES; i++)
+    secondary_memlocs[i] = 0;
+}
+#endif /* SECONDARY_MEMORY_NEEDED */
+\f
 /* Record one (sometimes two) reload that needs to be performed.
    IN is an rtx saying where the data are to be found before this instruction.
    OUT says where they must be stored after the instruction.
@@ -476,7 +560,10 @@ push_reload (in, out, inloc, outloc, class,
      we can't handle it here because CONST_INT does not indicate a mode.
 
      Similarly, we must reload the inside expression if we have a
-     STRICT_LOW_PART (presumably, in == out in the cas).  */
+     STRICT_LOW_PART (presumably, in == out in the cas).
+
+     Also reload the inner expression if it does not require a secondary
+     reload but the SUBREG does.  */
 
   if (in != 0 && GET_CODE (in) == SUBREG
       && (GET_CODE (SUBREG_REG (in)) != REG
@@ -494,7 +581,15 @@ push_reload (in, out, inloc, outloc, class,
                      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
                           / UNITS_PER_WORD)
                          != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
-                                              GET_MODE (SUBREG_REG (in)))))))))
+                                              GET_MODE (SUBREG_REG (in)))))))
+#ifdef SECONDARY_INPUT_RELOAD_CLASS
+         || (SECONDARY_INPUT_RELOAD_CLASS (class, inmode, in) != NO_REGS
+             && (SECONDARY_INPUT_RELOAD_CLASS (class,
+                                               GET_MODE (SUBREG_REG (in)),
+                                               SUBREG_REG (in))
+                 == NO_REGS))
+#endif
+         ))
     {
       in_subreg_loc = inloc;
       inloc = &SUBREG_REG (in);
@@ -529,7 +624,15 @@ push_reload (in, out, inloc, outloc, class,
                      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
                           / UNITS_PER_WORD)
                          != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
-                                              GET_MODE (SUBREG_REG (out)))))))))
+                                              GET_MODE (SUBREG_REG (out)))))))
+#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
+         || (SECONDARY_OUTPUT_RELOAD_CLASS (class, outmode, out) != NO_REGS
+             && (SECONDARY_OUTPUT_RELOAD_CLASS (class,
+                                                GET_MODE (SUBREG_REG (out)),
+                                                SUBREG_REG (out))
+                 == NO_REGS))
+#endif
+         ))
     {
       out_subreg_loc = outloc;
       outloc = &SUBREG_REG (out);
@@ -547,14 +650,35 @@ push_reload (in, out, inloc, outloc, class,
   /* If IN appears in OUT, we can't share any input-only reload for IN.  */
   if (in != 0 && out != 0 && GET_CODE (out) == MEM
       && (GET_CODE (in) == REG || GET_CODE (in) == MEM)
-      && reg_overlap_mentioned_p (in, XEXP (out, 0)))
+      && reg_overlap_mentioned_for_reload_p (in, XEXP (out, 0)))
     dont_share = 1;
 
+  /* If IN is a SUBREG of a hard register, make a new REG.  This
+     simplifies some of the cases below.  */
+
+  if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
+      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER)
+    in = gen_rtx (REG, GET_MODE (in),
+                 REGNO (SUBREG_REG (in)) + SUBREG_WORD (in));
+
+  /* Similarly for OUT.  */
+  if (out != 0 && GET_CODE (out) == SUBREG
+      && GET_CODE (SUBREG_REG (out)) == REG
+      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER)
+    out = gen_rtx (REG, GET_MODE (out),
+                 REGNO (SUBREG_REG (out)) + SUBREG_WORD (out));
+
   /* Narrow down the class of register wanted if that is
      desirable on this machine for efficiency.  */
   if (in != 0)
     class = PREFERRED_RELOAD_CLASS (in, class);
 
+  /* Output reloads may need analogous treatment, different in detail.  */
+#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
+  if (out != 0)
+    class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class);
+#endif
+
   /* Make sure we use a class that can handle the actual pseudo
      inside any subreg.  For example, on the 386, QImode regs
      can appear within SImode subregs.  Although GENERAL_REGS
@@ -571,9 +695,6 @@ push_reload (in, out, inloc, outloc, class,
     class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), class);
 #endif
 
-  if (class == NO_REGS)
-    abort ();
-
   /* Verify that this class is at least possible for the mode that
      is specified.  */
   if (this_insn_is_asm)
@@ -583,6 +704,15 @@ push_reload (in, out, inloc, outloc, class,
        mode = inmode;
       else
        mode = outmode;
+      if (mode == VOIDmode)
+       {
+         error_for_asm (this_insn, "cannot reload integer constant operand in `asm'");
+         mode = word_mode;
+         if (in != 0)
+           inmode = word_mode;
+         if (out != 0)
+           outmode = word_mode;
+       }
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (HARD_REGNO_MODE_OK (i, mode)
            && TEST_HARD_REG_BIT (reg_class_contents[(int) class], i))
@@ -603,6 +733,9 @@ push_reload (in, out, inloc, outloc, class,
        }
     }
 
+  if (class == NO_REGS)
+    abort ();
+
   /* We can use an existing reload if the class is right
      and at least one of IN and OUT is a match
      and the other is at worst neutral.
@@ -709,8 +842,8 @@ push_reload (in, out, inloc, outloc, class,
              || secondary_icode != CODE_FOR_nothing
              || secondary_out_icode != CODE_FOR_nothing))
        {
-         push_reload (0, out, 0, outloc, class, VOIDmode, outmode,
-                      strict_low, optional, needed_for);
+         push_reload (NULL_RTX, out, NULL_PTR, outloc, class,
+                      VOIDmode, outmode, strict_low, optional, needed_for);
          out = 0;
          outloc = 0;
          outmode = VOIDmode;
@@ -839,6 +972,19 @@ push_reload (in, out, inloc, outloc, class,
 
              n_reloads++;
              i = n_reloads;
+
+#ifdef SECONDARY_MEMORY_NEEDED
+             /* If we need a memory location to copy between the two
+                reload regs, set it up now.  */
+
+             if (in != 0 && secondary_icode == CODE_FOR_nothing
+                 && SECONDARY_MEMORY_NEEDED (secondary_class, class, inmode))
+               get_secondary_mem (in, inmode);
+
+             if (out != 0 && secondary_icode == CODE_FOR_nothing
+                 && SECONDARY_MEMORY_NEEDED (class, secondary_class, outmode))
+               get_secondary_mem (out, outmode);
+#endif
            }
        }
 #endif
@@ -864,6 +1010,21 @@ push_reload (in, out, inloc, outloc, class,
       reload_secondary_p[i] = 0;
 
       n_reloads++;
+
+#ifdef SECONDARY_MEMORY_NEEDED
+      /* If a memory location is needed for the copy, make one.  */
+      if (in != 0 && GET_CODE (in) == REG
+         && REGNO (in) < FIRST_PSEUDO_REGISTER
+         && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
+                                    class, inmode))
+       get_secondary_mem (in, inmode);
+
+      if (out != 0 && GET_CODE (out) == REG
+         && REGNO (out) < FIRST_PSEUDO_REGISTER
+         && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (REGNO (out)),
+                                     outmode))
+       get_secondary_mem (out, outmode);
+#endif
     }
   else
     {
@@ -1076,7 +1237,7 @@ combine_reloads ()
   if (reload_in[output_reload] != 0)
     return;
 
-  /* If this reload is for an earlyclobber operand, we can't do anyting.  */
+  /* If this reload is for an earlyclobber operand, we can't do anything.  */
 
   for (i = 0; i < n_earlyclobbers; i++)
     if (reload_out[output_reload] == reload_earlyclobbers[i])
@@ -1088,6 +1249,7 @@ combine_reloads ()
     if (reload_in[i] && ! reload_optional[i] && ! reload_nocombine[i]
        /* Life span of this reload must not extend past main insn.  */
        && reload_when_needed[i] != RELOAD_FOR_OUTPUT_RELOAD_ADDRESS
+       && ! reload_needed_for_multiple[i]
        && reload_inmode[i] == reload_outmode[output_reload]
        && reload_inc[i] == 0
        && reload_reg_rtx[i] == 0
@@ -1104,8 +1266,8 @@ combine_reloads ()
            /* Args reversed because the first arg seems to be
               the one that we imagine being modified
               while the second is the one that might be affected.  */
-           || (! reg_overlap_mentioned_p (reload_out[output_reload],
-                                          reload_in[i])
+           || (! reg_overlap_mentioned_for_reload_p (reload_out[output_reload],
+                                                     reload_in[i])
                /* However, if the input is a register that appears inside
                   the output, then we also can't share.
                   Imagine (set (mem (reg 69)) (plus (reg 69) ...)).
@@ -1113,8 +1275,8 @@ combine_reloads ()
                   result to be stored in memory, then that result
                   will clobber the address of the memory ref.  */
                && ! (GET_CODE (reload_in[i]) == REG
-                     && reg_overlap_mentioned_p (reload_in[i],
-                                                 reload_out[output_reload])))))
+                     && reg_overlap_mentioned_for_reload_p (reload_in[i],
+                                                            reload_out[output_reload])))))
       {
        int j;
 
@@ -1162,8 +1324,8 @@ combine_reloads ()
   for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
     if (REG_NOTE_KIND (note) == REG_DEAD
        && GET_CODE (XEXP (note, 0)) == REG
-       && ! reg_overlap_mentioned_p (XEXP (note, 0),
-                                     reload_out[output_reload])
+       && ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
+                                                reload_out[output_reload])
        && REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
        && HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), reload_outmode[output_reload])
        && TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[output_reload]],
@@ -1236,6 +1398,7 @@ find_dummy_reload (real_in, real_out, inloc, outloc, class, for_real)
     {
       register int regno = REGNO (out) + out_offset;
       int nwords = HARD_REGNO_NREGS (regno, GET_MODE (real_out));
+      rtx saved_rtx;
 
       /* When we consider whether the insn uses OUT,
         ignore references within IN.  They don't prevent us
@@ -1246,6 +1409,7 @@ find_dummy_reload (real_in, real_out, inloc, outloc, class, for_real)
         If the insn uses IN elsewhere and it contains OUT,
         that counts.  We can't be sure it's the "same" operand
         so it might not go through this reload.  */
+      saved_rtx = *inloc;
       *inloc = const0_rtx;
 
       if (regno < FIRST_PSEUDO_REGISTER
@@ -1272,7 +1436,7 @@ find_dummy_reload (real_in, real_out, inloc, outloc, class, for_real)
            }
        }
 
-      *inloc = real_in;
+      *inloc = saved_rtx;
     }
 
   /* Consider using IN if OUT was not acceptable
@@ -1292,7 +1456,7 @@ find_dummy_reload (real_in, real_out, inloc, outloc, class, for_real)
       register int regno = REGNO (in) + in_offset;
       int nwords = HARD_REGNO_NREGS (regno, GET_MODE (real_in));
 
-      if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, 0)
+      if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, NULL_PTR)
          && ! hard_reg_set_here_p (regno, regno + nwords,
                                    PATTERN (this_insn)))
        {
@@ -1428,6 +1592,16 @@ operands_match_p (x, y)
       else
        j = REGNO (y);
 
+      /* On a WORDS_BIG_ENDIAN machine, point to the last register of a
+        multiple hard register group, so that for example (reg:DI 0) and
+        (reg:SI 1) will be considered the same register.  */
+      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
+         && i < FIRST_PSEUDO_REGISTER)
+       i += (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD) - 1;
+      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
+         && j < FIRST_PSEUDO_REGISTER)
+       j += (GET_MODE_SIZE (GET_MODE (y)) / UNITS_PER_WORD) - 1;
+
       return i == j;
     }
   /* If two operands must match, because they are really a single
@@ -1472,6 +1646,11 @@ operands_match_p (x, y)
       int val;
       switch (fmt[i])
        {
+       case 'w':
+         if (XWINT (x, i) != XWINT (y, i))
+           return 0;
+         break;
+
        case 'i':
          if (XINT (x, i) != XINT (y, i))
            return 0;
@@ -1502,7 +1681,7 @@ operands_match_p (x, y)
 \f
 /* Return the number of times character C occurs in string S.  */
 
-static int
+int
 n_occurrences (c, s)
      char c;
      char *s;
@@ -1518,8 +1697,8 @@ struct decomposition
   int reg_flag;
   int safe;
   rtx base;
-  int start;
-  int end;
+  HOST_WIDE_INT start;
+  HOST_WIDE_INT end;
 };
 
 /* Describe the range of registers or memory referenced by X.
@@ -1662,7 +1841,7 @@ immune_p (x, y, ydata)
   struct decomposition xdata;
 
   if (ydata.reg_flag)
-    return !refers_to_regno_for_reload_p (ydata.start, ydata.end, x, 0);
+    return !refers_to_regno_for_reload_p (ydata.start, ydata.end, x, NULL_PTR);
   if (ydata.safe)
     return 1;
 
@@ -1696,7 +1875,7 @@ immune_p (x, y, ydata)
   return (xdata.start >= ydata.end || ydata.start >= xdata.end);
 }
 
-/* Similiar, but calls decompose.  */
+/* Similar, but calls decompose.  */
 
 int
 safe_from_earlyclobber (op, clobber)
@@ -1805,6 +1984,13 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
     no_output_reloads = 1;
 #endif
      
+#ifdef SECONDARY_MEMORY_NEEDED
+  /* The eliminated forms of any secondary memory locations are per-insn, so
+     clear them out here.  */
+
+  bzero (secondary_memlocs_elim, sizeof secondary_memlocs_elim);
+#endif
+
   /* Find what kind of insn this is.  NOPERANDS gets number of operands.
      Make OPERANDS point to a vector of operand values.
      Make OPERAND_LOCS point to a vector of pointers to
@@ -1913,19 +2099,34 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
       while (c = *p++)
        if (c == '%')
          {
-           /* The last operand should not be marked commutative.  This
-              problem is hard to detect, so make it obvious by calling
-              abort here.  */
+           /* The last operand should not be marked commutative.  */
            if (i == noperands - 1)
-             abort ();
-
-           commutative = i;
+             {
+               if (this_insn_is_asm)
+                 warning_for_asm (this_insn,
+                                  "`%%' constraint used with last operand");
+               else
+                 abort ();
+             }
+           else
+             commutative = i;
          }
        else if (c >= '0' && c <= '9')
          {
            c -= '0';
            operands_match[c][i]
              = operands_match_p (recog_operand[c], recog_operand[i]);
+
+           /* An operand may not match itself.  */
+           if (c == i)
+             {
+               if (this_insn_is_asm)
+                 warning_for_asm (this_insn,
+                                  "operand %d has constraint %d", i, c);
+               else
+                 abort ();
+             }
+
            /* If C can be commuted with C+1, and C might need to match I,
               then C+1 might also need to match I.  */
            if (commutative >= 0)
@@ -1963,16 +2164,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
       register RTX_CODE code = GET_CODE (recog_operand[i]);
       modified[i] = RELOAD_READ;
       address_reloaded[i] = 0;
-      preferred_class[i]
-       = ((code == REG && REGNO (recog_operand[i]) > FIRST_PSEUDO_REGISTER)
-          ? reg_preferred_class (REGNO (recog_operand[i])) : NO_REGS);
-      pref_or_nothing[i]
-       = (code == REG && REGNO (recog_operand[i]) > FIRST_PSEUDO_REGISTER
-          && reg_preferred_or_nothing (REGNO (recog_operand[i])));
 
       if (constraints[i][0] == 'p')
        {
-         find_reloads_address (VOIDmode, 0,
+         find_reloads_address (VOIDmode, NULL_PTR,
                                recog_operand[i], recog_operand_loc[i],
                                recog_operand[i], ind_levels);
          substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
@@ -2037,13 +2232,17 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                                    &XEXP (recog_operand[i], 0),
                                    recog_operand[i], ind_levels);
              substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
-
-             /* This is no longer a psuedo register.  To prevent later code
-                from thinking it still is, we must reset the preferred_class
-                to NO_REGS.  */
-             preferred_class[i] = NO_REGS;
            }
        }
+      /* If the operand is still a register (we didn't replace it with an
+        equivalent), get the preferred class to reload it into.  */
+      code = GET_CODE (recog_operand[i]);
+      preferred_class[i]
+       = ((code == REG && REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER)
+          ? reg_preferred_class (REGNO (recog_operand[i])) : NO_REGS);
+      pref_or_nothing[i]
+       = (code == REG && REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER
+          && reg_alternate_class (REGNO (recog_operand[i])) == NO_REGS);
     }
 
   /* If this is simply a copy from operand 1 to operand 0, merge the
@@ -2123,14 +2322,18 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
              /* Force reload if this is not a register or if there may may
                 be a problem accessing the register in the outer mode.  */
              if (GET_CODE (operand) != REG
-#ifdef BYTE_LOADS_ZERO_EXTEND
+#if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
+                 /* ??? The comment below clearly does not match the code.
+                    What the code below actually does is set force_reload
+                    for a paradoxical subreg of a pseudo.  rms and kenner
+                    can't see the point of doing this.  */
                  /* Nonparadoxical subreg of a pseudoreg.
                     Don't to load the full width if on this machine
-                    we expected the fetch to zero-extend.  */
+                    we expected the fetch to extend.  */
                  || ((GET_MODE_SIZE (operand_mode[i])
                       > GET_MODE_SIZE (GET_MODE (operand)))
                      && REGNO (operand) >= FIRST_PSEUDO_REGISTER)
-#endif /* BYTE_LOADS_ZERO_EXTEND */
+#endif
                  /* Subreg of a hard reg which can't handle the subreg's mode
                     or which would handle that mode in the wrong number of
                     registers for subregging to work.  */
@@ -2180,7 +2383,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                break;
 
              case '%':
-               commutative = i;
+               /* The last operand should not be marked commutative.  */
+               if (i != noperands - 1)
+                 commutative = i;
                break;
 
              case '?':
@@ -2341,7 +2546,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                /* Match any floating double constant, but only if
                   we can examine the bits of it reliably.  */
                if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
-                    || HOST_BITS_PER_INT != BITS_PER_WORD)
+                    || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
                    && GET_MODE (operand) != VOIDmode && ! flag_pretend_float)
                  break;
                if (GET_CODE (operand) == CONST_DOUBLE)
@@ -2504,11 +2709,18 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
             Don't bother with this if this alternative will accept this
             operand.
 
+            Don't do this for a multiword operand, if
+            we have to worry about small classes, because making reg groups
+            harder to allocate is asking for trouble.
+
             Don't do this if the preferred class has only one register
             because we might otherwise exhaust the class.  */
 
 
          if (! win && this_alternative[i] != (int) NO_REGS
+#ifdef SMALL_REGISTER_CLASSES
+             && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
+#endif
              && reg_class_size[(int) preferred_class[i]] > 1)
            {
              if (! reg_class_subset_p (this_alternative[i],
@@ -2788,10 +3000,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                 && GET_CODE (recog_operand[i]) == MEM)
          {
            operand_reloadnum[i]
-             = push_reload (XEXP (recog_operand[i], 0), 0,
-                            &XEXP (recog_operand[i], 0), 0,
+             = push_reload (XEXP (recog_operand[i], 0), NULL_RTX,
+                            &XEXP (recog_operand[i], 0), NULL_PTR,
                             BASE_REG_CLASS, GET_MODE (XEXP (recog_operand[i], 0)),
-                            VOIDmode, 0, 0, 0);
+                            VOIDmode, 0, 0, NULL_RTX);
            reload_inc[operand_reloadnum[i]]
              = GET_MODE_SIZE (GET_MODE (recog_operand[i]));
          }
@@ -2806,7 +3018,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                         (modified[i] == RELOAD_READ ? VOIDmode : operand_mode[i]),
                         (insn_code_number < 0 ? 0
                          : insn_operand_strict_low[insn_code_number][i]),
-                        0, 0);
+                        0, NULL_RTX);
        /* In a matching pair of operands, one must be input only
           and the other must be output only.
           Pass the input operand as IN and the other as OUT.  */
@@ -2821,7 +3033,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                             (enum reg_class) goal_alternative[i],
                             operand_mode[i],
                             operand_mode[goal_alternative_matched[i]],
-                            0, 0, 0);
+                            0, 0, NULL_RTX);
            operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
          }
        else if (modified[i] == RELOAD_WRITE
@@ -2835,7 +3047,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                             (enum reg_class) goal_alternative[i],
                             operand_mode[goal_alternative_matched[i]],
                             operand_mode[i],
-                            0, 0, 0);
+                            0, 0, NULL_RTX);
            operand_reloadnum[i] = output_reloadnum;
          }
        else if (insn_code_number >= 0)
@@ -2879,7 +3091,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                           (modified[i] == RELOAD_READ ? VOIDmode : operand_mode[i]),
                           (insn_code_number < 0 ? 0
                            : insn_operand_strict_low[insn_code_number][i]),
-                          1, 0);
+                          1, NULL_RTX);
        /* Make an optional reload for an explicit mem ref.  */
        else if (GET_CODE (operand) == MEM
                 && (enum reg_class) goal_alternative[i] != NO_REGS
@@ -2897,7 +3109,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                           (modified[i] == RELOAD_READ ? VOIDmode : operand_mode[i]),
                           (insn_code_number < 0 ? 0
                            : insn_operand_strict_low[insn_code_number][i]),
-                          1, 0);
+                          1, NULL_RTX);
        else
          non_reloaded_operands[n_non_reloaded_operands++] = recog_operand[i];
       }
@@ -2998,7 +3210,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
 
          /* Now get the operand values out of the insn.  */
 
-         decode_asm_operands (body, recog_operand, recog_operand_loc, 0, 0);
+         decode_asm_operands (body, recog_operand, recog_operand_loc,
+                              NULL_PTR, NULL_PTR);
          break;
        }
 
@@ -3021,7 +3234,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
 
       if (insn_code_number >= 0)
        if (insn_operand_address_p[insn_code_number][i])
-         find_reloads_address (VOIDmode, 0,
+         find_reloads_address (VOIDmode, NULL_PTR,
                                recog_operand[i], recog_operand_loc[i],
                                recog_operand[i], ind_levels);
       if (code == MEM)
@@ -3111,6 +3324,13 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
 
          if (output_address && reload_when_needed[i] == RELOAD_OTHER)
            reload_needed_for_multiple[i] = 1;
+
+         /* If we have earlyclobbers, make sure nothing overlaps them.  */
+         if (n_earlyclobbers > 0)
+           {
+             reload_when_needed[i] = RELOAD_OTHER;
+             reload_needed_for_multiple[i] = 1;
+           }
        }
     }
 
@@ -3146,7 +3366,7 @@ alternative_allows_memconst (constraint, altnum)
 /* Scan X for memory references and scan the addresses for reloading.
    Also checks for references to "constant" regs that we want to eliminate
    and replaces them with the values they stand for.
-   We may alter X descructively if it contains a reference to such.
+   We may alter X destructively if it contains a reference to such.
    If X is just a constant reg, we return the equivalent value
    instead of X.
 
@@ -3189,7 +3409,7 @@ find_reloads_toplev (x, ind_levels, is_set_dest)
 
          x = gen_rtx (MEM, GET_MODE (x), addr);
          RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
-         find_reloads_address (GET_MODE (x), 0,
+         find_reloads_address (GET_MODE (x), NULL_PTR,
                                XEXP (x, 0),
                                &XEXP (x, 0), x, ind_levels);
        }
@@ -3246,12 +3466,12 @@ find_reloads_toplev (x, ind_levels, is_set_dest)
         not offsettable.  In that case, alter_subreg would produce an
         invalid address on big-endian machines.
 
-        For machines that zero-extend byte loads, we must not reload using
+        For machines that extend byte loads, we must not reload using
         a wider mode if we have a paradoxical SUBREG.  find_reloads will
         force a reload in that case.  So we should not do anything here.  */
 
       else if (regno >= FIRST_PSEUDO_REGISTER
-#ifdef BYTE_LOADS_ZERO_EXTEND
+#if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
               && (GET_MODE_SIZE (GET_MODE (x))
                   <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
 #endif
@@ -3272,7 +3492,7 @@ find_reloads_toplev (x, ind_levels, is_set_dest)
          addr = plus_constant (addr, offset);
          x = gen_rtx (MEM, GET_MODE (x), addr);
          RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
-         find_reloads_address (GET_MODE (x), 0,
+         find_reloads_address (GET_MODE (x), NULL_PTR,
                                XEXP (x, 0),
                                &XEXP (x, 0), x, ind_levels);
        }
@@ -3360,9 +3580,9 @@ find_reloads_address (mode, memrefloc, ad, loc, operand, ind_levels)
       else if (reg_equiv_address[regno] != 0)
        {
          tem = make_memloc (ad, regno);
-         find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
+         find_reloads_address (GET_MODE (tem), NULL_PTR, XEXP (tem, 0),
                                &XEXP (tem, 0), operand, ind_levels);
-         push_reload (tem, 0, loc, 0, BASE_REG_CLASS,
+         push_reload (tem, NULL_RTX, loc, NULL_PTR, BASE_REG_CLASS,
                       GET_MODE (ad), VOIDmode, 0, 0,
                       operand);
          return 1;
@@ -3397,7 +3617,7 @@ find_reloads_address (mode, memrefloc, ad, loc, operand, ind_levels)
        return 0;
 
       /* If we do not have one of the cases above, we must do the reload.  */
-      push_reload (ad, 0, loc, 0, BASE_REG_CLASS,
+      push_reload (ad, NULL_RTX, loc, NULL_PTR, BASE_REG_CLASS,
                   GET_MODE (ad), VOIDmode, 0, 0, operand);
       return 1;
     }
@@ -3442,6 +3662,19 @@ find_reloads_address (mode, memrefloc, ad, loc, operand, ind_levels)
       tem = ad;
       find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0),
                            operand, ind_levels == 0 ? 0 : ind_levels - 1);
+
+      /* If tem was changed, then we must create a new memory reference to
+        hold it and store it back into memrefloc.  */
+      if (tem != ad && memrefloc)
+       {
+         rtx oldref = *memrefloc;
+         *memrefloc = copy_rtx (*memrefloc);
+         copy_replacements (tem, XEXP (*memrefloc, 0));
+         loc = &XEXP (*memrefloc, 0);
+         if (operand == oldref)
+           operand = *memrefloc;
+       }
+
       /* Check similar cases as for indirect addresses as above except
         that we can allow pseudos and a MEM since they should have been
         taken care of above.  */
@@ -3456,7 +3689,7 @@ find_reloads_address (mode, memrefloc, ad, loc, operand, ind_levels)
        {
          /* Must use TEM here, not AD, since it is the one that will
             have any subexpressions reloaded, if needed.  */
-         push_reload (tem, 0, loc, 0,
+         push_reload (tem, NULL_RTX, loc, NULL_PTR,
                       BASE_REG_CLASS, GET_MODE (tem), VOIDmode, 0,
                       0, operand);
          return 1;
@@ -3599,7 +3832,7 @@ find_reloads_address (mode, memrefloc, ad, loc, operand, ind_levels)
 
   /* If constants aren't valid addresses, reload the constant address
      into a register.  */
-  if (CONSTANT_ADDRESS_P (ad) && ! strict_memory_address_p (mode, ad))
+  if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
     {
       /* If AD is in address in the constant pool, the MEM rtx may be shared.
         Unshare it so we can safely alter it.  */
@@ -3911,7 +4144,7 @@ find_reloads_address_1 (x, context, loc, operand, ind_levels)
              register rtx link;
 
              int reloadnum
-               = push_reload (x, 0, loc, 0,
+               = push_reload (x, NULL_RTX, loc, NULL_PTR,
                               context ? INDEX_REG_CLASS : BASE_REG_CLASS,
                               GET_MODE (x), GET_MODE (x), VOIDmode, 0, operand);
              reload_inc[reloadnum]
@@ -3951,7 +4184,7 @@ find_reloads_address_1 (x, context, loc, operand, ind_levels)
                                XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 0),
                                operand, ind_levels);
 
-         reloadnum = push_reload (x, 0, loc, 0,
+         reloadnum = push_reload (x, NULL_RTX, loc, NULL_PTR,
                                   context ? INDEX_REG_CLASS : BASE_REG_CLASS,
                                   GET_MODE (x), VOIDmode, 0, 0, operand);
          reload_inc[reloadnum]
@@ -3981,7 +4214,7 @@ find_reloads_address_1 (x, context, loc, operand, ind_levels)
       find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
                            operand, ind_levels);
 
-      push_reload (*loc, 0, loc, 0,
+      push_reload (*loc, NULL_RTX, loc, NULL_PTR,
                   context ? INDEX_REG_CLASS : BASE_REG_CLASS,
                   GET_MODE (x), VOIDmode, 0, 0, operand);
       return 1;
@@ -3992,9 +4225,10 @@ find_reloads_address_1 (x, context, loc, operand, ind_levels)
 
       if (reg_equiv_constant[regno] != 0)
        {
-         push_reload (reg_equiv_constant[regno], 0, loc, 0,
-                      context ? INDEX_REG_CLASS : BASE_REG_CLASS,
-                      GET_MODE (x), VOIDmode, 0, 0, operand);
+         find_reloads_address_part (reg_equiv_constant[regno], loc, 
+                                    (context ? INDEX_REG_CLASS
+                                     : BASE_REG_CLASS),
+                                    GET_MODE (x), operand, ind_levels);
          return 1;
        }
 
@@ -4002,7 +4236,7 @@ find_reloads_address_1 (x, context, loc, operand, ind_levels)
         that feeds this insn.  */
       if (reg_equiv_mem[regno] != 0)
        {
-         push_reload (reg_equiv_mem[regno], 0, loc, 0,
+         push_reload (reg_equiv_mem[regno], NULL_RTX, loc, NULL_PTR,
                       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
                       GET_MODE (x), VOIDmode, 0, 0, operand);
          return 1;
@@ -4021,7 +4255,7 @@ find_reloads_address_1 (x, context, loc, operand, ind_levels)
           || !(context ? REGNO_OK_FOR_INDEX_P (regno)
                : REGNO_OK_FOR_BASE_P (regno))))
        {
-         push_reload (x, 0, loc, 0,
+         push_reload (x, NULL_RTX, loc, NULL_PTR,
                       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
                       GET_MODE (x), VOIDmode, 0, 0, operand);
          return 1;
@@ -4033,7 +4267,7 @@ find_reloads_address_1 (x, context, loc, operand, ind_levels)
         from before this insn to after it.  */
       if (regno_clobbered_p (regno, this_insn))
        {
-         push_reload (x, 0, loc, 0,
+         push_reload (x, NULL_RTX, loc, NULL_PTR,
                       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
                       GET_MODE (x), VOIDmode, 0, 0, operand);
          return 1;
@@ -4099,7 +4333,8 @@ find_reloads_address_part (x, loc, class, mode, needed_for, ind_levels)
                            needed_for, ind_levels);
     }
 
-  push_reload (x, 0, loc, 0, class, mode, VOIDmode, 0, 0, needed_for);
+  push_reload (x, NULL_RTX, loc, NULL_PTR, class,
+              mode, VOIDmode, 0, 0, needed_for);
 }
 \f
 /* Substitute into X the registers into which we have reloaded
@@ -4123,7 +4358,7 @@ subst_reloads ()
          /* Encapsulate RELOADREG so its machine mode matches what
             used to be there.  */
          if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
-           reloadreg = gen_rtx (REG, r->mode, REGNO (reloadreg));
+           reloadreg = gen_lowpart_common (r->mode, reloadreg);
 
          /* If we are putting this into a SUBREG and RELOADREG is a
             SUBREG, we would be making nested SUBREGs, so we have to fix
@@ -4262,15 +4497,20 @@ refers_to_regno_for_reload_p (regno, endregno, x, loc)
     case REG:
       i = REGNO (x);
 
-      if (i >= FIRST_PSEUDO_REGISTER && reg_renumber[i] == -1
-         && ((reg_equiv_address[i]
-              && refers_to_regno_for_reload_p (regno, endregno,
-                                               reg_equiv_address[i], 0))
-             || (reg_equiv_mem[i]
-                 && refers_to_regno_for_reload_p (regno, endregno,
-                                                  XEXP (reg_equiv_mem[i], 0),
-                                                  0))))
-       return 1;
+      /* If this is a pseudo, a hard register must not have been allocated.
+        X must therefore either be a constant or be in memory.  */
+      if (i >= FIRST_PSEUDO_REGISTER)
+       {
+         if (reg_equiv_memory_loc[i])
+           return refers_to_regno_for_reload_p (regno, endregno,
+                                                reg_equiv_memory_loc[i],
+                                                NULL_PTR);
+
+         if (reg_equiv_constant[i])
+           return 0;
+
+         abort ();
+       }
 
       return (endregno > i
              && regno < i + (i < FIRST_PSEUDO_REGISTER 
@@ -4345,6 +4585,86 @@ refers_to_regno_for_reload_p (regno, endregno, x, loc)
     }
   return 0;
 }
+
+/* Nonzero if modifying X will affect IN.  If X is a register or a SUBREG,
+   we check if any register number in X conflicts with the relevant register
+   numbers.  If X is a constant, return 0.  If X is a MEM, return 1 iff IN
+   contains a MEM (we don't bother checking for memory addresses that can't
+   conflict because we expect this to be a rare case. 
+
+   This function is similar to reg_overlap_mention_p in rtlanal.c except
+   that we look at equivalences for pseudos that didn't get hard registers.  */
+
+int
+reg_overlap_mentioned_for_reload_p (x, in)
+     rtx x, in;
+{
+  int regno, endregno;
+
+  if (GET_CODE (x) == SUBREG)
+    {
+      regno = REGNO (SUBREG_REG (x));
+      if (regno < FIRST_PSEUDO_REGISTER)
+       regno += SUBREG_WORD (x);
+    }
+  else if (GET_CODE (x) == REG)
+    {
+      regno = REGNO (x);
+
+      /* If this is a pseudo, it must not have been assigned a hard register.
+        Therefore, it must either be in memory or be a constant.  */
+
+      if (regno >= FIRST_PSEUDO_REGISTER)
+       {
+         if (reg_equiv_memory_loc[regno])
+           return refers_to_mem_for_reload_p (in);
+         else if (reg_equiv_constant[regno])
+           return 0;
+         abort ();
+       }
+    }
+  else if (CONSTANT_P (x))
+    return 0;
+  else if (GET_CODE (x) == MEM)
+    return refers_to_mem_for_reload_p (in);
+  else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
+          || GET_CODE (x) == CC0)
+    return reg_mentioned_p (x, in);
+  else
+    abort ();
+
+  endregno = regno + (regno < FIRST_PSEUDO_REGISTER
+                     ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+
+  return refers_to_regno_for_reload_p (regno, endregno, in, NULL_PTR);
+}
+
+/* Return nonzero if anything in X contains a MEM.  Look also for pseudo
+   registers.  */
+
+int
+refers_to_mem_for_reload_p (x)
+     rtx x;
+{
+  char *fmt;
+  int i;
+
+  if (GET_CODE (x) == MEM)
+    return 1;
+
+  if (GET_CODE (x) == REG)
+    return (REGNO (x) >= FIRST_PSEUDO_REGISTER
+           && reg_equiv_memory_loc[REGNO (x)]);
+                       
+  fmt = GET_RTX_FORMAT (GET_CODE (x));
+  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
+    if (fmt[i] == 'e'
+       && (GET_CODE (XEXP (x, i)) == MEM
+           || refers_to_mem_for_reload_p (XEXP (x, i))))
+      return 1;
+  
+  return 0;
+}
 \f
 #if 0
 
@@ -4538,10 +4858,12 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
                  /* If we are looking for a constant,
                     and something equivalent to that constant was copied
                     into a reg, we can use that reg.  */
-                 || (goal_const && (tem = find_reg_note (p, REG_EQUIV, 0))
+                 || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
+                                                         NULL_RTX))
                      && rtx_equal_p (XEXP (tem, 0), goal)
-                     && (valueno = true_regnum (valtry = SET_DEST (pat))))
-                 || (goal_const && (tem = find_reg_note (p, REG_EQUIV, 0))
+                     && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
+                 || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
+                                                         NULL_RTX))
                      && GET_CODE (SET_DEST (pat)) == REG
                      && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
                      && GET_MODE_CLASS (GET_MODE (XEXP (tem, 0))) == MODE_FLOAT
@@ -4549,8 +4871,9 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
                      && INTVAL (goal) == CONST_DOUBLE_LOW (XEXP (tem, 0))
                      && (valtry = operand_subword (SET_DEST (pat), 0, 0,
                                                    VOIDmode))
-                     && (valueno = true_regnum (valtry)))
-                 || (goal_const && (tem = find_reg_note (p, REG_EQUIV, 0))
+                     && (valueno = true_regnum (valtry)) >= 0)
+                 || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
+                                                         NULL_RTX))
                      && GET_CODE (SET_DEST (pat)) == REG
                      && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
                      && GET_MODE_CLASS (GET_MODE (XEXP (tem, 0))) == MODE_FLOAT
@@ -4558,7 +4881,7 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
                      && INTVAL (goal) == CONST_DOUBLE_HIGH (XEXP (tem, 0))
                      && (valtry
                          = operand_subword (SET_DEST (pat), 1, 0, VOIDmode))
-                     && (valueno = true_regnum (valtry)))))
+                     && (valueno = true_regnum (valtry)) >= 0)))
            if (other >= 0
                ? valueno == other
                : ((unsigned) valueno < FIRST_PSEUDO_REGISTER
@@ -4586,7 +4909,8 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
   /* If we propose to get the value from the stack pointer or if GOAL is
      a MEM based on the stack pointer, we need a stable SP.  */
   if (valueno == STACK_POINTER_REGNUM
-      || (goal_mem && reg_overlap_mentioned_p (stack_pointer_rtx, goal)))
+      || (goal_mem && reg_overlap_mentioned_for_reload_p (stack_pointer_rtx,
+                                                         goal)))
     need_stable_sp = 1;
 
   /* Reject VALUE if the copy-insn moved the wrong sort of datum.  */
@@ -4597,9 +4921,10 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
      and is also a register that appears in the address of GOAL.  */
 
   if (goal_mem && value == SET_DEST (PATTERN (where))
-      && refers_to_regno_p (valueno,
-                           valueno + HARD_REGNO_NREGS (valueno, mode),
-                           goal, 0))
+      && refers_to_regno_for_reload_p (valueno,
+                                      (valueno
+                                       + HARD_REGNO_NREGS (valueno, mode)),
+                                      goal, NULL_PTR))
     return 0;
 
   /* Reject registers that overlap GOAL.  */
@@ -4712,7 +5037,7 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
                      && xregno + xnregs > valueno)
                    return 0;
                  if (goal_mem_addr_varies
-                     && reg_overlap_mentioned_p (dest, goal))
+                     && reg_overlap_mentioned_for_reload_p (dest, goal))
                    return 0;
                }
              else if (goal_mem && GET_CODE (dest) == MEM
@@ -4750,7 +5075,8 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
                              && xregno + xnregs > valueno)
                            return 0;
                          if (goal_mem_addr_varies
-                             && reg_overlap_mentioned_p (dest, goal))
+                             && reg_overlap_mentioned_for_reload_p (dest,
+                                                                    goal))
                            return 0;
                        }
                      else if (goal_mem && GET_CODE (dest) == MEM
@@ -4781,7 +5107,8 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
                  if (incno < valueno + valuenregs && incno >= valueno)
                    return 0;
                  if (goal_mem_addr_varies
-                     && reg_overlap_mentioned_p (XEXP (link, 0), goal))
+                     && reg_overlap_mentioned_for_reload_p (XEXP (link, 0),
+                                                            goal))
                    return 0;
                }
          }