OSDN Git Service

PR target/36780
[pf3gnuchains/gcc-fork.git] / gcc / reload.c
index e80ae12..a6ea4ff 100644 (file)
@@ -1,6 +1,6 @@
 /* Search an insn for pseudo regs that must be in hard regs and are not.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -263,7 +263,7 @@ static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode,
 static int hard_reg_set_here_p (unsigned int, unsigned int, rtx);
 static struct decomposition decompose (rtx);
 static int immune_p (rtx, rtx, struct decomposition);
-static int alternative_allows_memconst (const char *, int);
+static bool alternative_allows_const_pool_ref (rtx, const char *, int);
 static rtx find_reloads_toplev (rtx, int, enum reload_type, int, int, rtx,
                                int *);
 static rtx make_memloc (rtx, int);
@@ -319,7 +319,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
                       enum machine_mode reload_mode, enum reload_type type,
                       enum insn_code *picode, secondary_reload_info *prev_sri)
 {
-  enum reg_class class = NO_REGS;
+  enum reg_class rclass = NO_REGS;
   enum reg_class scratch_class;
   enum machine_mode mode = reload_mode;
   enum insn_code icode = CODE_FOR_nothing;
@@ -362,15 +362,15 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
 
   sri.icode = CODE_FOR_nothing;
   sri.prev_sri = prev_sri;
-  class = targetm.secondary_reload (in_p, x, reload_class, reload_mode, &sri);
+  rclass = targetm.secondary_reload (in_p, x, reload_class, reload_mode, &sri);
   icode = sri.icode;
 
   /* If we don't need any secondary registers, done.  */
-  if (class == NO_REGS && icode == CODE_FOR_nothing)
+  if (rclass == NO_REGS && icode == CODE_FOR_nothing)
     return -1;
 
-  if (class != NO_REGS)
-    t_reload = push_secondary_reload (in_p, x, opnum, optional, class,
+  if (rclass != NO_REGS)
+    t_reload = push_secondary_reload (in_p, x, opnum, optional, rclass,
                                      reload_mode, type, &t_icode, &sri);
 
   /* If we will be using an insn, the secondary reload is for a
@@ -392,7 +392,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
         an icode to reload from an intermediate tertiary reload register.
         We should probably have a new field in struct reload to tag a
         chain of scratch operand reloads onto.   */
-      gcc_assert (class == NO_REGS);
+      gcc_assert (rclass == NO_REGS);
 
       scratch_constraint = insn_data[(int) icode].operand[2].constraint;
       gcc_assert (*scratch_constraint == '=');
@@ -404,7 +404,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
                       : REG_CLASS_FROM_CONSTRAINT ((unsigned char) letter,
                                                   scratch_constraint));
 
-      class = scratch_class;
+      rclass = scratch_class;
       mode = insn_data[(int) icode].operand[2].mode;
     }
 
@@ -422,21 +422,21 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
      Allow this when a reload_in/out pattern is being used.  I.e. assume
      that the generated code handles this case.  */
 
-  gcc_assert (!in_p || class != reload_class || icode != CODE_FOR_nothing
+  gcc_assert (!in_p || rclass != reload_class || icode != CODE_FOR_nothing
              || t_icode != CODE_FOR_nothing);
 
   /* See if we can reuse an existing secondary reload.  */
   for (s_reload = 0; s_reload < n_reloads; s_reload++)
     if (rld[s_reload].secondary_p
-       && (reg_class_subset_p (class, rld[s_reload].class)
-           || reg_class_subset_p (rld[s_reload].class, class))
+       && (reg_class_subset_p (rclass, rld[s_reload].rclass)
+           || reg_class_subset_p (rld[s_reload].rclass, rclass))
        && ((in_p && rld[s_reload].inmode == mode)
            || (! in_p && rld[s_reload].outmode == mode))
        && ((in_p && rld[s_reload].secondary_in_reload == t_reload)
            || (! in_p && rld[s_reload].secondary_out_reload == t_reload))
        && ((in_p && rld[s_reload].secondary_in_icode == t_icode)
            || (! in_p && rld[s_reload].secondary_out_icode == t_icode))
-       && (SMALL_REGISTER_CLASS_P (class) || SMALL_REGISTER_CLASSES)
+       && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
        && MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
                             opnum, rld[s_reload].opnum))
       {
@@ -445,8 +445,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
        if (! in_p)
          rld[s_reload].outmode = mode;
 
-       if (reg_class_subset_p (class, rld[s_reload].class))
-         rld[s_reload].class = class;
+       if (reg_class_subset_p (rclass, rld[s_reload].rclass))
+         rld[s_reload].rclass = rclass;
 
        rld[s_reload].opnum = MIN (rld[s_reload].opnum, opnum);
        rld[s_reload].optional &= optional;
@@ -454,6 +454,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
        if (MERGE_TO_OTHER (secondary_type, rld[s_reload].when_needed,
                            opnum, rld[s_reload].opnum))
          rld[s_reload].when_needed = RELOAD_OTHER;
+
+       break;
       }
 
   if (s_reload == n_reloads)
