OSDN Git Service

m68k: Limit TAS to 68000 and CF ISA_B.
[pf3gnuchains/gcc-fork.git] / gcc / reload.c
index 17d4f28..8420c80 100644 (file)
@@ -111,13 +111,14 @@ a register with any other reload.  */
 #include "params.h"
 #include "target.h"
 #include "ira.h"
 #include "params.h"
 #include "target.h"
 #include "ira.h"
-#include "toplev.h" /* exact_log2 may be used by targets */
 
 
-/* True if X is a constant that can be forced into the constant pool.  */
-#define CONST_POOL_OK_P(X)                     \
-  (CONSTANT_P (X)                              \
+/* True if X is a constant that can be forced into the constant pool.
+   MODE is the mode of the operand, or VOIDmode if not known.  */
+#define CONST_POOL_OK_P(MODE, X)               \
+  ((MODE) != VOIDmode                          \
+   && CONSTANT_P (X)                           \
    && GET_CODE (X) != HIGH                     \
    && GET_CODE (X) != HIGH                     \
-   && !targetm.cannot_force_const_mem (X))
+   && !targetm.cannot_force_const_mem (MODE, X))
 
 /* True if C is a non-empty register class that has too few registers
    to be safely used as a reload target class.  */
 
 /* True if C is a non-empty register class that has too few registers
    to be safely used as a reload target class.  */
@@ -157,8 +158,6 @@ static int replace_reloads;
 struct replacement
 {
   rtx *where;                  /* Location to store in */
 struct replacement
 {
   rtx *where;                  /* Location to store in */
-  rtx *subreg_loc;             /* Location of SUBREG if WHERE is inside
-                                  a SUBREG; 0 otherwise.  */
   int what;                    /* which reload this is for */
   enum machine_mode mode;      /* mode it must have */
 };
   int what;                    /* which reload this is for */
   enum machine_mode mode;      /* mode it must have */
 };
@@ -257,14 +256,13 @@ static int push_secondary_reload (int, rtx, int, int, enum reg_class,
                                  enum insn_code *, secondary_reload_info *);
 static enum reg_class find_valid_class (enum machine_mode, enum machine_mode,
                                        int, unsigned int);
                                  enum insn_code *, secondary_reload_info *);
 static enum reg_class find_valid_class (enum machine_mode, enum machine_mode,
                                        int, unsigned int);
-static int reload_inner_reg_of_subreg (rtx, enum machine_mode, int);
 static void push_replacement (rtx *, int, enum machine_mode);
 static void dup_replacements (rtx *, rtx *);
 static void combine_reloads (void);
 static int find_reusable_reload (rtx *, rtx, enum reg_class,
                                 enum reload_type, int, int);
 static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode,
 static void push_replacement (rtx *, int, enum machine_mode);
 static void dup_replacements (rtx *, rtx *);
 static void combine_reloads (void);
 static int find_reusable_reload (rtx *, rtx, enum reg_class,
                                 enum reload_type, int, int);
 static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode,
-                             enum machine_mode, enum reg_class, int, int);
+                             enum machine_mode, reg_class_t, int, int);
 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 hard_reg_set_here_p (unsigned int, unsigned int, rtx);
 static struct decomposition decompose (rtx);
 static int immune_p (rtx, rtx, struct decomposition);
@@ -279,14 +277,14 @@ static int find_reloads_address (enum machine_mode, rtx *, rtx, rtx *,
 static rtx subst_reg_equivs (rtx, rtx);
 static rtx subst_indexed_address (rtx);
 static void update_auto_inc_notes (rtx, int, int);
 static rtx subst_reg_equivs (rtx, rtx);
 static rtx subst_indexed_address (rtx);
 static void update_auto_inc_notes (rtx, int, int);
-static int find_reloads_address_1 (enum machine_mode, rtx, int,
+static int find_reloads_address_1 (enum machine_mode, addr_space_t, rtx, int,
                                   enum rtx_code, enum rtx_code, rtx *,
                                   int, enum reload_type,int, rtx);
 static void find_reloads_address_part (rtx, rtx *, enum reg_class,
                                       enum machine_mode, int,
                                       enum reload_type, int);
 static rtx find_reloads_subreg_address (rtx, int, int, enum reload_type,
                                   enum rtx_code, enum rtx_code, rtx *,
                                   int, enum reload_type,int, rtx);
 static void find_reloads_address_part (rtx, rtx *, enum reg_class,
                                       enum machine_mode, int,
                                       enum reload_type, int);
 static rtx find_reloads_subreg_address (rtx, int, int, enum reload_type,
-                                       int, rtx);
+                                       int, rtx, int *);
 static void copy_replacements_1 (rtx *, rtx *, int);
 static int find_inc_amount (rtx, rtx);
 static int refers_to_mem_for_reload_p (rtx);
 static void copy_replacements_1 (rtx *, rtx *, int);
 static int find_inc_amount (rtx, rtx);
 static int refers_to_mem_for_reload_p (rtx);
@@ -301,13 +299,13 @@ push_reg_equiv_alt_mem (int regno, rtx mem)
 {
   rtx it;
 
 {
   rtx it;
 
-  for (it = reg_equiv_alt_mem_list [regno]; it; it = XEXP (it, 1))
+  for (it = reg_equiv_alt_mem_list (regno); it; it = XEXP (it, 1))
     if (rtx_equal_p (XEXP (it, 0), mem))
       return;
 
     if (rtx_equal_p (XEXP (it, 0), mem))
       return;
 
-  reg_equiv_alt_mem_list [regno]
+  reg_equiv_alt_mem_list (regno)
     = alloc_EXPR_LIST (REG_EQUIV, mem,
     = alloc_EXPR_LIST (REG_EQUIV, mem,
-                      reg_equiv_alt_mem_list [regno]);
+                      reg_equiv_alt_mem_list (regno));
 }
 \f
 /* Determine if any secondary reloads are needed for loading (if IN_P is
 }
 \f
 /* Determine if any secondary reloads are needed for loading (if IN_P is
@@ -348,9 +346,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
 
   /* If X is a paradoxical SUBREG, use the inner value to determine both the
      mode and object being reloaded.  */
 
   /* If X is a paradoxical SUBREG, use the inner value to determine both the
      mode and object being reloaded.  */
-  if (GET_CODE (x) == SUBREG
-      && (GET_MODE_SIZE (GET_MODE (x))
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
+  if (paradoxical_subreg_p (x))
     {
       x = SUBREG_REG (x);
       reload_mode = GET_MODE (x);
     {
       x = SUBREG_REG (x);
       reload_mode = GET_MODE (x);
@@ -363,8 +359,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
      might be sensitive to the form of the MEM.  */
 
   if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER
      might be sensitive to the form of the MEM.  */
 
   if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER
-      && reg_equiv_mem[REGNO (x)] != 0)
-    x = reg_equiv_mem[REGNO (x)];
+      && reg_equiv_mem (REGNO (x)))
+    x = reg_equiv_mem (REGNO (x));
 
   sri.icode = CODE_FOR_nothing;
   sri.prev_sri = prev_sri;
 
   sri.icode = CODE_FOR_nothing;
   sri.prev_sri = prev_sri;
@@ -794,39 +790,39 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
   return n_reloads;
 }
 
   return n_reloads;
 }
 
-/* Return nonzero if X is a SUBREG which will require reloading of its
-   SUBREG_REG expression.  */
+/* Return true if X is a SUBREG that will need reloading of its SUBREG_REG
+   expression.  MODE is the mode that X will be used in.  OUTPUT is true if
+   the function is invoked for the output part of an enclosing reload.  */
 
 
-static int
-reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, int output)
+static bool
+reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, bool output)
 {
   rtx inner;
 
   /* Only SUBREGs are problematical.  */
   if (GET_CODE (x) != SUBREG)
 {
   rtx inner;
 
   /* Only SUBREGs are problematical.  */
   if (GET_CODE (x) != SUBREG)
-    return 0;
+    return false;
 
   inner = SUBREG_REG (x);
 
 
   inner = SUBREG_REG (x);
 
-  /* If INNER is a constant or PLUS, then INNER must be reloaded.  */
+  /* If INNER is a constant or PLUS, then INNER will need reloading.  */
   if (CONSTANT_P (inner) || GET_CODE (inner) == PLUS)
   if (CONSTANT_P (inner) || GET_CODE (inner) == PLUS)
-    return 1;
+    return true;
 
 
-  /* If INNER is not a hard register, then INNER will not need to
-     be reloaded.  */
-  if (!REG_P (inner)
-      || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
-    return 0;
+  /* If INNER is not a hard register, then INNER will not need reloading.  */
+  if (!(REG_P (inner) && HARD_REGISTER_P (inner)))
+    return false;
 
   /* If INNER is not ok for MODE, then INNER will need reloading.  */
 
   /* If INNER is not ok for MODE, then INNER will need reloading.  */
-  if (! HARD_REGNO_MODE_OK (subreg_regno (x), mode))
-    return 1;
-
-  /* If the outer part is a word or smaller, INNER larger than a
-     word and the number of regs for INNER is not the same as the
-     number of words in INNER, then INNER will need reloading.  */
-  return (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
-         && output
+  if (!HARD_REGNO_MODE_OK (subreg_regno (x), mode))
+    return true;
+
+  /* If this is for an output, and the outer part is a word or smaller,
+     INNER is larger than a word and the number of registers in INNER is
+     not the same as the number of words in INNER, then INNER will need
+     reloading (with an in-out reload).  */
+  return (output
+         && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
          && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD
          && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD)
              != (int) hard_regno_nregs[REGNO (inner)][GET_MODE (inner)]));
          && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD
          && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD)
              != (int) hard_regno_nregs[REGNO (inner)][GET_MODE (inner)]));
@@ -924,7 +920,9 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
   int i;
   int dont_share = 0;
   int dont_remove_subreg = 0;
   int i;
   int dont_share = 0;
   int dont_remove_subreg = 0;
+#ifdef LIMIT_RELOAD_CLASS
   rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
   rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
+#endif
   int secondary_in_reload = -1, secondary_out_reload = -1;
   enum insn_code secondary_in_icode = CODE_FOR_nothing;
   enum insn_code secondary_out_icode = CODE_FOR_nothing;
   int secondary_in_reload = -1, secondary_out_reload = -1;
   enum insn_code secondary_in_icode = CODE_FOR_nothing;
   enum insn_code secondary_out_icode = CODE_FOR_nothing;