@@ -465,7 +467,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
         way reloads are output.  */
 
       if (in_p && icode == CODE_FOR_nothing
-         && SECONDARY_MEMORY_NEEDED (class, reload_class, mode))
+         && SECONDARY_MEMORY_NEEDED (rclass, reload_class, mode))
        {
          get_secondary_mem (x, reload_mode, opnum, type);
 
@@ -477,7 +479,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
 
       /* We need to make a new secondary reload for this register class.  */
       rld[s_reload].in = rld[s_reload].out = 0;
-      rld[s_reload].class = class;
+      rld[s_reload].rclass = rclass;
 
       rld[s_reload].inmode = in_p ? mode : VOIDmode;
       rld[s_reload].outmode = ! in_p ? mode : VOIDmode;
@@ -501,7 +503,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
 
 #ifdef SECONDARY_MEMORY_NEEDED
       if (! in_p && icode == CODE_FOR_nothing
-         && SECONDARY_MEMORY_NEEDED (reload_class, class, mode))
+         && SECONDARY_MEMORY_NEEDED (reload_class, rclass, mode))
        get_secondary_mem (x, mode, opnum, type);
 #endif
     }
@@ -514,7 +516,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
    register and a scratch register is needed, we return the class of the
    intermediate register.  */
 enum reg_class
-secondary_reload_class (bool in_p, enum reg_class class,
+secondary_reload_class (bool in_p, enum reg_class rclass,
                        enum machine_mode mode, rtx x)
 {
   enum insn_code icode;
@@ -522,13 +524,13 @@ secondary_reload_class (bool in_p, enum reg_class class,
 
   sri.icode = CODE_FOR_nothing;
   sri.prev_sri = NULL;
-  class = targetm.secondary_reload (in_p, x, class, mode, &sri);
+  rclass = targetm.secondary_reload (in_p, x, rclass, mode, &sri);
   icode = sri.icode;
 
   /* If there are no secondary reloads at all, we return NO_REGS.
      If an intermediate register is needed, we return its class.  */
-  if (icode == CODE_FOR_nothing || class != NO_REGS)
-    return class;
+  if (icode == CODE_FOR_nothing || rclass != NO_REGS)
+    return rclass;
 
   /* No intermediate register is needed, but we have a special reload
      pattern, which we assume for now needs a scratch register.  */
@@ -545,7 +547,7 @@ scratch_reload_class (enum insn_code icode)
 {
   const char *scratch_constraint;
   char scratch_letter;
-  enum reg_class class;
+  enum reg_class rclass;
 
   gcc_assert (insn_data[(int) icode].n_operands == 3);
   scratch_constraint = insn_data[(int) icode].operand[2].constraint;
@@ -556,10 +558,10 @@ scratch_reload_class (enum insn_code icode)
   scratch_letter = *scratch_constraint;
   if (scratch_letter == 'r')
     return GENERAL_REGS;
-  class = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
+  rclass = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
                                     scratch_constraint);
-  gcc_assert (class != NO_REGS);
-  return class;
+  gcc_assert (rclass != NO_REGS);
+  return rclass;
 }
 \f
 #ifdef SECONDARY_MEMORY_NEEDED
@@ -658,24 +660,24 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
                  unsigned int dest_regno ATTRIBUTE_UNUSED)
 {
   int best_cost = -1;
-  int class;
+  int rclass;
   int regno;
   enum reg_class best_class = NO_REGS;
   enum reg_class dest_class ATTRIBUTE_UNUSED = REGNO_REG_CLASS (dest_regno);
   unsigned int best_size = 0;
   int cost;
 
-  for (class = 1; class < N_REG_CLASSES; class++)
+  for (rclass = 1; rclass < N_REG_CLASSES; rclass++)
     {
       int bad = 0;
       int good = 0;
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER - n && ! bad; regno++)
-       if (TEST_HARD_REG_BIT (reg_class_contents[class], regno))
+       if (TEST_HARD_REG_BIT (reg_class_contents[rclass], regno))
          {
            if (HARD_REGNO_MODE_OK (regno, inner))
              {
                good = 1;
-               if (! TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
+               if (! TEST_HARD_REG_BIT (reg_class_contents[rclass], regno + n)
                    || ! HARD_REGNO_MODE_OK (regno + n, outer))
                  bad = 1;
              }
@@ -683,15 +685,15 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
 
       if (bad || !good)
        continue;
-      cost = REGISTER_MOVE_COST (outer, class, dest_class);
+      cost = REGISTER_MOVE_COST (outer, rclass, dest_class);
 
-      if ((reg_class_size[class] > best_size
+      if ((reg_class_size[rclass] > best_size
           && (best_cost < 0 || best_cost >= cost))
          || best_cost > cost)
        {
-         best_class = class;
-         best_size = reg_class_size[class];
-         best_cost = REGISTER_MOVE_COST (outer, class, dest_class);
+         best_class = rclass;
+         best_size = reg_class_size[rclass];
+         best_cost = REGISTER_MOVE_COST (outer, rclass, dest_class);
        }
     }
 
@@ -702,14 +704,14 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
 \f
 /* Return the number of a previously made reload that can be combined with
    a new one, or n_reloads if none of the existing reloads can be used.
-   OUT, CLASS, TYPE and OPNUM are the same arguments as passed to
+   OUT, RCLASS, TYPE and OPNUM are the same arguments as passed to
    push_reload, they determine the kind of the new reload that we try to
    combine.  P_IN points to the corresponding value of IN, which can be
    modified by this function.
    DONT_SHARE is nonzero if we can't share any input-only reload for IN.  */
 
 static int
-find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
+find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
                      enum reload_type type, int opnum, int dont_share)
 {
   rtx in = *p_in;
@@ -730,18 +732,18 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
      than we otherwise would.  */
 
   for (i = 0; i < n_reloads; i++)
-    if ((reg_class_subset_p (class, rld[i].class)
-        || reg_class_subset_p (rld[i].class, class))
+    if ((reg_class_subset_p (rclass, rld[i].rclass)
+        || reg_class_subset_p (rld[i].rclass, rclass))
        /* If the existing reload has a register, it must fit our class.  */
        && (rld[i].reg_rtx == 0
-           || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+           || TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
                                  true_regnum (rld[i].reg_rtx)))
        && ((in != 0 && MATCHES (rld[i].in, in) && ! dont_share
             && (out == 0 || rld[i].out == 0 || MATCHES (rld[i].out, out)))
            || (out != 0 && MATCHES (rld[i].out, out)
                && (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
        && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
-       && (SMALL_REGISTER_CLASS_P (class) || SMALL_REGISTER_CLASSES)
+       && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
        && MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
       return i;
 
@@ -751,12 +753,12 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
      the preincrementation as happening before any ref in this insn
      to that register.  */
   for (i = 0; i < n_reloads; i++)
-    if ((reg_class_subset_p (class, rld[i].class)
-        || reg_class_subset_p (rld[i].class, class))
+    if ((reg_class_subset_p (rclass, rld[i].rclass)
+        || reg_class_subset_p (rld[i].rclass, rclass))
        /* If the existing reload has a register, it must fit our
           class.  */
        && (rld[i].reg_rtx == 0
-           || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+           || TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
                                  true_regnum (rld[i].reg_rtx)))
        && out == 0 && rld[i].out == 0 && rld[i].in != 0
        && ((REG_P (in)
@@ -766,7 +768,7 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
                && GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC
                && MATCHES (XEXP (in, 0), rld[i].in)))
        && (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
-       && (SMALL_REGISTER_CLASS_P (class) || SMALL_REGISTER_CLASSES)
+       && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
        && MERGABLE_RELOADS (type, rld[i].when_needed,
                             opnum, rld[i].opnum))
       {
@@ -876,7 +878,7 @@ can_reload_into (rtx in, int regno, enum machine_mode mode)
    If IN and OUT are both nonzero, it means the same register must be used
    to reload both IN and OUT.
 
-   CLASS is a register class required for the reloaded data.
+   RCLASS is a register class required for the reloaded data.
    INMODE is the machine mode that the instruction requires
    for the reg that replaces IN and OUTMODE is likewise for OUT.
 
@@ -902,7 +904,7 @@ can_reload_into (rtx in, int regno, enum machine_mode mode)
 
 int
 push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
-            enum reg_class class, enum machine_mode inmode,
+            enum reg_class rclass, enum machine_mode inmode,
             enum machine_mode outmode, int strict_low, int optional,
             int opnum, enum reload_type type)
 {
@@ -922,29 +924,33 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   if (outmode == VOIDmode && out != 0)
     outmode = GET_MODE (out);
 
-  /* If IN is a pseudo register everywhere-equivalent to a constant, and
-     it is not in a hard register, reload straight from the constant,
-     since we want to get rid of such pseudo registers.
-     Often this is done earlier, but not always in find_reloads_address.  */
+  /* If find_reloads and friends until now missed to replace a pseudo
+     with a constant of reg_equiv_constant something went wrong
+     beforehand.
+     Note that it can't simply be done here if we missed it earlier
+     since the constant might need to be pushed into the literal pool
+     and the resulting memref would probably need further
+     reloading.  */
   if (in != 0 && REG_P (in))
     {
       int regno = REGNO (in);
 
-      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
-         && reg_equiv_constant[regno] != 0)
-       in = reg_equiv_constant[regno];
+      gcc_assert (regno < FIRST_PSEUDO_REGISTER
+                 || reg_renumber[regno] >= 0
+                 || reg_equiv_constant[regno] == NULL_RTX);
     }
 
-  /* Likewise for OUT.  Of course, OUT will never be equivalent to
-     an actual constant, but it might be equivalent to a memory location
-     (in the case of a parameter).  */
+  /* reg_equiv_constant only contains constants which are obviously
+     not appropriate as destination.  So if we would need to replace
+     the destination pseudo with a constant we are in real
+     trouble.  */
   if (out != 0 && REG_P (out))
     {
       int regno = REGNO (out);
 
-      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
-         && reg_equiv_constant[regno] != 0)
-       out = reg_equiv_constant[regno];
+      gcc_assert (regno < FIRST_PSEUDO_REGISTER
+                 || reg_renumber[regno] >= 0
+                 || reg_equiv_constant[regno] == NULL_RTX);
     }
 
   /* If we have a read-write operand with an address side-effect,
@@ -982,7 +988,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
      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 this case).
 
      Also reload the inner expression if it does not require a secondary
      reload but the SUBREG does.
@@ -997,7 +1003,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   if (in != 0 && GET_CODE (in) == SUBREG
       && (subreg_lowpart_p (in) || strict_low)
 #ifdef CANNOT_CHANGE_MODE_CLASS
-      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, class)
+      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
 #endif
       && (CONSTANT_P (SUBREG_REG (in))
          || GET_CODE (SUBREG_REG (in)) == PLUS
@@ -1037,8 +1043,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
                       != (int) hard_regno_nregs[REGNO (SUBREG_REG (in))]
                                                [GET_MODE (SUBREG_REG (in))]))
                  || ! HARD_REGNO_MODE_OK (subreg_regno (in), inmode)))
-         || (secondary_reload_class (1, class, inmode, in) != NO_REGS
-             && (secondary_reload_class (1, class, GET_MODE (SUBREG_REG (in)),
+         || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
+             && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)),
                                          SUBREG_REG (in))
                  == NO_REGS))
 #ifdef CANNOT_CHANGE_MODE_CLASS
@@ -1073,7 +1079,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 
   if (in != 0 && reload_inner_reg_of_subreg (in, inmode, 0))
     {
-      enum reg_class in_class = class;
+      enum reg_class in_class = rclass;
 
       if (REG_P (SUBREG_REG (in)))
        in_class
@@ -1103,7 +1109,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   if (out != 0 && GET_CODE (out) == SUBREG
       && (subreg_lowpart_p (out) || strict_low)
 #ifdef CANNOT_CHANGE_MODE_CLASS
-      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, class)
+      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, rclass)
 #endif
       && (CONSTANT_P (SUBREG_REG (out))
          || strict_low
@@ -1130,8 +1136,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
                       != (int) hard_regno_nregs[REGNO (SUBREG_REG (out))]
                                                [GET_MODE (SUBREG_REG (out))]))
                  || ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode)))
-         || (secondary_reload_class (0, class, outmode, out) != NO_REGS
-             && (secondary_reload_class (0, class, GET_MODE (SUBREG_REG (out)),
+         || (secondary_reload_class (0, rclass, outmode, out) != NO_REGS
+             && (secondary_reload_class (0, rclass, GET_MODE (SUBREG_REG (out)),
                                          SUBREG_REG (out))
                  == NO_REGS))
 #ifdef CANNOT_CHANGE_MODE_CLASS
@@ -1205,10 +1211,10 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   /* Narrow down the class of register wanted if that is
      desirable on this machine for efficiency.  */
   {
-    enum reg_class preferred_class = class;
+    enum reg_class preferred_class = rclass;
 
     if (in != 0)
-      preferred_class = PREFERRED_RELOAD_CLASS (in, class);
+      preferred_class = PREFERRED_RELOAD_CLASS (in, rclass);
 
   /* Output reloads may need analogous treatment, different in detail.  */
 #ifdef PREFERRED_OUTPUT_RELOAD_CLASS
@@ -1219,7 +1225,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
     /* Discard what the target said if we cannot do it.  */
     if (preferred_class != NO_REGS
        || (optional && type == RELOAD_FOR_OUTPUT))
-      class = preferred_class;
+      rclass = preferred_class;
   }
 
   /* Make sure we use a class that can handle the actual pseudo
@@ -1228,14 +1234,14 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
      can handle SImode, QImode needs a smaller class.  */
 #ifdef LIMIT_RELOAD_CLASS
   if (in_subreg_loc)
-    class = LIMIT_RELOAD_CLASS (inmode, class);
+    rclass = LIMIT_RELOAD_CLASS (inmode, rclass);
   else if (in != 0 && GET_CODE (in) == SUBREG)
-    class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), class);
+    rclass = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), rclass);
 
   if (out_subreg_loc)
-    class = LIMIT_RELOAD_CLASS (outmode, class);
+    rclass = LIMIT_RELOAD_CLASS (outmode, rclass);
   if (out != 0 && GET_CODE (out) == SUBREG)
-    class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), class);
+    rclass = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), rclass);
 #endif
 
   /* Verify that this class is at least possible for the mode that
@@ -1259,7 +1265,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
        }
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (HARD_REGNO_MODE_OK (i, mode)
-           && in_hard_reg_set_p (reg_class_contents[(int) class], mode, i))
+           && in_hard_reg_set_p (reg_class_contents[(int) rclass], mode, i))
          break;
       if (i == FIRST_PSEUDO_REGISTER)
        {
@@ -1284,10 +1290,10 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   /* Optional output reloads are always OK even if we have no register class,
      since the function of these reloads is only to have spill_reg_store etc.
      set, so that the storing insn can be deleted later.  */
-  gcc_assert (class != NO_REGS
+  gcc_assert (rclass != NO_REGS
              || (optional != 0 && type == RELOAD_FOR_OUTPUT));
 
-  i = find_reusable_reload (&in, out, class, type, opnum, dont_share);
+  i = find_reusable_reload (&in, out, rclass, type, opnum, dont_share);
 
   if (i == n_reloads)
     {
@@ -1297,11 +1303,11 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 
       if (in != 0)
        secondary_in_reload
-         = push_secondary_reload (1, in, opnum, optional, class, inmode, type,
+         = push_secondary_reload (1, in, opnum, optional, rclass, inmode, type,
                                   &secondary_in_icode, NULL);
       if (out != 0 && GET_CODE (out) != SCRATCH)
        secondary_out_reload
-         = push_secondary_reload (0, out, opnum, optional, class, outmode,
+         = push_secondary_reload (0, out, opnum, optional, rclass, outmode,
                                   type, &secondary_out_icode, NULL);
 
       /* We found no existing reload suitable for re-use.
@@ -1314,14 +1320,14 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
              || (GET_CODE (in) == SUBREG && REG_P (SUBREG_REG (in))))
          && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
          && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
-                                     class, inmode))
+                                     rclass, inmode))
        get_secondary_mem (in, inmode, opnum, type);
 #endif
 
       i = n_reloads;
       rld[i].in = in;
       rld[i].out = out;
-      rld[i].class = class;
+      rld[i].rclass = rclass;
       rld[i].inmode = inmode;
       rld[i].outmode = outmode;
       rld[i].reg_rtx = 0;
@@ -1345,7 +1351,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
           && (REG_P (out)
              || (GET_CODE (out) == SUBREG && REG_P (SUBREG_REG (out))))
          && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
-         && SECONDARY_MEMORY_NEEDED (class,
+         && SECONDARY_MEMORY_NEEDED (rclass,
                                      REGNO_REG_CLASS (reg_or_subregno (out)),
                                      outmode))
        get_secondary_mem (out, outmode, opnum, type);
@@ -1405,8 +1411,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
          rld[i].out = out;
          rld[i].out_reg = outloc ? *outloc : 0;
        }
-      if (reg_class_subset_p (class, rld[i].class))
-       rld[i].class = class;
+      if (reg_class_subset_p (rclass, rld[i].rclass))
+       rld[i].rclass = rclass;
       rld[i].optional &= optional;
       if (MERGE_TO_OTHER (type, rld[i].when_needed,
                          opnum, rld[i].opnum))
@@ -1478,7 +1484,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
     {
       rld[i].reg_rtx = find_dummy_reload (in, out, inloc, outloc,
                                          inmode, outmode,
-                                         rld[i].class, i,
+                                         rld[i].rclass, i,
                                          earlyclobber_operand_p (out));
 
       /* If the outgoing register already contains the same value
@@ -1555,7 +1561,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 
            for (offs = 0; offs < nregs; offs++)
              if (fixed_regs[regno + offs]
-                 || ! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+                 || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
                                          regno + offs))
                break;
 
@@ -1724,8 +1730,8 @@ combine_reloads (void)
        && rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS
        && rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
        && rld[i].when_needed != RELOAD_OTHER
-       && (CLASS_MAX_NREGS (rld[i].class, rld[i].inmode)
-           == CLASS_MAX_NREGS (rld[output_reload].class,
+       && (CLASS_MAX_NREGS (rld[i].rclass, rld[i].inmode)
+           == CLASS_MAX_NREGS (rld[output_reload].rclass,
                                rld[output_reload].outmode))
        && rld[i].inc == 0
        && rld[i].reg_rtx == 0
@@ -1738,11 +1744,11 @@ combine_reloads (void)
                            secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
 #endif
        && (SMALL_REGISTER_CLASSES
-           ? (rld[i].class == rld[output_reload].class)
-           : (reg_class_subset_p (rld[i].class,
-                                  rld[output_reload].class)
-              || reg_class_subset_p (rld[output_reload].class,
-                                     rld[i].class)))
+           ? (rld[i].rclass == rld[output_reload].rclass)
+           : (reg_class_subset_p (rld[i].rclass,
+                                  rld[output_reload].rclass)
+              || reg_class_subset_p (rld[output_reload].rclass,
+                                     rld[i].rclass)))
        && (MATCHES (rld[i].in, rld[output_reload].out)
            /* Args reversed because the first arg seems to be
               the one that we imagine being modified
@@ -1760,7 +1766,7 @@ combine_reloads (void)
                                                             rld[output_reload].out))))
        && ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode,
                                         rld[i].when_needed != RELOAD_FOR_INPUT)
-       && (reg_class_size[(int) rld[i].class]
+       && (reg_class_size[(int) rld[i].rclass]
            || SMALL_REGISTER_CLASSES)
        /* We will allow making things slightly worse by combining an
           input and an output, but no worse than that.  */
@@ -1793,9 +1799,9 @@ combine_reloads (void)
            = secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum];
 #endif
        /* If required, minimize the register class.  */
-       if (reg_class_subset_p (rld[output_reload].class,
-                               rld[i].class))
-         rld[i].class = rld[output_reload].class;
+       if (reg_class_subset_p (rld[output_reload].rclass,
+                               rld[i].rclass))
+         rld[i].rclass = rld[output_reload].rclass;
 
        /* Transfer all replacements from the old reload to the combined.  */
        for (j = 0; j < n_replacements; j++)
@@ -1829,7 +1835,7 @@ combine_reloads (void)
                                                rld[output_reload].out)
        && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
        && HARD_REGNO_MODE_OK (regno, rld[output_reload].outmode)
-       && TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
+       && TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].rclass],
                              regno)
        && (hard_regno_nregs[regno][rld[output_reload].outmode]
            <= hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))])