@@ -950,7 +948,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 
       gcc_assert (regno < FIRST_PSEUDO_REGISTER
                  || reg_renumber[regno] >= 0
 
       gcc_assert (regno < FIRST_PSEUDO_REGISTER
                  || reg_renumber[regno] >= 0
-                 || reg_equiv_constant[regno] == NULL_RTX);
+                 || reg_equiv_constant (regno) == NULL_RTX);
     }
 
   /* reg_equiv_constant only contains constants which are obviously
     }
 
   /* reg_equiv_constant only contains constants which are obviously
@@ -963,7 +961,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 
       gcc_assert (regno < FIRST_PSEUDO_REGISTER
                  || reg_renumber[regno] >= 0
 
       gcc_assert (regno < FIRST_PSEUDO_REGISTER
                  || reg_renumber[regno] >= 0
-                 || reg_equiv_constant[regno] == NULL_RTX);
+                 || reg_equiv_constant (regno) == NULL_RTX);
     }
 
   /* If we have a read-write operand with an address side-effect,
     }
 
   /* If we have a read-write operand with an address side-effect,
@@ -991,9 +989,9 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
      For machines that extend byte loads, do this for any SUBREG of a pseudo
      where both M1 and M2 are a word or smaller, M1 is wider than M2, and
      M2 is an integral mode that gets extended when loaded.
      For machines that extend byte loads, do this for any SUBREG of a pseudo
      where both M1 and M2 are a word or smaller, M1 is wider than M2, and
      M2 is an integral mode that gets extended when loaded.
-     Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
-     either M1 is not valid for R or M2 is wider than a word but we only
-     need one word to store an M2-sized quantity in R.
+     Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R
+     where either M1 is not valid for R or M2 is wider than a word but we
+     only need one register to store an M2-sized quantity in R.
      (However, if OUT is nonzero, we need to reload the reg *and*
      the subreg, so do nothing here, and let following statement handle it.)
 
      (However, if OUT is nonzero, we need to reload the reg *and*
      the subreg, so do nothing here, and let following statement handle it.)
 
@@ -1018,26 +1016,27 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 #ifdef CANNOT_CHANGE_MODE_CLASS
       && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
 #endif
 #ifdef CANNOT_CHANGE_MODE_CLASS
       && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
 #endif
+      && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (in))]
       && (CONSTANT_P (SUBREG_REG (in))
          || GET_CODE (SUBREG_REG (in)) == PLUS
          || strict_low
          || (((REG_P (SUBREG_REG (in))
                && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (in)))
       && (CONSTANT_P (SUBREG_REG (in))
          || GET_CODE (SUBREG_REG (in)) == PLUS
          || strict_low
          || (((REG_P (SUBREG_REG (in))
                && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (in)))
-             && ((GET_MODE_SIZE (inmode)
-                  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
+             && ((GET_MODE_PRECISION (inmode)
+                  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
 #ifdef LOAD_EXTEND_OP
                  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
                      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
                          <= UNITS_PER_WORD)
 #ifdef LOAD_EXTEND_OP
                  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
                      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
                          <= UNITS_PER_WORD)
-                     && (GET_MODE_SIZE (inmode)
-                         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
+                     && (GET_MODE_PRECISION (inmode)
+                         > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
                      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
                      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
 #endif
 #ifdef WORD_REGISTER_OPERATIONS
                      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
                      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
 #endif
 #ifdef WORD_REGISTER_OPERATIONS
-                 || ((GET_MODE_SIZE (inmode)
-                      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
+                 || ((GET_MODE_PRECISION (inmode)
+                      < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
                      && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
                          ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
                           / UNITS_PER_WORD)))
                      && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
                          ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
                           / UNITS_PER_WORD)))
@@ -1068,7 +1067,9 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 #endif
          ))
     {
 #endif
          ))
     {
+#ifdef LIMIT_RELOAD_CLASS
       in_subreg_loc = inloc;
       in_subreg_loc = inloc;
+#endif
       inloc = &SUBREG_REG (in);
       in = *inloc;
 #if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
       inloc = &SUBREG_REG (in);
       in = *inloc;
 #if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
@@ -1080,17 +1081,16 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
       inmode = GET_MODE (in);
     }
 
       inmode = GET_MODE (in);
     }
 
-  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
-     either M1 is not valid for R or M2 is wider than a word but we only
-     need one word to store an M2-sized quantity in R.
+  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R
+     where M1 is not valid for R if it was not handled by the code above.
+
+     Similar issue for (SUBREG constant ...) if it was not handled by the
+     code above.  This can happen if SUBREG_BYTE != 0.
 
      However, we must reload the inner reg *as well as* the subreg in
      that case.  */
 
 
      However, we must reload the inner reg *as well as* the subreg in
      that case.  */
 
-  /* Similar issue for (SUBREG constant ...) if it was not handled by the
-     code above.  This can happen if SUBREG_BYTE != 0.  */
-
-  if (in != 0 && reload_inner_reg_of_subreg (in, inmode, 0))
+  if (in != 0 && reload_inner_reg_of_subreg (in, inmode, false))
     {
       enum reg_class in_class = rclass;
 
     {
       enum reg_class in_class = rclass;
 
@@ -1115,25 +1115,26 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 
   /* Similarly for paradoxical and problematical SUBREGs on the output.
      Note that there is no reason we need worry about the previous value
 
   /* Similarly for paradoxical and problematical SUBREGs on the output.
      Note that there is no reason we need worry about the previous value
-     of SUBREG_REG (out); even if wider than out,
-     storing in a subreg is entitled to clobber it all
-     (except in the case of STRICT_LOW_PART,
-     and in that case the constraint should label it input-output.)  */
+     of SUBREG_REG (out); even if wider than out, storing in a subreg is
+     entitled to clobber it all (except in the case of a word mode subreg
+     or of a STRICT_LOW_PART, in that latter case the constraint should
+     label it input-output.)  */
   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, rclass)
 #endif
   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, rclass)
 #endif
+      && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (out))]
       && (CONSTANT_P (SUBREG_REG (out))
          || strict_low
          || (((REG_P (SUBREG_REG (out))
                && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (out)))
       && (CONSTANT_P (SUBREG_REG (out))
          || strict_low
          || (((REG_P (SUBREG_REG (out))
                && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (out)))
-             && ((GET_MODE_SIZE (outmode)
-                  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
+             && ((GET_MODE_PRECISION (outmode)
+                  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
 #ifdef WORD_REGISTER_OPERATIONS
 #ifdef WORD_REGISTER_OPERATIONS
-                 || ((GET_MODE_SIZE (outmode)
-                      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
+                 || ((GET_MODE_PRECISION (outmode)
+                      < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
                      && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
                          ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
                           / UNITS_PER_WORD)))
                      && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
                          ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
                           / UNITS_PER_WORD)))
@@ -1141,14 +1142,12 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
                  ))
          || (REG_P (SUBREG_REG (out))
              && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
                  ))
          || (REG_P (SUBREG_REG (out))
              && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
-             && ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
-                  && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
-                      > UNITS_PER_WORD)
-                  && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
-                       / UNITS_PER_WORD)
-                      != (int) hard_regno_nregs[REGNO (SUBREG_REG (out))]
-                                               [GET_MODE (SUBREG_REG (out))]))
-                 || ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode)))
+             /* The case of a word mode subreg
+                is handled differently in the following statement.  */
+             && ! (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
+                   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
+                       > UNITS_PER_WORD))
+             && ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode))
          || (secondary_reload_class (0, rclass, outmode, out) != NO_REGS
              && (secondary_reload_class (0, rclass, GET_MODE (SUBREG_REG (out)),
                                          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))
@@ -1162,7 +1161,9 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
 #endif
          ))
     {
 #endif
          ))
     {
+#ifdef LIMIT_RELOAD_CLASS
       out_subreg_loc = outloc;
       out_subreg_loc = outloc;
+#endif
       outloc = &SUBREG_REG (out);
       out = *outloc;
 #if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
       outloc = &SUBREG_REG (out);
       out = *outloc;
 #if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
@@ -1173,31 +1174,32 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
       outmode = GET_MODE (out);
     }
 
       outmode = GET_MODE (out);
     }
 
-  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
-     either M1 is not valid for R or M2 is wider than a word but we only
-     need one word to store an M2-sized quantity in R.
+  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R
+     where either M1 is not valid for R or M2 is wider than a word but we
+     only need one register to store an M2-sized quantity in R.
 
      However, we must reload the inner reg *as well as* the subreg in
 
      However, we must reload the inner reg *as well as* the subreg in
-     that case.  In this case, the inner reg is an in-out reload.  */
+     that case and the inner reg is an in-out reload.  */
 
 
-  if (out != 0 && reload_inner_reg_of_subreg (out, outmode, 1))
+  if (out != 0 && reload_inner_reg_of_subreg (out, outmode, true))
     {
     {
+      enum reg_class in_out_class
+       = find_valid_class (outmode, GET_MODE (SUBREG_REG (out)),
+                           subreg_regno_offset (REGNO (SUBREG_REG (out)),
+                                                GET_MODE (SUBREG_REG (out)),
+                                                SUBREG_BYTE (out),
+                                                GET_MODE (out)),
+                           REGNO (SUBREG_REG (out)));
+
       /* This relies on the fact that emit_reload_insns outputs the
         instructions for output reloads of type RELOAD_OTHER in reverse
         order of the reloads.  Thus if the outer reload is also of type
         RELOAD_OTHER, we are guaranteed that this inner reload will be
         output after the outer reload.  */
       /* This relies on the fact that emit_reload_insns outputs the
         instructions for output reloads of type RELOAD_OTHER in reverse
         order of the reloads.  Thus if the outer reload is also of type
         RELOAD_OTHER, we are guaranteed that this inner reload will be
         output after the outer reload.  */
-      dont_remove_subreg = 1;
       push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
       push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
-                  &SUBREG_REG (out),
-                  find_valid_class (outmode, GET_MODE (SUBREG_REG (out)),
-                                    subreg_regno_offset (REGNO (SUBREG_REG (out)),
-                                                         GET_MODE (SUBREG_REG (out)),
-                                                         SUBREG_BYTE (out),
-                                                         GET_MODE (out)),
-                                    REGNO (SUBREG_REG (out))),
-                  VOIDmode, VOIDmode, 0, 0,
-                  opnum, RELOAD_OTHER);
+                  &SUBREG_REG (out), in_out_class, VOIDmode, VOIDmode,
+                  0, 0, opnum, RELOAD_OTHER);
+      dont_remove_subreg = 1;
     }
 
   /* If IN appears in OUT, we can't share any input-only reload for IN.  */
     }
 
   /* If IN appears in OUT, we can't share any input-only reload for IN.  */
@@ -1224,21 +1226,20 @@ 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.  */
   {
   /* Narrow down the class of register wanted if that is
      desirable on this machine for efficiency.  */
   {
-    enum reg_class preferred_class = rclass;
+    reg_class_t preferred_class = rclass;
 
     if (in != 0)
 
     if (in != 0)
-      preferred_class = (enum reg_class) targetm.preferred_reload_class (in, rclass);
+      preferred_class = targetm.preferred_reload_class (in, rclass);
 
 
-  /* Output reloads may need analogous treatment, different in detail.  */
-#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
+    /* Output reloads may need analogous treatment, different in detail.  */
     if (out != 0)
     if (out != 0)
-      preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class);
-#endif
+      preferred_class
+       = targetm.preferred_output_reload_class (out, preferred_class);
 
     /* Discard what the target said if we cannot do it.  */
     if (preferred_class != NO_REGS
        || (optional && type == RELOAD_FOR_OUTPUT))
 
     /* Discard what the target said if we cannot do it.  */
     if (preferred_class != NO_REGS
        || (optional && type == RELOAD_FOR_OUTPUT))
-      rclass = preferred_class;
+      rclass = (enum reg_class) preferred_class;
   }
 
   /* Make sure we use a class that can handle the actual pseudo
   }
 
   /* Make sure we use a class that can handle the actual pseudo
@@ -1494,7 +1495,6 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
        {
          struct replacement *r = &replacements[n_replacements++];
          r->what = i;
        {
          struct replacement *r = &replacements[n_replacements++];
          r->what = i;
-         r->subreg_loc = in_subreg_loc;
          r->where = inloc;
          r->mode = inmode;
        }
          r->where = inloc;
          r->mode = inmode;
        }
@@ -1503,7 +1503,6 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
          struct replacement *r = &replacements[n_replacements++];
          r->what = i;
          r->where = outloc;
          struct replacement *r = &replacements[n_replacements++];
          r->what = i;
          r->where = outloc;
-         r->subreg_loc = out_subreg_loc;
          r->mode = outmode;
        }
     }
          r->mode = outmode;
        }
     }
@@ -1632,7 +1631,6 @@ push_replacement (rtx *loc, int reloadnum, enum machine_mode mode)
       struct replacement *r = &replacements[n_replacements++];
       r->what = reloadnum;
       r->where = loc;
       struct replacement *r = &replacements[n_replacements++];
       r->what = reloadnum;
       r->where = loc;
-      r->subreg_loc = 0;
       r->mode = mode;
     }
 }
       r->mode = mode;
     }
 }
@@ -1766,9 +1764,9 @@ 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
        && 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].rclass, rld[i].inmode)
-           == CLASS_MAX_NREGS (rld[output_reload].rclass,
-                               rld[output_reload].outmode))
+       && (ira_reg_class_max_nregs [(int)rld[i].rclass][(int) rld[i].inmode]
+           == ira_reg_class_max_nregs [(int) rld[output_reload].rclass]
+                                      [(int) rld[output_reload].outmode])
        && rld[i].inc == 0
        && rld[i].reg_rtx == 0
 #ifdef SECONDARY_MEMORY_NEEDED
        && rld[i].inc == 0
        && rld[i].reg_rtx == 0
 #ifdef SECONDARY_MEMORY_NEEDED
@@ -1920,7 +1918,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,
 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 rclass, int for_real, int earlyclobber)
+                  reg_class_t rclass, int for_real, int earlyclobber)
 {
   rtx in = real_in;
   rtx out = real_out;
 {
   rtx in = real_in;
   rtx out = real_out;
@@ -2217,15 +2215,15 @@ operands_match_p (rtx x, rtx y)
       else
        j = REGNO (y);
 
       else
        j = REGNO (y);
 
-      /* On a WORDS_BIG_ENDIAN machine, point to the last register of a
+      /* On a REG_WORDS_BIG_ENDIAN machine, point to the last register of a
         multiple hard register group of scalar integer registers, so that
         for example (reg:DI 0) and (reg:SI 1) will be considered the same
         register.  */
         multiple hard register group of scalar integer registers, 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