@@ -1837,10 +1843,10 @@ combine_reloads (void)
           won't want this register.  */
        && ((secondary_out = rld[output_reload].secondary_out_reload) == -1
            || (!(TEST_HARD_REG_BIT
-                 (reg_class_contents[(int) rld[secondary_out].class], regno))
+                 (reg_class_contents[(int) rld[secondary_out].rclass], regno))
                && ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
                    || !(TEST_HARD_REG_BIT
-                        (reg_class_contents[(int) rld[secondary_out].class],
+                        (reg_class_contents[(int) rld[secondary_out].rclass],
                          regno)))))
        && !fixed_regs[regno]
        /* Check that a former pseudo is valid; see find_dummy_reload.  */
@@ -1861,7 +1867,7 @@ combine_reloads (void)
    If so, return the register rtx that proves acceptable.
 
    INLOC and OUTLOC are locations where IN and OUT appear in the insn.
-   CLASS is the register class required for the reload.
+   RCLASS is the register class required for the reload.
 
    If FOR_REAL is >= 0, it is the number of the reload,
    and in some cases when it can be discovered that OUT doesn't need
@@ -1878,7 +1884,7 @@ combine_reloads (void)
 static rtx
 find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
                   enum machine_mode inmode, enum machine_mode outmode,
-                  enum reg_class class, int for_real, int earlyclobber)
+                  enum reg_class rclass, int for_real, int earlyclobber)
 {
   rtx in = real_in;
   rtx out = real_out;
@@ -1921,9 +1927,9 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
   /* Narrow down the reg class, the same way push_reload will;
      otherwise we might find a dummy now, but push_reload won't.  */
   {
-    enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, class);
+    enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, rclass);
     if (preferred_class != NO_REGS)
-      class = preferred_class;
+      rclass = preferred_class;
   }
 
   /* See if OUT will do.  */
@@ -1954,7 +1960,7 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
          unsigned int i;
 
          for (i = 0; i < nwords; i++)
-           if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+           if (! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
                                     regno + i))
              break;
 
@@ -2022,7 +2028,7 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
          unsigned int i;
 
          for (i = 0; i < nwords; i++)
-           if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+           if (! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
                                     regno + i))
              break;
 
@@ -2517,7 +2523,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
   int noperands;
   /* These start out as the constraints for the insn
      and they are chewed up as we consider alternatives.  */
-  char *constraints[MAX_RECOG_OPERANDS];
+  const char *constraints[MAX_RECOG_OPERANDS];
   /* These are the preferred classes for an operand, or NO_REGS if it isn't
      a register.  */
   enum reg_class preferred_class[MAX_RECOG_OPERANDS];
@@ -2624,7 +2630,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
 
   memcpy (operand_mode, recog_data.operand_mode,
          noperands * sizeof (enum machine_mode));
-  memcpy (constraints, recog_data.constraints, noperands * sizeof (char *));
+  memcpy (constraints, recog_data.constraints,
+         noperands * sizeof (const char *));
 
   commutative = -1;
 
@@ -2635,8 +2642,9 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
 
   for (i = 0; i < noperands; i++)
     {
-      char *p;
+      const char *p;
       int c;
+      char *end;
 
       substed_operand[i] = recog_data.operand[i];
       p = constraints[i];
@@ -2680,7 +2688,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
              {
-               c = strtoul (p - 1, &p, 10);
+               c = strtoul (p - 1, &end, 10);
+               p = end;
 
                operands_match[c][i]
                  = operands_match_p (recog_data.operand[c],
@@ -2908,11 +2917,21 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
         a bad register class to only count 1/3 as much.  */
       int reject = 0;
 
+      if (!recog_data.alternative_enabled_p[this_alternative_number])
+       {
+         int i;
+
+         for (i = 0; i < recog_data.n_operands; i++)
+           constraints[i] = skip_alternative (constraints[i]);
+
+         continue;
+       }
+
       this_earlyclobber = 0;
 
       for (i = 0; i < noperands; i++)
        {
-         char *p = constraints[i];
+         const char *p = constraints[i];
          char *end;
          int len;
          int win = 0;
@@ -3176,7 +3195,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                badop = 0;
                break;
 
-             case 'm':
+             case TARGET_MEM_CONSTRAINT:
                if (force_reload)
                  break;
                if (MEM_P (operand)
@@ -3711,7 +3730,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
          address_reloaded[commutative + 1] = t;
 
          memcpy (constraints, recog_data.constraints,
-                 noperands * sizeof (char *));
+                 noperands * sizeof (const char *));
          goto try_swapped;
        }
       else
@@ -3832,13 +3851,19 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
            || no_input_reloads)
        && operand_mode[i] != VOIDmode)
       {
+       int this_address_reloaded;
+
+       this_address_reloaded = 0;
        substed_operand[i] = recog_data.operand[i]
          = find_reloads_toplev (force_const_mem (operand_mode[i],
                                                  recog_data.operand[i]),
                                 i, address_type[i], ind_levels, 0, insn,
-                                NULL);
-       if (alternative_allows_memconst (recog_data.constraints[i],
-                                        goal_alternative_number))
+                                &this_address_reloaded);
+       if (alternative_allows_const_pool_ref (this_address_reloaded == 0
+                                              ? substed_operand[i]
+                                              : NULL,
+                                              recog_data.constraints[i],
+                                              goal_alternative_number))
          goal_alternative_win[i] = 1;
       }
 