+      if (REG_WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
          && SCALAR_INT_MODE_P (GET_MODE (x))
          && i < FIRST_PSEUDO_REGISTER)
        i += hard_regno_nregs[i][GET_MODE (x)] - 1;
          && SCALAR_INT_MODE_P (GET_MODE (x))
          && i < FIRST_PSEUDO_REGISTER)
        i += hard_regno_nregs[i][GET_MODE (x)] - 1;
-      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
+      if (REG_WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
          && SCALAR_INT_MODE_P (GET_MODE (y))
          && j < FIRST_PSEUDO_REGISTER)
        j += hard_regno_nregs[j][GET_MODE (y)] - 1;
          && SCALAR_INT_MODE_P (GET_MODE (y))
          && j < FIRST_PSEUDO_REGISTER)
        j += hard_regno_nregs[j][GET_MODE (y)] - 1;
@@ -2588,7 +2586,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
   enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS];
   int no_input_reloads = 0, no_output_reloads = 0;
   int n_alternatives;
   enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS];
   int no_input_reloads = 0, no_output_reloads = 0;
   int n_alternatives;
-  enum reg_class this_alternative[MAX_RECOG_OPERANDS];
+  reg_class_t this_alternative[MAX_RECOG_OPERANDS];
   char this_alternative_match_win[MAX_RECOG_OPERANDS];
   char this_alternative_win[MAX_RECOG_OPERANDS];
   char this_alternative_offmemok[MAX_RECOG_OPERANDS];
   char this_alternative_match_win[MAX_RECOG_OPERANDS];
   char this_alternative_win[MAX_RECOG_OPERANDS];
   char this_alternative_offmemok[MAX_RECOG_OPERANDS];
@@ -2824,6 +2822,13 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
          /* Address operands are reloaded in their existing mode,
             no matter what is specified in the machine description.  */
          operand_mode[i] = GET_MODE (recog_data.operand[i]);
          /* Address operands are reloaded in their existing mode,
             no matter what is specified in the machine description.  */
          operand_mode[i] = GET_MODE (recog_data.operand[i]);
+
+         /* If the address is a single CONST_INT pick address mode
+            instead otherwise we will later not know in which mode
+            the reload should be performed.  */
+         if (operand_mode[i] == VOIDmode)
+           operand_mode[i] = Pmode;
+
        }
       else if (code == MEM)
        {
        }
       else if (code == MEM)
        {
@@ -2857,10 +2862,10 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
              && REG_P (reg)
              && (GET_MODE_SIZE (GET_MODE (reg))
                  >= GET_MODE_SIZE (GET_MODE (op)))
              && REG_P (reg)
              && (GET_MODE_SIZE (GET_MODE (reg))
                  >= GET_MODE_SIZE (GET_MODE (op)))
-             && reg_equiv_constant[REGNO (reg)] == 0)
+             && reg_equiv_constant (REGNO (reg)) == 0)
            set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
                                                   insn),
            set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
                                                   insn),
-                                REG_EQUAL, reg_equiv_memory_loc[REGNO (reg)]);
+                                REG_EQUAL, reg_equiv_memory_loc (REGNO (reg)));
 
          substed_operand[i] = recog_data.operand[i] = op;
        }
 
          substed_operand[i] = recog_data.operand[i] = op;
        }
@@ -2881,7 +2886,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
             that we don't try to replace it in the insn in which it
             is being set.  */
          int regno = REGNO (recog_data.operand[i]);
             that we don't try to replace it in the insn in which it
             is being set.  */
          int regno = REGNO (recog_data.operand[i]);
-         if (reg_equiv_constant[regno] != 0
+         if (reg_equiv_constant (regno) != 0
              && (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i]))
            {
              /* Record the existing mode so that the check if constants are
              && (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i]))
            {
              /* Record the existing mode so that the check if constants are
@@ -2891,10 +2896,10 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                operand_mode[i] = GET_MODE (recog_data.operand[i]);
 
              substed_operand[i] = recog_data.operand[i]
                operand_mode[i] = GET_MODE (recog_data.operand[i]);
 
              substed_operand[i] = recog_data.operand[i]
-               = reg_equiv_constant[regno];
+               = reg_equiv_constant (regno);
            }
            }
-         if (reg_equiv_memory_loc[regno] != 0
-             && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+         if (reg_equiv_memory_loc (regno) != 0
+             && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
            /* We need not give a valid is_set_dest argument since the case
               of a constant equivalence was checked above.  */
            substed_operand[i] = recog_data.operand[i]
            /* We need not give a valid is_set_dest argument since the case
               of a constant equivalence was checked above.  */
            substed_operand[i] = recog_data.operand[i]
@@ -3234,8 +3239,9 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
              case 'p':
                /* All necessary reloads for an address_operand
                   were handled in find_reloads_address.  */
              case 'p':
                /* All necessary reloads for an address_operand
                   were handled in find_reloads_address.  */
-               this_alternative[i] = base_reg_class (VOIDmode, ADDRESS,
-                                                     SCRATCH);
+               this_alternative[i]
+                 = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
+                                   ADDRESS, SCRATCH);
                win = 1;
                badop = 0;
                break;
                win = 1;
                badop = 0;
                break;
@@ -3248,7 +3254,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                        && REGNO (operand) >= FIRST_PSEUDO_REGISTER
                        && reg_renumber[REGNO (operand)] < 0))
                  win = 1;
                        && REGNO (operand) >= FIRST_PSEUDO_REGISTER
                        && reg_renumber[REGNO (operand)] < 0))
                  win = 1;
-               if (CONST_POOL_OK_P (operand))
+               if (CONST_POOL_OK_P (operand_mode[i], operand))
                  badop = 0;
                constmemok = 1;
                break;
                  badop = 0;
                constmemok = 1;
                break;
@@ -3282,7 +3288,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                       to override the handling of reg_equiv_address.  */
                    && !(REG_P (XEXP (operand, 0))
                         && (ind_levels == 0
                       to override the handling of reg_equiv_address.  */
                    && !(REG_P (XEXP (operand, 0))
                         && (ind_levels == 0
-                            || reg_equiv_address[REGNO (XEXP (operand, 0))] != 0)))
+                            || reg_equiv_address (REGNO (XEXP (operand, 0))) != 0)))
                  win = 1;
                break;
 
                  win = 1;
                break;
 
@@ -3306,11 +3312,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                           loading it into a register; hence it will be
                           offsettable, but we cannot say that reg_equiv_mem
                           is offsettable without checking.  */
                           loading it into a register; hence it will be
                           offsettable, but we cannot say that reg_equiv_mem
                           is offsettable without checking.  */
-                       && ((reg_equiv_mem[REGNO (operand)] != 0
-                            && offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
-                           || (reg_equiv_address[REGNO (operand)] != 0))))
+                       && ((reg_equiv_mem (REGNO (operand)) != 0
+                            && offsettable_memref_p (reg_equiv_mem (REGNO (operand))))
+                           || (reg_equiv_address (REGNO (operand)) != 0))))
                  win = 1;
                  win = 1;
-               if (CONST_POOL_OK_P (operand)
+               if (CONST_POOL_OK_P (operand_mode[i], operand)
                    || MEM_P (operand))
                  badop = 0;
                constmemok = 1;
                    || MEM_P (operand))
                  badop = 0;
                constmemok = 1;
@@ -3418,15 +3424,15 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                        else if (REG_P (operand)
                                 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
                                 && reg_renumber[REGNO (operand)] < 0
                        else if (REG_P (operand)
                                 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
                                 && reg_renumber[REGNO (operand)] < 0
-                                && ((reg_equiv_mem[REGNO (operand)] != 0
-                                     && EXTRA_CONSTRAINT_STR (reg_equiv_mem[REGNO (operand)], c, p))
-                                    || (reg_equiv_address[REGNO (operand)] != 0)))
+                                && ((reg_equiv_mem (REGNO (operand)) != 0
+                                     && EXTRA_CONSTRAINT_STR (reg_equiv_mem (REGNO (operand)), c, p))
+                                    || (reg_equiv_address (REGNO (operand)) != 0)))
                          win = 1;
 
                        /* If we didn't already win, we can reload
                           constants via force_const_mem, and other
                           MEMs by reloading the address like for 'o'.  */
                          win = 1;
 
                        /* If we didn't already win, we can reload
                           constants via force_const_mem, and other
                           MEMs by reloading the address like for 'o'.  */
-                       if (CONST_POOL_OK_P (operand)
+                       if (CONST_POOL_OK_P (operand_mode[i], operand)
                            || MEM_P (operand))
                          badop = 0;
                        constmemok = 1;
                            || MEM_P (operand))
                          badop = 0;
                        constmemok = 1;
@@ -3440,9 +3446,9 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
 
                        /* If we didn't already win, we can reload
                           the address into a base register.  */
 
                        /* If we didn't already win, we can reload
                           the address into a base register.  */
-                       this_alternative[i] = base_reg_class (VOIDmode,
-                                                             ADDRESS,
-                                                             SCRATCH);
+                       this_alternative[i]
+                         = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
+                                           ADDRESS, SCRATCH);
                        badop = 0;
                        break;
                      }
                        badop = 0;
                        break;
                      }
@@ -3505,12 +3511,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                 an early reload pass.  Note that the test here is
                 precisely the same as in the code below that calls
                 force_const_mem.  */
                 an early reload pass.  Note that the test here is
                 precisely the same as in the code below that calls
                 force_const_mem.  */
-             if (CONST_POOL_OK_P (operand)
+             if (CONST_POOL_OK_P (operand_mode[i], operand)
                  && ((targetm.preferred_reload_class (operand,
                                                       this_alternative[i])
                       == NO_REGS)
                  && ((targetm.preferred_reload_class (operand,
                                                       this_alternative[i])
                       == NO_REGS)
-                     || no_input_reloads)
-                 && operand_mode[i] != VOIDmode)
+                     || no_input_reloads))
                {
                  const_to_mem = 1;
                  if (this_alternative[i] != NO_REGS)
                {
                  const_to_mem = 1;
                  if (this_alternative[i] != NO_REGS)
@@ -3539,13 +3544,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
                      == NO_REGS)
                    reject = 600;
 
                      == NO_REGS)
                    reject = 600;
 