@@ -4058,7 +4083,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                  PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, operand),
                                              insn), QImode);
                if (modified[i] != RELOAD_READ)
-                 emit_insn_after (gen_rtx_CLOBBER (VOIDmode, operand), insn);
+                 emit_insn_after (gen_clobber (operand), insn);
              }
          }
       }
@@ -4120,9 +4145,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
              && (!JUMP_P (insn)
                  || !label_is_jump_target_p (XEXP (substitution, 0),
                                              insn)))
-           REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL_OPERAND,
-                                                 XEXP (substitution, 0),
-                                                 REG_NOTES (insn));
+           add_reg_note (insn, REG_LABEL_OPERAND, XEXP (substitution, 0));
        }
       else
        retval |= (substed_operand[i] != *recog_data.operand_loc[i]);
@@ -4161,7 +4184,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
        && rld[i].out == 0)
       {
        rld[i].reg_rtx
-         = find_equiv_reg (rld[i].in, insn, rld[i].class, -1,
+         = find_equiv_reg (rld[i].in, insn, rld[i].rclass, -1,
                            static_reload_reg_p, 0, rld[i].inmode);
        /* Prevent generation of insn to load the value
           because the one we found already has the value.  */
@@ -4430,7 +4453,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
        if (i != j && rld[j].in != 0 && rld[j].out == 0
            && rld[j].when_needed == rld[i].when_needed
            && MATCHES (rld[i].in, rld[j].in)
-           && rld[i].class == rld[j].class
+           && rld[i].rclass == rld[j].rclass
            && !rld[i].nocombine && !rld[j].nocombine
            && rld[i].reg_rtx == rld[j].reg_rtx)
          {
@@ -4459,7 +4482,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
               > GET_MODE_SIZE (rld[i].inmode)))
          ? rld[i].outmode : rld[i].inmode;
 
-      rld[i].nregs = CLASS_MAX_NREGS (rld[i].class, rld[i].mode);
+      rld[i].nregs = CLASS_MAX_NREGS (rld[i].rclass, rld[i].mode);
     }
 
   /* Special case a simple move with an input reload and a
@@ -4476,14 +4499,14 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
        unsigned int regno = REGNO (dest);
 
        if (regno < FIRST_PSEUDO_REGISTER
-           && TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno)
+           && TEST_HARD_REG_BIT (reg_class_contents[rld[i].rclass], regno)
            && HARD_REGNO_MODE_OK (regno, rld[i].mode))
          {
            int nr = hard_regno_nregs[regno][rld[i].mode];
            int ok = 1, nri;
 
            for (nri = 1; nri < nr; nri ++)
-             if (! TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno + nri))
+             if (! TEST_HARD_REG_BIT (reg_class_contents[rld[i].rclass], regno + nri))
                ok = 0;
 
            if (ok)
@@ -4494,26 +4517,42 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
   return retval;
 }
 
-/* Return 1 if alternative number ALTNUM in constraint-string CONSTRAINT
-   accepts a memory operand with constant address.  */
+/* Return true if alternative number ALTNUM in constraint-string
+   CONSTRAINT is guaranteed to accept a reloaded constant-pool reference.
+   MEM gives the reference if it didn't need any reloads, otherwise it
+   is null.  */
 