-#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
                  if (operand_type[i] == RELOAD_FOR_OUTPUT
                  if (operand_type[i] == RELOAD_FOR_OUTPUT
-                     && (PREFERRED_OUTPUT_RELOAD_CLASS (operand,
-                                                       this_alternative[i])
+                     && (targetm.preferred_output_reload_class (operand,
+                                                                this_alternative[i])
                          == NO_REGS))
                    reject = 600;
                          == NO_REGS))
                    reject = 600;
-#endif
                }
 
              /* We prefer to reload pseudos over reloading other things,
                }
 
              /* We prefer to reload pseudos over reloading other things,
@@ -3696,7 +3699,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
            {
              goal_alternative_win[i] = this_alternative_win[i];
              goal_alternative_match_win[i] = this_alternative_match_win[i];
            {
              goal_alternative_win[i] = this_alternative_win[i];
              goal_alternative_match_win[i] = this_alternative_match_win[i];
-             goal_alternative[i] = (reg_class_t) this_alternative[i];
+             goal_alternative[i] = this_alternative[i];
              goal_alternative_offmemok[i] = this_alternative_offmemok[i];
              goal_alternative_matches[i] = this_alternative_matches[i];
              goal_alternative_earlyclobber[i]
              goal_alternative_offmemok[i] = this_alternative_offmemok[i];
              goal_alternative_matches[i] = this_alternative_matches[i];
              goal_alternative_earlyclobber[i]
@@ -3723,7 +3726,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
            {
              for (i = 0; i < noperands; i++)
                {
            {
              for (i = 0; i < noperands; i++)
                {
-                 goal_alternative[i] = (reg_class_t) this_alternative[i];
+                 goal_alternative[i] = this_alternative[i];
                  goal_alternative_win[i] = this_alternative_win[i];
                  goal_alternative_match_win[i]
                    = this_alternative_match_win[i];
                  goal_alternative_win[i] = this_alternative_win[i];
                  goal_alternative_match_win[i]
                    = this_alternative_match_win[i];
@@ -3915,11 +3918,10 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
            op = XEXP (op, 1);
          }
 
            op = XEXP (op, 1);
          }
 
-       if (CONST_POOL_OK_P (op)
+       if (CONST_POOL_OK_P (mode, op)
            && ((targetm.preferred_reload_class (op, goal_alternative[i])
                 == NO_REGS)
            && ((targetm.preferred_reload_class (op, goal_alternative[i])
                 == NO_REGS)
-               || no_input_reloads)
-           && mode != VOIDmode)
+               || no_input_reloads))
          {
            int this_address_reloaded;
            rtx tem = force_const_mem (mode, op);
          {
            int this_address_reloaded;
            rtx tem = force_const_mem (mode, op);
@@ -3976,18 +3978,16 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
            /* If the address to be reloaded is a VOIDmode constant,
               use the default address mode as mode of the reload register,
               as would have been done by find_reloads_address.  */
            /* If the address to be reloaded is a VOIDmode constant,
               use the default address mode as mode of the reload register,
               as would have been done by find_reloads_address.  */
+           addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
            enum machine_mode address_mode;
            address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
            if (address_mode == VOIDmode)
            enum machine_mode address_mode;
            address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
            if (address_mode == VOIDmode)
-             {
-               addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
-               address_mode = targetm.addr_space.address_mode (as);
-             }
+             address_mode = targetm.addr_space.address_mode (as);
 
            operand_reloadnum[i]
              = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
                             &XEXP (recog_data.operand[i], 0), (rtx*) 0,
 
            operand_reloadnum[i]
              = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
                             &XEXP (recog_data.operand[i], 0), (rtx*) 0,
-                            base_reg_class (VOIDmode, MEM, SCRATCH),
+                            base_reg_class (VOIDmode, as, MEM, SCRATCH),
                             address_mode,
                             VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
            rld[operand_reloadnum[i]].inc
                             address_mode,
                             VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
            rld[operand_reloadnum[i]].inc
@@ -4208,7 +4208,12 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
              && (!JUMP_P (insn)
                  || !label_is_jump_target_p (XEXP (substitution, 0),
                                              insn)))
              && (!JUMP_P (insn)
                  || !label_is_jump_target_p (XEXP (substitution, 0),
                                              insn)))
-           add_reg_note (insn, REG_LABEL_OPERAND, XEXP (substitution, 0));
+           {
+             add_reg_note (insn, REG_LABEL_OPERAND, XEXP (substitution, 0));
+             if (LABEL_P (XEXP (substitution, 0)))
+               ++LABEL_NUSES (XEXP (substitution, 0));
+           }
+
        }
       else
        retval |= (substed_operand[i] != *recog_data.operand_loc[i]);
        }
       else
        retval |= (substed_operand[i] != *recog_data.operand_loc[i]);
@@ -4545,7 +4550,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;
 
               > GET_MODE_SIZE (rld[i].inmode)))
          ? rld[i].outmode : rld[i].inmode;
 