-static int
-alternative_allows_memconst (const char *constraint, int altnum)
+static bool
+alternative_allows_const_pool_ref (rtx mem, const char *constraint, int altnum)
 {
   int c;
+
   /* Skip alternatives before the one requested.  */
   while (altnum > 0)
     {
       while (*constraint++ != ',');
       altnum--;
     }
-  /* Scan the requested alternative for 'm' or 'o'.
-     If one of them is present, this alternative accepts memory constants.  */
+  /* Scan the requested alternative for TARGET_MEM_CONSTRAINT or 'o'.
+     If one of them is present, this alternative accepts the result of
+     passing a constant-pool reference through find_reloads_toplev.
+
+     The same is true of extra memory constraints if the address
+     was reloaded into a register.  However, the target may elect
+     to disallow the original constant address, forcing it to be
+     reloaded into a register instead.  */
   for (; (c = *constraint) && c != ',' && c != '#';
        constraint += CONSTRAINT_LEN (c, constraint))
-    if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c, constraint))
-      return 1;
-  return 0;
+    {
+      if (c == TARGET_MEM_CONSTRAINT || c == 'o')
+       return true;
+#ifdef EXTRA_CONSTRAINT_STR
+      if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
+         && (mem == NULL || EXTRA_CONSTRAINT_STR (mem, c, constraint)))
+       return true;
+#endif
+    }
+  return false;
 }
 \f
 /* Scan X for memory references and scan the addresses for reloading.
@@ -4772,15 +4811,12 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
     {
       regno = REGNO (ad);
 
-      /* If the register is equivalent to an invariant expression, substitute
-        the invariant, and eliminate any eliminable register references.  */
-      tem = reg_equiv_constant[regno];
-      if (tem != 0
-         && (tem = eliminate_regs (tem, mode, insn))
-         && strict_memory_address_p (mode, tem))
+      if (reg_equiv_constant[regno] != 0)
        {
-         *loc = ad = tem;
-         return 0;
+         find_reloads_address_part (reg_equiv_constant[regno], loc,
+                                    base_reg_class (mode, MEM, SCRATCH),
+                                    GET_MODE (ad), opnum, type, ind_levels);
+         return 1;
        }
 
       tem = reg_equiv_memory_loc[regno];
@@ -5736,7 +5772,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
              else
                {
                  reloadnum
-                   = push_reload (x, NULL_RTX, loc, (rtx*) 0,
+                   = push_reload (x, x, loc, (rtx*) 0,
                                   context_reg_class,
                                   GET_MODE (x), GET_MODE (x), 0, 0,
                                   opnum, type);
@@ -5880,14 +5916,14 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
             is larger than the class size, then reload the whole SUBREG.  */
          else
            {
-             enum reg_class class = context_reg_class;
-             if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
-                 > reg_class_size[class])
+             enum reg_class rclass = context_reg_class;
+             if ((unsigned) CLASS_MAX_NREGS (rclass, GET_MODE (SUBREG_REG (x)))
+                 > reg_class_size[rclass])
                {
                  x = find_reloads_subreg_address (x, 0, opnum, 
                                                   ADDR_TYPE (type),
                                                   ind_levels, insn);
-                 push_reload (x, NULL_RTX, loc, (rtx*) 0, class,
+                 push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
                               GET_MODE (x), VOIDmode, 0, 0, opnum, type);
                  return 1;
                }
@@ -5918,7 +5954,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
 }
 \f
 /* X, which is found at *LOC, is a part of an address that needs to be
-   reloaded into a register of class CLASS.  If X is a constant, or if
+   reloaded into a register of class RCLASS.  If X is a constant, or if
    X is a PLUS that contains a constant, check that the constant is a
    legitimate operand and that we are supposed to be able to load
    it into the register.
@@ -5933,13 +5969,13 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
    supports.  */
 
 static void
-find_reloads_address_part (rtx x, rtx *loc, enum reg_class class,
+find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
                           enum machine_mode mode, int opnum,
                           enum reload_type type, int ind_levels)
 {
   if (CONSTANT_P (x)
       && (! LEGITIMATE_CONSTANT_P (x)
-         || PREFERRED_RELOAD_CLASS (x, class) == NO_REGS))
+         || PREFERRED_RELOAD_CLASS (x, rclass) == NO_REGS))
     {
       x = force_const_mem (mode, x);
       find_reloads_address (mode, &x, XEXP (x, 0), &XEXP (x, 0),
@@ -5949,7 +5985,7 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class class,
   else if (GET_CODE (x) == PLUS
           && CONSTANT_P (XEXP (x, 1))
           && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
-              || PREFERRED_RELOAD_CLASS (XEXP (x, 1), class) == NO_REGS))
+              || PREFERRED_RELOAD_CLASS (XEXP (x, 1), rclass) == NO_REGS))
     {
       rtx tem;
 
@@ -5959,7 +5995,7 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class class,
                            opnum, type, ind_levels, 0);
     }
 
-  push_reload (x, NULL_RTX, loc, (rtx*) 0, class,
+  push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
               mode, VOIDmode, 0, 0, opnum, type);
 }
 \f
@@ -6013,7 +6049,6 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
              unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
              int offset;
              rtx orig = tem;
-             enum machine_mode orig_mode = GET_MODE (orig);
              int reloaded;
 
              /* For big-endian paradoxical subregs, SUBREG_BYTE does not
@@ -6025,6 +6060,8 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
 
              XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
              PUT_MODE (tem, GET_MODE (x));
+             if (MEM_OFFSET (tem))
+               set_mem_offset (tem, plus_constant (MEM_OFFSET (tem), offset));
 
              /* If this was a paradoxical subreg that we replaced, the
                 resulting memory must be sufficiently aligned to allow
@@ -6057,15 +6094,16 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
              /* For some processors an address may be valid in the
                 original mode but not in a smaller mode.  For
                 example, ARM accepts a scaled index register in
-                SImode but not in HImode.  find_reloads_address
+                SImode but not in HImode.  Similarly, the address may
+                have been valid before the subreg offset was added,
+                but not afterwards.  find_reloads_address
                 assumes that we pass it a valid address, and doesn't
                 force a reload.  This will probably be fine if
                 find_reloads_address finds some reloads.  But if it
                 doesn't find any, then we may have just converted a
                 valid address into an invalid one.  Check for that
                 here.  */
-             if (reloaded != 1
-                 && strict_memory_address_p (orig_mode, XEXP (tem, 0))
+             if (reloaded == 0
                  && !strict_memory_address_p (GET_MODE (tem),
                                               XEXP (tem, 0)))
                push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
@@ -6562,7 +6600,7 @@ refers_to_mem_for_reload_p (rtx x)
 \f
 /* Check the insns before INSN to see if there is a suitable register
    containing the same value as GOAL.
-   If OTHER is -1, look for a register in class CLASS.
+   If OTHER is -1, look for a register in class RCLASS.
    Otherwise, just see if register number OTHER shares GOAL's value.
 
    Return an rtx for the register found, or zero if none is found.
@@ -6588,7 +6626,7 @@ refers_to_mem_for_reload_p (rtx x)
    as if it were a constant except that sp is required to be unchanging.  */
 
 rtx
-find_equiv_reg (rtx goal, rtx insn, enum reg_class class, int other,
+find_equiv_reg (rtx goal, rtx insn, enum reg_class rclass, int other,
                short *reload_reg_p, int goalreg, enum machine_mode mode)
 {
   rtx p = insn;
@@ -6734,7 +6772,7 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class class, int other,
                }
              else if ((unsigned) valueno >= FIRST_PSEUDO_REGISTER)
                continue;
-             else if (!in_hard_reg_set_p (reg_class_contents[(int) class],
+             else if (!in_hard_reg_set_p (reg_class_contents[(int) rclass],
                                          mode, valueno))
                continue;
              value = valtry;
@@ -7224,7 +7262,7 @@ debug_reload_to_stream (FILE *f)
          fprintf (f, "\n\t");
        }
 
-      fprintf (f, "%s, ", reg_class_names[(int) rld[r].class]);
+      fprintf (f, "%s, ", reg_class_names[(int) rld[r].rclass]);
 
       fprintf (f, "%s (opnum = %d)",
               reload_when_needed_name[(int) rld[r].when_needed],