-      rld[i].nregs = CLASS_MAX_NREGS (rld[i].rclass, rld[i].mode);
+      rld[i].nregs = ira_reg_class_max_nregs [rld[i].rclass][rld[i].mode];
     }
 
   /* Special case a simple move with an input reload and a
     }
 
   /* Special case a simple move with an input reload and a
@@ -4594,7 +4599,8 @@ alternative_allows_const_pool_ref (rtx mem ATTRIBUTE_UNUSED,
   /* Skip alternatives before the one requested.  */
   while (altnum > 0)
     {
   /* Skip alternatives before the one requested.  */
   while (altnum > 0)
     {
-      while (*constraint++ != ',');
+      while (*constraint++ != ',')
+       ;
       altnum--;
     }
   /* Scan the requested alternative for TARGET_MEM_CONSTRAINT or 'o'.
       altnum--;
     }
   /* Scan the requested alternative for TARGET_MEM_CONSTRAINT or 'o'.
@@ -4656,20 +4662,20 @@ find_reloads_toplev (rtx x, int opnum, enum reload_type type,
     {
       /* This code is duplicated for speed in find_reloads.  */
       int regno = REGNO (x);
     {
       /* This code is duplicated for speed in find_reloads.  */
       int regno = REGNO (x);
-      if (reg_equiv_constant[regno] != 0 && !is_set_dest)
-       x = reg_equiv_constant[regno];
+      if (reg_equiv_constant (regno) != 0 && !is_set_dest)
+       x = reg_equiv_constant (regno);
 #if 0
       /*  This creates (subreg (mem...)) which would cause an unnecessary
          reload of the mem.  */
 #if 0
       /*  This creates (subreg (mem...)) which would cause an unnecessary
          reload of the mem.  */
-      else if (reg_equiv_mem[regno] != 0)
-       x = reg_equiv_mem[regno];
+      else if (reg_equiv_mem (regno) != 0)
+       x = reg_equiv_mem (regno);
 #endif
 #endif
-      else if (reg_equiv_memory_loc[regno]
-              && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+      else if (reg_equiv_memory_loc (regno)
+              && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
        {
          rtx mem = make_memloc (x, regno);
        {
          rtx mem = make_memloc (x, regno);
-         if (reg_equiv_address[regno]
-             || ! rtx_equal_p (mem, reg_equiv_mem[regno]))
+         if (reg_equiv_address (regno)
+             || ! rtx_equal_p (mem, reg_equiv_mem (regno)))
            {
              /* If this is not a toplevel operand, find_reloads doesn't see
                 this substitution.  We have to emit a USE of the pseudo so
            {
              /* If this is not a toplevel operand, find_reloads doesn't see
                 this substitution.  We have to emit a USE of the pseudo so
@@ -4719,13 +4725,14 @@ find_reloads_toplev (rtx x, int opnum, enum reload_type type,
 
       if (regno >= FIRST_PSEUDO_REGISTER
          && reg_renumber[regno] < 0
 
       if (regno >= FIRST_PSEUDO_REGISTER
          && reg_renumber[regno] < 0
-         && reg_equiv_constant[regno] != 0)
+         && reg_equiv_constant (regno) != 0)
        {
          tem =
        {
          tem =
-           simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno],
+           simplify_gen_subreg (GET_MODE (x), reg_equiv_constant (regno),
                                 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
          gcc_assert (tem);
                                 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
          gcc_assert (tem);
-         if (CONSTANT_P (tem) && !LEGITIMATE_CONSTANT_P (tem))
+         if (CONSTANT_P (tem)
+             && !targetm.legitimate_constant_p (GET_MODE (x), tem))
            {
              tem = force_const_mem (GET_MODE (x), tem);
              i = find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
            {
              tem = force_const_mem (GET_MODE (x), tem);
              i = find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
@@ -4752,18 +4759,17 @@ find_reloads_toplev (rtx x, int opnum, enum reload_type type,
 
       if (regno >= FIRST_PSEUDO_REGISTER
 #ifdef LOAD_EXTEND_OP
 
       if (regno >= FIRST_PSEUDO_REGISTER
 #ifdef LOAD_EXTEND_OP
-              && (GET_MODE_SIZE (GET_MODE (x))
-                  <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+         && !paradoxical_subreg_p (x)
 #endif
 #endif
-              && (reg_equiv_address[regno] != 0
-                  || (reg_equiv_mem[regno] != 0
-                      && (! strict_memory_address_addr_space_p
-                              (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
-                               MEM_ADDR_SPACE (reg_equiv_mem[regno]))
-                          || ! offsettable_memref_p (reg_equiv_mem[regno])
-                          || num_not_at_initial_offset))))
+         && (reg_equiv_address (regno) != 0
+             || (reg_equiv_mem (regno) != 0
+                 && (! strict_memory_address_addr_space_p
+                     (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
+                      MEM_ADDR_SPACE (reg_equiv_mem (regno)))
+                     || ! offsettable_memref_p (reg_equiv_mem (regno))
+                     || num_not_at_initial_offset))))
        x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
        x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
-                                        insn);
+                                          insn, address_reloaded);
     }
 
   for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     }
 
   for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
@@ -4798,7 +4804,7 @@ make_memloc (rtx ad, int regno)
   /* We must rerun eliminate_regs, in case the elimination
      offsets have changed.  */
   rtx tem
   /* We must rerun eliminate_regs, in case the elimination
      offsets have changed.  */
   rtx tem
-    = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], VOIDmode, NULL_RTX),
+    = XEXP (eliminate_regs (reg_equiv_memory_loc (regno), VOIDmode, NULL_RTX),
            0);
 
   /* If TEM might contain a pseudo, we must copy it to avoid
            0);
 
   /* If TEM might contain a pseudo, we must copy it to avoid
@@ -4806,12 +4812,12 @@ make_memloc (rtx ad, int regno)
   if (rtx_varies_p (tem, 0))
     tem = copy_rtx (tem);
 
   if (rtx_varies_p (tem, 0))
     tem = copy_rtx (tem);
 
-  tem = replace_equiv_address_nv (reg_equiv_memory_loc[regno], tem);
+  tem = replace_equiv_address_nv (reg_equiv_memory_loc (regno), tem);
   tem = adjust_address_nv (tem, GET_MODE (ad), 0);
 
   /* Copy the result if it's still the same as the equivalence, to avoid
      modifying it when we do the substitution for the reload.  */
   tem = adjust_address_nv (tem, GET_MODE (ad), 0);
 
   /* Copy the result if it's still the same as the equivalence, to avoid
      modifying it when we do the substitution for the reload.  */
-  if (tem == reg_equiv_memory_loc[regno])
+  if (tem == reg_equiv_memory_loc (regno))
     tem = copy_rtx (tem);
   return tem;
 }
     tem = copy_rtx (tem);
   return tem;
 }
@@ -4880,18 +4886,18 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
     {
       regno = REGNO (ad);
 
     {
       regno = REGNO (ad);
 
-      if (reg_equiv_constant[regno] != 0)
+      if (reg_equiv_constant (regno) != 0)
        {
        {
-         find_reloads_address_part (reg_equiv_constant[regno], loc,
-                                    base_reg_class (mode, MEM, SCRATCH),
+         find_reloads_address_part (reg_equiv_constant (regno), loc,
+                                    base_reg_class (mode, as, MEM, SCRATCH),
                                     GET_MODE (ad), opnum, type, ind_levels);
          return 1;
        }
 
                                     GET_MODE (ad), opnum, type, ind_levels);
          return 1;
        }
 
-      tem = reg_equiv_memory_loc[regno];
+      tem = reg_equiv_memory_loc (regno);
       if (tem != 0)
        {
       if (tem != 0)
        {
-         if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
+         if (reg_equiv_address (regno) != 0 || num_not_at_initial_offset)
            {
              tem = make_memloc (ad, regno);
              if (! strict_memory_address_addr_space_p (GET_MODE (tem),
            {
              tem = make_memloc (ad, regno);
              if (! strict_memory_address_addr_space_p (GET_MODE (tem),
@@ -4923,7 +4929,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
                     in the final reload pass.  */
                  if (replace_reloads
                      && num_not_at_initial_offset
                     in the final reload pass.  */
                  if (replace_reloads
                      && num_not_at_initial_offset
-                     && ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+                     && ! rtx_equal_p (tem, reg_equiv_mem (regno)))
                    {
                      *loc = tem;
                      /* We mark the USE with QImode so that we
                    {
                      *loc = tem;
                      /* We mark the USE with QImode so that we
@@ -4946,12 +4952,13 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
         subject of a CLOBBER in this insn.  */
 
       else if (regno < FIRST_PSEUDO_REGISTER
         subject of a CLOBBER in this insn.  */
 
       else if (regno < FIRST_PSEUDO_REGISTER
-              && regno_ok_for_base_p (regno, mode, MEM, SCRATCH)
+              && regno_ok_for_base_p (regno, mode, as, MEM, SCRATCH)
               && ! regno_clobbered_p (regno, this_insn, mode, 0))
        return 0;
 
       /* If we do not have one of the cases above, we must do the reload.  */
               && ! regno_clobbered_p (regno, this_insn, mode, 0))
        return 0;
 
       /* If we do not have one of the cases above, we must do the reload.  */
-      push_reload (ad, NULL_RTX, loc, (rtx*) 0, base_reg_class (mode, MEM, SCRATCH),
+      push_reload (ad, NULL_RTX, loc, (rtx*) 0,
+                  base_reg_class (mode, as, MEM, SCRATCH),
                   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
       return 1;
     }
                   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
       return 1;
     }
@@ -4969,7 +4976,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
       if (GET_CODE (ad) == PLUS
          && CONST_INT_P (XEXP (ad, 1))
          && REG_P (XEXP (ad, 0))
       if (GET_CODE (ad) == PLUS
          && CONST_INT_P (XEXP (ad, 1))
          && REG_P (XEXP (ad, 0))
-         && reg_equiv_constant[REGNO (XEXP (ad, 0))] == 0)
+         && reg_equiv_constant (REGNO (XEXP (ad, 0))) == 0)
        return 0;
 
       subst_reg_equivs_changed = 0;
        return 0;
 
       subst_reg_equivs_changed = 0;
@@ -5052,7 +5059,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
          /* Must use TEM here, not AD, since it is the one that will
             have any subexpressions reloaded, if needed.  */
          push_reload (tem, NULL_RTX, loc, (rtx*) 0,
          /* Must use TEM here, not AD, since it is the one that will
             have any subexpressions reloaded, if needed.  */
          push_reload (tem, NULL_RTX, loc, (rtx*) 0,
-                      base_reg_class (mode, MEM, SCRATCH), GET_MODE (tem),
+                      base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (tem),
                       VOIDmode, 0,
                       0, opnum, type);
          return ! removed_and;
                       VOIDmode, 0,
                       0, opnum, type);
          return ! removed_and;
@@ -5070,8 +5077,13 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
           && REG_P (XEXP (ad, 0))
           && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
           && CONST_INT_P (XEXP (ad, 1))
           && REG_P (XEXP (ad, 0))
           && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
           && CONST_INT_P (XEXP (ad, 1))
-          && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, PLUS,
-                                  CONST_INT))
+          && (regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as, PLUS,
+                                   CONST_INT)
+              /* Similarly, if we were to reload the base register and the
+                 mem+offset address is still invalid, then we want to reload
+                 the whole address, not just the base register.  */
+              || ! maybe_memory_address_addr_space_p
+                    (mode, ad, as, &(XEXP (ad, 0)))))
 
     {
       /* Unshare the MEM rtx so we can safely alter it.  */
 
     {
       /* Unshare the MEM rtx so we can safely alter it.  */
@@ -5083,7 +5095,9 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
            loc = &XEXP (*loc, 0);
        }
 
            loc = &XEXP (*loc, 0);
        }
 
-      if (double_reg_address_ok)
+      if (double_reg_address_ok
+         && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as,
+                                 PLUS, CONST_INT))
        {
          /* Unshare the sum as well.  */
          *loc = ad = copy_rtx (ad);
        {
          /* Unshare the sum as well.  */
          *loc = ad = copy_rtx (ad);
@@ -5101,7 +5115,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
             reload the sum into a base reg.
             That will at least work.  */
          find_reloads_address_part (ad, loc,
             reload the sum into a base reg.
             That will at least work.  */
          find_reloads_address_part (ad, loc,
-                                    base_reg_class (mode, MEM, SCRATCH),
+                                    base_reg_class (mode, as, MEM, SCRATCH),
                                     GET_MODE (ad), opnum, type, ind_levels);
        }
       return ! removed_and;
                                     GET_MODE (ad), opnum, type, ind_levels);
        }
       return ! removed_and;
@@ -5153,7 +5167,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
 
       addend = XEXP (XEXP (ad, 0), 1 - op_index);
 
 
       addend = XEXP (XEXP (ad, 0), 1 - op_index);
 
-      if ((regno_ok_for_base_p (REGNO (operand), mode, inner_code,
+      if ((regno_ok_for_base_p (REGNO (operand), mode, as, inner_code,
                                GET_CODE (addend))
           || operand == frame_pointer_rtx
 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
                                GET_CODE (addend))
           || operand == frame_pointer_rtx
 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
@@ -5182,11 +5196,11 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
                                 op_index == 0 ? addend : offset_reg);
          *loc = ad;
 
                                 op_index == 0 ? addend : offset_reg);
          *loc = ad;
 
-         cls = base_reg_class (mode, MEM, GET_CODE (addend));
+         cls = base_reg_class (mode, as, MEM, GET_CODE (addend));
          find_reloads_address_part (XEXP (ad, op_index),
                                     &XEXP (ad, op_index), cls,
                                     GET_MODE (ad), opnum, type, ind_levels);
          find_reloads_address_part (XEXP (ad, op_index),
                                     &XEXP (ad, op_index), cls,
                                     GET_MODE (ad), opnum, type, ind_levels);
-         find_reloads_address_1 (mode,
+         find_reloads_address_1 (mode, as,
                                  XEXP (ad, 1 - op_index), 1, GET_CODE (ad),
                                  GET_CODE (XEXP (ad, op_index)),
                                  &XEXP (ad, 1 - op_index), opnum,
                                  XEXP (ad, 1 - op_index), 1, GET_CODE (ad),
                                  GET_CODE (XEXP (ad, op_index)),
                                  &XEXP (ad, 1 - op_index), opnum,
@@ -5239,13 +5253,14 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
            loc = &XEXP (*loc, 0);
        }
 
            loc = &XEXP (*loc, 0);
        }
 
-      find_reloads_address_part (ad, loc, base_reg_class (mode, MEM, SCRATCH),
+      find_reloads_address_part (ad, loc,
+                                base_reg_class (mode, as, MEM, SCRATCH),
                                 address_mode, opnum, type, ind_levels);
       return ! removed_and;
     }
 
                                 address_mode, opnum, type, ind_levels);
       return ! removed_and;
     }
 
-  return find_reloads_address_1 (mode, ad, 0, MEM, SCRATCH, loc, opnum, type,
-                                ind_levels, insn);
+  return find_reloads_address_1 (mode, as, ad, 0, MEM, SCRATCH, loc,
+                                opnum, type, ind_levels, insn);
 }
 \f
 /* Find all pseudo regs appearing in AD
 }
 \f
 /* Find all pseudo regs appearing in AD
@@ -5279,15 +5294,15 @@ subst_reg_equivs (rtx ad, rtx insn)
       {
        int regno = REGNO (ad);
 
       {
        int regno = REGNO (ad);
 
-       if (reg_equiv_constant[regno] != 0)
+       if (reg_equiv_constant (regno) != 0)
          {
            subst_reg_equivs_changed = 1;
          {
            subst_reg_equivs_changed = 1;
-           return reg_equiv_constant[regno];
+           return reg_equiv_constant (regno);
          }
          }
-       if (reg_equiv_memory_loc[regno] && num_not_at_initial_offset)
+       if (reg_equiv_memory_loc (regno) && num_not_at_initial_offset)
          {
            rtx mem = make_memloc (ad, regno);
          {
            rtx mem = make_memloc (ad, regno);
-           if (! rtx_equal_p (mem, reg_equiv_mem[regno]))
+           if (! rtx_equal_p (mem, reg_equiv_mem (regno)))
              {
                subst_reg_equivs_changed = 1;
                /* We mark the USE with QImode so that we recognize it
              {
                subst_reg_equivs_changed = 1;
                /* We mark the USE with QImode so that we recognize it
@@ -5390,13 +5405,13 @@ subst_indexed_address (rtx addr)
       if (REG_P (op0)
          && (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
          && reg_renumber[regno] < 0
       if (REG_P (op0)
          && (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
          && reg_renumber[regno] < 0
-         && reg_equiv_constant[regno] != 0)
-       op0 = reg_equiv_constant[regno];
+         && reg_equiv_constant (regno) != 0)
+       op0 = reg_equiv_constant (regno);
       else if (REG_P (op1)
               && (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
               && reg_renumber[regno] < 0
       else if (REG_P (op1)
               && (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
               && reg_renumber[regno] < 0
-              && reg_equiv_constant[regno] != 0)
-       op1 = reg_equiv_constant[regno];
+              && reg_equiv_constant (regno) != 0)
+       op1 = reg_equiv_constant (regno);
       else if (GET_CODE (op0) == PLUS
               && (tem = subst_indexed_address (op0)) != op0)
        op0 = tem;
       else if (GET_CODE (op0) == PLUS
               && (tem = subst_indexed_address (op0)) != op0)
        op0 = tem;
@@ -5478,14 +5493,15 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
    handles those cases gracefully.  */
 
 static int
    handles those cases gracefully.  */
 
 static int
-find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
+find_reloads_address_1 (enum machine_mode mode, addr_space_t as,
+                       rtx x, int context,
                        enum rtx_code outer_code, enum rtx_code index_code,
                        rtx *loc, int opnum, enum reload_type type,
                        int ind_levels, rtx insn)
 {
                        enum rtx_code outer_code, enum rtx_code index_code,
                        rtx *loc, int opnum, enum reload_type type,
                        int ind_levels, rtx insn)
 {
-#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, OUTER, INDEX)         \
+#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, AS, OUTER, INDEX)     \
   ((CONTEXT) == 0                                                      \
   ((CONTEXT) == 0                                                      \
-   ? regno_ok_for_base_p (REGNO, MODE, OUTER, INDEX)                   \
+   ? regno_ok_for_base_p (REGNO, MODE, AS, OUTER, INDEX)               \
    : REGNO_OK_FOR_INDEX_P (REGNO))
 
   enum reg_class context_reg_class;
    : REGNO_OK_FOR_INDEX_P (REGNO))
 
   enum reg_class context_reg_class;
@@ -5494,7 +5510,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
   if (context == 1)
     context_reg_class = INDEX_REG_CLASS;
   else
   if (context == 1)
     context_reg_class = INDEX_REG_CLASS;
   else
-    context_reg_class = base_reg_class (mode, outer_code, index_code);
+    context_reg_class = base_reg_class (mode, as, outer_code, index_code);
 
   switch (code)
     {
 
   switch (code)
     {
@@ -5551,10 +5567,10 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
            || code0 == ZERO_EXTEND || code1 == MEM)
          {
        if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
            || code0 == ZERO_EXTEND || code1 == MEM)
          {
-           find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
+           find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
                                    &XEXP (x, 0), opnum, type, ind_levels,
                                    insn);
                                    &XEXP (x, 0), opnum, type, ind_levels,
                                    insn);
-           find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0,
+           find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0,
                                    &XEXP (x, 1), opnum, type, ind_levels,
                                    insn);
          }
                                    &XEXP (x, 1), opnum, type, ind_levels,
                                    insn);
          }
@@ -5562,56 +5578,56 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
                 || code1 == ZERO_EXTEND || code0 == MEM)
          {
        else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
                 || code1 == ZERO_EXTEND || code0 == MEM)
          {
-           find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1,
+           find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1,
                                    &XEXP (x, 0), opnum, type, ind_levels,
                                    insn);
                                    &XEXP (x, 0), opnum, type, ind_levels,
                                    insn);
-           find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
+           find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
                                    &XEXP (x, 1), opnum, type, ind_levels,
                                    insn);
          }
 
        else if (code0 == CONST_INT || code0 == CONST
                 || code0 == SYMBOL_REF || code0 == LABEL_REF)
                                    &XEXP (x, 1), opnum, type, ind_levels,
                                    insn);
          }
 
        else if (code0 == CONST_INT || code0 == CONST
                 || code0 == SYMBOL_REF || code0 == LABEL_REF)
-         find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0,
+         find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0,
                                  &XEXP (x, 1), opnum, type, ind_levels,
                                  insn);
 
        else if (code1 == CONST_INT || code1 == CONST
                 || code1 == SYMBOL_REF || code1 == LABEL_REF)
                                  &XEXP (x, 1), opnum, type, ind_levels,
                                  insn);
 
        else if (code1 == CONST_INT || code1 == CONST
                 || code1 == SYMBOL_REF || code1 == LABEL_REF)
-         find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1,
+         find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1,
                                  &XEXP (x, 0), opnum, type, ind_levels,
                                  insn);
 
        else if (code0 == REG && code1 == REG)
          {
            if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
                                  &XEXP (x, 0), opnum, type, ind_levels,
                                  insn);
 
        else if (code0 == REG && code1 == REG)
          {
            if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
-               && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
+               && regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG))
              return 0;
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
              return 0;
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
-                    && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
+                    && regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG))
              return 0;
              return 0;
-           else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
-             find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
+           else if (regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG))
+             find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
                                      &XEXP (x, 1), opnum, type, ind_levels,
                                      insn);
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)))
                                      &XEXP (x, 1), opnum, type, ind_levels,
                                      insn);
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)))
-             find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
+             find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
                                      &XEXP (x, 0), opnum, type, ind_levels,
                                      insn);
                                      &XEXP (x, 0), opnum, type, ind_levels,
                                      insn);
-           else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
-             find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
+           else if (regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG))
+             find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
                                      &XEXP (x, 0), opnum, type, ind_levels,
                                      insn);
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
                                      &XEXP (x, 0), opnum, type, ind_levels,
                                      insn);
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
-             find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
+             find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG,
                                      &XEXP (x, 1), opnum, type, ind_levels,
                                      insn);
            else
              {
                                      &XEXP (x, 1), opnum, type, ind_levels,
                                      insn);
            else
              {
-               find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
+               find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
                                        &XEXP (x, 0), opnum, type, ind_levels,
                                        insn);
                                        &XEXP (x, 0), opnum, type, ind_levels,
                                        insn);
-               find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
+               find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
                                        &XEXP (x, 1), opnum, type, ind_levels,
                                        insn);
              }
                                        &XEXP (x, 1), opnum, type, ind_levels,
                                        insn);
              }
@@ -5619,20 +5635,20 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
 
        else if (code0 == REG)
          {
 
        else if (code0 == REG)
          {
-           find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
+           find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
                                    &XEXP (x, 0), opnum, type, ind_levels,
                                    insn);
                                    &XEXP (x, 0), opnum, type, ind_levels,
                                    insn);
-           find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
+           find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG,
                                    &XEXP (x, 1), opnum, type, ind_levels,
                                    insn);
          }
 
        else if (code1 == REG)
          {
                                    &XEXP (x, 1), opnum, type, ind_levels,
                                    insn);
          }
 
        else if (code1 == REG)
          {
-           find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
+           find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
                                    &XEXP (x, 1), opnum, type, ind_levels,
                                    insn);
                                    &XEXP (x, 1), opnum, type, ind_levels,
                                    insn);
-           find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
+           find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
                                    &XEXP (x, 0), opnum, type, ind_levels,
                                    insn);
          }
                                    &XEXP (x, 0), opnum, type, ind_levels,
                                    insn);
          }
@@ -5674,7 +5690,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        if ((REG_P (XEXP (op1, 1))
             && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
            || GET_CODE (XEXP (op1, 1)) == PLUS)
        if ((REG_P (XEXP (op1, 1))
             && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
            || GET_CODE (XEXP (op1, 1)) == PLUS)
-         find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH,
+         find_reloads_address_1 (mode, as, XEXP (op1, 1), 1, code, SCRATCH,
                                  &XEXP (op1, 1), opnum, RELOAD_OTHER,
                                  ind_levels, insn);
 
                                  &XEXP (op1, 1), opnum, RELOAD_OTHER,
                                  ind_levels, insn);
 
@@ -5685,18 +5701,18 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
 
        /* A register that is incremented cannot be constant!  */
        gcc_assert (regno < FIRST_PSEUDO_REGISTER
 
        /* A register that is incremented cannot be constant!  */
        gcc_assert (regno < FIRST_PSEUDO_REGISTER
-                   || reg_equiv_constant[regno] == 0);
+                   || reg_equiv_constant (regno) == 0);
 
        /* Handle a register that is equivalent to a memory location
            which cannot be addressed directly.  */
 
        /* Handle a register that is equivalent to a memory location
            which cannot be addressed directly.  */
-       if (reg_equiv_memory_loc[regno] != 0
-           && (reg_equiv_address[regno] != 0
+       if (reg_equiv_memory_loc (regno) != 0
+           && (reg_equiv_address (regno) != 0
                || num_not_at_initial_offset))
          {
            rtx tem = make_memloc (XEXP (x, 0), regno);
 
                || num_not_at_initial_offset))
          {
            rtx tem = make_memloc (XEXP (x, 0), regno);
 
-           if (reg_equiv_address[regno]
-               || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+           if (reg_equiv_address (regno)
+               || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
              {
                rtx orig = tem;
 
              {
                rtx orig = tem;
 
@@ -5716,8 +5732,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
                   register.  */
                reloadnum = push_reload (tem, tem, &XEXP (x, 0),
                                         &XEXP (op1, 0),
                   register.  */
                reloadnum = push_reload (tem, tem, &XEXP (x, 0),
                                         &XEXP (op1, 0),
-                                        base_reg_class (mode, code,
-                                                        index_code),
+                                        base_reg_class (mode, as,
+                                                        code, index_code),
                                         GET_MODE (x), GET_MODE (x), 0,
                                         0, opnum, RELOAD_OTHER);
 
                                         GET_MODE (x), GET_MODE (x), 0,
                                         0, opnum, RELOAD_OTHER);
 
@@ -5730,11 +5746,12 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
          regno = reg_renumber[regno];
 
        /* We require a base register here...  */
          regno = reg_renumber[regno];
 
        /* We require a base register here...  */
-       if (!regno_ok_for_base_p (regno, GET_MODE (x), code, index_code))
+       if (!regno_ok_for_base_p (regno, GET_MODE (x), as, code, index_code))
          {
            reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
                                     &XEXP (op1, 0), &XEXP (x, 0),
          {
            reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
                                     &XEXP (op1, 0), &XEXP (x, 0),
-                                    base_reg_class (mode, code, index_code),
+                                    base_reg_class (mode, as,
+                                                    code, index_code),
                                     GET_MODE (x), GET_MODE (x), 0, 0,
                                     opnum, RELOAD_OTHER);
 
                                     GET_MODE (x), GET_MODE (x), 0, 0,
                                     opnum, RELOAD_OTHER);
 
@@ -5756,16 +5773,16 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
 
          /* A register that is incremented cannot be constant!  */
          gcc_assert (regno < FIRST_PSEUDO_REGISTER
 
          /* A register that is incremented cannot be constant!  */
          gcc_assert (regno < FIRST_PSEUDO_REGISTER
-                     || reg_equiv_constant[regno] == 0);
+                     || reg_equiv_constant (regno) == 0);
 
          /* Handle a register that is equivalent to a memory location
             which cannot be addressed directly.  */
 
          /* Handle a register that is equivalent to a memory location
             which cannot be addressed directly.  */
-         if (reg_equiv_memory_loc[regno] != 0
-             && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+         if (reg_equiv_memory_loc (regno) != 0
+             && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
            {
              rtx tem = make_memloc (XEXP (x, 0), regno);
            {
              rtx tem = make_memloc (XEXP (x, 0), regno);
-             if (reg_equiv_address[regno]
-                 || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+             if (reg_equiv_address (regno)
+                 || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
                {
                  rtx orig = tem;
 
                {
                  rtx orig = tem;
 
@@ -5800,7 +5817,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
          if (reg_renumber[regno] >= 0)
            regno = reg_renumber[regno];
          if (regno >= FIRST_PSEUDO_REGISTER
          if (reg_renumber[regno] >= 0)
            regno = reg_renumber[regno];
          if (regno >= FIRST_PSEUDO_REGISTER
-             || !REG_OK_FOR_CONTEXT (context, regno, mode, code,
+             || !REG_OK_FOR_CONTEXT (context, regno, mode, as, code,
                                      index_code))
            {
              int reloadnum;
                                      index_code))
            {
              int reloadnum;
@@ -5815,18 +5832,16 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
                 Also don't do this if we can probably update x directly.  */
              rtx equiv = (MEM_P (XEXP (x, 0))
                           ? XEXP (x, 0)
                 Also don't do this if we can probably update x directly.  */
              rtx equiv = (MEM_P (XEXP (x, 0))
                           ? XEXP (x, 0)
-                          : reg_equiv_mem[regno]);
-             int icode = (int) optab_handler (add_optab, GET_MODE (x));
+                          : reg_equiv_mem (regno));
+             enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
              if (insn && NONJUMP_INSN_P (insn) && equiv
                  && memory_operand (equiv, GET_MODE (equiv))
 #ifdef HAVE_cc0
                  && ! sets_cc0_p (PATTERN (insn))
 #endif
                  && ! (icode != CODE_FOR_nothing
              if (insn && NONJUMP_INSN_P (insn) && equiv
                  && memory_operand (equiv, GET_MODE (equiv))
 #ifdef HAVE_cc0
                  && ! sets_cc0_p (PATTERN (insn))
 #endif
                  && ! (icode != CODE_FOR_nothing
-                       && ((*insn_data[icode].operand[0].predicate)
-                           (equiv, GET_MODE (x)))
-                       && ((*insn_data[icode].operand[1].predicate)
-                           (equiv, GET_MODE (x)))))
+                       && insn_operand_matches (icode, 0, equiv)
+                       && insn_operand_matches (icode, 1, equiv)))
                {
                  /* We use the original pseudo for loc, so that
                     emit_reload_insns() knows which pseudo this
                {
                  /* We use the original pseudo for loc, so that
                     emit_reload_insns() knows which pseudo this
@@ -5871,7 +5886,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
         reloaded.  Targets that are better off reloading just either part
         (or perhaps even a different part of an outer expression), should
         define LEGITIMIZE_RELOAD_ADDRESS.  */
         reloaded.  Targets that are better off reloading just either part
         (or perhaps even a different part of an outer expression), should
         define LEGITIMIZE_RELOAD_ADDRESS.  */
-      find_reloads_address_1 (GET_MODE (XEXP (x, 0)), XEXP (x, 0),
+      find_reloads_address_1 (GET_MODE (XEXP (x, 0)), as, XEXP (x, 0),
                              context, code, SCRATCH, &XEXP (x, 0), opnum,
                              type, ind_levels, insn);
       push_reload (x, NULL_RTX, loc, (rtx*) 0,
                              context, code, SCRATCH, &XEXP (x, 0), opnum,
                              type, ind_levels, insn);
       push_reload (x, NULL_RTX, loc, (rtx*) 0,
@@ -5903,9 +5918,9 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
       {
        int regno = REGNO (x);
 
       {
        int regno = REGNO (x);
 
-       if (reg_equiv_constant[regno] != 0)
+       if (reg_equiv_constant (regno) != 0)
          {
          {
-           find_reloads_address_part (reg_equiv_constant[regno], loc,
+           find_reloads_address_part (reg_equiv_constant (regno), loc,
                                       context_reg_class,
                                       GET_MODE (x), opnum, type, ind_levels);
            return 1;
                                       context_reg_class,
                                       GET_MODE (x), opnum, type, ind_levels);
            return 1;
@@ -5913,21 +5928,21 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
 
 #if 0 /* This might screw code in reload1.c to delete prior output-reload
         that feeds this insn.  */
 
 #if 0 /* This might screw code in reload1.c to delete prior output-reload
         that feeds this insn.  */
-       if (reg_equiv_mem[regno] != 0)
+       if (reg_equiv_mem (regno) != 0)
          {
          {
-           push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0,
+           push_reload (reg_equiv_mem (regno), NULL_RTX, loc, (rtx*) 0,
                         context_reg_class,
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
 #endif
 
                         context_reg_class,
                         GET_MODE (x), VOIDmode, 0, 0, opnum, type);
            return 1;
          }
 #endif
 
-       if (reg_equiv_memory_loc[regno]
-           && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
+       if (reg_equiv_memory_loc (regno)
+           && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
          {
            rtx tem = make_memloc (x, regno);
          {
            rtx tem = make_memloc (x, regno);
-           if (reg_equiv_address[regno] != 0
-               || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+           if (reg_equiv_address (regno) != 0
+               || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
              {
                x = tem;
                find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
              {
                x = tem;
                find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
@@ -5942,7 +5957,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
          regno = reg_renumber[regno];
 
        if (regno >= FIRST_PSEUDO_REGISTER
          regno = reg_renumber[regno];
 
        if (regno >= FIRST_PSEUDO_REGISTER
-           || !REG_OK_FOR_CONTEXT (context, regno, mode, outer_code,
+           || !REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code,
                                    index_code))
          {
            push_reload (x, NULL_RTX, loc, (rtx*) 0,
                                    index_code))
          {
            push_reload (x, NULL_RTX, loc, (rtx*) 0,
@@ -5975,7 +5990,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
            {
              int regno ATTRIBUTE_UNUSED = subreg_regno (x);
 
            {
              int regno ATTRIBUTE_UNUSED = subreg_regno (x);
 
-             if (!REG_OK_FOR_CONTEXT (context, regno, mode, outer_code,
+             if (!REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code,
                                       index_code))
                {
                  push_reload (x, NULL_RTX, loc, (rtx*) 0,
                                       index_code))
                {
                  push_reload (x, NULL_RTX, loc, (rtx*) 0,
@@ -5989,12 +6004,12 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
          else
            {
              enum reg_class rclass = context_reg_class;
          else
            {
              enum reg_class rclass = context_reg_class;
-             if ((unsigned) CLASS_MAX_NREGS (rclass, GET_MODE (SUBREG_REG (x)))
-                 > reg_class_size[rclass])
+             if (ira_reg_class_max_nregs [rclass][GET_MODE (SUBREG_REG (x))]
+                 > reg_class_size[(int) rclass])
                {
                  x = find_reloads_subreg_address (x, 0, opnum,
                                                   ADDR_TYPE (type),
                {
                  x = find_reloads_subreg_address (x, 0, opnum,
                                                   ADDR_TYPE (type),
-                                                  ind_levels, insn);
+                                                  ind_levels, insn, NULL);
                  push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
                               GET_MODE (x), VOIDmode, 0, 0, opnum, type);
                  return 1;
                  push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
                               GET_MODE (x), VOIDmode, 0, 0, opnum, type);
                  return 1;
@@ -6016,8 +6031,9 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
        if (fmt[i] == 'e')
          /* Pass SCRATCH for INDEX_CODE, since CODE can never be a PLUS once
             we get here.  */
        if (fmt[i] == 'e')
          /* Pass SCRATCH for INDEX_CODE, since CODE can never be a PLUS once
             we get here.  */
-         find_reloads_address_1 (mode, XEXP (x, i), context, code, SCRATCH,
-                                 &XEXP (x, i), opnum, type, ind_levels, insn);
+         find_reloads_address_1 (mode, as, XEXP (x, i), context,
+                                 code, SCRATCH, &XEXP (x, i),
+                                 opnum, type, ind_levels, insn);
       }
   }
 
       }
   }
 
@@ -6046,7 +6062,7 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
                           enum reload_type type, int ind_levels)
 {
   if (CONSTANT_P (x)
                           enum reload_type type, int ind_levels)
 {
   if (CONSTANT_P (x)
-      && (! LEGITIMATE_CONSTANT_P (x)
+      && (!targetm.legitimate_constant_p (mode, x)
          || targetm.preferred_reload_class (x, rclass) == NO_REGS))
     {
       x = force_const_mem (mode, x);
          || targetm.preferred_reload_class (x, rclass) == NO_REGS))
     {
       x = force_const_mem (mode, x);
@@ -6056,7 +6072,7 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
 
   else if (GET_CODE (x) == PLUS
           && CONSTANT_P (XEXP (x, 1))
 
   else if (GET_CODE (x) == PLUS
           && CONSTANT_P (XEXP (x, 1))
-          && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
+          && (!targetm.legitimate_constant_p (GET_MODE (x), XEXP (x, 1))
               || targetm.preferred_reload_class (XEXP (x, 1), rclass)
                   == NO_REGS))
     {
               || targetm.preferred_reload_class (XEXP (x, 1), rclass)
                   == NO_REGS))
     {
@@ -6096,17 +6112,19 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
 
 static rtx
 find_reloads_subreg_address (rtx x, int force_replace, int opnum,
 
 static rtx
 find_reloads_subreg_address (rtx x, int force_replace, int opnum,
-                            enum reload_type type, int ind_levels, rtx insn)
+                            enum reload_type type, int ind_levels, rtx insn,
+                            int *address_reloaded)
 {
   int regno = REGNO (SUBREG_REG (x));
 {
   int regno = REGNO (SUBREG_REG (x));
+  int reloaded = 0;
 
 
-  if (reg_equiv_memory_loc[regno])
+  if (reg_equiv_memory_loc (regno))
     {
       /* If the address is not directly addressable, or if the address is not
         offsettable, then it must be replaced.  */
       if (! force_replace
     {
       /* If the address is not directly addressable, or if the address is not
         offsettable, then it must be replaced.  */
       if (! force_replace
-         && (reg_equiv_address[regno]
-             || ! offsettable_memref_p (reg_equiv_mem[regno])))
+         && (reg_equiv_address (regno)
+             || ! offsettable_memref_p (reg_equiv_mem (regno))))
        force_replace = 1;
 
       if (force_replace || num_not_at_initial_offset)
        force_replace = 1;
 
       if (force_replace || num_not_at_initial_offset)
@@ -6116,13 +6134,12 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
          /* If the address changes because of register elimination, then
             it must be replaced.  */
          if (force_replace
          /* If the address changes because of register elimination, then
             it must be replaced.  */
          if (force_replace
-             || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
+             || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
            {
              unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
              unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
              int offset;
              rtx orig = tem;
            {
              unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
              unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
              int offset;
              rtx orig = tem;
-             int reloaded;
 
              /* For big-endian paradoxical subregs, SUBREG_BYTE does not
                 hold the correct (negative) byte offset.  */
 
              /* For big-endian paradoxical subregs, SUBREG_BYTE does not
                 hold the correct (negative) byte offset.  */
@@ -6133,11 +6150,11 @@ 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));
 
              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 (MEM_SIZE (tem)
-                 && INTVAL (MEM_SIZE (tem)) != (HOST_WIDE_INT) outer_size)
-               set_mem_size (tem, GEN_INT (outer_size));
+             if (MEM_OFFSET_KNOWN_P (tem))
+               set_mem_offset (tem, MEM_OFFSET (tem) + offset);
+             if (MEM_SIZE_KNOWN_P (tem)
+                 && MEM_SIZE (tem) != (HOST_WIDE_INT) outer_size)
+               set_mem_size (tem, outer_size);
 
              /* If this was a paradoxical subreg that we replaced, the
                 resulting memory must be sufficiently aligned to allow
 
              /* If this was a paradoxical subreg that we replaced, the
                 resulting memory must be sufficiently aligned to allow
@@ -6187,15 +6204,19 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
                 If find_reloads_address already completed replaced
                 the address, there is nothing further to do.  */
              if (reloaded == 0
                 If find_reloads_address already completed replaced
                 the address, there is nothing further to do.  */
              if (reloaded == 0
-                 && reg_equiv_mem[regno] != 0
+                 && reg_equiv_mem (regno) != 0
                  && !strict_memory_address_addr_space_p
                  && !strict_memory_address_addr_space_p
-                       (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
-                        MEM_ADDR_SPACE (reg_equiv_mem[regno])))
-               push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
-                            base_reg_class (GET_MODE (tem), MEM, SCRATCH),
-                            GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,
-                            opnum, type);
-
+                       (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
+                        MEM_ADDR_SPACE (reg_equiv_mem (regno))))
+               {
+                 push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
+                              base_reg_class (GET_MODE (tem),
+                                              MEM_ADDR_SPACE (tem),
+                                              MEM, SCRATCH),
+                              GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,
+                              opnum, type);
+                 reloaded = 1;
+               }
              /* If this is not a toplevel operand, find_reloads doesn't see
                 this substitution.  We have to emit a USE of the pseudo so
                 that delete_output_reload can see it.  */
              /* If this is not a toplevel operand, find_reloads doesn't see
                 this substitution.  We have to emit a USE of the pseudo so
                 that delete_output_reload can see it.  */
@@ -6210,6 +6231,9 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
            }
        }
     }
            }
        }
     }
+  if (address_reloaded)
+    *address_reloaded = reloaded;
+
   return x;
 }
 \f
   return x;
 }
 \f
@@ -6248,14 +6272,14 @@ subst_reloads (rtx insn)
          for (check_regno = 0; check_regno < max_regno; check_regno++)
            {
 #define CHECK_MODF(ARRAY)                                              \
          for (check_regno = 0; check_regno < max_regno; check_regno++)
            {
 #define CHECK_MODF(ARRAY)                                              \
-             gcc_assert (!ARRAY[check_regno]                           \
+             gcc_assert (!VEC_index (reg_equivs_t, reg_equivs, check_regno).ARRAY              \
                          || !loc_mentioned_in_p (r->where,             \
                          || !loc_mentioned_in_p (r->where,             \
-                                                 ARRAY[check_regno]))
+                                                 VEC_index (reg_equivs_t, reg_equivs, check_regno).ARRAY))
 
 
-             CHECK_MODF (reg_equiv_constant);
-             CHECK_MODF (reg_equiv_memory_loc);
-             CHECK_MODF (reg_equiv_address);
-             CHECK_MODF (reg_equiv_mem);
+             CHECK_MODF (equiv_constant);
+             CHECK_MODF (equiv_memory_loc);
+             CHECK_MODF (equiv_address);
+             CHECK_MODF (equiv_mem);
 #undef CHECK_MODF
            }
 #endif /* DEBUG_RELOAD */
 #undef CHECK_MODF
            }
 #endif /* DEBUG_RELOAD */
@@ -6277,33 +6301,7 @@ subst_reloads (rtx insn)
          if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
            reloadreg = reload_adjust_reg_for_mode (reloadreg, r->mode);
 
          if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
            reloadreg = reload_adjust_reg_for_mode (reloadreg, r->mode);
 
-         /* If we are putting this into a SUBREG and RELOADREG is a
-            SUBREG, we would be making nested SUBREGs, so we have to fix
-            this up.  Note that r->where == &SUBREG_REG (*r->subreg_loc).  */
-
-         if (r->subreg_loc != 0 && GET_CODE (reloadreg) == SUBREG)
-           {
-             if (GET_MODE (*r->subreg_loc)
-                 == GET_MODE (SUBREG_REG (reloadreg)))
-               *r->subreg_loc = SUBREG_REG (reloadreg);
-             else
-               {
-                 int final_offset =
-                   SUBREG_BYTE (*r->subreg_loc) + SUBREG_BYTE (reloadreg);
-
-                 /* When working with SUBREGs the rule is that the byte
-                    offset must be a multiple of the SUBREG's mode.  */
-                 final_offset = (final_offset /
-                                 GET_MODE_SIZE (GET_MODE (*r->subreg_loc)));
-                 final_offset = (final_offset *
-                                 GET_MODE_SIZE (GET_MODE (*r->subreg_loc)));
-
-                 *r->where = SUBREG_REG (reloadreg);
-                 SUBREG_BYTE (*r->subreg_loc) = final_offset;
-               }
-           }
-         else
-           *r->where = reloadreg;
+         *r->where = reloadreg;
        }
       /* If reload got no reg and isn't optional, something's wrong.  */
       else
        }
       /* If reload got no reg and isn't optional, something's wrong.  */
       else
@@ -6317,10 +6315,6 @@ subst_reloads (rtx insn)
 void
 copy_replacements (rtx x, rtx y)
 {
 void
 copy_replacements (rtx x, rtx y)
 {
-  /* We can't support X being a SUBREG because we might then need to know its
-     location if something inside it was replaced.  */
-  gcc_assert (GET_CODE (x) != SUBREG);
-
   copy_replacements_1 (&x, &y, n_replacements);
 }
 
   copy_replacements_1 (&x, &y, n_replacements);
 }
 
@@ -6334,24 +6328,13 @@ copy_replacements_1 (rtx *px, rtx *py, int orig_replacements)
   const char *fmt;
 
   for (j = 0; j < orig_replacements; j++)
   const char *fmt;
 
   for (j = 0; j < orig_replacements; j++)
-    {
-      if (replacements[j].subreg_loc == px)
-       {
-         r = &replacements[n_replacements++];
-         r->where = replacements[j].where;
-         r->subreg_loc = py;
-         r->what = replacements[j].what;
-         r->mode = replacements[j].mode;
-       }
-      else if (replacements[j].where == px)
-       {
-         r = &replacements[n_replacements++];
-         r->where = py;
-         r->subreg_loc = 0;
-         r->what = replacements[j].what;
-         r->mode = replacements[j].mode;
-       }
-    }
+    if (replacements[j].where == px)
+      {
+       r = &replacements[n_replacements++];
+       r->where = py;
+       r->what = replacements[j].what;
+       r->mode = replacements[j].mode;
+      }
 
   x = *px;
   y = *py;
 
   x = *px;
   y = *py;
@@ -6377,13 +6360,8 @@ move_replacements (rtx *x, rtx *y)
   int i;
 
   for (i = 0; i < n_replacements; i++)
   int i;
 
   for (i = 0; i < n_replacements; i++)
-    if (replacements[i].subreg_loc == x)
-      replacements[i].subreg_loc = y;
-    else if (replacements[i].where == x)
-      {
-       replacements[i].where = y;
-       replacements[i].subreg_loc = 0;
-      }
+    if (replacements[i].where == x)
+      replacements[i].where = y;
 }
 \f
 /* If LOC was scheduled to be replaced by something, return the replacement.
 }
 \f
 /* If LOC was scheduled to be replaced by something, return the replacement.
@@ -6401,36 +6379,19 @@ find_replacement (rtx *loc)
       if (reloadreg && r->where == loc)
        {
          if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
       if (reloadreg && r->where == loc)
        {
          if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
-           reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
+           reloadreg = reload_adjust_reg_for_mode (reloadreg, r->mode);
 
          return reloadreg;
        }
 
          return reloadreg;
        }
-      else if (reloadreg && r->subreg_loc == loc)
+      else if (reloadreg && GET_CODE (*loc) == SUBREG
+              && r->where == &SUBREG_REG (*loc))
        {
        {
-         /* RELOADREG must be either a REG or a SUBREG.
-
-            ??? Is it actually still ever a SUBREG?  If so, why?  */
-
-         if (REG_P (reloadreg))
-           return gen_rtx_REG (GET_MODE (*loc),
-                               (REGNO (reloadreg) +
-                                subreg_regno_offset (REGNO (SUBREG_REG (*loc)),
-                                                     GET_MODE (SUBREG_REG (*loc)),
-                                                     SUBREG_BYTE (*loc),
-                                                     GET_MODE (*loc))));
-         else if (GET_MODE (reloadreg) == GET_MODE (*loc))
-           return reloadreg;
-         else
-           {
-             int final_offset = SUBREG_BYTE (reloadreg) + SUBREG_BYTE (*loc);
-
-             /* When working with SUBREGs the rule is that the byte
-                offset must be a multiple of the SUBREG's mode.  */
-             final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (*loc)));
-             final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (*loc)));
-             return gen_rtx_SUBREG (GET_MODE (*loc), SUBREG_REG (reloadreg),
-                                    final_offset);
-           }
+         if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
+           reloadreg = reload_adjust_reg_for_mode (reloadreg, r->mode);
+
+         return simplify_gen_subreg (GET_MODE (*loc), reloadreg,
+                                     GET_MODE (SUBREG_REG (*loc)),
+                                     SUBREG_BYTE (*loc));
        }
     }
 
        }
     }
 
@@ -6483,12 +6444,12 @@ refers_to_regno_for_reload_p (unsigned int regno, unsigned int endregno,
         X must therefore either be a constant or be in memory.  */
       if (r >= FIRST_PSEUDO_REGISTER)
        {
         X must therefore either be a constant or be in memory.  */
       if (r >= FIRST_PSEUDO_REGISTER)
        {
-         if (reg_equiv_memory_loc[r])
+         if (reg_equiv_memory_loc (r))
            return refers_to_regno_for_reload_p (regno, endregno,
            return refers_to_regno_for_reload_p (regno, endregno,
-                                                reg_equiv_memory_loc[r],
+                                                reg_equiv_memory_loc (r),
                                                 (rtx*) 0);
 
                                                 (rtx*) 0);
 
-         gcc_assert (reg_equiv_constant[r] || reg_equiv_invariant[r]);
+         gcc_assert (reg_equiv_constant (r) || reg_equiv_invariant (r));
          return 0;
        }
 
          return 0;
        }
 
@@ -6618,9 +6579,9 @@ reg_overlap_mentioned_for_reload_p (rtx x, rtx in)
 
       if (regno >= FIRST_PSEUDO_REGISTER)
        {
 
       if (regno >= FIRST_PSEUDO_REGISTER)
        {
-         if (reg_equiv_memory_loc[regno])
+         if (reg_equiv_memory_loc (regno))
            return refers_to_mem_for_reload_p (in);
            return refers_to_mem_for_reload_p (in);
-         gcc_assert (reg_equiv_constant[regno]);
+         gcc_assert (reg_equiv_constant (regno));
          return 0;
        }
 
          return 0;
        }
 
@@ -6671,7 +6632,7 @@ refers_to_mem_for_reload_p (rtx x)
 
   if (REG_P (x))
     return (REGNO (x) >= FIRST_PSEUDO_REGISTER
 
   if (REG_P (x))
     return (REGNO (x) >= FIRST_PSEUDO_REGISTER
-           && reg_equiv_memory_loc[REGNO (x)]);
+           && 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--)
 
   fmt = GET_RTX_FORMAT (GET_CODE (x));
   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
@@ -6781,6 +6742,15 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class rclass, int other,
          || num > PARAM_VALUE (PARAM_MAX_RELOAD_SEARCH_INSNS))
        return 0;
 
          || num > PARAM_VALUE (PARAM_MAX_RELOAD_SEARCH_INSNS))
        return 0;
 
+      /* Don't reuse register contents from before a setjmp-type
+        function call; on the second return (from the longjmp) it
+        might have been clobbered by a later reuse.  It doesn't
+        seem worthwhile to actually go and see if it is actually
+        reused even if that information would be readily available;
+        just don't reuse it across the setjmp call.  */
+      if (CALL_P (p) && find_reg_note (p, REG_SETJMP, NULL_RTX))
+       return 0;
+
       if (NONJUMP_INSN_P (p)
          /* If we don't want spill regs ...  */
          && (! (reload_reg_p != 0
       if (NONJUMP_INSN_P (p)
          /* If we don't want spill regs ...  */
          && (! (reload_reg_p != 0
@@ -7025,7 +6995,7 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class rclass, int other,
                       && ! push_operand (dest, GET_MODE (dest)))
                return 0;
              else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
                       && ! push_operand (dest, GET_MODE (dest)))
                return 0;
              else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
-                      && reg_equiv_memory_loc[regno] != 0)
+                      && reg_equiv_memory_loc (regno) != 0)
                return 0;
              else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
                return 0;
                return 0;
              else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
                return 0;
@@ -7070,7 +7040,7 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class rclass, int other,
                               && ! push_operand (dest, GET_MODE (dest)))
                        return 0;
                      else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
                               && ! push_operand (dest, GET_MODE (dest)))
                        return 0;
                      else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
-                              && reg_equiv_memory_loc[regno] != 0)
+                              && reg_equiv_memory_loc (regno) != 0)
                        return 0;
                      else if (need_stable_sp
                               && push_operand (dest, GET_MODE (dest)))
                        return 0;
                      else if (need_stable_sp
                               && push_operand (dest, GET_MODE (dest)))
@@ -7269,7 +7239,7 @@ regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
        {
          rtx elt = XVECEXP (PATTERN (insn), 0, i);
          if ((GET_CODE (elt) == CLOBBER
        {
          rtx elt = XVECEXP (PATTERN (insn), 0, i);
          if ((GET_CODE (elt) == CLOBBER
-              || (sets == 1 && GET_CODE (PATTERN (insn)) == SET))
+              || (sets == 1 && GET_CODE (elt) == SET))
              && REG_P (XEXP (elt, 0)))
            {
              unsigned int test = REGNO (XEXP (elt, 0));
              && REG_P (XEXP (elt, 0)))
            {
              unsigned int test = REGNO (XEXP (elt, 0));
@@ -7297,7 +7267,7 @@ reload_adjust_reg_for_mode (rtx reloadreg, enum machine_mode mode)
 
   regno = REGNO (reloadreg);
 
 
   regno = REGNO (reloadreg);
 
-  if (WORDS_BIG_ENDIAN)
+  if (REG_WORDS_BIG_ENDIAN)
     regno += (int) hard_regno_nregs[regno][GET_MODE (reloadreg)]
       - (int) hard_regno_nregs[regno][mode];
 
     regno += (int) hard_regno_nregs[regno][GET_MODE (reloadreg)]
       - (int) hard_regno_nregs[regno][mode];