/* Search an insn for pseudo regs that must be in hard regs and are not.
   Copyright (C) 1987-2019 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* This file contains subroutines used only from the file reload1.c.
   It knows how to scan one insn for operands and values
   that need to be copied into registers to make valid code.
   It also finds other operands and values which are valid
   but for which equivalent values in registers exist and
   ought to be used instead.

   Before processing the first insn of the function, call `init_reload'.
   init_reload actually has to be called earlier anyway.

   To scan an insn, call `find_reloads'.  This does two things:
   1. sets up tables describing which values must be reloaded
   for this insn, and what kind of hard regs they must be reloaded into;
   2. optionally record the locations where those values appear in
   the data, so they can be replaced properly later.
   This is done only if the second arg to `find_reloads' is nonzero.

   The third arg to `find_reloads' specifies the number of levels
   of indirect addressing supported by the machine.  If it is zero,
   indirect addressing is not valid.  If it is one, (MEM (REG n))
   is valid even if (REG n) did not get a hard register; if it is two,
   (MEM (MEM (REG n))) is also valid even if (REG n) did not get a
   hard register, and similarly for higher values.

   Then you must choose the hard regs to reload those pseudo regs into,
   and generate appropriate load insns before this insn and perhaps
   also store insns after this insn.  Set up the array `reload_reg_rtx'
   to contain the REG rtx's for the registers you used.  In some
   cases `find_reloads' will return a nonzero value in `reload_reg_rtx'
   for certain reloads.  Then that tells you which register to use,
   so you do not need to allocate one.  But you still do need to add extra
   instructions to copy the value into and out of that register.

   Finally you must call `subst_reloads' to substitute the reload reg rtx's
   into the locations already recorded.

NOTE SIDE EFFECTS:

   find_reloads can alter the operands of the instruction it is called on.

   1. Two operands of any sort may be interchanged, if they are in a
   commutative instruction.
   This happens only if find_reloads thinks the instruction will compile
   better that way.

   2. Pseudo-registers that are equivalent to constants are replaced
   with those constants if they are not in hard registers.

1 happens every time find_reloads is called.
2 happens only when REPLACE is 1, which is only when
actually doing the reloads, not when just counting them.

Using a reload register for several reloads in one insn:

When an insn has reloads, it is considered as having three parts:
the input reloads, the insn itself after reloading, and the output reloads.
Reloads of values used in memory addresses are often needed for only one part.

When this is so, reload_when_needed records which part needs the reload.
Two reloads for different parts of the insn can share the same reload
register.

When a reload is used for addresses in multiple parts, or when it is
an ordinary operand, it is classified as RELOAD_OTHER, and cannot share
a register with any other reload.  */

#define REG_OK_STRICT

/* We do not enable this with CHECKING_P, since it is awfully slow.  */
#undef DEBUG_RELOAD

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "optabs.h"
#include "regs.h"
#include "ira.h"
#include "recog.h"
#include "rtl-error.h"
#include "reload.h"
#include "addresses.h"
#include "params.h"

/* 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			\
   && !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.  */

static inline bool
small_register_class_p (reg_class_t rclass)
{
  return (reg_class_size [(int) rclass] == 1
	  || (reg_class_size [(int) rclass] >= 1 
	      && targetm.class_likely_spilled_p (rclass)));
}


/* All reloads of the current insn are recorded here.  See reload.h for
   comments.  */
int n_reloads;
struct reload rld[MAX_RELOADS];

/* All the "earlyclobber" operands of the current insn
   are recorded here.  */
int n_earlyclobbers;
rtx reload_earlyclobbers[MAX_RECOG_OPERANDS];

int reload_n_operands;

/* Replacing reloads.

   If `replace_reloads' is nonzero, then as each reload is recorded
   an entry is made for it in the table `replacements'.
   Then later `subst_reloads' can look through that table and
   perform all the replacements needed.  */

/* Nonzero means record the places to replace.  */
static int replace_reloads;

/* Each replacement is recorded with a structure like this.  */
struct replacement
{
  rtx *where;			/* Location to store in */
  int what;			/* which reload this is for */
  machine_mode mode;	/* mode it must have */
};

static struct replacement replacements[MAX_RECOG_OPERANDS * ((MAX_REGS_PER_ADDRESS * 2) + 1)];

/* Number of replacements currently recorded.  */
static int n_replacements;

/* Used to track what is modified by an operand.  */
struct decomposition
{
  int reg_flag;		/* Nonzero if referencing a register.  */
  int safe;		/* Nonzero if this can't conflict with anything.  */
  rtx base;		/* Base address for MEM.  */
  poly_int64_pod start;	/* Starting offset or register number.  */
  poly_int64_pod end;	/* Ending offset or register number.  */
};

/* Save MEMs needed to copy from one class of registers to another.  One MEM
   is used per mode, but normally only one or two modes are ever used.

   We keep two versions, before and after register elimination.  The one
   after register elimination is record separately for each operand.  This
   is done in case the address is not valid to be sure that we separately
   reload each.  */

static rtx secondary_memlocs[NUM_MACHINE_MODES];
static rtx secondary_memlocs_elim[NUM_MACHINE_MODES][MAX_RECOG_OPERANDS];
static int secondary_memlocs_elim_used = 0;

/* The instruction we are doing reloads for;
   so we can test whether a register dies in it.  */
static rtx_insn *this_insn;

/* Nonzero if this instruction is a user-specified asm with operands.  */
static int this_insn_is_asm;

/* If hard_regs_live_known is nonzero,
   we can tell which hard regs are currently live,
   at least enough to succeed in choosing dummy reloads.  */
static int hard_regs_live_known;

/* Indexed by hard reg number,
   element is nonnegative if hard reg has been spilled.
   This vector is passed to `find_reloads' as an argument
   and is not changed here.  */
static short *static_reload_reg_p;

/* Set to 1 in subst_reg_equivs if it changes anything.  */
static int subst_reg_equivs_changed;

/* On return from push_reload, holds the reload-number for the OUT
   operand, which can be different for that from the input operand.  */
static int output_reloadnum;

  /* Compare two RTX's.  */
#define MATCHES(x, y) \
 (x == y || (x != 0 && (REG_P (x)				\
			? REG_P (y) && REGNO (x) == REGNO (y)	\
			: rtx_equal_p (x, y) && ! side_effects_p (x))))

  /* Indicates if two reloads purposes are for similar enough things that we
     can merge their reloads.  */
#define MERGABLE_RELOADS(when1, when2, op1, op2) \
  ((when1) == RELOAD_OTHER || (when2) == RELOAD_OTHER	\
   || ((when1) == (when2) && (op1) == (op2))		\
   || ((when1) == RELOAD_FOR_INPUT && (when2) == RELOAD_FOR_INPUT) \
   || ((when1) == RELOAD_FOR_OPERAND_ADDRESS		\
       && (when2) == RELOAD_FOR_OPERAND_ADDRESS)	\
   || ((when1) == RELOAD_FOR_OTHER_ADDRESS		\
       && (when2) == RELOAD_FOR_OTHER_ADDRESS))

  /* Nonzero if these two reload purposes produce RELOAD_OTHER when merged.  */
#define MERGE_TO_OTHER(when1, when2, op1, op2) \
  ((when1) != (when2)					\
   || ! ((op1) == (op2)					\
	 || (when1) == RELOAD_FOR_INPUT			\
	 || (when1) == RELOAD_FOR_OPERAND_ADDRESS	\
	 || (when1) == RELOAD_FOR_OTHER_ADDRESS))

  /* If we are going to reload an address, compute the reload type to
     use.  */
#define ADDR_TYPE(type)					\
  ((type) == RELOAD_FOR_INPUT_ADDRESS			\
   ? RELOAD_FOR_INPADDR_ADDRESS				\
   : ((type) == RELOAD_FOR_OUTPUT_ADDRESS		\
      ? RELOAD_FOR_OUTADDR_ADDRESS			\
      : (type)))

static int push_secondary_reload (int, rtx, int, int, enum reg_class,
				  machine_mode, enum reload_type,
				  enum insn_code *, secondary_reload_info *);
static enum reg_class find_valid_class (machine_mode, machine_mode,
					int, unsigned int);
static void push_replacement (rtx *, int, 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 *, machine_mode,
			      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 bool alternative_allows_const_pool_ref (rtx, const char *, int);
static rtx find_reloads_toplev (rtx, int, enum reload_type, int, int,
				rtx_insn *, int *);
static rtx make_memloc (rtx, int);
static int maybe_memory_address_addr_space_p (machine_mode, rtx,
					      addr_space_t, rtx *);
static int find_reloads_address (machine_mode, rtx *, rtx, rtx *,
				 int, enum reload_type, int, rtx_insn *);
static rtx subst_reg_equivs (rtx, rtx_insn *);
static rtx subst_indexed_address (rtx);
static void update_auto_inc_notes (rtx_insn *, int, int);
static int find_reloads_address_1 (machine_mode, addr_space_t, rtx, int,
				   enum rtx_code, enum rtx_code, rtx *,
				   int, enum reload_type,int, rtx_insn *);
static void find_reloads_address_part (rtx, rtx *, enum reg_class,
				       machine_mode, int,
				       enum reload_type, int);
static rtx find_reloads_subreg_address (rtx, int, enum reload_type,
					int, rtx_insn *, int *);
static void copy_replacements_1 (rtx *, rtx *, int);
static poly_int64 find_inc_amount (rtx, rtx);
static int refers_to_mem_for_reload_p (rtx);
static int refers_to_regno_for_reload_p (unsigned int, unsigned int,
					 rtx, rtx *);

/* Add NEW to reg_equiv_alt_mem_list[REGNO] if it's not present in the
   list yet.  */

static void
push_reg_equiv_alt_mem (int regno, rtx mem)
{
  rtx it;

  for (it = reg_equiv_alt_mem_list (regno); it; it = XEXP (it, 1))
    if (rtx_equal_p (XEXP (it, 0), mem))
      return;

  reg_equiv_alt_mem_list (regno)
    = alloc_EXPR_LIST (REG_EQUIV, mem,
		       reg_equiv_alt_mem_list (regno));
}

/* Determine if any secondary reloads are needed for loading (if IN_P is
   nonzero) or storing (if IN_P is zero) X to or from a reload register of
   register class RELOAD_CLASS in mode RELOAD_MODE.  If secondary reloads
   are needed, push them.

   Return the reload number of the secondary reload we made, or -1 if
   we didn't need one.  *PICODE is set to the insn_code to use if we do
   need a secondary reload.  */

static int
push_secondary_reload (int in_p, rtx x, int opnum, int optional,
		       enum reg_class reload_class,
		       machine_mode reload_mode, enum reload_type type,
		       enum insn_code *picode, secondary_reload_info *prev_sri)
{
  enum reg_class rclass = NO_REGS;
  enum reg_class scratch_class;
  machine_mode mode = reload_mode;
  enum insn_code icode = CODE_FOR_nothing;
  enum insn_code t_icode = CODE_FOR_nothing;
  enum reload_type secondary_type;
  int s_reload, t_reload = -1;
  const char *scratch_constraint;
  secondary_reload_info sri;

  if (type == RELOAD_FOR_INPUT_ADDRESS
      || type == RELOAD_FOR_OUTPUT_ADDRESS
      || type == RELOAD_FOR_INPADDR_ADDRESS
      || type == RELOAD_FOR_OUTADDR_ADDRESS)
    secondary_type = type;
  else
    secondary_type = in_p ? RELOAD_FOR_INPUT_ADDRESS : RELOAD_FOR_OUTPUT_ADDRESS;

  *picode = CODE_FOR_nothing;

  /* If X is a paradoxical SUBREG, use the inner value to determine both the
     mode and object being reloaded.  */
  if (paradoxical_subreg_p (x))
    {
      x = SUBREG_REG (x);
      reload_mode = GET_MODE (x);
    }

  /* If X is a pseudo-register that has an equivalent MEM (actually, if it
     is still a pseudo-register by now, it *must* have an equivalent MEM
     but we don't want to assume that), use that equivalent when seeing if
     a secondary reload is needed since whether or not a reload is needed
     might be sensitive to the form of the MEM.  */

  if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER
      && reg_equiv_mem (REGNO (x)))
    x = reg_equiv_mem (REGNO (x));

  sri.icode = CODE_FOR_nothing;
  sri.prev_sri = prev_sri;
  rclass = (enum reg_class) targetm.secondary_reload (in_p, x, reload_class,
						      reload_mode, &sri);
  icode = (enum insn_code) sri.icode;

  /* If we don't need any secondary registers, done.  */
  if (rclass == NO_REGS && icode == CODE_FOR_nothing)
    return -1;

  if (rclass != NO_REGS)
    t_reload = push_secondary_reload (in_p, x, opnum, optional, rclass,
				      reload_mode, type, &t_icode, &sri);

  /* If we will be using an insn, the secondary reload is for a
     scratch register.  */

  if (icode != CODE_FOR_nothing)
    {
      /* If IN_P is nonzero, the reload register will be the output in
	 operand 0.  If IN_P is zero, the reload register will be the input
	 in operand 1.  Outputs should have an initial "=", which we must
	 skip.  */

      /* ??? It would be useful to be able to handle only two, or more than
	 three, operands, but for now we can only handle the case of having
	 exactly three: output, input and one temp/scratch.  */
      gcc_assert (insn_data[(int) icode].n_operands == 3);

      /* ??? We currently have no way to represent a reload that needs
	 an icode to reload from an intermediate tertiary reload register.
	 We should probably have a new field in struct reload to tag a
	 chain of scratch operand reloads onto.   */
      gcc_assert (rclass == NO_REGS);

      scratch_constraint = insn_data[(int) icode].operand[2].constraint;
      gcc_assert (*scratch_constraint == '=');
      scratch_constraint++;
      if (*scratch_constraint == '&')
	scratch_constraint++;
      scratch_class = (reg_class_for_constraint
		       (lookup_constraint (scratch_constraint)));

      rclass = scratch_class;
      mode = insn_data[(int) icode].operand[2].mode;
    }

  /* This case isn't valid, so fail.  Reload is allowed to use the same
     register for RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_INPUT reloads, but
     in the case of a secondary register, we actually need two different
     registers for correct code.  We fail here to prevent the possibility of
     silently generating incorrect code later.

     The convention is that secondary input reloads are valid only if the
     secondary_class is different from class.  If you have such a case, you
     cannot use secondary reloads, you must work around the problem some
     other way.

     Allow this when a reload_in/out pattern is being used.  I.e. assume
     that the generated code handles this case.  */

  gcc_assert (!in_p || rclass != reload_class || icode != CODE_FOR_nothing
	      || t_icode != CODE_FOR_nothing);

  /* See if we can reuse an existing secondary reload.  */
  for (s_reload = 0; s_reload < n_reloads; s_reload++)
    if (rld[s_reload].secondary_p
	&& (reg_class_subset_p (rclass, rld[s_reload].rclass)
	    || reg_class_subset_p (rld[s_reload].rclass, rclass))
	&& ((in_p && rld[s_reload].inmode == mode)
	    || (! in_p && rld[s_reload].outmode == mode))
	&& ((in_p && rld[s_reload].secondary_in_reload == t_reload)
	    || (! in_p && rld[s_reload].secondary_out_reload == t_reload))
	&& ((in_p && rld[s_reload].secondary_in_icode == t_icode)
	    || (! in_p && rld[s_reload].secondary_out_icode == t_icode))
	&& (small_register_class_p (rclass)
	    || targetm.small_register_classes_for_mode_p (VOIDmode))
	&& MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
			     opnum, rld[s_reload].opnum))
      {
	if (in_p)
	  rld[s_reload].inmode = mode;
	if (! in_p)
	  rld[s_reload].outmode = mode;

	if (reg_class_subset_p (rclass, rld[s_reload].rclass))
	  rld[s_reload].rclass = rclass;

	rld[s_reload].opnum = MIN (rld[s_reload].opnum, opnum);
	rld[s_reload].optional &= optional;
	rld[s_reload].secondary_p = 1;
	if (MERGE_TO_OTHER (secondary_type, rld[s_reload].when_needed,
			    opnum, rld[s_reload].opnum))
	  rld[s_reload].when_needed = RELOAD_OTHER;

	break;
      }

  if (s_reload == n_reloads)
    {
      /* If we need a memory location to copy between the two reload regs,
	 set it up now.  Note that we do the input case before making
	 the reload and the output case after.  This is due to the
	 way reloads are output.  */

      if (in_p && icode == CODE_FOR_nothing
	  && targetm.secondary_memory_needed (mode, rclass, reload_class))
	{
	  get_secondary_mem (x, reload_mode, opnum, type);

	  /* We may have just added new reloads.  Make sure we add
	     the new reload at the end.  */
	  s_reload = n_reloads;
	}

      /* We need to make a new secondary reload for this register class.  */
      rld[s_reload].in = rld[s_reload].out = 0;
      rld[s_reload].rclass = rclass;

      rld[s_reload].inmode = in_p ? mode : VOIDmode;
      rld[s_reload].outmode = ! in_p ? mode : VOIDmode;
      rld[s_reload].reg_rtx = 0;
      rld[s_reload].optional = optional;
      rld[s_reload].inc = 0;
      /* Maybe we could combine these, but it seems too tricky.  */
      rld[s_reload].nocombine = 1;
      rld[s_reload].in_reg = 0;
      rld[s_reload].out_reg = 0;
      rld[s_reload].opnum = opnum;
      rld[s_reload].when_needed = secondary_type;
      rld[s_reload].secondary_in_reload = in_p ? t_reload : -1;
      rld[s_reload].secondary_out_reload = ! in_p ? t_reload : -1;
      rld[s_reload].secondary_in_icode = in_p ? t_icode : CODE_FOR_nothing;
      rld[s_reload].secondary_out_icode
	= ! in_p ? t_icode : CODE_FOR_nothing;
      rld[s_reload].secondary_p = 1;

      n_reloads++;

      if (! in_p && icode == CODE_FOR_nothing
	  && targetm.secondary_memory_needed (mode, reload_class, rclass))
	get_secondary_mem (x, mode, opnum, type);
    }

  *picode = icode;
  return s_reload;
}

/* If a secondary reload is needed, return its class.  If both an intermediate
   register and a scratch register is needed, we return the class of the
   intermediate register.  */
reg_class_t
secondary_reload_class (bool in_p, reg_class_t rclass, machine_mode mode,
			rtx x)
{
  enum insn_code icode;
  secondary_reload_info sri;

  sri.icode = CODE_FOR_nothing;
  sri.prev_sri = NULL;
  rclass
    = (enum reg_class) targetm.secondary_reload (in_p, x, rclass, mode, &sri);
  icode = (enum insn_code) sri.icode;

  /* If there are no secondary reloads at all, we return NO_REGS.
     If an intermediate register is needed, we return its class.  */
  if (icode == CODE_FOR_nothing || rclass != NO_REGS)
    return rclass;

  /* No intermediate register is needed, but we have a special reload
     pattern, which we assume for now needs a scratch register.  */
  return scratch_reload_class (icode);
}

/* ICODE is the insn_code of a reload pattern.  Check that it has exactly
   three operands, verify that operand 2 is an output operand, and return
   its register class.
   ??? We'd like to be able to handle any pattern with at least 2 operands,
   for zero or more scratch registers, but that needs more infrastructure.  */
enum reg_class
scratch_reload_class (enum insn_code icode)
{
  const char *scratch_constraint;
  enum reg_class rclass;

  gcc_assert (insn_data[(int) icode].n_operands == 3);
  scratch_constraint = insn_data[(int) icode].operand[2].constraint;
  gcc_assert (*scratch_constraint == '=');
  scratch_constraint++;
  if (*scratch_constraint == '&')
    scratch_constraint++;
  rclass = reg_class_for_constraint (lookup_constraint (scratch_constraint));
  gcc_assert (rclass != NO_REGS);
  return rclass;
}

/* Return a memory location that will be used to copy X in mode MODE.
   If we haven't already made a location for this mode in this insn,
   call find_reloads_address on the location being returned.  */

rtx
get_secondary_mem (rtx x ATTRIBUTE_UNUSED, machine_mode mode,
		   int opnum, enum reload_type type)
{
  rtx loc;
  int mem_valid;

  /* By default, if MODE is narrower than a word, widen it to a word.
     This is required because most machines that require these memory
     locations do not support short load and stores from all registers
     (e.g., FP registers).  */

  mode = targetm.secondary_memory_needed_mode (mode);

  /* If we already have made a MEM for this operand in MODE, return it.  */
  if (secondary_memlocs_elim[(int) mode][opnum] != 0)
    return secondary_memlocs_elim[(int) mode][opnum];

  /* If this is the first time we've tried to get a MEM for this mode,
     allocate a new one.  `something_changed' in reload will get set
     by noticing that the frame size has changed.  */

  if (secondary_memlocs[(int) mode] == 0)
    {
#ifdef SECONDARY_MEMORY_NEEDED_RTX
      secondary_memlocs[(int) mode] = SECONDARY_MEMORY_NEEDED_RTX (mode);
#else
      secondary_memlocs[(int) mode]
	= assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
#endif
    }

  /* Get a version of the address doing any eliminations needed.  If that
     didn't give us a new MEM, make a new one if it isn't valid.  */

  loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX);
  mem_valid = strict_memory_address_addr_space_p (mode, XEXP (loc, 0),
						  MEM_ADDR_SPACE (loc));

  if (! mem_valid && loc == secondary_memlocs[(int) mode])
    loc = copy_rtx (loc);

  /* The only time the call below will do anything is if the stack
     offset is too large.  In that case IND_LEVELS doesn't matter, so we
     can just pass a zero.  Adjust the type to be the address of the
     corresponding object.  If the address was valid, save the eliminated
     address.  If it wasn't valid, we need to make a reload each time, so
     don't save it.  */

  if (! mem_valid)
    {
      type =  (type == RELOAD_FOR_INPUT ? RELOAD_FOR_INPUT_ADDRESS
	       : type == RELOAD_FOR_OUTPUT ? RELOAD_FOR_OUTPUT_ADDRESS
	       : RELOAD_OTHER);

      find_reloads_address (mode, &loc, XEXP (loc, 0), &XEXP (loc, 0),
			    opnum, type, 0, 0);
    }

  secondary_memlocs_elim[(int) mode][opnum] = loc;
  if (secondary_memlocs_elim_used <= (int)mode)
    secondary_memlocs_elim_used = (int)mode + 1;
  return loc;
}

/* Clear any secondary memory locations we've made.  */

void
clear_secondary_mem (void)
{
  memset (secondary_memlocs, 0, sizeof secondary_memlocs);
}


/* Find the largest class which has at least one register valid in
   mode INNER, and which for every such register, that register number
   plus N is also valid in OUTER (if in range) and is cheap to move
   into REGNO.  Such a class must exist.  */

static enum reg_class
find_valid_class (machine_mode outer ATTRIBUTE_UNUSED,
		  machine_mode inner ATTRIBUTE_UNUSED, int n,
		  unsigned int dest_regno ATTRIBUTE_UNUSED)
{
  int best_cost = -1;
  int rclass;
  int regno;
  enum reg_class best_class = NO_REGS;
  enum reg_class dest_class ATTRIBUTE_UNUSED = REGNO_REG_CLASS (dest_regno);
  unsigned int best_size = 0;
  int cost;

  for (rclass = 1; rclass < N_REG_CLASSES; rclass++)
    {
      int bad = 0;
      int good = 0;
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER - n && ! bad; regno++)
	if (TEST_HARD_REG_BIT (reg_class_contents[rclass], regno))
	  {
	    if (targetm.hard_regno_mode_ok (regno, inner))
	      {
		good = 1;
		if (TEST_HARD_REG_BIT (reg_class_contents[rclass], regno + n)
		    && !targetm.hard_regno_mode_ok (regno + n, outer))
		  bad = 1;
	      }
	  }

      if (bad || !good)
	continue;
      cost = register_move_cost (outer, (enum reg_class) rclass, dest_class);

      if ((reg_class_size[rclass] > best_size
	   && (best_cost < 0 || best_cost >= cost))
	  || best_cost > cost)
	{
	  best_class = (enum reg_class) rclass;
	  best_size = reg_class_size[rclass];
	  best_cost = register_move_cost (outer, (enum reg_class) rclass,
					  dest_class);
	}
    }

  gcc_assert (best_size != 0);

  return best_class;
}

/* We are trying to reload a subreg of something that is not a register.
   Find the largest class which contains only registers valid in
   mode MODE.  OUTER is the mode of the subreg, DEST_CLASS the class in
   which we would eventually like to obtain the object.  */

static enum reg_class
find_valid_class_1 (machine_mode outer ATTRIBUTE_UNUSED,
		    machine_mode mode ATTRIBUTE_UNUSED,
		    enum reg_class dest_class ATTRIBUTE_UNUSED)
{
  int best_cost = -1;
  int rclass;
  int regno;
  enum reg_class best_class = NO_REGS;
  unsigned int best_size = 0;
  int cost;

  for (rclass = 1; rclass < N_REG_CLASSES; rclass++)
    {
      unsigned int computed_rclass_size = 0;

      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
        {
          if (in_hard_reg_set_p (reg_class_contents[rclass], mode, regno)
	      && targetm.hard_regno_mode_ok (regno, mode))
            computed_rclass_size++;
        }

      cost = register_move_cost (outer, (enum reg_class) rclass, dest_class);

      if ((computed_rclass_size > best_size
	   && (best_cost < 0 || best_cost >= cost))
	  || best_cost > cost)
	{
	  best_class = (enum reg_class) rclass;
	  best_size = computed_rclass_size;
	  best_cost = register_move_cost (outer, (enum reg_class) rclass,
					  dest_class);
	}
    }

  gcc_assert (best_size != 0);

#ifdef LIMIT_RELOAD_CLASS
  best_class = LIMIT_RELOAD_CLASS (mode, best_class);
#endif
  return best_class;
}

/* Return the number of a previously made reload that can be combined with
   a new one, or n_reloads if none of the existing reloads can be used.
   OUT, RCLASS, TYPE and OPNUM are the same arguments as passed to
   push_reload, they determine the kind of the new reload that we try to
   combine.  P_IN points to the corresponding value of IN, which can be
   modified by this function.
   DONT_SHARE is nonzero if we can't share any input-only reload for IN.  */

static int
find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
		      enum reload_type type, int opnum, int dont_share)
{
  rtx in = *p_in;
  int i;
  /* We can't merge two reloads if the output of either one is
     earlyclobbered.  */

  if (earlyclobber_operand_p (out))
    return n_reloads;

  /* We can use an existing reload if the class is right
     and at least one of IN and OUT is a match
     and the other is at worst neutral.
     (A zero compared against anything is neutral.)

     For targets with small register classes, don't use existing reloads
     unless they are for the same thing since that can cause us to need
     more reload registers than we otherwise would.  */

  for (i = 0; i < n_reloads; i++)
    if ((reg_class_subset_p (rclass, rld[i].rclass)
	 || reg_class_subset_p (rld[i].rclass, rclass))
	/* If the existing reload has a register, it must fit our class.  */
	&& (rld[i].reg_rtx == 0
	    || TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
				  true_regnum (rld[i].reg_rtx)))
	&& ((in != 0 && MATCHES (rld[i].in, in) && ! dont_share
	     && (out == 0 || rld[i].out == 0 || MATCHES (rld[i].out, out)))
	    || (out != 0 && MATCHES (rld[i].out, out)
		&& (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
	&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
	&& (small_register_class_p (rclass)
	    || targetm.small_register_classes_for_mode_p (VOIDmode))
	&& MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
      return i;

  /* Reloading a plain reg for input can match a reload to postincrement
     that reg, since the postincrement's value is the right value.
     Likewise, it can match a preincrement reload, since we regard
     the preincrementation as happening before any ref in this insn
     to that register.  */
  for (i = 0; i < n_reloads; i++)
    if ((reg_class_subset_p (rclass, rld[i].rclass)
	 || reg_class_subset_p (rld[i].rclass, rclass))
	/* If the existing reload has a register, it must fit our
	   class.  */
	&& (rld[i].reg_rtx == 0
	    || TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
				  true_regnum (rld[i].reg_rtx)))
	&& out == 0 && rld[i].out == 0 && rld[i].in != 0
	&& ((REG_P (in)
	     && GET_RTX_CLASS (GET_CODE (rld[i].in)) == RTX_AUTOINC
	     && MATCHES (XEXP (rld[i].in, 0), in))
	    || (REG_P (rld[i].in)
		&& GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC
		&& MATCHES (XEXP (in, 0), rld[i].in)))
	&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
	&& (small_register_class_p (rclass)
	    || targetm.small_register_classes_for_mode_p (VOIDmode))
	&& MERGABLE_RELOADS (type, rld[i].when_needed,
			     opnum, rld[i].opnum))
      {
	/* Make sure reload_in ultimately has the increment,
	   not the plain register.  */
	if (REG_P (in))
	  *p_in = rld[i].in;
	return i;
      }
  return n_reloads;
}

/* Return true if:

   (a) (subreg:OUTER_MODE REG ...) represents a word or subword subreg
       of a multiword value; and

   (b) the number of *words* in REG does not match the number of *registers*
       in REG.  */

static bool
complex_word_subreg_p (machine_mode outer_mode, rtx reg)
{
  machine_mode inner_mode = GET_MODE (reg);
  poly_uint64 reg_words = REG_NREGS (reg) * UNITS_PER_WORD;
  return (known_le (GET_MODE_SIZE (outer_mode), UNITS_PER_WORD)
	  && maybe_gt (GET_MODE_SIZE (inner_mode), UNITS_PER_WORD)
	  && !known_equal_after_align_up (GET_MODE_SIZE (inner_mode),
					  reg_words, UNITS_PER_WORD));
}

/* 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 bool
reload_inner_reg_of_subreg (rtx x, machine_mode mode, bool output)
{
  rtx inner;

  /* Only SUBREGs are problematical.  */
  if (GET_CODE (x) != SUBREG)
    return false;

  inner = SUBREG_REG (x);

  /* If INNER is a constant or PLUS, then INNER will need reloading.  */
  if (CONSTANT_P (inner) || GET_CODE (inner) == PLUS)
    return true;

  /* 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 (!targetm.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 && complex_word_subreg_p (mode, inner);
}

/* Return nonzero if IN can be reloaded into REGNO with mode MODE without
   requiring an extra reload register.  The caller has already found that
   IN contains some reference to REGNO, so check that we can produce the
   new value in a single step.  E.g. if we have
   (set (reg r13) (plus (reg r13) (const int 1))), and there is an
   instruction that adds one to a register, this should succeed.
   However, if we have something like
   (set (reg r13) (plus (reg r13) (const int 999))), and the constant 999
   needs to be loaded into a register first, we need a separate reload
   register.
   Such PLUS reloads are generated by find_reload_address_part.
   The out-of-range PLUS expressions are usually introduced in the instruction
   patterns by register elimination and substituting pseudos without a home
   by their function-invariant equivalences.  */
static int
can_reload_into (rtx in, int regno, machine_mode mode)
{
  rtx dst;
  rtx_insn *test_insn;
  int r = 0;
  struct recog_data_d save_recog_data;

  /* For matching constraints, we often get notional input reloads where
     we want to use the original register as the reload register.  I.e.
     technically this is a non-optional input-output reload, but IN is
     already a valid register, and has been chosen as the reload register.
     Speed this up, since it trivially works.  */
  if (REG_P (in))
    return 1;

  /* To test MEMs properly, we'd have to take into account all the reloads
     that are already scheduled, which can become quite complicated.
     And since we've already handled address reloads for this MEM, it
     should always succeed anyway.  */
  if (MEM_P (in))
    return 1;

  /* If we can make a simple SET insn that does the job, everything should
     be fine.  */
  dst =  gen_rtx_REG (mode, regno);
  test_insn = make_insn_raw (gen_rtx_SET (dst, in));
  save_recog_data = recog_data;
  if (recog_memoized (test_insn) >= 0)
    {
      extract_insn (test_insn);
      r = constrain_operands (1, get_enabled_alternatives (test_insn));
    }
  recog_data = save_recog_data;
  return r;
}

/* Record one reload that needs to be performed.
   IN is an rtx saying where the data are to be found before this instruction.
   OUT says where they must be stored after the instruction.
   (IN is zero for data not read, and OUT is zero for data not written.)
   INLOC and OUTLOC point to the places in the instructions where
   IN and OUT were found.
   If IN and OUT are both nonzero, it means the same register must be used
   to reload both IN and OUT.

   RCLASS is a register class required for the reloaded data.
   INMODE is the machine mode that the instruction requires
   for the reg that replaces IN and OUTMODE is likewise for OUT.

   If IN is zero, then OUT's location and mode should be passed as
   INLOC and INMODE.

   STRICT_LOW is the 1 if there is a containing STRICT_LOW_PART rtx.

   OPTIONAL nonzero means this reload does not need to be performed:
   it can be discarded if that is more convenient.

   OPNUM and TYPE say what the purpose of this reload is.

   The return value is the reload-number for this reload.

   If both IN and OUT are nonzero, in some rare cases we might
   want to make two separate reloads.  (Actually we never do this now.)
   Therefore, the reload-number for OUT is stored in
   output_reloadnum when we return; the return value applies to IN.
   Usually (presently always), when IN and OUT are nonzero,
   the two reload-numbers are equal, but the caller should be careful to
   distinguish them.  */

int
push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
	     enum reg_class rclass, machine_mode inmode,
	     machine_mode outmode, int strict_low, int optional,
	     int opnum, enum reload_type type)
{
  int i;
  int dont_share = 0;
  int dont_remove_subreg = 0;
#ifdef LIMIT_RELOAD_CLASS
  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;
  enum reg_class subreg_in_class ATTRIBUTE_UNUSED;
  subreg_in_class = NO_REGS;

  /* INMODE and/or OUTMODE could be VOIDmode if no mode
     has been specified for the operand.  In that case,
     use the operand's mode as the mode to reload.  */
  if (inmode == VOIDmode && in != 0)
    inmode = GET_MODE (in);
  if (outmode == VOIDmode && out != 0)
    outmode = GET_MODE (out);

  /* If find_reloads and friends until now missed to replace a pseudo
     with a constant of reg_equiv_constant something went wrong
     beforehand.
     Note that it can't simply be done here if we missed it earlier
     since the constant might need to be pushed into the literal pool
     and the resulting memref would probably need further
     reloading.  */
  if (in != 0 && REG_P (in))
    {
      int regno = REGNO (in);

      gcc_assert (regno < FIRST_PSEUDO_REGISTER
		  || reg_renumber[regno] >= 0
		  || reg_equiv_constant (regno) == NULL_RTX);
    }

  /* reg_equiv_constant only contains constants which are obviously
     not appropriate as destination.  So if we would need to replace
     the destination pseudo with a constant we are in real
     trouble.  */
  if (out != 0 && REG_P (out))
    {
      int regno = REGNO (out);

      gcc_assert (regno < FIRST_PSEUDO_REGISTER
		  || reg_renumber[regno] >= 0
		  || reg_equiv_constant (regno) == NULL_RTX);
    }

  /* If we have a read-write operand with an address side-effect,
     change either IN or OUT so the side-effect happens only once.  */
  if (in != 0 && out != 0 && MEM_P (in) && rtx_equal_p (in, out))
    switch (GET_CODE (XEXP (in, 0)))
      {
      case POST_INC: case POST_DEC:   case POST_MODIFY:
	in = replace_equiv_address_nv (in, XEXP (XEXP (in, 0), 0));
	break;

      case PRE_INC: case PRE_DEC: case PRE_MODIFY:
	out = replace_equiv_address_nv (out, XEXP (XEXP (out, 0), 0));
	break;

      default:
	break;
      }

  /* If we are reloading a (SUBREG constant ...), really reload just the
     inside expression in its own mode.  Similarly for (SUBREG (PLUS ...)).
     If we have (SUBREG:M1 (MEM:M2 ...) ...) (or an inner REG that is still
     a pseudo and hence will become a MEM) with M1 wider than M2 and the
     register is a pseudo, also reload the inside expression.
     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 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.)

     Note that the case of (SUBREG (CONST_INT...)...) is handled elsewhere;
     we can't handle it here because CONST_INT does not indicate a mode.

     Similarly, we must reload the inside expression if we have a
     STRICT_LOW_PART (presumably, in == out in this case).

     Also reload the inner expression if it does not require a secondary
     reload but the SUBREG does.

     Finally, reload the inner expression if it is a register that is in
     the class whose registers cannot be referenced in a different size
     and M1 is not the same size as M2.  If subreg_lowpart_p is false, we
     cannot reload just the inside since we might end up with the wrong
     register class.  But if it is inside a STRICT_LOW_PART, we have
     no choice, so we hope we do get the right register class there.  */

  scalar_int_mode inner_mode;
  if (in != 0 && GET_CODE (in) == SUBREG
      && (subreg_lowpart_p (in) || strict_low)
      && targetm.can_change_mode_class (GET_MODE (SUBREG_REG (in)),
					inmode, rclass)
      && contains_allocatable_reg_of_mode[rclass][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)))
	      && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
		  || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD)
		      && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (in)),
						 &inner_mode)
		      && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD
		      && paradoxical_subreg_p (inmode, inner_mode)
		      && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)
		  || (WORD_REGISTER_OPERATIONS
		      && partial_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
		      && (known_equal_after_align_down
			  (GET_MODE_SIZE (inmode) - 1,
			   GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1,
			   UNITS_PER_WORD)))))
	  || (REG_P (SUBREG_REG (in))
	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
	      /* The case where out is nonzero
		 is handled differently in the following statement.  */
	      && (out == 0 || subreg_lowpart_p (in))
	      && (complex_word_subreg_p (inmode, SUBREG_REG (in))
		  || !targetm.hard_regno_mode_ok (subreg_regno (in), inmode)))
	  || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
	      && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)),
					  SUBREG_REG (in))
		  == NO_REGS))
	  || (REG_P (SUBREG_REG (in))
	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
	      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (in)),
					 GET_MODE (SUBREG_REG (in)), inmode))))
    {
#ifdef LIMIT_RELOAD_CLASS
      in_subreg_loc = inloc;
#endif
      inloc = &SUBREG_REG (in);
      in = *inloc;

      if (!WORD_REGISTER_OPERATIONS
	  && LOAD_EXTEND_OP (GET_MODE (in)) == UNKNOWN
	  && MEM_P (in))
	/* This is supposed to happen only for paradoxical subregs made by
	   combine.c.  (SUBREG (MEM)) isn't supposed to occur other ways.  */
	gcc_assert (known_le (GET_MODE_SIZE (GET_MODE (in)),
			      GET_MODE_SIZE (inmode)));

      inmode = GET_MODE (in);
    }

  /* 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.  */

  if (in != 0 && reload_inner_reg_of_subreg (in, inmode, false))
    {
      if (REG_P (SUBREG_REG (in)))
	subreg_in_class
	  = find_valid_class (inmode, GET_MODE (SUBREG_REG (in)),
			      subreg_regno_offset (REGNO (SUBREG_REG (in)),
						   GET_MODE (SUBREG_REG (in)),
						   SUBREG_BYTE (in),
						   GET_MODE (in)),
			      REGNO (SUBREG_REG (in)));
      else if (CONSTANT_P (SUBREG_REG (in))
               || GET_CODE (SUBREG_REG (in)) == PLUS)
	subreg_in_class = find_valid_class_1 (inmode,
					      GET_MODE (SUBREG_REG (in)),
					      rclass);

      /* This relies on the fact that emit_reload_insns outputs the
	 instructions for input reloads of type RELOAD_OTHER in the same
	 order as the reloads.  Thus if the outer reload is also of type
	 RELOAD_OTHER, we are guaranteed that this inner reload will be
	 output before the outer reload.  */
      push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), (rtx *) 0,
		   subreg_in_class, VOIDmode, VOIDmode, 0, 0, opnum, type);
      dont_remove_subreg = 1;
    }

  /* 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 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)
      && targetm.can_change_mode_class (GET_MODE (SUBREG_REG (out)),
					outmode, rclass)
      && contains_allocatable_reg_of_mode[rclass][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)))
	      && (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
		  || (WORD_REGISTER_OPERATIONS
		      && partial_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
		      && (known_equal_after_align_down
			  (GET_MODE_SIZE (outmode) - 1,
			   GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1,
			   UNITS_PER_WORD)))))
	  || (REG_P (SUBREG_REG (out))
	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
	      /* The case of a word mode subreg
		 is handled differently in the following statement.  */
	      && ! (known_le (GET_MODE_SIZE (outmode), UNITS_PER_WORD)
		    && maybe_gt (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))),
				 UNITS_PER_WORD))
	      && !targetm.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))
		  == NO_REGS))
	  || (REG_P (SUBREG_REG (out))
	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
	      && !REG_CAN_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
					 GET_MODE (SUBREG_REG (out)),
					 outmode))))
    {
#ifdef LIMIT_RELOAD_CLASS
      out_subreg_loc = outloc;
#endif
      outloc = &SUBREG_REG (out);
      out = *outloc;
      gcc_assert (WORD_REGISTER_OPERATIONS || !MEM_P (out)
		  || known_le (GET_MODE_SIZE (GET_MODE (out)),
			       GET_MODE_SIZE (outmode)));
      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 register to store an M2-sized quantity in R.

     However, we must reload the inner reg *as well as* the subreg in
     that case and the inner reg is an in-out reload.  */

  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.  */
      push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
		   &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 != 0 && out != 0 && MEM_P (out)
      && (REG_P (in) || MEM_P (in) || GET_CODE (in) == PLUS)
      && reg_overlap_mentioned_for_reload_p (in, XEXP (out, 0)))
    dont_share = 1;

  /* If IN is a SUBREG of a hard register, make a new REG.  This
     simplifies some of the cases below.  */

  if (in != 0 && GET_CODE (in) == SUBREG && REG_P (SUBREG_REG (in))
      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
      && ! dont_remove_subreg)
    in = gen_rtx_REG (GET_MODE (in), subreg_regno (in));

  /* Similarly for OUT.  */
  if (out != 0 && GET_CODE (out) == SUBREG
      && REG_P (SUBREG_REG (out))
      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
      && ! dont_remove_subreg)
    out = gen_rtx_REG (GET_MODE (out), subreg_regno (out));

  /* Narrow down the class of register wanted if that is
     desirable on this machine for efficiency.  */
  {
    reg_class_t preferred_class = rclass;

    if (in != 0)
      preferred_class = targetm.preferred_reload_class (in, rclass);

    /* Output reloads may need analogous treatment, different in detail.  */
    if (out != 0)
      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))
      rclass = (enum reg_class) preferred_class;
  }

  /* Make sure we use a class that can handle the actual pseudo
     inside any subreg.  For example, on the 386, QImode regs
     can appear within SImode subregs.  Although GENERAL_REGS
     can handle SImode, QImode needs a smaller class.  */
#ifdef LIMIT_RELOAD_CLASS
  if (in_subreg_loc)
    rclass = LIMIT_RELOAD_CLASS (inmode, rclass);
  else if (in != 0 && GET_CODE (in) == SUBREG)
    rclass = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), rclass);

  if (out_subreg_loc)
    rclass = LIMIT_RELOAD_CLASS (outmode, rclass);
  if (out != 0 && GET_CODE (out) == SUBREG)
    rclass = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), rclass);
#endif

  /* Verify that this class is at least possible for the mode that
     is specified.  */
  if (this_insn_is_asm)
    {
      machine_mode mode;
      if (paradoxical_subreg_p (inmode, outmode))
	mode = inmode;
      else
	mode = outmode;
      if (mode == VOIDmode)
	{
	  error_for_asm (this_insn, "cannot reload integer constant "
			 "operand in %<asm%>");
	  mode = word_mode;
	  if (in != 0)
	    inmode = word_mode;
	  if (out != 0)
	    outmode = word_mode;
	}
      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (targetm.hard_regno_mode_ok (i, mode)
	    && in_hard_reg_set_p (reg_class_contents[(int) rclass], mode, i))
	  break;
      if (i == FIRST_PSEUDO_REGISTER)
	{
	  error_for_asm (this_insn, "impossible register constraint "
			 "in %<asm%>");
	  /* Avoid further trouble with this insn.  */
	  PATTERN (this_insn) = gen_rtx_USE (VOIDmode, const0_rtx);
	  /* We used to continue here setting class to ALL_REGS, but it triggers
	     sanity check on i386 for:
	     void foo(long double d)
	     {
	       asm("" :: "a" (d));
	     }
	     Returning zero here ought to be safe as we take care in
	     find_reloads to not process the reloads when instruction was
	     replaced by USE.  */

	  return 0;
	}
    }

  /* Optional output reloads are always OK even if we have no register class,
     since the function of these reloads is only to have spill_reg_store etc.
     set, so that the storing insn can be deleted later.  */
  gcc_assert (rclass != NO_REGS
	      || (optional != 0 && type == RELOAD_FOR_OUTPUT));

  i = find_reusable_reload (&in, out, rclass, type, opnum, dont_share);

  if (i == n_reloads)
    {
      /* See if we need a secondary reload register to move between CLASS
	 and IN or CLASS and OUT.  Get the icode and push any required reloads
	 needed for each of them if so.  */

      if (in != 0)
	secondary_in_reload
	  = push_secondary_reload (1, in, opnum, optional, rclass, inmode, type,
				   &secondary_in_icode, NULL);
      if (out != 0 && GET_CODE (out) != SCRATCH)
	secondary_out_reload
	  = push_secondary_reload (0, out, opnum, optional, rclass, outmode,
				   type, &secondary_out_icode, NULL);

      /* We found no existing reload suitable for re-use.
	 So add an additional reload.  */

      if (subreg_in_class == NO_REGS
	  && in != 0
	  && (REG_P (in)
	      || (GET_CODE (in) == SUBREG && REG_P (SUBREG_REG (in))))
	  && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER)
	subreg_in_class = REGNO_REG_CLASS (reg_or_subregno (in));
      /* If a memory location is needed for the copy, make one.  */
      if (subreg_in_class != NO_REGS
	  && targetm.secondary_memory_needed (inmode, subreg_in_class, rclass))
	get_secondary_mem (in, inmode, opnum, type);

      i = n_reloads;
      rld[i].in = in;
      rld[i].out = out;
      rld[i].rclass = rclass;
      rld[i].inmode = inmode;
      rld[i].outmode = outmode;
      rld[i].reg_rtx = 0;
      rld[i].optional = optional;
      rld[i].inc = 0;
      rld[i].nocombine = 0;
      rld[i].in_reg = inloc ? *inloc : 0;
      rld[i].out_reg = outloc ? *outloc : 0;
      rld[i].opnum = opnum;
      rld[i].when_needed = type;
      rld[i].secondary_in_reload = secondary_in_reload;
      rld[i].secondary_out_reload = secondary_out_reload;
      rld[i].secondary_in_icode = secondary_in_icode;
      rld[i].secondary_out_icode = secondary_out_icode;
      rld[i].secondary_p = 0;

      n_reloads++;

      if (out != 0
          && (REG_P (out)
	      || (GET_CODE (out) == SUBREG && REG_P (SUBREG_REG (out))))
	  && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
	  && (targetm.secondary_memory_needed
	      (outmode, rclass, REGNO_REG_CLASS (reg_or_subregno (out)))))
	get_secondary_mem (out, outmode, opnum, type);
    }
  else
    {
      /* We are reusing an existing reload,
	 but we may have additional information for it.
	 For example, we may now have both IN and OUT
	 while the old one may have just one of them.  */

      /* The modes can be different.  If they are, we want to reload in
	 the larger mode, so that the value is valid for both modes.  */
      if (inmode != VOIDmode
	  && partial_subreg_p (rld[i].inmode, inmode))
	rld[i].inmode = inmode;
      if (outmode != VOIDmode
	  && partial_subreg_p (rld[i].outmode, outmode))
	rld[i].outmode = outmode;
      if (in != 0)
	{
	  rtx in_reg = inloc ? *inloc : 0;
	  /* If we merge reloads for two distinct rtl expressions that
	     are identical in content, there might be duplicate address
	     reloads.  Remove the extra set now, so that if we later find
	     that we can inherit this reload, we can get rid of the
	     address reloads altogether.

	     Do not do this if both reloads are optional since the result
	     would be an optional reload which could potentially leave
	     unresolved address replacements.

	     It is not sufficient to call transfer_replacements since
	     choose_reload_regs will remove the replacements for address
	     reloads of inherited reloads which results in the same
	     problem.  */
	  if (rld[i].in != in && rtx_equal_p (in, rld[i].in)
	      && ! (rld[i].optional && optional))
	    {
	      /* We must keep the address reload with the lower operand
		 number alive.  */
	      if (opnum > rld[i].opnum)
		{
		  remove_address_replacements (in);
		  in = rld[i].in;
		  in_reg = rld[i].in_reg;
		}
	      else
		remove_address_replacements (rld[i].in);
	    }
	  /* When emitting reloads we don't necessarily look at the in-
	     and outmode, but also directly at the operands (in and out).
	     So we can't simply overwrite them with whatever we have found
	     for this (to-be-merged) reload, we have to "merge" that too.
	     Reusing another reload already verified that we deal with the
	     same operands, just possibly in different modes.  So we
	     overwrite the operands only when the new mode is larger.
	     See also PR33613.  */
	  if (!rld[i].in
	      || partial_subreg_p (GET_MODE (rld[i].in), GET_MODE (in)))
	    rld[i].in = in;
	  if (!rld[i].in_reg
	      || (in_reg
		  && partial_subreg_p (GET_MODE (rld[i].in_reg),
				       GET_MODE (in_reg))))
	    rld[i].in_reg = in_reg;
	}
      if (out != 0)
	{
	  if (!rld[i].out
	      || (out
		  && partial_subreg_p (GET_MODE (rld[i].out),
				       GET_MODE (out))))
	    rld[i].out = out;
	  if (outloc
	      && (!rld[i].out_reg
		  || partial_subreg_p (GET_MODE (rld[i].out_reg),
				       GET_MODE (*outloc))))
	    rld[i].out_reg = *outloc;
	}
      if (reg_class_subset_p (rclass, rld[i].rclass))
	rld[i].rclass = rclass;
      rld[i].optional &= optional;
      if (MERGE_TO_OTHER (type, rld[i].when_needed,
			  opnum, rld[i].opnum))
	rld[i].when_needed = RELOAD_OTHER;
      rld[i].opnum = MIN (rld[i].opnum, opnum);
    }

  /* If the ostensible rtx being reloaded differs from the rtx found
     in the location to substitute, this reload is not safe to combine
     because we cannot reliably tell whether it appears in the insn.  */

  if (in != 0 && in != *inloc)
    rld[i].nocombine = 1;

#if 0
  /* This was replaced by changes in find_reloads_address_1 and the new
     function inc_for_reload, which go with a new meaning of reload_inc.  */

  /* If this is an IN/OUT reload in an insn that sets the CC,
     it must be for an autoincrement.  It doesn't work to store
     the incremented value after the insn because that would clobber the CC.
     So we must do the increment of the value reloaded from,
     increment it, store it back, then decrement again.  */
  if (out != 0 && sets_cc0_p (PATTERN (this_insn)))
    {
      out = 0;
      rld[i].out = 0;
      rld[i].inc = find_inc_amount (PATTERN (this_insn), in);
      /* If we did not find a nonzero amount-to-increment-by,
	 that contradicts the belief that IN is being incremented
	 in an address in this insn.  */
      gcc_assert (rld[i].inc != 0);
    }
#endif

  /* If we will replace IN and OUT with the reload-reg,
     record where they are located so that substitution need
     not do a tree walk.  */

  if (replace_reloads)
    {
      if (inloc != 0)
	{
	  struct replacement *r = &replacements[n_replacements++];
	  r->what = i;
	  r->where = inloc;
	  r->mode = inmode;
	}
      if (outloc != 0 && outloc != inloc)
	{
	  struct replacement *r = &replacements[n_replacements++];
	  r->what = i;
	  r->where = outloc;
	  r->mode = outmode;
	}
    }

  /* If this reload is just being introduced and it has both
     an incoming quantity and an outgoing quantity that are
     supposed to be made to match, see if either one of the two
     can serve as the place to reload into.

     If one of them is acceptable, set rld[i].reg_rtx
     to that one.  */

  if (in != 0 && out != 0 && in != out && rld[i].reg_rtx == 0)
    {
      rld[i].reg_rtx = find_dummy_reload (in, out, inloc, outloc,
					  inmode, outmode,
					  rld[i].rclass, i,
					  earlyclobber_operand_p (out));

      /* If the outgoing register already contains the same value
	 as the incoming one, we can dispense with loading it.
	 The easiest way to tell the caller that is to give a phony
	 value for the incoming operand (same as outgoing one).  */
      if (rld[i].reg_rtx == out
	  && (REG_P (in) || CONSTANT_P (in))
	  && find_equiv_reg (in, this_insn, NO_REGS, REGNO (out),
			     static_reload_reg_p, i, inmode) != 0)
	rld[i].in = out;
    }

  /* If this is an input reload and the operand contains a register that
     dies in this insn and is used nowhere else, see if it is the right class
     to be used for this reload.  Use it if so.  (This occurs most commonly
     in the case of paradoxical SUBREGs and in-out reloads).  We cannot do
     this if it is also an output reload that mentions the register unless
     the output is a SUBREG that clobbers an entire register.

     Note that the operand might be one of the spill regs, if it is a
     pseudo reg and we are in a block where spilling has not taken place.
     But if there is no spilling in this block, that is OK.
     An explicitly used hard reg cannot be a spill reg.  */

  if (rld[i].reg_rtx == 0 && in != 0 && hard_regs_live_known)
    {
      rtx note;
      int regno;
      machine_mode rel_mode = inmode;

      if (out && partial_subreg_p (rel_mode, outmode))
	rel_mode = outmode;

      for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
	if (REG_NOTE_KIND (note) == REG_DEAD
	    && REG_P (XEXP (note, 0))
	    && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
	    && reg_mentioned_p (XEXP (note, 0), in)
	    /* Check that a former pseudo is valid; see find_dummy_reload.  */
	    && (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
		|| (! bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
				    ORIGINAL_REGNO (XEXP (note, 0)))
		    && REG_NREGS (XEXP (note, 0)) == 1))
	    && ! refers_to_regno_for_reload_p (regno,
					       end_hard_regno (rel_mode,
							       regno),
					       PATTERN (this_insn), inloc)
	    && ! find_reg_fusage (this_insn, USE, XEXP (note, 0))
	    /* If this is also an output reload, IN cannot be used as
	       the reload register if it is set in this insn unless IN
	       is also OUT.  */
	    && (out == 0 || in == out
		|| ! hard_reg_set_here_p (regno,
					  end_hard_regno (rel_mode, regno),
					  PATTERN (this_insn)))
	    /* ??? Why is this code so different from the previous?
	       Is there any simple coherent way to describe the two together?
	       What's going on here.  */
	    && (in != out
		|| (GET_CODE (in) == SUBREG
		    && (known_equal_after_align_up
			(GET_MODE_SIZE (GET_MODE (in)),
			 GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))),
			 UNITS_PER_WORD))))
	    /* Make sure the operand fits in the reg that dies.  */
	    && known_le (GET_MODE_SIZE (rel_mode),
			 GET_MODE_SIZE (GET_MODE (XEXP (note, 0))))
	    && targetm.hard_regno_mode_ok (regno, inmode)
	    && targetm.hard_regno_mode_ok (regno, outmode))
	  {
	    unsigned int offs;
	    unsigned int nregs = MAX (hard_regno_nregs (regno, inmode),
				      hard_regno_nregs (regno, outmode));

	    for (offs = 0; offs < nregs; offs++)
	      if (fixed_regs[regno + offs]
		  || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
					  regno + offs))
		break;

	    if (offs == nregs
		&& (! (refers_to_regno_for_reload_p
		       (regno, end_hard_regno (inmode, regno), in, (rtx *) 0))
		    || can_reload_into (in, regno, inmode)))
	      {
		rld[i].reg_rtx = gen_rtx_REG (rel_mode, regno);
		break;
	      }
	  }
    }

  if (out)
    output_reloadnum = i;

  return i;
}

/* Record an additional place we must replace a value
   for which we have already recorded a reload.
   RELOADNUM is the value returned by push_reload
   when the reload was recorded.
   This is used in insn patterns that use match_dup.  */

static void
push_replacement (rtx *loc, int reloadnum, machine_mode mode)
{
  if (replace_reloads)
    {
      struct replacement *r = &replacements[n_replacements++];
      r->what = reloadnum;
      r->where = loc;
      r->mode = mode;
    }
}

/* Duplicate any replacement we have recorded to apply at
   location ORIG_LOC to also be performed at DUP_LOC.
   This is used in insn patterns that use match_dup.  */

static void
dup_replacements (rtx *dup_loc, rtx *orig_loc)
{
  int i, n = n_replacements;

  for (i = 0; i < n; i++)
    {
      struct replacement *r = &replacements[i];
      if (r->where == orig_loc)
	push_replacement (dup_loc, r->what, r->mode);
    }
}

/* Transfer all replacements that used to be in reload FROM to be in
   reload TO.  */

void
transfer_replacements (int to, int from)
{
  int i;

  for (i = 0; i < n_replacements; i++)
    if (replacements[i].what == from)
      replacements[i].what = to;
}

/* IN_RTX is the value loaded by a reload that we now decided to inherit,
   or a subpart of it.  If we have any replacements registered for IN_RTX,
   cancel the reloads that were supposed to load them.
   Return nonzero if we canceled any reloads.  */
int
remove_address_replacements (rtx in_rtx)
{
  int i, j;
  char reload_flags[MAX_RELOADS];
  int something_changed = 0;

  memset (reload_flags, 0, sizeof reload_flags);
  for (i = 0, j = 0; i < n_replacements; i++)
    {
      if (loc_mentioned_in_p (replacements[i].where, in_rtx))
	reload_flags[replacements[i].what] |= 1;
      else
	{
	  replacements[j++] = replacements[i];
	  reload_flags[replacements[i].what] |= 2;
	}
    }
  /* Note that the following store must be done before the recursive calls.  */
  n_replacements = j;

  for (i = n_reloads - 1; i >= 0; i--)
    {
      if (reload_flags[i] == 1)
	{
	  deallocate_reload_reg (i);
	  remove_address_replacements (rld[i].in);
	  rld[i].in = 0;
	  something_changed = 1;
	}
    }
  return something_changed;
}

/* If there is only one output reload, and it is not for an earlyclobber
   operand, try to combine it with a (logically unrelated) input reload
   to reduce the number of reload registers needed.

   This is safe if the input reload does not appear in
   the value being output-reloaded, because this implies
   it is not needed any more once the original insn completes.

   If that doesn't work, see we can use any of the registers that
   die in this insn as a reload register.  We can if it is of the right
   class and does not appear in the value being output-reloaded.  */

static void
combine_reloads (void)
{
  int i, regno;
  int output_reload = -1;
  int secondary_out = -1;
  rtx note;

  /* Find the output reload; return unless there is exactly one
     and that one is mandatory.  */

  for (i = 0; i < n_reloads; i++)
    if (rld[i].out != 0)
      {
	if (output_reload >= 0)
	  return;
	output_reload = i;
      }

  if (output_reload < 0 || rld[output_reload].optional)
    return;

  /* An input-output reload isn't combinable.  */

  if (rld[output_reload].in != 0)
    return;

  /* If this reload is for an earlyclobber operand, we can't do anything.  */
  if (earlyclobber_operand_p (rld[output_reload].out))
    return;

  /* If there is a reload for part of the address of this operand, we would
     need to change it to RELOAD_FOR_OTHER_ADDRESS.  But that would extend
     its life to the point where doing this combine would not lower the
     number of spill registers needed.  */
  for (i = 0; i < n_reloads; i++)
    if ((rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
	 || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
	&& rld[i].opnum == rld[output_reload].opnum)
      return;

  /* Check each input reload; can we combine it?  */

  for (i = 0; i < n_reloads; i++)
    if (rld[i].in && ! rld[i].optional && ! rld[i].nocombine
	/* Life span of this reload must not extend past main insn.  */
	&& rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS
	&& rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
	&& rld[i].when_needed != RELOAD_OTHER
	&& (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])
	&& known_eq (rld[i].inc, 0)
	&& rld[i].reg_rtx == 0
	/* Don't combine two reloads with different secondary
	   memory locations.  */
	&& (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum] == 0
	    || secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] == 0
	    || rtx_equal_p (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum],
			    secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
	&& (targetm.small_register_classes_for_mode_p (VOIDmode)
	    ? (rld[i].rclass == rld[output_reload].rclass)
	    : (reg_class_subset_p (rld[i].rclass,
				   rld[output_reload].rclass)
	       || reg_class_subset_p (rld[output_reload].rclass,
				      rld[i].rclass)))
	&& (MATCHES (rld[i].in, rld[output_reload].out)
	    /* Args reversed because the first arg seems to be
	       the one that we imagine being modified
	       while the second is the one that might be affected.  */
	    || (! reg_overlap_mentioned_for_reload_p (rld[output_reload].out,
						      rld[i].in)
		/* However, if the input is a register that appears inside
		   the output, then we also can't share.
		   Imagine (set (mem (reg 69)) (plus (reg 69) ...)).
		   If the same reload reg is used for both reg 69 and the
		   result to be stored in memory, then that result
		   will clobber the address of the memory ref.  */
		&& ! (REG_P (rld[i].in)
		      && reg_overlap_mentioned_for_reload_p (rld[i].in,
							     rld[output_reload].out))))
	&& ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode,
					 rld[i].when_needed != RELOAD_FOR_INPUT)
	&& (reg_class_size[(int) rld[i].rclass]
	    || targetm.small_register_classes_for_mode_p (VOIDmode))
	/* We will allow making things slightly worse by combining an
	   input and an output, but no worse than that.  */
	&& (rld[i].when_needed == RELOAD_FOR_INPUT
	    || rld[i].when_needed == RELOAD_FOR_OUTPUT))
      {
	int j;

	/* We have found a reload to combine with!  */
	rld[i].out = rld[output_reload].out;
	rld[i].out_reg = rld[output_reload].out_reg;
	rld[i].outmode = rld[output_reload].outmode;
	/* Mark the old output reload as inoperative.  */
	rld[output_reload].out = 0;
	/* The combined reload is needed for the entire insn.  */
	rld[i].when_needed = RELOAD_OTHER;
	/* If the output reload had a secondary reload, copy it.  */
	if (rld[output_reload].secondary_out_reload != -1)
	  {
	    rld[i].secondary_out_reload
	      = rld[output_reload].secondary_out_reload;
	    rld[i].secondary_out_icode
	      = rld[output_reload].secondary_out_icode;
	  }

	/* Copy any secondary MEM.  */
	if (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] != 0)
	  secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum]
	    = secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum];
	/* If required, minimize the register class.  */
	if (reg_class_subset_p (rld[output_reload].rclass,
				rld[i].rclass))
	  rld[i].rclass = rld[output_reload].rclass;

	/* Transfer all replacements from the old reload to the combined.  */
	for (j = 0; j < n_replacements; j++)
	  if (replacements[j].what == output_reload)
	    replacements[j].what = i;

	return;
      }

  /* If this insn has only one operand that is modified or written (assumed
     to be the first),  it must be the one corresponding to this reload.  It
     is safe to use anything that dies in this insn for that output provided
     that it does not occur in the output (we already know it isn't an
     earlyclobber.  If this is an asm insn, give up.  */

  if (INSN_CODE (this_insn) == -1)
    return;

  for (i = 1; i < insn_data[INSN_CODE (this_insn)].n_operands; i++)
    if (insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '='
	|| insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '+')
      return;

  /* See if some hard register that dies in this insn and is not used in
     the output is the right class.  Only works if the register we pick
     up can fully hold our output reload.  */
  for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
    if (REG_NOTE_KIND (note) == REG_DEAD
	&& REG_P (XEXP (note, 0))
	&& !reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
						rld[output_reload].out)
	&& (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
	&& targetm.hard_regno_mode_ok (regno, rld[output_reload].outmode)
	&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].rclass],
			      regno)
	&& (hard_regno_nregs (regno, rld[output_reload].outmode)
	    <= REG_NREGS (XEXP (note, 0)))
	/* Ensure that a secondary or tertiary reload for this output
	   won't want this register.  */
	&& ((secondary_out = rld[output_reload].secondary_out_reload) == -1
	    || (!(TEST_HARD_REG_BIT
		  (reg_class_contents[(int) rld[secondary_out].rclass], regno))
		&& ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
		    || !(TEST_HARD_REG_BIT
			 (reg_class_contents[(int) rld[secondary_out].rclass],
			  regno)))))
	&& !fixed_regs[regno]
	/* Check that a former pseudo is valid; see find_dummy_reload.  */
	&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
	    || (!bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
			       ORIGINAL_REGNO (XEXP (note, 0)))
		&& REG_NREGS (XEXP (note, 0)) == 1)))
      {
	rld[output_reload].reg_rtx
	  = gen_rtx_REG (rld[output_reload].outmode, regno);
	return;
      }
}

/* Try to find a reload register for an in-out reload (expressions IN and OUT).
   See if one of IN and OUT is a register that may be used;
   this is desirable since a spill-register won't be needed.
   If so, return the register rtx that proves acceptable.

   INLOC and OUTLOC are locations where IN and OUT appear in the insn.
   RCLASS is the register class required for the reload.

   If FOR_REAL is >= 0, it is the number of the reload,
   and in some cases when it can be discovered that OUT doesn't need
   to be computed, clear out rld[FOR_REAL].out.

   If FOR_REAL is -1, this should not be done, because this call
   is just to see if a register can be found, not to find and install it.

   EARLYCLOBBER is nonzero if OUT is an earlyclobber operand.  This
   puts an additional constraint on being able to use IN for OUT since
   IN must not appear elsewhere in the insn (it is assumed that IN itself
   is safe from the earlyclobber).  */

static rtx
find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
		   machine_mode inmode, machine_mode outmode,
		   reg_class_t rclass, int for_real, int earlyclobber)
{
  rtx in = real_in;
  rtx out = real_out;
  int in_offset = 0;
  int out_offset = 0;
  rtx value = 0;

  /* If operands exceed a word, we can't use either of them
     unless they have the same size.  */
  if (maybe_ne (GET_MODE_SIZE (outmode), GET_MODE_SIZE (inmode))
      && (maybe_gt (GET_MODE_SIZE (outmode), UNITS_PER_WORD)
	  || maybe_gt (GET_MODE_SIZE (inmode), UNITS_PER_WORD)))
    return 0;

  /* Note that {in,out}_offset are needed only when 'in' or 'out'
     respectively refers to a hard register.  */

  /* Find the inside of any subregs.  */
  while (GET_CODE (out) == SUBREG)
    {
      if (REG_P (SUBREG_REG (out))
	  && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER)
	out_offset += subreg_regno_offset (REGNO (SUBREG_REG (out)),
					   GET_MODE (SUBREG_REG (out)),
					   SUBREG_BYTE (out),
					   GET_MODE (out));
      out = SUBREG_REG (out);
    }
  while (GET_CODE (in) == SUBREG)
    {
      if (REG_P (SUBREG_REG (in))
	  && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER)
	in_offset += subreg_regno_offset (REGNO (SUBREG_REG (in)),
					  GET_MODE (SUBREG_REG (in)),
					  SUBREG_BYTE (in),
					  GET_MODE (in));
      in = SUBREG_REG (in);
    }

  /* Narrow down the reg class, the same way push_reload will;
     otherwise we might find a dummy now, but push_reload won't.  */
  {
    reg_class_t preferred_class = targetm.preferred_reload_class (in, rclass);
    if (preferred_class != NO_REGS)
      rclass = (enum reg_class) preferred_class;
  }

  /* See if OUT will do.  */
  if (REG_P (out)
      && REGNO (out) < FIRST_PSEUDO_REGISTER)
    {
      unsigned int regno = REGNO (out) + out_offset;
      unsigned int nwords = hard_regno_nregs (regno, outmode);
      rtx saved_rtx;

      /* When we consider whether the insn uses OUT,
	 ignore references within IN.  They don't prevent us
	 from copying IN into OUT, because those refs would
	 move into the insn that reloads IN.

	 However, we only ignore IN in its role as this reload.
	 If the insn uses IN elsewhere and it contains OUT,
	 that counts.  We can't be sure it's the "same" operand
	 so it might not go through this reload.  

         We also need to avoid using OUT if it, or part of it, is a
         fixed register.  Modifying such registers, even transiently,
         may have undefined effects on the machine, such as modifying
         the stack pointer.  */
      saved_rtx = *inloc;
      *inloc = const0_rtx;

      if (regno < FIRST_PSEUDO_REGISTER
	  && targetm.hard_regno_mode_ok (regno, outmode)
	  && ! refers_to_regno_for_reload_p (regno, regno + nwords,
					     PATTERN (this_insn), outloc))
	{
	  unsigned int i;

	  for (i = 0; i < nwords; i++)
	    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
				     regno + i)
		|| fixed_regs[regno + i])
	      break;

	  if (i == nwords)
	    {
	      if (REG_P (real_out))
		value = real_out;
	      else
		value = gen_rtx_REG (outmode, regno);
	    }
	}

      *inloc = saved_rtx;
    }

  /* Consider using IN if OUT was not acceptable
     or if OUT dies in this insn (like the quotient in a divmod insn).
     We can't use IN unless it is dies in this insn,
     which means we must know accurately which hard regs are live.
     Also, the result can't go in IN if IN is used within OUT,
     or if OUT is an earlyclobber and IN appears elsewhere in the insn.  */
  if (hard_regs_live_known
      && REG_P (in)
      && REGNO (in) < FIRST_PSEUDO_REGISTER
      && (value == 0
	  || find_reg_note (this_insn, REG_UNUSED, real_out))
      && find_reg_note (this_insn, REG_DEAD, real_in)
      && !fixed_regs[REGNO (in)]
      && targetm.hard_regno_mode_ok (REGNO (in),
				     /* The only case where out and real_out
					might have different modes is where
					real_out is a subreg, and in that
					case, out has a real mode.  */
				     (GET_MODE (out) != VOIDmode
				      ? GET_MODE (out) : outmode))
      && (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
	  /* However only do this if we can be sure that this input
	     operand doesn't correspond with an uninitialized pseudo.
	     global can assign some hardreg to it that is the same as
	     the one assigned to a different, also live pseudo (as it
	     can ignore the conflict).  We must never introduce writes
	     to such hardregs, as they would clobber the other live
	     pseudo.  See PR 20973.  */
	  || (!bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
			     ORIGINAL_REGNO (in))
	      /* Similarly, only do this if we can be sure that the death
		 note is still valid.  global can assign some hardreg to
		 the pseudo referenced in the note and simultaneously a
		 subword of this hardreg to a different, also live pseudo,
		 because only another subword of the hardreg is actually
		 used in the insn.  This cannot happen if the pseudo has
		 been assigned exactly one hardreg.  See PR 33732.  */
	      && REG_NREGS (in) == 1)))
    {
      unsigned int regno = REGNO (in) + in_offset;
      unsigned int nwords = hard_regno_nregs (regno, inmode);

      if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, (rtx*) 0)
	  && ! hard_reg_set_here_p (regno, regno + nwords,
				    PATTERN (this_insn))
	  && (! earlyclobber
	      || ! refers_to_regno_for_reload_p (regno, regno + nwords,
						 PATTERN (this_insn), inloc)))
	{
	  unsigned int i;

	  for (i = 0; i < nwords; i++)
	    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
				     regno + i))
	      break;

	  if (i == nwords)
	    {
	      /* If we were going to use OUT as the reload reg
		 and changed our mind, it means OUT is a dummy that
		 dies here.  So don't bother copying value to it.  */
	      if (for_real >= 0 && value == real_out)
		rld[for_real].out = 0;
	      if (REG_P (real_in))
		value = real_in;
	      else
		value = gen_rtx_REG (inmode, regno);
	    }
	}
    }

  return value;
}

/* This page contains subroutines used mainly for determining
   whether the IN or an OUT of a reload can serve as the
   reload register.  */

/* Return 1 if X is an operand of an insn that is being earlyclobbered.  */

int
earlyclobber_operand_p (rtx x)
{
  int i;

  for (i = 0; i < n_earlyclobbers; i++)
    if (reload_earlyclobbers[i] == x)
      return 1;

  return 0;
}

/* Return 1 if expression X alters a hard reg in the range
   from BEG_REGNO (inclusive) to END_REGNO (exclusive),
   either explicitly or in the guise of a pseudo-reg allocated to REGNO.
   X should be the body of an instruction.  */

static int
hard_reg_set_here_p (unsigned int beg_regno, unsigned int end_regno, rtx x)
{
  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
    {
      rtx op0 = SET_DEST (x);

      while (GET_CODE (op0) == SUBREG)
	op0 = SUBREG_REG (op0);
      if (REG_P (op0))
	{
	  unsigned int r = REGNO (op0);

	  /* See if this reg overlaps range under consideration.  */
	  if (r < end_regno
	      && end_hard_regno (GET_MODE (op0), r) > beg_regno)
	    return 1;
	}
    }
  else if (GET_CODE (x) == PARALLEL)
    {
      int i = XVECLEN (x, 0) - 1;

      for (; i >= 0; i--)
	if (hard_reg_set_here_p (beg_regno, end_regno, XVECEXP (x, 0, i)))
	  return 1;
    }

  return 0;
}

/* Return 1 if ADDR is a valid memory address for mode MODE
   in address space AS, and check that each pseudo reg has the
   proper kind of hard reg.  */

int
strict_memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
				    rtx addr, addr_space_t as)
{
#ifdef GO_IF_LEGITIMATE_ADDRESS
  gcc_assert (ADDR_SPACE_GENERIC_P (as));
  GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
  return 0;

 win:
  return 1;
#else
  return targetm.addr_space.legitimate_address_p (mode, addr, 1, as);
#endif
}

/* Like rtx_equal_p except that it allows a REG and a SUBREG to match
   if they are the same hard reg, and has special hacks for
   autoincrement and autodecrement.
   This is specifically intended for find_reloads to use
   in determining whether two operands match.
   X is the operand whose number is the lower of the two.

   The value is 2 if Y contains a pre-increment that matches
   a non-incrementing address in X.  */

/* ??? To be completely correct, we should arrange to pass
   for X the output operand and for Y the input operand.
   For now, we assume that the output operand has the lower number
   because that is natural in (SET output (... input ...)).  */

int
operands_match_p (rtx x, rtx y)
{
  int i;
  RTX_CODE code = GET_CODE (x);
  const char *fmt;
  int success_2;

  if (x == y)
    return 1;
  if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
      && (REG_P (y) || (GET_CODE (y) == SUBREG
				  && REG_P (SUBREG_REG (y)))))
    {
      int j;

      if (code == SUBREG)
	{
	  i = REGNO (SUBREG_REG (x));
	  if (i >= FIRST_PSEUDO_REGISTER)
	    goto slow;
	  i += subreg_regno_offset (REGNO (SUBREG_REG (x)),
				    GET_MODE (SUBREG_REG (x)),
				    SUBREG_BYTE (x),
				    GET_MODE (x));
	}
      else
	i = REGNO (x);

      if (GET_CODE (y) == SUBREG)
	{
	  j = REGNO (SUBREG_REG (y));
	  if (j >= FIRST_PSEUDO_REGISTER)
	    goto slow;
	  j += subreg_regno_offset (REGNO (SUBREG_REG (y)),
				    GET_MODE (SUBREG_REG (y)),
				    SUBREG_BYTE (y),
				    GET_MODE (y));
	}
      else
	j = REGNO (y);

      /* 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.  */
      scalar_int_mode xmode;
      if (REG_WORDS_BIG_ENDIAN
	  && is_a <scalar_int_mode> (GET_MODE (x), &xmode)
	  && GET_MODE_SIZE (xmode) > UNITS_PER_WORD
	  && i < FIRST_PSEUDO_REGISTER)
	i += hard_regno_nregs (i, xmode) - 1;
      scalar_int_mode ymode;
      if (REG_WORDS_BIG_ENDIAN
	  && is_a <scalar_int_mode> (GET_MODE (y), &ymode)
	  && GET_MODE_SIZE (ymode) > UNITS_PER_WORD
	  && j < FIRST_PSEUDO_REGISTER)
	j += hard_regno_nregs (j, ymode) - 1;

      return i == j;
    }
  /* If two operands must match, because they are really a single
     operand of an assembler insn, then two postincrements are invalid
     because the assembler insn would increment only once.
     On the other hand, a postincrement matches ordinary indexing
     if the postincrement is the output operand.  */
  if (code == POST_DEC || code == POST_INC || code == POST_MODIFY)
    return operands_match_p (XEXP (x, 0), y);
  /* Two preincrements are invalid
     because the assembler insn would increment only once.
     On the other hand, a preincrement matches ordinary indexing
     if the preincrement is the input operand.
     In this case, return 2, since some callers need to do special
     things when this happens.  */
  if (GET_CODE (y) == PRE_DEC || GET_CODE (y) == PRE_INC
      || GET_CODE (y) == PRE_MODIFY)
    return operands_match_p (x, XEXP (y, 0)) ? 2 : 0;

 slow:

  /* Now we have disposed of all the cases in which different rtx codes
     can match.  */
  if (code != GET_CODE (y))
    return 0;

  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
  if (GET_MODE (x) != GET_MODE (y))
    return 0;

  /* MEMs referring to different address space are not equivalent.  */
  if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
    return 0;

  switch (code)
    {
    CASE_CONST_UNIQUE:
      return 0;

    case LABEL_REF:
      return label_ref_label (x) == label_ref_label (y);
    case SYMBOL_REF:
      return XSTR (x, 0) == XSTR (y, 0);

    default:
      break;
    }

  /* Compare the elements.  If any pair of corresponding elements
     fail to match, return 0 for the whole things.  */

  success_2 = 0;
  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      int val, j;
      switch (fmt[i])
	{
	case 'w':
	  if (XWINT (x, i) != XWINT (y, i))
	    return 0;
	  break;

	case 'i':
	  if (XINT (x, i) != XINT (y, i))
	    return 0;
	  break;

	case 'p':
	  if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
	    return 0;
	  break;

	case 'e':
	  val = operands_match_p (XEXP (x, i), XEXP (y, i));
	  if (val == 0)
	    return 0;
	  /* If any subexpression returns 2,
	     we should return 2 if we are successful.  */
	  if (val == 2)
	    success_2 = 1;
	  break;

	case '0':
	  break;

	case 'E':
	  if (XVECLEN (x, i) != XVECLEN (y, i))
	    return 0;
	  for (j = XVECLEN (x, i) - 1; j >= 0; --j)
	    {
	      val = operands_match_p (XVECEXP (x, i, j), XVECEXP (y, i, j));
	      if (val == 0)
		return 0;
	      if (val == 2)
		success_2 = 1;
	    }
	  break;

	  /* It is believed that rtx's at this level will never
	     contain anything but integers and other rtx's,
	     except for within LABEL_REFs and SYMBOL_REFs.  */
	default:
	  gcc_unreachable ();
	}
    }
  return 1 + success_2;
}

/* Describe the range of registers or memory referenced by X.
   If X is a register, set REG_FLAG and put the first register
   number into START and the last plus one into END.
   If X is a memory reference, put a base address into BASE
   and a range of integer offsets into START and END.
   If X is pushing on the stack, we can assume it causes no trouble,
   so we set the SAFE field.  */

static struct decomposition
decompose (rtx x)
{
  struct decomposition val;
  int all_const = 0, regno;

  memset (&val, 0, sizeof (val));

  switch (GET_CODE (x))
    {
    case MEM:
      {
	rtx base = NULL_RTX, offset = 0;
	rtx addr = XEXP (x, 0);

	if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
	    || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
	  {
	    val.base = XEXP (addr, 0);
	    val.start = -GET_MODE_SIZE (GET_MODE (x));
	    val.end = GET_MODE_SIZE (GET_MODE (x));
	    val.safe = REGNO (val.base) == STACK_POINTER_REGNUM;
	    return val;
	  }

	if (GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
	  {
	    if (GET_CODE (XEXP (addr, 1)) == PLUS
		&& XEXP (addr, 0) == XEXP (XEXP (addr, 1), 0)
		&& CONSTANT_P (XEXP (XEXP (addr, 1), 1)))
	      {
		val.base  = XEXP (addr, 0);
		val.start = -INTVAL (XEXP (XEXP (addr, 1), 1));
		val.end   = INTVAL (XEXP (XEXP (addr, 1), 1));
		val.safe  = REGNO (val.base) == STACK_POINTER_REGNUM;
		return val;
	      }
	  }

	if (GET_CODE (addr) == CONST)
	  {
	    addr = XEXP (addr, 0);
	    all_const = 1;
	  }
	if (GET_CODE (addr) == PLUS)
	  {
	    if (CONSTANT_P (XEXP (addr, 0)))
	      {
		base = XEXP (addr, 1);
		offset = XEXP (addr, 0);
	      }
	    else if (CONSTANT_P (XEXP (addr, 1)))
	      {
		base = XEXP (addr, 0);
		offset = XEXP (addr, 1);
	      }
	  }

	if (offset == 0)
	  {
	    base = addr;
	    offset = const0_rtx;
	  }
	if (GET_CODE (offset) == CONST)
	  offset = XEXP (offset, 0);
	if (GET_CODE (offset) == PLUS)
	  {
	    if (CONST_INT_P (XEXP (offset, 0)))
	      {
		base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 1));
		offset = XEXP (offset, 0);
	      }
	    else if (CONST_INT_P (XEXP (offset, 1)))
	      {
		base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 0));
		offset = XEXP (offset, 1);
	      }
	    else
	      {
		base = gen_rtx_PLUS (GET_MODE (base), base, offset);
		offset = const0_rtx;
	      }
	  }
	else if (!CONST_INT_P (offset))
	  {
	    base = gen_rtx_PLUS (GET_MODE (base), base, offset);
	    offset = const0_rtx;
	  }

	if (all_const && GET_CODE (base) == PLUS)
	  base = gen_rtx_CONST (GET_MODE (base), base);

	gcc_assert (CONST_INT_P (offset));

	val.start = INTVAL (offset);
	val.end = val.start + GET_MODE_SIZE (GET_MODE (x));
	val.base = base;
      }
      break;

    case REG:
      val.reg_flag = 1;
      regno = true_regnum (x);
      if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
	{
	  /* A pseudo with no hard reg.  */
	  val.start = REGNO (x);
	  val.end = val.start + 1;
	}
      else
	{
	  /* A hard reg.  */
	  val.start = regno;
	  val.end = end_hard_regno (GET_MODE (x), regno);
	}
      break;

    case SUBREG:
      if (!REG_P (SUBREG_REG (x)))
	/* This could be more precise, but it's good enough.  */
	return decompose (SUBREG_REG (x));
      regno = true_regnum (x);
      if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
	return decompose (SUBREG_REG (x));

      /* A hard reg.  */
      val.reg_flag = 1;
      val.start = regno;
      val.end = regno + subreg_nregs (x);
      break;

    case SCRATCH:
      /* This hasn't been assigned yet, so it can't conflict yet.  */
      val.safe = 1;
      break;

    default:
      gcc_assert (CONSTANT_P (x));
      val.safe = 1;
      break;
    }
  return val;
}

/* Return 1 if altering Y will not modify the value of X.
   Y is also described by YDATA, which should be decompose (Y).  */

static int
immune_p (rtx x, rtx y, struct decomposition ydata)
{
  struct decomposition xdata;

  if (ydata.reg_flag)
    /* In this case the decomposition structure contains register
       numbers rather than byte offsets.  */
    return !refers_to_regno_for_reload_p (ydata.start.to_constant (),
					  ydata.end.to_constant (),
					  x, (rtx *) 0);
  if (ydata.safe)
    return 1;

  gcc_assert (MEM_P (y));
  /* If Y is memory and X is not, Y can't affect X.  */
  if (!MEM_P (x))
    return 1;

  xdata = decompose (x);

  if (! rtx_equal_p (xdata.base, ydata.base))
    {
      /* If bases are distinct symbolic constants, there is no overlap.  */
      if (CONSTANT_P (xdata.base) && CONSTANT_P (ydata.base))
	return 1;
      /* Constants and stack slots never overlap.  */
      if (CONSTANT_P (xdata.base)
	  && (ydata.base == frame_pointer_rtx
	      || ydata.base == hard_frame_pointer_rtx
	      || ydata.base == stack_pointer_rtx))
	return 1;
      if (CONSTANT_P (ydata.base)
	  && (xdata.base == frame_pointer_rtx
	      || xdata.base == hard_frame_pointer_rtx
	      || xdata.base == stack_pointer_rtx))
	return 1;
      /* If either base is variable, we don't know anything.  */
      return 0;
    }

  return known_ge (xdata.start, ydata.end) || known_ge (ydata.start, xdata.end);
}

/* Similar, but calls decompose.  */

int
safe_from_earlyclobber (rtx op, rtx clobber)
{
  struct decomposition early_data;

  early_data = decompose (clobber);
  return immune_p (op, clobber, early_data);
}

/* Main entry point of this file: search the body of INSN
   for values that need reloading and record them with push_reload.
   REPLACE nonzero means record also where the values occur
   so that subst_reloads can be used.

   IND_LEVELS says how many levels of indirection are supported by this
   machine; a value of zero means that a memory reference is not a valid
   memory address.

   LIVE_KNOWN says we have valid information about which hard
   regs are live at each point in the program; this is true when
   we are called from global_alloc but false when stupid register
   allocation has been done.

   RELOAD_REG_P if nonzero is a vector indexed by hard reg number
   which is nonnegative if the reg has been commandeered for reloading into.
   It is copied into STATIC_RELOAD_REG_P and referenced from there
   by various subroutines.

   Return TRUE if some operands need to be changed, because of swapping
   commutative operands, reg_equiv_address substitution, or whatever.  */

int
find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
	      short *reload_reg_p)
{
  int insn_code_number;
  int i, j;
  int noperands;
  /* These start out as the constraints for the insn
     and they are chewed up as we consider alternatives.  */
  const char *constraints[MAX_RECOG_OPERANDS];
  /* These are the preferred classes for an operand, or NO_REGS if it isn't
     a register.  */
  enum reg_class preferred_class[MAX_RECOG_OPERANDS];
  char pref_or_nothing[MAX_RECOG_OPERANDS];
  /* Nonzero for a MEM operand whose entire address needs a reload.
     May be -1 to indicate the entire address may or may not need a reload.  */
  int address_reloaded[MAX_RECOG_OPERANDS];
  /* Nonzero for an address operand that needs to be completely reloaded.
     May be -1 to indicate the entire operand may or may not need a reload.  */
  int address_operand_reloaded[MAX_RECOG_OPERANDS];
  /* Value of enum reload_type to use for operand.  */
  enum reload_type operand_type[MAX_RECOG_OPERANDS];
  /* Value of enum reload_type to use within address of operand.  */
  enum reload_type address_type[MAX_RECOG_OPERANDS];
  /* Save the usage of each operand.  */
  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;
  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_earlyclobber[MAX_RECOG_OPERANDS];
  int this_alternative_matches[MAX_RECOG_OPERANDS];
  reg_class_t goal_alternative[MAX_RECOG_OPERANDS];
  int this_alternative_number;
  int goal_alternative_number = 0;
  int operand_reloadnum[MAX_RECOG_OPERANDS];
  int goal_alternative_matches[MAX_RECOG_OPERANDS];
  int goal_alternative_matched[MAX_RECOG_OPERANDS];
  char goal_alternative_match_win[MAX_RECOG_OPERANDS];
  char goal_alternative_win[MAX_RECOG_OPERANDS];
  char goal_alternative_offmemok[MAX_RECOG_OPERANDS];
  char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
  int goal_alternative_swapped;
  int best;
  int commutative;
  char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
  rtx substed_operand[MAX_RECOG_OPERANDS];
  rtx body = PATTERN (insn);
  rtx set = single_set (insn);
  int goal_earlyclobber = 0, this_earlyclobber;
  machine_mode operand_mode[MAX_RECOG_OPERANDS];
  int retval = 0;

  this_insn = insn;
  n_reloads = 0;
  n_replacements = 0;
  n_earlyclobbers = 0;
  replace_reloads = replace;
  hard_regs_live_known = live_known;
  static_reload_reg_p = reload_reg_p;

  /* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
     neither are insns that SET cc0.  Insns that use CC0 are not allowed
     to have any input reloads.  */
  if (JUMP_P (insn) || CALL_P (insn))
    no_output_reloads = 1;

  if (HAVE_cc0 && reg_referenced_p (cc0_rtx, PATTERN (insn)))
    no_input_reloads = 1;
  if (HAVE_cc0 && reg_set_p (cc0_rtx, PATTERN (insn)))
    no_output_reloads = 1;

  /* The eliminated forms of any secondary memory locations are per-insn, so
     clear them out here.  */

  if (secondary_memlocs_elim_used)
    {
      memset (secondary_memlocs_elim, 0,
	      sizeof (secondary_memlocs_elim[0]) * secondary_memlocs_elim_used);
      secondary_memlocs_elim_used = 0;
    }

  /* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
     is cheap to move between them.  If it is not, there may not be an insn
     to do the copy, so we may need a reload.  */
  if (GET_CODE (body) == SET
      && REG_P (SET_DEST (body))
      && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
      && REG_P (SET_SRC (body))
      && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
      && register_move_cost (GET_MODE (SET_SRC (body)),
			     REGNO_REG_CLASS (REGNO (SET_SRC (body))),
			     REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
    return 0;

  extract_insn (insn);

  noperands = reload_n_operands = recog_data.n_operands;
  n_alternatives = recog_data.n_alternatives;

  /* Just return "no reloads" if insn has no operands with constraints.  */
  if (noperands == 0 || n_alternatives == 0)
    return 0;

  insn_code_number = INSN_CODE (insn);
  this_insn_is_asm = insn_code_number < 0;

  memcpy (operand_mode, recog_data.operand_mode,
	  noperands * sizeof (machine_mode));
  memcpy (constraints, recog_data.constraints,
	  noperands * sizeof (const char *));

  commutative = -1;

  /* If we will need to know, later, whether some pair of operands
     are the same, we must compare them now and save the result.
     Reloading the base and index registers will clobber them
     and afterward they will fail to match.  */

  for (i = 0; i < noperands; i++)
    {
      const char *p;
      int c;
      char *end;

      substed_operand[i] = recog_data.operand[i];
      p = constraints[i];

      modified[i] = RELOAD_READ;

      /* Scan this operand's constraint to see if it is an output operand,
	 an in-out operand, is commutative, or should match another.  */

      while ((c = *p))
	{
	  p += CONSTRAINT_LEN (c, p);
	  switch (c)
	    {
	    case '=':
	      modified[i] = RELOAD_WRITE;
	      break;
	    case '+':
	      modified[i] = RELOAD_READ_WRITE;
	      break;
	    case '%':
	      {
		/* The last operand should not be marked commutative.  */
		gcc_assert (i != noperands - 1);

		/* We currently only support one commutative pair of
		   operands.  Some existing asm code currently uses more
		   than one pair.  Previously, that would usually work,
		   but sometimes it would crash the compiler.  We
		   continue supporting that case as well as we can by
		   silently ignoring all but the first pair.  In the
		   future we may handle it correctly.  */
		if (commutative < 0)
		  commutative = i;
		else
		  gcc_assert (this_insn_is_asm);
	      }
	      break;
	    /* Use of ISDIGIT is tempting here, but it may get expensive because
	       of locale support we don't want.  */
	    case '0': case '1': case '2': case '3': case '4':
	    case '5': case '6': case '7': case '8': case '9':
	      {
		c = strtoul (p - 1, &end, 10);
		p = end;

		operands_match[c][i]
		  = operands_match_p (recog_data.operand[c],
				      recog_data.operand[i]);

		/* An operand may not match itself.  */
		gcc_assert (c != i);

		/* If C can be commuted with C+1, and C might need to match I,
		   then C+1 might also need to match I.  */
		if (commutative >= 0)
		  {
		    if (c == commutative || c == commutative + 1)
		      {
			int other = c + (c == commutative ? 1 : -1);
			operands_match[other][i]
			  = operands_match_p (recog_data.operand[other],
					      recog_data.operand[i]);
		      }
		    if (i == commutative || i == commutative + 1)
		      {
			int other = i + (i == commutative ? 1 : -1);
			operands_match[c][other]
			  = operands_match_p (recog_data.operand[c],
					      recog_data.operand[other]);
		      }
		    /* Note that C is supposed to be less than I.
		       No need to consider altering both C and I because in
		       that case we would alter one into the other.  */
		  }
	      }
	    }
	}
    }

  /* Examine each operand that is a memory reference or memory address
     and reload parts of the addresses into index registers.
     Also here any references to pseudo regs that didn't get hard regs
     but are equivalent to constants get replaced in the insn itself
     with those constants.  Nobody will ever see them again.

     Finally, set up the preferred classes of each operand.  */

  for (i = 0; i < noperands; i++)
    {
      RTX_CODE code = GET_CODE (recog_data.operand[i]);

      address_reloaded[i] = 0;
      address_operand_reloaded[i] = 0;
      operand_type[i] = (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT
			 : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT
			 : RELOAD_OTHER);
      address_type[i]
	= (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT_ADDRESS
	   : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT_ADDRESS
	   : RELOAD_OTHER);

      if (*constraints[i] == 0)
	/* Ignore things like match_operator operands.  */
	;
      else if (insn_extra_address_constraint
	       (lookup_constraint (constraints[i])))
	{
	  address_operand_reloaded[i]
	    = find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
				    recog_data.operand[i],
				    recog_data.operand_loc[i],
				    i, operand_type[i], ind_levels, insn);

	  /* If we now have a simple operand where we used to have a
	     PLUS or MULT, re-recognize and try again.  */
	  if ((OBJECT_P (*recog_data.operand_loc[i])
	       || GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
	      && (GET_CODE (recog_data.operand[i]) == MULT
		  || GET_CODE (recog_data.operand[i]) == PLUS))
	    {
	      INSN_CODE (insn) = -1;
	      retval = find_reloads (insn, replace, ind_levels, live_known,
				     reload_reg_p);
	      return retval;
	    }

	  recog_data.operand[i] = *recog_data.operand_loc[i];
	  substed_operand[i] = 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)
	{
	  address_reloaded[i]
	    = find_reloads_address (GET_MODE (recog_data.operand[i]),
				    recog_data.operand_loc[i],
				    XEXP (recog_data.operand[i], 0),
				    &XEXP (recog_data.operand[i], 0),
				    i, address_type[i], ind_levels, insn);
	  recog_data.operand[i] = *recog_data.operand_loc[i];
	  substed_operand[i] = recog_data.operand[i];
	}
      else if (code == SUBREG)
	{
	  rtx reg = SUBREG_REG (recog_data.operand[i]);
	  rtx op
	    = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
				   ind_levels,
				   set != 0
				   && &SET_DEST (set) == recog_data.operand_loc[i],
				   insn,
				   &address_reloaded[i]);

	  /* If we made a MEM to load (a part of) the stackslot of a pseudo
	     that didn't get a hard register, emit a USE with a REG_EQUAL
	     note in front so that we might inherit a previous, possibly
	     wider reload.  */

	  if (replace
	      && MEM_P (op)
	      && REG_P (reg)
	      && known_ge (GET_MODE_SIZE (GET_MODE (reg)),
			   GET_MODE_SIZE (GET_MODE (op)))
	      && reg_equiv_constant (REGNO (reg)) == 0)
	    set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
						   insn),
				 REG_EQUAL, reg_equiv_memory_loc (REGNO (reg)));

	  substed_operand[i] = recog_data.operand[i] = op;
	}
      else if (code == PLUS || GET_RTX_CLASS (code) == RTX_UNARY)
	/* We can get a PLUS as an "operand" as a result of register
	   elimination.  See eliminate_regs and gen_reload.  We handle
	   a unary operator by reloading the operand.  */
	substed_operand[i] = recog_data.operand[i]
	  = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
				 ind_levels, 0, insn,
				 &address_reloaded[i]);
      else if (code == REG)
	{
	  /* This is equivalent to calling find_reloads_toplev.
	     The code is duplicated for speed.
	     When we find a pseudo always equivalent to a constant,
	     we replace it by the constant.  We must be sure, however,
	     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
	      && (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i]))
	    {
	      /* Record the existing mode so that the check if constants are
		 allowed will work when operand_mode isn't specified.  */

	      if (operand_mode[i] == VOIDmode)
		operand_mode[i] = GET_MODE (recog_data.operand[i]);

	      substed_operand[i] = recog_data.operand[i]
		= reg_equiv_constant (regno);
	    }
	  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]
	      = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
				     ind_levels, 0, insn,
				     &address_reloaded[i]);
	}
      /* If the operand is still a register (we didn't replace it with an
	 equivalent), get the preferred class to reload it into.  */
      code = GET_CODE (recog_data.operand[i]);
      preferred_class[i]
	= ((code == REG && REGNO (recog_data.operand[i])
	    >= FIRST_PSEUDO_REGISTER)
	   ? reg_preferred_class (REGNO (recog_data.operand[i]))
	   : NO_REGS);
      pref_or_nothing[i]
	= (code == REG
	   && REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER
	   && reg_alternate_class (REGNO (recog_data.operand[i])) == NO_REGS);
    }

  /* If this is simply a copy from operand 1 to operand 0, merge the
     preferred classes for the operands.  */
  if (set != 0 && noperands >= 2 && recog_data.operand[0] == SET_DEST (set)
      && recog_data.operand[1] == SET_SRC (set))
    {
      preferred_class[0] = preferred_class[1]
	= reg_class_subunion[(int) preferred_class[0]][(int) preferred_class[1]];
      pref_or_nothing[0] |= pref_or_nothing[1];
      pref_or_nothing[1] |= pref_or_nothing[0];
    }

  /* Now see what we need for pseudo-regs that didn't get hard regs
     or got the wrong kind of hard reg.  For this, we must consider
     all the operands together against the register constraints.  */

  best = MAX_RECOG_OPERANDS * 2 + 600;

  goal_alternative_swapped = 0;

  /* The constraints are made of several alternatives.
     Each operand's constraint looks like foo,bar,... with commas
     separating the alternatives.  The first alternatives for all
     operands go together, the second alternatives go together, etc.

     First loop over alternatives.  */

  alternative_mask enabled = get_enabled_alternatives (insn);
  for (this_alternative_number = 0;
       this_alternative_number < n_alternatives;
       this_alternative_number++)
    {
      int swapped;

      if (!TEST_BIT (enabled, this_alternative_number))
	{
	  int i;

	  for (i = 0; i < recog_data.n_operands; i++)
	    constraints[i] = skip_alternative (constraints[i]);

	  continue;
	}

      /* If insn is commutative (it's safe to exchange a certain pair
	 of operands) then we need to try each alternative twice, the
	 second time matching those two operands as if we had
	 exchanged them.  To do this, really exchange them in
	 operands.  */
      for (swapped = 0; swapped < (commutative >= 0 ? 2 : 1); swapped++)
	{
	  /* Loop over operands for one constraint alternative.  */
	  /* LOSERS counts those that don't fit this alternative
	     and would require loading.  */
	  int losers = 0;
	  /* BAD is set to 1 if it some operand can't fit this alternative
	     even after reloading.  */
	  int bad = 0;
	  /* REJECT is a count of how undesirable this alternative says it is
	     if any reloading is required.  If the alternative matches exactly
	     then REJECT is ignored, but otherwise it gets this much
	     counted against it in addition to the reloading needed.  Each
	     ? counts three times here since we want the disparaging caused by
	     a bad register class to only count 1/3 as much.  */
	  int reject = 0;

	  if (swapped)
	    {
	      recog_data.operand[commutative] = substed_operand[commutative + 1];
	      recog_data.operand[commutative + 1] = substed_operand[commutative];
	      /* Swap the duplicates too.  */
	      for (i = 0; i < recog_data.n_dups; i++)
		if (recog_data.dup_num[i] == commutative
		    || recog_data.dup_num[i] == commutative + 1)
		  *recog_data.dup_loc[i]
		    = recog_data.operand[(int) recog_data.dup_num[i]];

	      std::swap (preferred_class[commutative],
			 preferred_class[commutative + 1]);
	      std::swap (pref_or_nothing[commutative],
			 pref_or_nothing[commutative + 1]);
	      std::swap (address_reloaded[commutative],
			 address_reloaded[commutative + 1]);
	    }

	  this_earlyclobber = 0;

	  for (i = 0; i < noperands; i++)
	    {
	      const char *p = constraints[i];
	      char *end;
	      int len;
	      int win = 0;
	      int did_match = 0;
	      /* 0 => this operand can be reloaded somehow for this alternative.  */
	      int badop = 1;
	      /* 0 => this operand can be reloaded if the alternative allows regs.  */
	      int winreg = 0;
	      int c;
	      int m;
	      rtx operand = recog_data.operand[i];
	      int offset = 0;
	      /* Nonzero means this is a MEM that must be reloaded into a reg
		 regardless of what the constraint says.  */
	      int force_reload = 0;
	      int offmemok = 0;
	      /* Nonzero if a constant forced into memory would be OK for this
		 operand.  */
	      int constmemok = 0;
	      int earlyclobber = 0;
	      enum constraint_num cn;
	      enum reg_class cl;

	      /* If the predicate accepts a unary operator, it means that
		 we need to reload the operand, but do not do this for
		 match_operator and friends.  */
	      if (UNARY_P (operand) && *p != 0)
		operand = XEXP (operand, 0);

	      /* If the operand is a SUBREG, extract
		 the REG or MEM (or maybe even a constant) within.
		 (Constants can occur as a result of reg_equiv_constant.)  */

	      while (GET_CODE (operand) == SUBREG)
		{
		  /* Offset only matters when operand is a REG and
		     it is a hard reg.  This is because it is passed
		     to reg_fits_class_p if it is a REG and all pseudos
		     return 0 from that function.  */
		  if (REG_P (SUBREG_REG (operand))
		      && REGNO (SUBREG_REG (operand)) < FIRST_PSEUDO_REGISTER)
		    {
		      if (simplify_subreg_regno (REGNO (SUBREG_REG (operand)),
						 GET_MODE (SUBREG_REG (operand)),
						 SUBREG_BYTE (operand),
						 GET_MODE (operand)) < 0)
			force_reload = 1;
		      offset += subreg_regno_offset (REGNO (SUBREG_REG (operand)),
						     GET_MODE (SUBREG_REG (operand)),
						     SUBREG_BYTE (operand),
						     GET_MODE (operand));
		    }
		  operand = SUBREG_REG (operand);
		  /* Force reload if this is a constant or PLUS or if there may
		     be a problem accessing OPERAND in the outer mode.  */
		  scalar_int_mode inner_mode;
		  if (CONSTANT_P (operand)
		      || GET_CODE (operand) == PLUS
		      /* We must force a reload of paradoxical SUBREGs
			 of a MEM because the alignment of the inner value
			 may not be enough to do the outer reference.  On
			 big-endian machines, it may also reference outside
			 the object.

			 On machines that extend byte operations and we have a
			 SUBREG where both the inner and outer modes are no wider
			 than a word and the inner mode is narrower, is integral,
			 and gets extended when loaded from memory, combine.c has
			 made assumptions about the behavior of the machine in such
			 register access.  If the data is, in fact, in memory we
			 must always load using the size assumed to be in the
			 register and let the insn do the different-sized
			 accesses.

			 This is doubly true if WORD_REGISTER_OPERATIONS.  In
			 this case eliminate_regs has left non-paradoxical
			 subregs for push_reload to see.  Make sure it does
			 by forcing the reload.

			 ??? When is it right at this stage to have a subreg
			 of a mem that is _not_ to be handled specially?  IMO
			 those should have been reduced to just a mem.  */
		      || ((MEM_P (operand)
			   || (REG_P (operand)
			       && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
			  && (WORD_REGISTER_OPERATIONS
			      || (((maybe_lt
				    (GET_MODE_BITSIZE (GET_MODE (operand)),
				     BIGGEST_ALIGNMENT))
				   && (paradoxical_subreg_p
				       (operand_mode[i], GET_MODE (operand)))))
			      || BYTES_BIG_ENDIAN
			      || (known_le (GET_MODE_SIZE (operand_mode[i]),
					    UNITS_PER_WORD)
				  && (is_a <scalar_int_mode>
				      (GET_MODE (operand), &inner_mode))
				  && (GET_MODE_SIZE (inner_mode)
				      <= UNITS_PER_WORD)
				  && paradoxical_subreg_p (operand_mode[i],
							   inner_mode)
				  && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)))
		      )
		    force_reload = 1;
		}

	      this_alternative[i] = NO_REGS;
	      this_alternative_win[i] = 0;
	      this_alternative_match_win[i] = 0;
	      this_alternative_offmemok[i] = 0;
	      this_alternative_earlyclobber[i] = 0;
	      this_alternative_matches[i] = -1;

	      /* An empty constraint or empty alternative
		 allows anything which matched the pattern.  */
	      if (*p == 0 || *p == ',')
		win = 1, badop = 0;

	      /* Scan this alternative's specs for this operand;
		 set WIN if the operand fits any letter in this alternative.
		 Otherwise, clear BADOP if this operand could
		 fit some letter after reloads,
		 or set WINREG if this operand could fit after reloads
		 provided the constraint allows some registers.  */

	      do
		switch ((c = *p, len = CONSTRAINT_LEN (c, p)), c)
		  {
		  case '\0':
		    len = 0;
		    break;
		  case ',':
		    c = '\0';
		    break;

		  case '?':
		    reject += 6;
		    break;

		  case '!':
		    reject = 600;
		    break;

		  case '#':
		    /* Ignore rest of this alternative as far as
		       reloading is concerned.  */
		    do
		      p++;
		    while (*p && *p != ',');
		    len = 0;
		    break;

		  case '0':  case '1':  case '2':  case '3':  case '4':
		  case '5':  case '6':  case '7':  case '8':  case '9':
		    m = strtoul (p, &end, 10);
		    p = end;
		    len = 0;

		    this_alternative_matches[i] = m;
		    /* We are supposed to match a previous operand.
		       If we do, we win if that one did.
		       If we do not, count both of the operands as losers.
		       (This is too conservative, since most of the time
		       only a single reload insn will be needed to make
		       the two operands win.  As a result, this alternative
		       may be rejected when it is actually desirable.)  */
		    if ((swapped && (m != commutative || i != commutative + 1))
			/* If we are matching as if two operands were swapped,
			   also pretend that operands_match had been computed
			   with swapped.
			   But if I is the second of those and C is the first,
			   don't exchange them, because operands_match is valid
			   only on one side of its diagonal.  */
			? (operands_match
			   [(m == commutative || m == commutative + 1)
			    ? 2 * commutative + 1 - m : m]
			   [(i == commutative || i == commutative + 1)
			    ? 2 * commutative + 1 - i : i])
			: operands_match[m][i])
		      {
			/* If we are matching a non-offsettable address where an
			   offsettable address was expected, then we must reject
			   this combination, because we can't reload it.  */
			if (this_alternative_offmemok[m]
			    && MEM_P (recog_data.operand[m])
			    && this_alternative[m] == NO_REGS
			    && ! this_alternative_win[m])
			  bad = 1;

			did_match = this_alternative_win[m];
		      }
		    else
		      {
			/* Operands don't match.  */
			rtx value;
			int loc1, loc2;
			/* Retroactively mark the operand we had to match
			   as a loser, if it wasn't already.  */
			if (this_alternative_win[m])
			  losers++;
			this_alternative_win[m] = 0;
			if (this_alternative[m] == NO_REGS)
			  bad = 1;
			/* But count the pair only once in the total badness of
			   this alternative, if the pair can be a dummy reload.
			   The pointers in operand_loc are not swapped; swap
			   them by hand if necessary.  */
			if (swapped && i == commutative)
			  loc1 = commutative + 1;
			else if (swapped && i == commutative + 1)
			  loc1 = commutative;
			else
			  loc1 = i;
			if (swapped && m == commutative)
			  loc2 = commutative + 1;
			else if (swapped && m == commutative + 1)
			  loc2 = commutative;
			else
			  loc2 = m;
			value
			  = find_dummy_reload (recog_data.operand[i],
					       recog_data.operand[m],
					       recog_data.operand_loc[loc1],
					       recog_data.operand_loc[loc2],
					       operand_mode[i], operand_mode[m],
					       this_alternative[m], -1,
					       this_alternative_earlyclobber[m]);

			if (value != 0)
			  losers--;
		      }
		    /* This can be fixed with reloads if the operand
		       we are supposed to match can be fixed with reloads.  */
		    badop = 0;
		    this_alternative[i] = this_alternative[m];

		    /* If we have to reload this operand and some previous
		       operand also had to match the same thing as this
		       operand, we don't know how to do that.  So reject this
		       alternative.  */
		    if (! did_match || force_reload)
		      for (j = 0; j < i; j++)
			if (this_alternative_matches[j]
			    == this_alternative_matches[i])
			  {
			    badop = 1;
			    break;
			  }
		    break;

		  case 'p':
		    /* All necessary reloads for an address_operand
		       were handled in find_reloads_address.  */
		    this_alternative[i]
		      = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
					ADDRESS, SCRATCH);
		    win = 1;
		    badop = 0;
		    break;

		  case TARGET_MEM_CONSTRAINT:
		    if (force_reload)
		      break;
		    if (MEM_P (operand)
			|| (REG_P (operand)
			    && REGNO (operand) >= FIRST_PSEUDO_REGISTER
			    && reg_renumber[REGNO (operand)] < 0))
		      win = 1;
		    if (CONST_POOL_OK_P (operand_mode[i], operand))
		      badop = 0;
		    constmemok = 1;
		    break;

		  case '<':
		    if (MEM_P (operand)
			&& ! address_reloaded[i]
			&& (GET_CODE (XEXP (operand, 0)) == PRE_DEC
			    || GET_CODE (XEXP (operand, 0)) == POST_DEC))
		      win = 1;
		    break;

		  case '>':
		    if (MEM_P (operand)
			&& ! address_reloaded[i]
			&& (GET_CODE (XEXP (operand, 0)) == PRE_INC
			    || GET_CODE (XEXP (operand, 0)) == POST_INC))
		      win = 1;
		    break;

		    /* Memory operand whose address is not offsettable.  */
		  case 'V':
		    if (force_reload)
		      break;
		    if (MEM_P (operand)
			&& ! (ind_levels ? offsettable_memref_p (operand)
			      : offsettable_nonstrict_memref_p (operand))
			/* Certain mem addresses will become offsettable
			   after they themselves are reloaded.  This is important;
			   we don't want our own handling of unoffsettables
			   to override the handling of reg_equiv_address.  */
			&& !(REG_P (XEXP (operand, 0))
			     && (ind_levels == 0
				 || reg_equiv_address (REGNO (XEXP (operand, 0))) != 0)))
		      win = 1;
		    break;

		    /* Memory operand whose address is offsettable.  */
		  case 'o':
		    if (force_reload)
		      break;
		    if ((MEM_P (operand)
			 /* If IND_LEVELS, find_reloads_address won't reload a
			    pseudo that didn't get a hard reg, so we have to
			    reject that case.  */
			 && ((ind_levels ? offsettable_memref_p (operand)
			      : offsettable_nonstrict_memref_p (operand))
			     /* A reloaded address is offsettable because it is now
				just a simple register indirect.  */
			     || address_reloaded[i] == 1))
			|| (REG_P (operand)
			    && REGNO (operand) >= FIRST_PSEUDO_REGISTER
			    && reg_renumber[REGNO (operand)] < 0
			    /* If reg_equiv_address is nonzero, we will be
			       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))))
		      win = 1;
		    if (CONST_POOL_OK_P (operand_mode[i], operand)
			|| MEM_P (operand))
		      badop = 0;
		    constmemok = 1;
		    offmemok = 1;
		    break;

		  case '&':
		    /* Output operand that is stored before the need for the
		       input operands (and their index registers) is over.  */
		    earlyclobber = 1, this_earlyclobber = 1;
		    break;

		  case 'X':
		    force_reload = 0;
		    win = 1;
		    break;

		  case 'g':
		    if (! force_reload
			/* A PLUS is never a valid operand, but reload can make
			   it from a register when eliminating registers.  */
			&& GET_CODE (operand) != PLUS
			/* A SCRATCH is not a valid operand.  */
			&& GET_CODE (operand) != SCRATCH
			&& (! CONSTANT_P (operand)
			    || ! flag_pic
			    || LEGITIMATE_PIC_OPERAND_P (operand))
			&& (GENERAL_REGS == ALL_REGS
			    || !REG_P (operand)
			    || (REGNO (operand) >= FIRST_PSEUDO_REGISTER
				&& reg_renumber[REGNO (operand)] < 0)))
		      win = 1;
		    cl = GENERAL_REGS;
		    goto reg;

		  default:
		    cn = lookup_constraint (p);
		    switch (get_constraint_type (cn))
		      {
		      case CT_REGISTER:
			cl = reg_class_for_constraint (cn);
			if (cl != NO_REGS)
			  goto reg;
			break;

		      case CT_CONST_INT:
			if (CONST_INT_P (operand)
			    && (insn_const_int_ok_for_constraint
				(INTVAL (operand), cn)))
			  win = true;
			break;

		      case CT_MEMORY:
			if (force_reload)
			  break;
			if (constraint_satisfied_p (operand, cn))
			  win = 1;
			/* If the address was already reloaded,
			   we win as well.  */
			else if (MEM_P (operand) && address_reloaded[i] == 1)
			  win = 1;
			/* Likewise if the address will be reloaded because
			   reg_equiv_address is nonzero.  For reg_equiv_mem
			   we have to check.  */
			else if (REG_P (operand)
				 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
				 && reg_renumber[REGNO (operand)] < 0
				 && ((reg_equiv_mem (REGNO (operand)) != 0
				      && (constraint_satisfied_p
					  (reg_equiv_mem (REGNO (operand)),
					   cn)))
				     || (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'.  */
			if (CONST_POOL_OK_P (operand_mode[i], operand)
			    || MEM_P (operand))
			  badop = 0;
			constmemok = 1;
			offmemok = 1;
			break;

		      case CT_SPECIAL_MEMORY:
			if (force_reload)
			  break;
			if (constraint_satisfied_p (operand, cn))
			  win = 1;
			/* Likewise if the address will be reloaded because
			   reg_equiv_address is nonzero.  For reg_equiv_mem
			   we have to check.  */
			else if (REG_P (operand)
				 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
				 && reg_renumber[REGNO (operand)] < 0
				 && reg_equiv_mem (REGNO (operand)) != 0
				 && (constraint_satisfied_p
				     (reg_equiv_mem (REGNO (operand)), cn)))
			  win = 1;
			break;

		      case CT_ADDRESS:
			if (constraint_satisfied_p (operand, cn))
			  win = 1;

			/* If we didn't already win, we can reload
			   the address into a base register.  */
			this_alternative[i]
			  = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
					    ADDRESS, SCRATCH);
			badop = 0;
			break;

		      case CT_FIXED_FORM:
			if (constraint_satisfied_p (operand, cn))
			  win = 1;
			break;
		      }
		    break;

		  reg:
		    this_alternative[i]
		      = reg_class_subunion[this_alternative[i]][cl];
		    if (GET_MODE (operand) == BLKmode)
		      break;
		    winreg = 1;
		    if (REG_P (operand)
			&& reg_fits_class_p (operand, this_alternative[i],
  			             offset, GET_MODE (recog_data.operand[i])))
		      win = 1;
		    break;
		  }
	      while ((p += len), c);

	      if (swapped == (commutative >= 0 ? 1 : 0))
		constraints[i] = p;

	      /* If this operand could be handled with a reg,
		 and some reg is allowed, then this operand can be handled.  */
	      if (winreg && this_alternative[i] != NO_REGS
		  && (win || !class_only_fixed_regs[this_alternative[i]]))
		badop = 0;

	      /* Record which operands fit this alternative.  */
	      this_alternative_earlyclobber[i] = earlyclobber;
	      if (win && ! force_reload)
		this_alternative_win[i] = 1;
	      else if (did_match && ! force_reload)
		this_alternative_match_win[i] = 1;
	      else
		{
		  int const_to_mem = 0;

		  this_alternative_offmemok[i] = offmemok;
		  losers++;
		  if (badop)
		    bad = 1;
		  /* Alternative loses if it has no regs for a reg operand.  */
		  if (REG_P (operand)
		      && this_alternative[i] == NO_REGS
		      && this_alternative_matches[i] < 0)
		    bad = 1;

		  /* If this is a constant that is reloaded into the desired
		     class by copying it to memory first, count that as another
		     reload.  This is consistent with other code and is
		     required to avoid choosing another alternative when
		     the constant is moved into memory by this function on
		     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_mode[i], operand)
		      && ((targetm.preferred_reload_class (operand,
							   this_alternative[i])
			   == NO_REGS)
			  || no_input_reloads))
		    {
		      const_to_mem = 1;
		      if (this_alternative[i] != NO_REGS)
			losers++;
		    }

		  /* Alternative loses if it requires a type of reload not
		     permitted for this insn.  We can always reload SCRATCH
		     and objects with a REG_UNUSED note.  */
		  if (GET_CODE (operand) != SCRATCH
		      && modified[i] != RELOAD_READ && no_output_reloads
		      && ! find_reg_note (insn, REG_UNUSED, operand))
		    bad = 1;
		  else if (modified[i] != RELOAD_WRITE && no_input_reloads
			   && ! const_to_mem)
		    bad = 1;

		  /* If we can't reload this value at all, reject this
		     alternative.  Note that we could also lose due to
		     LIMIT_RELOAD_CLASS, but we don't check that
		     here.  */

		  if (! CONSTANT_P (operand) && this_alternative[i] != NO_REGS)
		    {
		      if (targetm.preferred_reload_class (operand,
							  this_alternative[i])
			  == NO_REGS)
			reject = 600;

		      if (operand_type[i] == RELOAD_FOR_OUTPUT
			  && (targetm.preferred_output_reload_class (operand,
							    this_alternative[i])
			      == NO_REGS))
			reject = 600;
		    }

		  /* We prefer to reload pseudos over reloading other things,
		     since such reloads may be able to be eliminated later.
		     If we are reloading a SCRATCH, we won't be generating any
		     insns, just using a register, so it is also preferred.
		     So bump REJECT in other cases.  Don't do this in the
		     case where we are forcing a constant into memory and
		     it will then win since we don't want to have a different
		     alternative match then.  */
		  if (! (REG_P (operand)
			 && REGNO (operand) >= FIRST_PSEUDO_REGISTER)
		      && GET_CODE (operand) != SCRATCH
		      && ! (const_to_mem && constmemok))
		    reject += 2;

		  /* Input reloads can be inherited more often than output
		     reloads can be removed, so penalize output reloads.  */
		  if (operand_type[i] != RELOAD_FOR_INPUT
		      && GET_CODE (operand) != SCRATCH)
		    reject++;
		}

	      /* If this operand is a pseudo register that didn't get
		 a hard reg and this alternative accepts some
		 register, see if the class that we want is a subset
		 of the preferred class for this register.  If not,
		 but it intersects that class, use the preferred class
		 instead.  If it does not intersect the preferred
		 class, show that usage of this alternative should be
		 discouraged; it will be discouraged more still if the
		 register is `preferred or nothing'.  We do this
		 because it increases the chance of reusing our spill
		 register in a later insn and avoiding a pair of
		 memory stores and loads.

		 Don't bother with this if this alternative will
		 accept this operand.

		 Don't do this for a multiword operand, since it is
		 only a small win and has the risk of requiring more
		 spill registers, which could cause a large loss.

		 Don't do this if the preferred class has only one
		 register because we might otherwise exhaust the
		 class.  */

	      if (! win && ! did_match
		  && this_alternative[i] != NO_REGS
		  && known_le (GET_MODE_SIZE (operand_mode[i]), UNITS_PER_WORD)
		  && reg_class_size [(int) preferred_class[i]] > 0
		  && ! small_register_class_p (preferred_class[i]))
		{
		  if (! reg_class_subset_p (this_alternative[i],
					    preferred_class[i]))
		    {
		      /* Since we don't have a way of forming the intersection,
			 we just do something special if the preferred class
			 is a subset of the class we have; that's the most
			 common case anyway.  */
		      if (reg_class_subset_p (preferred_class[i],
					      this_alternative[i]))
			this_alternative[i] = preferred_class[i];
		      else
			reject += (2 + 2 * pref_or_nothing[i]);
		    }
		}
	    }

	  /* Now see if any output operands that are marked "earlyclobber"
	     in this alternative conflict with any input operands
	     or any memory addresses.  */

	  for (i = 0; i < noperands; i++)
	    if (this_alternative_earlyclobber[i]
		&& (this_alternative_win[i] || this_alternative_match_win[i]))
	      {
		struct decomposition early_data;

		early_data = decompose (recog_data.operand[i]);

		gcc_assert (modified[i] != RELOAD_READ);

		if (this_alternative[i] == NO_REGS)
		  {
		    this_alternative_earlyclobber[i] = 0;
		    gcc_assert (this_insn_is_asm);
		    error_for_asm (this_insn,
			      "%<&%> constraint used with no register class");
		  }

		for (j = 0; j < noperands; j++)
		  /* Is this an input operand or a memory ref?  */
		  if ((MEM_P (recog_data.operand[j])
		       || modified[j] != RELOAD_WRITE)
		      && j != i
		      /* Ignore things like match_operator operands.  */
		      && !recog_data.is_operator[j]
		      /* Don't count an input operand that is constrained to match
			 the early clobber operand.  */
		      && ! (this_alternative_matches[j] == i
			    && rtx_equal_p (recog_data.operand[i],
					    recog_data.operand[j]))
		      /* Is it altered by storing the earlyclobber operand?  */
		      && !immune_p (recog_data.operand[j], recog_data.operand[i],
				    early_data))
		    {
		      /* If the output is in a non-empty few-regs class,
			 it's costly to reload it, so reload the input instead.  */
		      if (small_register_class_p (this_alternative[i])
			  && (REG_P (recog_data.operand[j])
			      || GET_CODE (recog_data.operand[j]) == SUBREG))
			{
			  losers++;
			  this_alternative_win[j] = 0;
			  this_alternative_match_win[j] = 0;
			}
		      else
			break;
		    }
		/* If an earlyclobber operand conflicts with something,
		   it must be reloaded, so request this and count the cost.  */
		if (j != noperands)
		  {
		    losers++;
		    this_alternative_win[i] = 0;
		    this_alternative_match_win[j] = 0;
		    for (j = 0; j < noperands; j++)
		      if (this_alternative_matches[j] == i
			  && this_alternative_match_win[j])
			{
			  this_alternative_win[j] = 0;
			  this_alternative_match_win[j] = 0;
			  losers++;
			}
		  }
	      }

	  /* If one alternative accepts all the operands, no reload required,
	     choose that alternative; don't consider the remaining ones.  */
	  if (losers == 0)
	    {
	      /* Unswap these so that they are never swapped at `finish'.  */
	      if (swapped)
		{
		  recog_data.operand[commutative] = substed_operand[commutative];
		  recog_data.operand[commutative + 1]
		    = substed_operand[commutative + 1];
		}
	      for (i = 0; i < noperands; i++)
		{
		  goal_alternative_win[i] = this_alternative_win[i];
		  goal_alternative_match_win[i] = this_alternative_match_win[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]
		    = this_alternative_earlyclobber[i];
		}
	      goal_alternative_number = this_alternative_number;
	      goal_alternative_swapped = swapped;
	      goal_earlyclobber = this_earlyclobber;
	      goto finish;
	    }

	  /* REJECT, set by the ! and ? constraint characters and when a register
	     would be reloaded into a non-preferred class, discourages the use of
	     this alternative for a reload goal.  REJECT is incremented by six
	     for each ? and two for each non-preferred class.  */
	  losers = losers * 6 + reject;

	  /* If this alternative can be made to work by reloading,
	     and it needs less reloading than the others checked so far,
	     record it as the chosen goal for reloading.  */
	  if (! bad)
	    {
	      if (best > losers)
		{
		  for (i = 0; i < noperands; 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_offmemok[i]
			= this_alternative_offmemok[i];
		      goal_alternative_matches[i] = this_alternative_matches[i];
		      goal_alternative_earlyclobber[i]
			= this_alternative_earlyclobber[i];
		    }
		  goal_alternative_swapped = swapped;
		  best = losers;
		  goal_alternative_number = this_alternative_number;
		  goal_earlyclobber = this_earlyclobber;
		}
	    }

	  if (swapped)
	    {
	      /* If the commutative operands have been swapped, swap
		 them back in order to check the next alternative.  */
	      recog_data.operand[commutative] = substed_operand[commutative];
	      recog_data.operand[commutative + 1] = substed_operand[commutative + 1];
	      /* Unswap the duplicates too.  */
	      for (i = 0; i < recog_data.n_dups; i++)
		if (recog_data.dup_num[i] == commutative
		    || recog_data.dup_num[i] == commutative + 1)
		  *recog_data.dup_loc[i]
		    = recog_data.operand[(int) recog_data.dup_num[i]];

	      /* Unswap the operand related information as well.  */
	      std::swap (preferred_class[commutative],
			 preferred_class[commutative + 1]);
	      std::swap (pref_or_nothing[commutative],
			 pref_or_nothing[commutative + 1]);
	      std::swap (address_reloaded[commutative],
			 address_reloaded[commutative + 1]);
	    }
	}
    }

  /* The operands don't meet the constraints.
     goal_alternative describes the alternative
     that we could reach by reloading the fewest operands.
     Reload so as to fit it.  */

  if (best == MAX_RECOG_OPERANDS * 2 + 600)
    {
      /* No alternative works with reloads??  */
      if (insn_code_number >= 0)
	fatal_insn ("unable to generate reloads for:", insn);
      error_for_asm (insn, "inconsistent operand constraints in an %<asm%>");
      /* Avoid further trouble with this insn.  */
      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
      n_reloads = 0;
      return 0;
    }

  /* Jump to `finish' from above if all operands are valid already.
     In that case, goal_alternative_win is all 1.  */
 finish:

  /* Right now, for any pair of operands I and J that are required to match,
     with I < J,
     goal_alternative_matches[J] is I.
     Set up goal_alternative_matched as the inverse function:
     goal_alternative_matched[I] = J.  */

  for (i = 0; i < noperands; i++)
    goal_alternative_matched[i] = -1;

  for (i = 0; i < noperands; i++)
    if (! goal_alternative_win[i]
	&& goal_alternative_matches[i] >= 0)
      goal_alternative_matched[goal_alternative_matches[i]] = i;

  for (i = 0; i < noperands; i++)
    goal_alternative_win[i] |= goal_alternative_match_win[i];

  /* If the best alternative is with operands 1 and 2 swapped,
     consider them swapped before reporting the reloads.  Update the
     operand numbers of any reloads already pushed.  */

  if (goal_alternative_swapped)
    {
      std::swap (substed_operand[commutative],
		 substed_operand[commutative + 1]);
      std::swap (recog_data.operand[commutative],
		 recog_data.operand[commutative + 1]);
      std::swap (*recog_data.operand_loc[commutative],
		 *recog_data.operand_loc[commutative + 1]);

      for (i = 0; i < recog_data.n_dups; i++)
	if (recog_data.dup_num[i] == commutative
	    || recog_data.dup_num[i] == commutative + 1)
	  *recog_data.dup_loc[i]
	    = recog_data.operand[(int) recog_data.dup_num[i]];

      for (i = 0; i < n_reloads; i++)
	{
	  if (rld[i].opnum == commutative)
	    rld[i].opnum = commutative + 1;
	  else if (rld[i].opnum == commutative + 1)
	    rld[i].opnum = commutative;
	}
    }

  for (i = 0; i < noperands; i++)
    {
      operand_reloadnum[i] = -1;

      /* If this is an earlyclobber operand, we need to widen the scope.
	 The reload must remain valid from the start of the insn being
	 reloaded until after the operand is stored into its destination.
	 We approximate this with RELOAD_OTHER even though we know that we
	 do not conflict with RELOAD_FOR_INPUT_ADDRESS reloads.

	 One special case that is worth checking is when we have an
	 output that is earlyclobber but isn't used past the insn (typically
	 a SCRATCH).  In this case, we only need have the reload live
	 through the insn itself, but not for any of our input or output
	 reloads.
	 But we must not accidentally narrow the scope of an existing
	 RELOAD_OTHER reload - leave these alone.

	 In any case, anything needed to address this operand can remain
	 however they were previously categorized.  */

      if (goal_alternative_earlyclobber[i] && operand_type[i] != RELOAD_OTHER)
	operand_type[i]
	  = (find_reg_note (insn, REG_UNUSED, recog_data.operand[i])
	     ? RELOAD_FOR_INSN : RELOAD_OTHER);
    }

  /* Any constants that aren't allowed and can't be reloaded
     into registers are here changed into memory references.  */
  for (i = 0; i < noperands; i++)
    if (! goal_alternative_win[i])
      {
	rtx op = recog_data.operand[i];
	rtx subreg = NULL_RTX;
	rtx plus = NULL_RTX;
	machine_mode mode = operand_mode[i];

	/* Reloads of SUBREGs of CONSTANT RTXs are handled later in
	   push_reload so we have to let them pass here.  */
	if (GET_CODE (op) == SUBREG)
	  {
	    subreg = op;
	    op = SUBREG_REG (op);
	    mode = GET_MODE (op);
	  }

	if (GET_CODE (op) == PLUS)
	  {
	    plus = op;
	    op = XEXP (op, 1);
	  }

	if (CONST_POOL_OK_P (mode, op)
	    && ((targetm.preferred_reload_class (op, goal_alternative[i])
		 == NO_REGS)
		|| no_input_reloads))
	  {
	    int this_address_reloaded;
	    rtx tem = force_const_mem (mode, op);

	    /* If we stripped a SUBREG or a PLUS above add it back.  */
	    if (plus != NULL_RTX)
	      tem = gen_rtx_PLUS (mode, XEXP (plus, 0), tem);

	    if (subreg != NULL_RTX)
	      tem = gen_rtx_SUBREG (operand_mode[i], tem, SUBREG_BYTE (subreg));

	    this_address_reloaded = 0;
	    substed_operand[i] = recog_data.operand[i]
	      = find_reloads_toplev (tem, i, address_type[i], ind_levels,
				     0, insn, &this_address_reloaded);

	    /* If the alternative accepts constant pool refs directly
	       there will be no reload needed at all.  */
	    if (plus == NULL_RTX
		&& subreg == NULL_RTX
		&& alternative_allows_const_pool_ref (this_address_reloaded != 1
						      ? substed_operand[i]
						      : NULL,
						      recog_data.constraints[i],
						      goal_alternative_number))
	      goal_alternative_win[i] = 1;
	  }
      }

  /* Record the values of the earlyclobber operands for the caller.  */
  if (goal_earlyclobber)
    for (i = 0; i < noperands; i++)
      if (goal_alternative_earlyclobber[i])
	reload_earlyclobbers[n_earlyclobbers++] = recog_data.operand[i];

  /* Now record reloads for all the operands that need them.  */
  for (i = 0; i < noperands; i++)
    if (! goal_alternative_win[i])
      {
	/* Operands that match previous ones have already been handled.  */
	if (goal_alternative_matches[i] >= 0)
	  ;
	/* Handle an operand with a nonoffsettable address
	   appearing where an offsettable address will do
	   by reloading the address into a base register.

	   ??? We can also do this when the operand is a register and
	   reg_equiv_mem is not offsettable, but this is a bit tricky,
	   so we don't bother with it.  It may not be worth doing.  */
	else if (goal_alternative_matched[i] == -1
		 && goal_alternative_offmemok[i]
		 && MEM_P (recog_data.operand[i]))
	  {
	    /* 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]);
	    machine_mode address_mode;

	    address_mode = get_address_mode (recog_data.operand[i]);
	    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, as, MEM, SCRATCH),
			     address_mode,
			     VOIDmode, 0, 0, i, RELOAD_OTHER);
	    rld[operand_reloadnum[i]].inc
	      = GET_MODE_SIZE (GET_MODE (recog_data.operand[i]));

	    /* If this operand is an output, we will have made any
	       reloads for its address as RELOAD_FOR_OUTPUT_ADDRESS, but
	       now we are treating part of the operand as an input, so
	       we must change these to RELOAD_FOR_OTHER_ADDRESS.  */

	    if (modified[i] == RELOAD_WRITE)
	      {
		for (j = 0; j < n_reloads; j++)
		  {
		    if (rld[j].opnum == i)
		      {
			if (rld[j].when_needed == RELOAD_FOR_OUTPUT_ADDRESS)
			  rld[j].when_needed = RELOAD_FOR_OTHER_ADDRESS;
			else if (rld[j].when_needed
				 == RELOAD_FOR_OUTADDR_ADDRESS)
			  rld[j].when_needed = RELOAD_FOR_OTHER_ADDRESS;
		      }
		  }
	      }
	  }
	else if (goal_alternative_matched[i] == -1)
	  {
	    operand_reloadnum[i]
	      = push_reload ((modified[i] != RELOAD_WRITE
			      ? recog_data.operand[i] : 0),
			     (modified[i] != RELOAD_READ
			      ? recog_data.operand[i] : 0),
			     (modified[i] != RELOAD_WRITE
			      ? recog_data.operand_loc[i] : 0),
			     (modified[i] != RELOAD_READ
			      ? recog_data.operand_loc[i] : 0),
			     (enum reg_class) goal_alternative[i],
			     (modified[i] == RELOAD_WRITE
			      ? VOIDmode : operand_mode[i]),
			     (modified[i] == RELOAD_READ
			      ? VOIDmode : operand_mode[i]),
			     (insn_code_number < 0 ? 0
			      : insn_data[insn_code_number].operand[i].strict_low),
			     0, i, operand_type[i]);
	  }
	/* In a matching pair of operands, one must be input only
	   and the other must be output only.
	   Pass the input operand as IN and the other as OUT.  */
	else if (modified[i] == RELOAD_READ
		 && modified[goal_alternative_matched[i]] == RELOAD_WRITE)
	  {
	    operand_reloadnum[i]
	      = push_reload (recog_data.operand[i],
			     recog_data.operand[goal_alternative_matched[i]],
			     recog_data.operand_loc[i],
			     recog_data.operand_loc[goal_alternative_matched[i]],
			     (enum reg_class) goal_alternative[i],
			     operand_mode[i],
			     operand_mode[goal_alternative_matched[i]],
			     0, 0, i, RELOAD_OTHER);
	    operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
	  }
	else if (modified[i] == RELOAD_WRITE
		 && modified[goal_alternative_matched[i]] == RELOAD_READ)
	  {
	    operand_reloadnum[goal_alternative_matched[i]]
	      = push_reload (recog_data.operand[goal_alternative_matched[i]],
			     recog_data.operand[i],
			     recog_data.operand_loc[goal_alternative_matched[i]],
			     recog_data.operand_loc[i],
			     (enum reg_class) goal_alternative[i],
			     operand_mode[goal_alternative_matched[i]],
			     operand_mode[i],
			     0, 0, i, RELOAD_OTHER);
	    operand_reloadnum[i] = output_reloadnum;
	  }
	else
	  {
	    gcc_assert (insn_code_number < 0);
	    error_for_asm (insn, "inconsistent operand constraints "
			   "in an %<asm%>");
	    /* Avoid further trouble with this insn.  */
	    PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
	    n_reloads = 0;
	    return 0;
	  }
      }
    else if (goal_alternative_matched[i] < 0
	     && goal_alternative_matches[i] < 0
	     && address_operand_reloaded[i] != 1
	     && optimize)
      {
	/* For each non-matching operand that's a MEM or a pseudo-register
	   that didn't get a hard register, make an optional reload.
	   This may get done even if the insn needs no reloads otherwise.  */

	rtx operand = recog_data.operand[i];

	while (GET_CODE (operand) == SUBREG)
	  operand = SUBREG_REG (operand);
	if ((MEM_P (operand)
	     || (REG_P (operand)
		 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
	    /* If this is only for an output, the optional reload would not
	       actually cause us to use a register now, just note that
	       something is stored here.  */
	    && (goal_alternative[i] != NO_REGS
		|| modified[i] == RELOAD_WRITE)
	    && ! no_input_reloads
	    /* An optional output reload might allow to delete INSN later.
	       We mustn't make in-out reloads on insns that are not permitted
	       output reloads.
	       If this is an asm, we can't delete it; we must not even call
	       push_reload for an optional output reload in this case,
	       because we can't be sure that the constraint allows a register,
	       and push_reload verifies the constraints for asms.  */
	    && (modified[i] == RELOAD_READ
		|| (! no_output_reloads && ! this_insn_is_asm)))
	  operand_reloadnum[i]
	    = push_reload ((modified[i] != RELOAD_WRITE
			    ? recog_data.operand[i] : 0),
			   (modified[i] != RELOAD_READ
			    ? recog_data.operand[i] : 0),
			   (modified[i] != RELOAD_WRITE
			    ? recog_data.operand_loc[i] : 0),
			   (modified[i] != RELOAD_READ
			    ? recog_data.operand_loc[i] : 0),
			   (enum reg_class) goal_alternative[i],
			   (modified[i] == RELOAD_WRITE
			    ? VOIDmode : operand_mode[i]),
			   (modified[i] == RELOAD_READ
			    ? VOIDmode : operand_mode[i]),
			   (insn_code_number < 0 ? 0
			    : insn_data[insn_code_number].operand[i].strict_low),
			   1, i, operand_type[i]);
	/* If a memory reference remains (either as a MEM or a pseudo that
	   did not get a hard register), yet we can't make an optional
	   reload, check if this is actually a pseudo register reference;
	   we then need to emit a USE and/or a CLOBBER so that reload
	   inheritance will do the right thing.  */
	else if (replace
		 && (MEM_P (operand)
		     || (REG_P (operand)
			 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
			 && reg_renumber [REGNO (operand)] < 0)))
	  {
	    operand = *recog_data.operand_loc[i];

	    while (GET_CODE (operand) == SUBREG)
	      operand = SUBREG_REG (operand);
	    if (REG_P (operand))
	      {
		if (modified[i] != RELOAD_WRITE)
		  /* We mark the USE with QImode so that we recognize
		     it as one that can be safely deleted at the end
		     of reload.  */
		  PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, operand),
					      insn), QImode);
		if (modified[i] != RELOAD_READ)
		  emit_insn_after (gen_clobber (operand), insn);
	      }
	  }
      }
    else if (goal_alternative_matches[i] >= 0
	     && goal_alternative_win[goal_alternative_matches[i]]
	     && modified[i] == RELOAD_READ
	     && modified[goal_alternative_matches[i]] == RELOAD_WRITE
	     && ! no_input_reloads && ! no_output_reloads
	     && optimize)
      {
	/* Similarly, make an optional reload for a pair of matching
	   objects that are in MEM or a pseudo that didn't get a hard reg.  */

	rtx operand = recog_data.operand[i];

	while (GET_CODE (operand) == SUBREG)
	  operand = SUBREG_REG (operand);
	if ((MEM_P (operand)
	     || (REG_P (operand)
		 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
	    && (goal_alternative[goal_alternative_matches[i]] != NO_REGS))
	  operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]]
	    = push_reload (recog_data.operand[goal_alternative_matches[i]],
			   recog_data.operand[i],
			   recog_data.operand_loc[goal_alternative_matches[i]],
			   recog_data.operand_loc[i],
			   (enum reg_class) goal_alternative[goal_alternative_matches[i]],
			   operand_mode[goal_alternative_matches[i]],
			   operand_mode[i],
			   0, 1, goal_alternative_matches[i], RELOAD_OTHER);
      }

  /* Perform whatever substitutions on the operands we are supposed
     to make due to commutativity or replacement of registers
     with equivalent constants or memory slots.  */

  for (i = 0; i < noperands; i++)
    {
      /* We only do this on the last pass through reload, because it is
	 possible for some data (like reg_equiv_address) to be changed during
	 later passes.  Moreover, we lose the opportunity to get a useful
	 reload_{in,out}_reg when we do these replacements.  */

      if (replace)
	{
	  rtx substitution = substed_operand[i];

	  *recog_data.operand_loc[i] = substitution;

	  /* If we're replacing an operand with a LABEL_REF, we need to
	     make sure that there's a REG_LABEL_OPERAND note attached to
	     this instruction.  */
	  if (GET_CODE (substitution) == LABEL_REF
	      && !find_reg_note (insn, REG_LABEL_OPERAND,
				 label_ref_label (substitution))
	      /* For a JUMP_P, if it was a branch target it must have
		 already been recorded as such.  */
	      && (!JUMP_P (insn)
		  || !label_is_jump_target_p (label_ref_label (substitution),
					      insn)))
	    {
	      add_reg_note (insn, REG_LABEL_OPERAND,
			    label_ref_label (substitution));
	      if (LABEL_P (label_ref_label (substitution)))
		++LABEL_NUSES (label_ref_label (substitution));
	    }

	}
      else
	retval |= (substed_operand[i] != *recog_data.operand_loc[i]);
    }

  /* If this insn pattern contains any MATCH_DUP's, make sure that
     they will be substituted if the operands they match are substituted.
     Also do now any substitutions we already did on the operands.

     Don't do this if we aren't making replacements because we might be
     propagating things allocated by frame pointer elimination into places
     it doesn't expect.  */

  if (insn_code_number >= 0 && replace)
    for (i = insn_data[insn_code_number].n_dups - 1; i >= 0; i--)
      {
	int opno = recog_data.dup_num[i];
	*recog_data.dup_loc[i] = *recog_data.operand_loc[opno];
	dup_replacements (recog_data.dup_loc[i], recog_data.operand_loc[opno]);
      }

#if 0
  /* This loses because reloading of prior insns can invalidate the equivalence
     (or at least find_equiv_reg isn't smart enough to find it any more),
     causing this insn to need more reload regs than it needed before.
     It may be too late to make the reload regs available.
     Now this optimization is done safely in choose_reload_regs.  */

  /* For each reload of a reg into some other class of reg,
     search for an existing equivalent reg (same value now) in the right class.
     We can use it as long as we don't need to change its contents.  */
  for (i = 0; i < n_reloads; i++)
    if (rld[i].reg_rtx == 0
	&& rld[i].in != 0
	&& REG_P (rld[i].in)
	&& rld[i].out == 0)
      {
	rld[i].reg_rtx
	  = find_equiv_reg (rld[i].in, insn, rld[i].rclass, -1,
			    static_reload_reg_p, 0, rld[i].inmode);
	/* Prevent generation of insn to load the value
	   because the one we found already has the value.  */
	if (rld[i].reg_rtx)
	  rld[i].in = rld[i].reg_rtx;
      }
#endif

  /* If we detected error and replaced asm instruction by USE, forget about the
     reloads.  */
  if (GET_CODE (PATTERN (insn)) == USE
      && CONST_INT_P (XEXP (PATTERN (insn), 0)))
    n_reloads = 0;

  /* Perhaps an output reload can be combined with another
     to reduce needs by one.  */
  if (!goal_earlyclobber)
    combine_reloads ();

  /* If we have a pair of reloads for parts of an address, they are reloading
     the same object, the operands themselves were not reloaded, and they
     are for two operands that are supposed to match, merge the reloads and
     change the type of the surviving reload to RELOAD_FOR_OPERAND_ADDRESS.  */

  for (i = 0; i < n_reloads; i++)
    {
      int k;

      for (j = i + 1; j < n_reloads; j++)
	if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
	     || rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
	     || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
	     || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
	    && (rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
		|| rld[j].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
		|| rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS
		|| rld[j].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
	    && rtx_equal_p (rld[i].in, rld[j].in)
	    && (operand_reloadnum[rld[i].opnum] < 0
		|| rld[operand_reloadnum[rld[i].opnum]].optional)
	    && (operand_reloadnum[rld[j].opnum] < 0
		|| rld[operand_reloadnum[rld[j].opnum]].optional)
	    && (goal_alternative_matches[rld[i].opnum] == rld[j].opnum
		|| (goal_alternative_matches[rld[j].opnum]
		    == rld[i].opnum)))
	  {
	    for (k = 0; k < n_replacements; k++)
	      if (replacements[k].what == j)
		replacements[k].what = i;

	    if (rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
		|| rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
	      rld[i].when_needed = RELOAD_FOR_OPADDR_ADDR;
	    else
	      rld[i].when_needed = RELOAD_FOR_OPERAND_ADDRESS;
	    rld[j].in = 0;
	  }
    }

  /* Scan all the reloads and update their type.
     If a reload is for the address of an operand and we didn't reload
     that operand, change the type.  Similarly, change the operand number
     of a reload when two operands match.  If a reload is optional, treat it
     as though the operand isn't reloaded.

     ??? This latter case is somewhat odd because if we do the optional
     reload, it means the object is hanging around.  Thus we need only
     do the address reload if the optional reload was NOT done.

     Change secondary reloads to be the address type of their operand, not
     the normal type.

     If an operand's reload is now RELOAD_OTHER, change any
     RELOAD_FOR_INPUT_ADDRESS reloads of that operand to
     RELOAD_FOR_OTHER_ADDRESS.  */

  for (i = 0; i < n_reloads; i++)
    {
      if (rld[i].secondary_p
	  && rld[i].when_needed == operand_type[rld[i].opnum])
	rld[i].when_needed = address_type[rld[i].opnum];

      if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
	   || rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
	   || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
	   || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
	  && (operand_reloadnum[rld[i].opnum] < 0
	      || rld[operand_reloadnum[rld[i].opnum]].optional))
	{
	  /* If we have a secondary reload to go along with this reload,
	     change its type to RELOAD_FOR_OPADDR_ADDR.  */

	  if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
	       || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
	      && rld[i].secondary_in_reload != -1)
	    {
	      int secondary_in_reload = rld[i].secondary_in_reload;

	      rld[secondary_in_reload].when_needed = RELOAD_FOR_OPADDR_ADDR;

	      /* If there's a tertiary reload we have to change it also.  */
	      if (secondary_in_reload > 0
		  && rld[secondary_in_reload].secondary_in_reload != -1)
		rld[rld[secondary_in_reload].secondary_in_reload].when_needed
		  = RELOAD_FOR_OPADDR_ADDR;
	    }

	  if ((rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
	       || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
	      && rld[i].secondary_out_reload != -1)
	    {
	      int secondary_out_reload = rld[i].secondary_out_reload;

	      rld[secondary_out_reload].when_needed = RELOAD_FOR_OPADDR_ADDR;

	      /* If there's a tertiary reload we have to change it also.  */
	      if (secondary_out_reload
		  && rld[secondary_out_reload].secondary_out_reload != -1)
		rld[rld[secondary_out_reload].secondary_out_reload].when_needed
		  = RELOAD_FOR_OPADDR_ADDR;
	    }

	  if (rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
	      || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
	    rld[i].when_needed = RELOAD_FOR_OPADDR_ADDR;
	  else
	    rld[i].when_needed = RELOAD_FOR_OPERAND_ADDRESS;
	}

      if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
	   || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
	  && operand_reloadnum[rld[i].opnum] >= 0
	  && (rld[operand_reloadnum[rld[i].opnum]].when_needed
	      == RELOAD_OTHER))
	rld[i].when_needed = RELOAD_FOR_OTHER_ADDRESS;

      if (goal_alternative_matches[rld[i].opnum] >= 0)
	rld[i].opnum = goal_alternative_matches[rld[i].opnum];
    }

  /* Scan all the reloads, and check for RELOAD_FOR_OPERAND_ADDRESS reloads.
     If we have more than one, then convert all RELOAD_FOR_OPADDR_ADDR
     reloads to RELOAD_FOR_OPERAND_ADDRESS reloads.

     choose_reload_regs assumes that RELOAD_FOR_OPADDR_ADDR reloads never
     conflict with RELOAD_FOR_OPERAND_ADDRESS reloads.  This is true for a
     single pair of RELOAD_FOR_OPADDR_ADDR/RELOAD_FOR_OPERAND_ADDRESS reloads.
     However, if there is more than one RELOAD_FOR_OPERAND_ADDRESS reload,
     then a RELOAD_FOR_OPADDR_ADDR reload conflicts with all
     RELOAD_FOR_OPERAND_ADDRESS reloads other than the one that uses it.
     This is complicated by the fact that a single operand can have more
     than one RELOAD_FOR_OPERAND_ADDRESS reload.  It is very difficult to fix
     choose_reload_regs without affecting code quality, and cases that
     actually fail are extremely rare, so it turns out to be better to fix
     the problem here by not generating cases that choose_reload_regs will
     fail for.  */
  /* There is a similar problem with RELOAD_FOR_INPUT_ADDRESS /
     RELOAD_FOR_OUTPUT_ADDRESS when there is more than one of a kind for
     a single operand.
     We can reduce the register pressure by exploiting that a
     RELOAD_FOR_X_ADDR_ADDR that precedes all RELOAD_FOR_X_ADDRESS reloads
     does not conflict with any of them, if it is only used for the first of
     the RELOAD_FOR_X_ADDRESS reloads.  */
  {
    int first_op_addr_num = -2;
    int first_inpaddr_num[MAX_RECOG_OPERANDS];
    int first_outpaddr_num[MAX_RECOG_OPERANDS];
    int need_change = 0;
    /* We use last_op_addr_reload and the contents of the above arrays
       first as flags - -2 means no instance encountered, -1 means exactly
       one instance encountered.
       If more than one instance has been encountered, we store the reload
       number of the first reload of the kind in question; reload numbers
       are known to be non-negative.  */
    for (i = 0; i < noperands; i++)
      first_inpaddr_num[i] = first_outpaddr_num[i] = -2;
    for (i = n_reloads - 1; i >= 0; i--)
      {
	switch (rld[i].when_needed)
	  {
	  case RELOAD_FOR_OPERAND_ADDRESS:
	    if (++first_op_addr_num >= 0)
	      {
		first_op_addr_num = i;
		need_change = 1;
	      }
	    break;
	  case RELOAD_FOR_INPUT_ADDRESS:
	    if (++first_inpaddr_num[rld[i].opnum] >= 0)
	      {
		first_inpaddr_num[rld[i].opnum] = i;
		need_change = 1;
	      }
	    break;
	  case RELOAD_FOR_OUTPUT_ADDRESS:
	    if (++first_outpaddr_num[rld[i].opnum] >= 0)
	      {
		first_outpaddr_num[rld[i].opnum] = i;
		need_change = 1;
	      }
	    break;
	  default:
	    break;
	  }
      }

    if (need_change)
      {
	for (i = 0; i < n_reloads; i++)
	  {
	    int first_num;
	    enum reload_type type;

	    switch (rld[i].when_needed)
	      {
	      case RELOAD_FOR_OPADDR_ADDR:
		first_num = first_op_addr_num;
		type = RELOAD_FOR_OPERAND_ADDRESS;
		break;
	      case RELOAD_FOR_INPADDR_ADDRESS:
		first_num = first_inpaddr_num[rld[i].opnum];
		type = RELOAD_FOR_INPUT_ADDRESS;
		break;
	      case RELOAD_FOR_OUTADDR_ADDRESS:
		first_num = first_outpaddr_num[rld[i].opnum];
		type = RELOAD_FOR_OUTPUT_ADDRESS;
		break;
	      default:
		continue;
	      }
	    if (first_num < 0)
	      continue;
	    else if (i > first_num)
	      rld[i].when_needed = type;
	    else
	      {
		/* Check if the only TYPE reload that uses reload I is
		   reload FIRST_NUM.  */
		for (j = n_reloads - 1; j > first_num; j--)
		  {
		    if (rld[j].when_needed == type
			&& (rld[i].secondary_p
			    ? rld[j].secondary_in_reload == i
			    : reg_mentioned_p (rld[i].in, rld[j].in)))
		      {
			rld[i].when_needed = type;
			break;
		      }
		  }
	      }
	  }
      }
  }

  /* See if we have any reloads that are now allowed to be merged
     because we've changed when the reload is needed to
     RELOAD_FOR_OPERAND_ADDRESS or RELOAD_FOR_OTHER_ADDRESS.  Only
     check for the most common cases.  */

  for (i = 0; i < n_reloads; i++)
    if (rld[i].in != 0 && rld[i].out == 0
	&& (rld[i].when_needed == RELOAD_FOR_OPERAND_ADDRESS
	    || rld[i].when_needed == RELOAD_FOR_OPADDR_ADDR
	    || rld[i].when_needed == RELOAD_FOR_OTHER_ADDRESS))
      for (j = 0; j < n_reloads; j++)
	if (i != j && rld[j].in != 0 && rld[j].out == 0
	    && rld[j].when_needed == rld[i].when_needed
	    && MATCHES (rld[i].in, rld[j].in)
	    && rld[i].rclass == rld[j].rclass
	    && !rld[i].nocombine && !rld[j].nocombine
	    && rld[i].reg_rtx == rld[j].reg_rtx)
	  {
	    rld[i].opnum = MIN (rld[i].opnum, rld[j].opnum);
	    transfer_replacements (i, j);
	    rld[j].in = 0;
	  }

  /* If we made any reloads for addresses, see if they violate a
     "no input reloads" requirement for this insn.  But loads that we
     do after the insn (such as for output addresses) are fine.  */
  if (HAVE_cc0 && no_input_reloads)
    for (i = 0; i < n_reloads; i++)
      gcc_assert (rld[i].in == 0
		  || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS
		  || rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS);

  /* Compute reload_mode and reload_nregs.  */
  for (i = 0; i < n_reloads; i++)
    {
      rld[i].mode = rld[i].inmode;
      if (rld[i].mode == VOIDmode
	  || partial_subreg_p (rld[i].mode, rld[i].outmode))
	rld[i].mode = rld[i].outmode;

      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
     destination of a hard reg, if the hard reg is ok, use it.  */
  for (i = 0; i < n_reloads; i++)
    if (rld[i].when_needed == RELOAD_FOR_INPUT
	&& GET_CODE (PATTERN (insn)) == SET
	&& REG_P (SET_DEST (PATTERN (insn)))
	&& (SET_SRC (PATTERN (insn)) == rld[i].in
	    || SET_SRC (PATTERN (insn)) == rld[i].in_reg)
	&& !elimination_target_reg_p (SET_DEST (PATTERN (insn))))
      {
	rtx dest = SET_DEST (PATTERN (insn));
	unsigned int regno = REGNO (dest);

	if (regno < FIRST_PSEUDO_REGISTER
	    && TEST_HARD_REG_BIT (reg_class_contents[rld[i].rclass], regno)
	    && targetm.hard_regno_mode_ok (regno, rld[i].mode))
	  {
	    int nr = hard_regno_nregs (regno, rld[i].mode);
	    int ok = 1, nri;

	    for (nri = 1; nri < nr; nri ++)
	      if (! TEST_HARD_REG_BIT (reg_class_contents[rld[i].rclass], regno + nri))
		{
		  ok = 0;
		  break;
		}

	    if (ok)
	      rld[i].reg_rtx = dest;
	  }
      }

  return retval;
}

/* Return true if alternative number ALTNUM in constraint-string
   CONSTRAINT is guaranteed to accept a reloaded constant-pool reference.
   MEM gives the reference if its address hasn't been fully reloaded,
   otherwise it is NULL.  */

static bool
alternative_allows_const_pool_ref (rtx mem ATTRIBUTE_UNUSED,
				   const char *constraint, int altnum)
{
  int c;

  /* Skip alternatives before the one requested.  */
  while (altnum > 0)
    {
      while (*constraint++ != ',')
	;
      altnum--;
    }
  /* Scan the requested alternative for TARGET_MEM_CONSTRAINT or 'o'.
     If one of them is present, this alternative accepts the result of
     passing a constant-pool reference through find_reloads_toplev.

     The same is true of extra memory constraints if the address
     was reloaded into a register.  However, the target may elect
     to disallow the original constant address, forcing it to be
     reloaded into a register instead.  */
  for (; (c = *constraint) && c != ',' && c != '#';
       constraint += CONSTRAINT_LEN (c, constraint))
    {
      enum constraint_num cn = lookup_constraint (constraint);
      if (insn_extra_memory_constraint (cn)
	  && (mem == NULL || constraint_satisfied_p (mem, cn)))
	return true;
    }
  return false;
}

/* Scan X for memory references and scan the addresses for reloading.
   Also checks for references to "constant" regs that we want to eliminate
   and replaces them with the values they stand for.
   We may alter X destructively if it contains a reference to such.
   If X is just a constant reg, we return the equivalent value
   instead of X.

   IND_LEVELS says how many levels of indirect addressing this machine
   supports.

   OPNUM and TYPE identify the purpose of the reload.

   IS_SET_DEST is true if X is the destination of a SET, which is not
   appropriate to be replaced by a constant.

   INSN, if nonzero, is the insn in which we do the reload.  It is used
   to determine if we may generate output reloads, and where to put USEs
   for pseudos that we have to replace with stack slots.

   ADDRESS_RELOADED.  If nonzero, is a pointer to where we put the
   result of find_reloads_address.  */

static rtx
find_reloads_toplev (rtx x, int opnum, enum reload_type type,
		     int ind_levels, int is_set_dest, rtx_insn *insn,
		     int *address_reloaded)
{
  RTX_CODE code = GET_CODE (x);

  const char *fmt = GET_RTX_FORMAT (code);
  int i;
  int copied;

  if (code == REG)
    {
      /* 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 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);
#endif
      else if (reg_equiv_memory_loc (regno)
	       && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
	{
	  rtx mem = make_memloc (x, 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
		 that delete_output_reload can see it.  */
	      if (replace_reloads && recog_data.operand[opnum] != x)
		/* We mark the USE with QImode so that we recognize it
		   as one that can be safely deleted at the end of
		   reload.  */
		PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, x), insn),
			  QImode);
	      x = mem;
	      i = find_reloads_address (GET_MODE (x), &x, XEXP (x, 0), &XEXP (x, 0),
					opnum, type, ind_levels, insn);
	      if (!rtx_equal_p (x, mem))
		push_reg_equiv_alt_mem (regno, x);
	      if (address_reloaded)
		*address_reloaded = i;
	    }
	}
      return x;
    }
  if (code == MEM)
    {
      rtx tem = x;

      i = find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0),
				opnum, type, ind_levels, insn);
      if (address_reloaded)
	*address_reloaded = i;

      return tem;
    }

  if (code == SUBREG && REG_P (SUBREG_REG (x)))
    {
      /* Check for SUBREG containing a REG that's equivalent to a
	 constant.  If the constant has a known value, truncate it
	 right now.  Similarly if we are extracting a single-word of a
	 multi-word constant.  If the constant is symbolic, allow it
	 to be substituted normally.  push_reload will strip the
	 subreg later.  The constant must not be VOIDmode, because we
	 will lose the mode of the register (this should never happen
	 because one of the cases above should handle it).  */

      int regno = REGNO (SUBREG_REG (x));
      rtx tem;

      if (regno >= FIRST_PSEUDO_REGISTER
	  && reg_renumber[regno] < 0
	  && reg_equiv_constant (regno) != 0)
	{
	  tem =
	    simplify_gen_subreg (GET_MODE (x), reg_equiv_constant (regno),
				 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
	  gcc_assert (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),
					&XEXP (tem, 0), opnum, type,
					ind_levels, insn);
	      if (address_reloaded)
		*address_reloaded = i;
	    }
	  return tem;
	}

      /* If the subreg contains a reg that will be converted to a mem,
	 attempt to convert the whole subreg to a (narrower or wider)
	 memory reference instead.  If this succeeds, we're done --
	 otherwise fall through to check whether the inner reg still
	 needs address reloads anyway.  */

      if (regno >= FIRST_PSEUDO_REGISTER
	  && reg_equiv_memory_loc (regno) != 0)
	{
	  tem = find_reloads_subreg_address (x, opnum, type, ind_levels,
					     insn, address_reloaded);
	  if (tem)
	    return tem;
	}
    }

  for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  rtx new_part = find_reloads_toplev (XEXP (x, i), opnum, type,
					      ind_levels, is_set_dest, insn,
					      address_reloaded);
	  /* If we have replaced a reg with it's equivalent memory loc -
	     that can still be handled here e.g. if it's in a paradoxical
	     subreg - we must make the change in a copy, rather than using
	     a destructive change.  This way, find_reloads can still elect
	     not to do the change.  */
	  if (new_part != XEXP (x, i) && ! CONSTANT_P (new_part) && ! copied)
	    {
	      x = shallow_copy_rtx (x);
	      copied = 1;
	    }
	  XEXP (x, i) = new_part;
	}
    }
  return x;
}

/* Return a mem ref for the memory equivalent of reg REGNO.
   This mem ref is not shared with anything.  */

static rtx
make_memloc (rtx ad, int regno)
{
  /* 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),
	    0);

  /* If TEM might contain a pseudo, we must copy it to avoid
     modifying it when we do the substitution for the reload.  */
  if (rtx_varies_p (tem, 0))
    tem = copy_rtx (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.  */
  if (tem == reg_equiv_memory_loc (regno))
    tem = copy_rtx (tem);
  return tem;
}

/* Returns true if AD could be turned into a valid memory reference
   to mode MODE in address space AS by reloading the part pointed to
   by PART into a register.  */

static int
maybe_memory_address_addr_space_p (machine_mode mode, rtx ad,
				   addr_space_t as, rtx *part)
{
  int retv;
  rtx tem = *part;
  rtx reg = gen_rtx_REG (GET_MODE (tem), max_reg_num ());

  *part = reg;
  retv = memory_address_addr_space_p (mode, ad, as);
  *part = tem;

  return retv;
}

/* Record all reloads needed for handling memory address AD
   which appears in *LOC in a memory reference to mode MODE
   which itself is found in location  *MEMREFLOC.
   Note that we take shortcuts assuming that no multi-reg machine mode
   occurs as part of an address.

   OPNUM and TYPE specify the purpose of this reload.

   IND_LEVELS says how many levels of indirect addressing this machine
   supports.

   INSN, if nonzero, is the insn in which we do the reload.  It is used
   to determine if we may generate output reloads, and where to put USEs
   for pseudos that we have to replace with stack slots.

   Value is one if this address is reloaded or replaced as a whole; it is
   zero if the top level of this address was not reloaded or replaced, and
   it is -1 if it may or may not have been reloaded or replaced.

   Note that there is no verification that the address will be valid after
   this routine does its work.  Instead, we rely on the fact that the address
   was valid when reload started.  So we need only undo things that reload
   could have broken.  These are wrong register types, pseudos not allocated
   to a hard register, and frame pointer elimination.  */

static int
find_reloads_address (machine_mode mode, rtx *memrefloc, rtx ad,
		      rtx *loc, int opnum, enum reload_type type,
		      int ind_levels, rtx_insn *insn)
{
  addr_space_t as = memrefloc? MEM_ADDR_SPACE (*memrefloc)
			     : ADDR_SPACE_GENERIC;
  int regno;
  int removed_and = 0;
  int op_index;
  rtx tem;

  /* If the address is a register, see if it is a legitimate address and
     reload if not.  We first handle the cases where we need not reload
     or where we must reload in a non-standard way.  */

  if (REG_P (ad))
    {
      regno = REGNO (ad);

      if (reg_equiv_constant (regno) != 0)
	{
	  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;
	}

      tem = reg_equiv_memory_loc (regno);
      if (tem != 0)
	{
	  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),
							XEXP (tem, 0),
							MEM_ADDR_SPACE (tem)))
		{
		  rtx orig = tem;

		  find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
					&XEXP (tem, 0), opnum,
					ADDR_TYPE (type), ind_levels, insn);
		  if (!rtx_equal_p (tem, orig))
		    push_reg_equiv_alt_mem (regno, tem);
		}
	      /* We can avoid a reload if the register's equivalent memory
		 expression is valid as an indirect memory address.
		 But not all addresses are valid in a mem used as an indirect
		 address: only reg or reg+constant.  */

	      if (ind_levels > 0
		  && strict_memory_address_addr_space_p (mode, tem, as)
		  && (REG_P (XEXP (tem, 0))
		      || (GET_CODE (XEXP (tem, 0)) == PLUS
			  && REG_P (XEXP (XEXP (tem, 0), 0))
			  && CONSTANT_P (XEXP (XEXP (tem, 0), 1)))))
		{
		  /* TEM is not the same as what we'll be replacing the
		     pseudo with after reload, put a USE in front of INSN
		     in the final reload pass.  */
		  if (replace_reloads
		      && num_not_at_initial_offset
		      && ! rtx_equal_p (tem, reg_equiv_mem (regno)))
		    {
		      *loc = tem;
		      /* We mark the USE with QImode so that we
			 recognize it as one that can be safely
			 deleted at the end of reload.  */
		      PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, ad),
						  insn), QImode);

		      /* This doesn't really count as replacing the address
			 as a whole, since it is still a memory access.  */
		    }
		  return 0;
		}
	      ad = tem;
	    }
	}

      /* The only remaining case where we can avoid a reload is if this is a
	 hard register that is valid as a base register and which is not the
	 subject of a CLOBBER in this insn.  */

      else if (regno < FIRST_PSEUDO_REGISTER
	       && 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.  */
      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;
    }

  if (strict_memory_address_addr_space_p (mode, ad, as))
    {
      /* The address appears valid, so reloads are not needed.
	 But the address may contain an eliminable register.
	 This can happen because a machine with indirect addressing
	 may consider a pseudo register by itself a valid address even when
	 it has failed to get a hard reg.
	 So do a tree-walk to find and eliminate all such regs.  */

      /* But first quickly dispose of a common case.  */
      if (GET_CODE (ad) == PLUS
	  && CONST_INT_P (XEXP (ad, 1))
	  && REG_P (XEXP (ad, 0))
	  && reg_equiv_constant (REGNO (XEXP (ad, 0))) == 0)
	return 0;

      subst_reg_equivs_changed = 0;
      *loc = subst_reg_equivs (ad, insn);

      if (! subst_reg_equivs_changed)
	return 0;

      /* Check result for validity after substitution.  */
      if (strict_memory_address_addr_space_p (mode, ad, as))
	return 0;
    }

#ifdef LEGITIMIZE_RELOAD_ADDRESS
  do
    {
      if (memrefloc && ADDR_SPACE_GENERIC_P (as))
	{
	  LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
				     ind_levels, win);
	}
      break;
    win:
      *memrefloc = copy_rtx (*memrefloc);
      XEXP (*memrefloc, 0) = ad;
      move_replacements (&ad, &XEXP (*memrefloc, 0));
      return -1;
    }
  while (0);
#endif

  /* The address is not valid.  We have to figure out why.  First see if
     we have an outer AND and remove it if so.  Then analyze what's inside.  */

  if (GET_CODE (ad) == AND)
    {
      removed_and = 1;
      loc = &XEXP (ad, 0);
      ad = *loc;
    }

  /* One possibility for why the address is invalid is that it is itself
     a MEM.  This can happen when the frame pointer is being eliminated, a
     pseudo is not allocated to a hard register, and the offset between the
     frame and stack pointers is not its initial value.  In that case the
     pseudo will have been replaced by a MEM referring to the
     stack pointer.  */
  if (MEM_P (ad))
    {
      /* First ensure that the address in this MEM is valid.  Then, unless
	 indirect addresses are valid, reload the MEM into a register.  */
      tem = ad;
      find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0),
			    opnum, ADDR_TYPE (type),
			    ind_levels == 0 ? 0 : ind_levels - 1, insn);

      /* If tem was changed, then we must create a new memory reference to
	 hold it and store it back into memrefloc.  */
      if (tem != ad && memrefloc)
	{
	  *memrefloc = copy_rtx (*memrefloc);
	  copy_replacements (tem, XEXP (*memrefloc, 0));
	  loc = &XEXP (*memrefloc, 0);
	  if (removed_and)
	    loc = &XEXP (*loc, 0);
	}

      /* Check similar cases as for indirect addresses as above except
	 that we can allow pseudos and a MEM since they should have been
	 taken care of above.  */

      if (ind_levels == 0
	  || (GET_CODE (XEXP (tem, 0)) == SYMBOL_REF && ! indirect_symref_ok)
	  || MEM_P (XEXP (tem, 0))
	  || ! (REG_P (XEXP (tem, 0))
		|| (GET_CODE (XEXP (tem, 0)) == PLUS
		    && REG_P (XEXP (XEXP (tem, 0), 0))
		    && CONST_INT_P (XEXP (XEXP (tem, 0), 1)))))
	{
	  /* 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, as, MEM, SCRATCH), GET_MODE (tem),
		       VOIDmode, 0,
		       0, opnum, type);
	  return ! removed_and;
	}
      else
	return 0;
    }

  /* If we have address of a stack slot but it's not valid because the
     displacement is too large, compute the sum in a register.
     Handle all base registers here, not just fp/ap/sp, because on some
     targets (namely SH) we can also get too large displacements from
     big-endian corrections.  */
  else if (GET_CODE (ad) == PLUS
	   && 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, 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.  */
      if (memrefloc)
	{
	  *memrefloc = copy_rtx (*memrefloc);
	  loc = &XEXP (*memrefloc, 0);
	  if (removed_and)
	    loc = &XEXP (*loc, 0);
	}

      if (double_reg_address_ok[mode]
	  && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as,
				  PLUS, CONST_INT))
	{
	  /* Unshare the sum as well.  */
	  *loc = ad = copy_rtx (ad);

	  /* Reload the displacement into an index reg.
	     We assume the frame pointer or arg pointer is a base reg.  */
	  find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
				     INDEX_REG_CLASS, GET_MODE (ad), opnum,
				     type, ind_levels);
	  return 0;
	}
      else
	{
	  /* If the sum of two regs is not necessarily valid,
	     reload the sum into a base reg.
	     That will at least work.  */
	  find_reloads_address_part (ad, loc,
				     base_reg_class (mode, as, MEM, SCRATCH),
				     GET_MODE (ad), opnum, type, ind_levels);
	}
      return ! removed_and;
    }

  /* If we have an indexed stack slot, there are three possible reasons why
     it might be invalid: The index might need to be reloaded, the address
     might have been made by frame pointer elimination and hence have a
     constant out of range, or both reasons might apply.

     We can easily check for an index needing reload, but even if that is the
     case, we might also have an invalid constant.  To avoid making the
     conservative assumption and requiring two reloads, we see if this address
     is valid when not interpreted strictly.  If it is, the only problem is
     that the index needs a reload and find_reloads_address_1 will take care
     of it.

     Handle all base registers here, not just fp/ap/sp, because on some
     targets (namely SPARC) we can also get invalid addresses from preventive
     subreg big-endian corrections made by find_reloads_toplev.  We
     can also get expressions involving LO_SUM (rather than PLUS) from
     find_reloads_subreg_address.

     If we decide to do something, it must be that `double_reg_address_ok'
     is true.  We generate a reload of the base register + constant and
     rework the sum so that the reload register will be added to the index.
     This is safe because we know the address isn't shared.

     We check for the base register as both the first and second operand of
     the innermost PLUS and/or LO_SUM.  */

  for (op_index = 0; op_index < 2; ++op_index)
    {
      rtx operand, addend;
      enum rtx_code inner_code;

      if (GET_CODE (ad) != PLUS)
	  continue;

      inner_code = GET_CODE (XEXP (ad, 0));
      if (!(GET_CODE (ad) == PLUS
	    && CONST_INT_P (XEXP (ad, 1))
	    && (inner_code == PLUS || inner_code == LO_SUM)))
	continue;

      operand = XEXP (XEXP (ad, 0), op_index);
      if (!REG_P (operand) || REGNO (operand) >= FIRST_PSEUDO_REGISTER)
	continue;

      addend = XEXP (XEXP (ad, 0), 1 - op_index);

      if ((regno_ok_for_base_p (REGNO (operand), mode, as, inner_code,
				GET_CODE (addend))
	   || operand == frame_pointer_rtx
	   || (!HARD_FRAME_POINTER_IS_FRAME_POINTER
	       && operand == hard_frame_pointer_rtx)
	   || (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	       && operand == arg_pointer_rtx)
	   || operand == stack_pointer_rtx)
	  && ! maybe_memory_address_addr_space_p
		(mode, ad, as, &XEXP (XEXP (ad, 0), 1 - op_index)))
	{
	  rtx offset_reg;
	  enum reg_class cls;

	  offset_reg = plus_constant (GET_MODE (ad), operand,
				      INTVAL (XEXP (ad, 1)));

	  /* Form the adjusted address.  */
	  if (GET_CODE (XEXP (ad, 0)) == PLUS)
	    ad = gen_rtx_PLUS (GET_MODE (ad),
			       op_index == 0 ? offset_reg : addend,
			       op_index == 0 ? addend : offset_reg);
	  else
	    ad = gen_rtx_LO_SUM (GET_MODE (ad),
				 op_index == 0 ? offset_reg : addend,
				 op_index == 0 ? addend : offset_reg);
	  *loc = ad;

	  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_1 (mode, as,
				  XEXP (ad, 1 - op_index), 1, GET_CODE (ad),
				  GET_CODE (XEXP (ad, op_index)),
				  &XEXP (ad, 1 - op_index), opnum,
				  type, 0, insn);

	  return 0;
	}
    }

  /* See if address becomes valid when an eliminable register
     in a sum is replaced.  */

  tem = ad;
  if (GET_CODE (ad) == PLUS)
    tem = subst_indexed_address (ad);
  if (tem != ad && strict_memory_address_addr_space_p (mode, tem, as))
    {
      /* Ok, we win that way.  Replace any additional eliminable
	 registers.  */

      subst_reg_equivs_changed = 0;
      tem = subst_reg_equivs (tem, insn);

      /* Make sure that didn't make the address invalid again.  */

      if (! subst_reg_equivs_changed
	  || strict_memory_address_addr_space_p (mode, tem, as))
	{
	  *loc = tem;
	  return 0;
	}
    }

  /* If constants aren't valid addresses, reload the constant address
     into a register.  */
  if (CONSTANT_P (ad) && ! strict_memory_address_addr_space_p (mode, ad, as))
    {
      machine_mode address_mode = GET_MODE (ad);
      if (address_mode == VOIDmode)
	address_mode = targetm.addr_space.address_mode (as);

      /* If AD is an address in the constant pool, the MEM rtx may be shared.
	 Unshare it so we can safely alter it.  */
      if (memrefloc && GET_CODE (ad) == SYMBOL_REF
	  && CONSTANT_POOL_ADDRESS_P (ad))
	{
	  *memrefloc = copy_rtx (*memrefloc);
	  loc = &XEXP (*memrefloc, 0);
	  if (removed_and)
	    loc = &XEXP (*loc, 0);
	}

      find_reloads_address_part (ad, loc,
				 base_reg_class (mode, as, MEM, SCRATCH),
				 address_mode, opnum, type, ind_levels);
      return ! removed_and;
    }

  return find_reloads_address_1 (mode, as, ad, 0, MEM, SCRATCH, loc,
				 opnum, type, ind_levels, insn);
}

/* Find all pseudo regs appearing in AD
   that are eliminable in favor of equivalent values
   and do not have hard regs; replace them by their equivalents.
   INSN, if nonzero, is the insn in which we do the reload.  We put USEs in
   front of it for pseudos that we have to replace with stack slots.  */

static rtx
subst_reg_equivs (rtx ad, rtx_insn *insn)
{
  RTX_CODE code = GET_CODE (ad);
  int i;
  const char *fmt;

  switch (code)
    {
    case HIGH:
    case CONST:
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case LABEL_REF:
    case PC:
    case CC0:
      return ad;

    case REG:
      {
	int regno = REGNO (ad);

	if (reg_equiv_constant (regno) != 0)
	  {
	    subst_reg_equivs_changed = 1;
	    return reg_equiv_constant (regno);
	  }
	if (reg_equiv_memory_loc (regno) && num_not_at_initial_offset)
	  {
	    rtx mem = make_memloc (ad, 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
		   as one that can be safely deleted at the end of
		   reload.  */
		PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn),
			  QImode);
		return mem;
	      }
	  }
      }
      return ad;

    case PLUS:
      /* Quickly dispose of a common case.  */
      if (XEXP (ad, 0) == frame_pointer_rtx
	  && CONST_INT_P (XEXP (ad, 1)))
	return ad;
      break;

    default:
      break;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      XEXP (ad, i) = subst_reg_equivs (XEXP (ad, i), insn);
  return ad;
}

/* Compute the sum of X and Y, making canonicalizations assumed in an
   address, namely: sum constant integers, surround the sum of two
   constants with a CONST, put the constant as the second operand, and
   group the constant on the outermost sum.

   This routine assumes both inputs are already in canonical form.  */

rtx
form_sum (machine_mode mode, rtx x, rtx y)
{
  rtx tem;

  gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
  gcc_assert (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode);

  if (CONST_INT_P (x))
    return plus_constant (mode, y, INTVAL (x));
  else if (CONST_INT_P (y))
    return plus_constant (mode, x, INTVAL (y));
  else if (CONSTANT_P (x))
    tem = x, x = y, y = tem;

  if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
    return form_sum (mode, XEXP (x, 0), form_sum (mode, XEXP (x, 1), y));

  /* Note that if the operands of Y are specified in the opposite
     order in the recursive calls below, infinite recursion will occur.  */
  if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
    return form_sum (mode, form_sum (mode, x, XEXP (y, 0)), XEXP (y, 1));

  /* If both constant, encapsulate sum.  Otherwise, just form sum.  A
     constant will have been placed second.  */
  if (CONSTANT_P (x) && CONSTANT_P (y))
    {
      if (GET_CODE (x) == CONST)
	x = XEXP (x, 0);
      if (GET_CODE (y) == CONST)
	y = XEXP (y, 0);

      return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y));
    }

  return gen_rtx_PLUS (mode, x, y);
}

/* If ADDR is a sum containing a pseudo register that should be
   replaced with a constant (from reg_equiv_constant),
   return the result of doing so, and also apply the associative
   law so that the result is more likely to be a valid address.
   (But it is not guaranteed to be one.)

   Note that at most one register is replaced, even if more are
   replaceable.  Also, we try to put the result into a canonical form
   so it is more likely to be a valid address.

   In all other cases, return ADDR.  */

static rtx
subst_indexed_address (rtx addr)
{
  rtx op0 = 0, op1 = 0, op2 = 0;
  rtx tem;
  int regno;

  if (GET_CODE (addr) == PLUS)
    {
      /* Try to find a register to replace.  */
      op0 = XEXP (addr, 0), op1 = XEXP (addr, 1), op2 = 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);
      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);
      else if (GET_CODE (op0) == PLUS
	       && (tem = subst_indexed_address (op0)) != op0)
	op0 = tem;
      else if (GET_CODE (op1) == PLUS
	       && (tem = subst_indexed_address (op1)) != op1)
	op1 = tem;
      else
	return addr;

      /* Pick out up to three things to add.  */
      if (GET_CODE (op1) == PLUS)
	op2 = XEXP (op1, 1), op1 = XEXP (op1, 0);
      else if (GET_CODE (op0) == PLUS)
	op2 = op1, op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);

      /* Compute the sum.  */
      if (op2 != 0)
	op1 = form_sum (GET_MODE (addr), op1, op2);
      if (op1 != 0)
	op0 = form_sum (GET_MODE (addr), op0, op1);

      return op0;
    }
  return addr;
}

/* Update the REG_INC notes for an insn.  It updates all REG_INC
   notes for the instruction which refer to REGNO the to refer
   to the reload number.

   INSN is the insn for which any REG_INC notes need updating.

   REGNO is the register number which has been reloaded.

   RELOADNUM is the reload number.  */

static void
update_auto_inc_notes (rtx_insn *insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
		       int reloadnum ATTRIBUTE_UNUSED)
{
  if (!AUTO_INC_DEC)
    return;

  for (rtx link = REG_NOTES (insn); link; link = XEXP (link, 1))
    if (REG_NOTE_KIND (link) == REG_INC
        && (int) REGNO (XEXP (link, 0)) == regno)
      push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
}

/* Record the pseudo registers we must reload into hard registers in a
   subexpression of a would-be memory address, X referring to a value
   in mode MODE.  (This function is not called if the address we find
   is strictly valid.)

   CONTEXT = 1 means we are considering regs as index regs,
   = 0 means we are considering them as base regs.
   OUTER_CODE is the code of the enclosing RTX, typically a MEM, a PLUS,
   or an autoinc code.
   If CONTEXT == 0 and OUTER_CODE is a PLUS or LO_SUM, then INDEX_CODE
   is the code of the index part of the address.  Otherwise, pass SCRATCH
   for this argument.
   OPNUM and TYPE specify the purpose of any reloads made.

   IND_LEVELS says how many levels of indirect addressing are
   supported at this point in the address.

   INSN, if nonzero, is the insn in which we do the reload.  It is used
   to determine if we may generate output reloads.

   We return nonzero if X, as a whole, is reloaded or replaced.  */

/* Note that we take shortcuts assuming that no multi-reg machine mode
   occurs as part of an address.
   Also, this is not fully machine-customizable; it works for machines
   such as VAXen and 68000's and 32000's, but other possible machines
   could have addressing modes that this does not handle right.
   If you add push_reload calls here, you need to make sure gen_reload
   handles those cases gracefully.  */

static int
find_reloads_address_1 (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 *insn)
{
#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, AS, OUTER, INDEX)	\
  ((CONTEXT) == 0							\
   ? regno_ok_for_base_p (REGNO, MODE, AS, OUTER, INDEX)		\
   : REGNO_OK_FOR_INDEX_P (REGNO))

  enum reg_class context_reg_class;
  RTX_CODE code = GET_CODE (x);
  bool reloaded_inner_of_autoinc = false;

  if (context == 1)
    context_reg_class = INDEX_REG_CLASS;
  else
    context_reg_class = base_reg_class (mode, as, outer_code, index_code);

  switch (code)
    {
    case PLUS:
      {
	rtx orig_op0 = XEXP (x, 0);
	rtx orig_op1 = XEXP (x, 1);
	RTX_CODE code0 = GET_CODE (orig_op0);
	RTX_CODE code1 = GET_CODE (orig_op1);
	rtx op0 = orig_op0;
	rtx op1 = orig_op1;

	if (GET_CODE (op0) == SUBREG)
	  {
	    op0 = SUBREG_REG (op0);
	    code0 = GET_CODE (op0);
	    if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
	      op0 = gen_rtx_REG (word_mode,
				 (REGNO (op0) +
				  subreg_regno_offset (REGNO (SUBREG_REG (orig_op0)),
						       GET_MODE (SUBREG_REG (orig_op0)),
						       SUBREG_BYTE (orig_op0),
						       GET_MODE (orig_op0))));
	  }

	if (GET_CODE (op1) == SUBREG)
	  {
	    op1 = SUBREG_REG (op1);
	    code1 = GET_CODE (op1);
	    if (code1 == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER)
	      /* ??? Why is this given op1's mode and above for
		 ??? op0 SUBREGs we use word_mode?  */
	      op1 = gen_rtx_REG (GET_MODE (op1),
				 (REGNO (op1) +
				  subreg_regno_offset (REGNO (SUBREG_REG (orig_op1)),
						       GET_MODE (SUBREG_REG (orig_op1)),
						       SUBREG_BYTE (orig_op1),
						       GET_MODE (orig_op1))));
	  }
	/* Plus in the index register may be created only as a result of
	   register rematerialization for expression like &localvar*4.  Reload it.
	   It may be possible to combine the displacement on the outer level,
	   but it is probably not worthwhile to do so.  */
	if (context == 1)
	  {
	    find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
				  opnum, ADDR_TYPE (type), ind_levels, insn);
	    push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
			 context_reg_class,
			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
	    return 1;
	  }

	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
	    || code0 == ZERO_EXTEND || code1 == MEM)
	  {
	    find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
				    &XEXP (x, 0), opnum, type, ind_levels,
				    insn);
	    find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0,
				    &XEXP (x, 1), opnum, type, ind_levels,
				    insn);
	  }

	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
		 || code1 == ZERO_EXTEND || code0 == MEM)
	  {
	    find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1,
				    &XEXP (x, 0), opnum, type, ind_levels,
				    insn);
	    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)
	  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)
	  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))
		&& regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG))
	      return 0;
	    else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
		     && regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG))
	      return 0;
	    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)))
	      find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
				      &XEXP (x, 0), opnum, type, ind_levels,
				      insn);
	    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)))
	      find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG,
				      &XEXP (x, 1), opnum, type, ind_levels,
				      insn);
	    else
	      {
		find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
					&XEXP (x, 0), opnum, type, ind_levels,
					insn);
		find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
					&XEXP (x, 1), opnum, type, ind_levels,
					insn);
	      }
	  }

	else if (code0 == REG)
	  {
	    find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
				    &XEXP (x, 0), opnum, type, ind_levels,
				    insn);
	    find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG,
				    &XEXP (x, 1), opnum, type, ind_levels,
				    insn);
	  }

	else if (code1 == REG)
	  {
	    find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH,
				    &XEXP (x, 1), opnum, type, ind_levels,
				    insn);
	    find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG,
				    &XEXP (x, 0), opnum, type, ind_levels,
				    insn);
	  }
      }

      return 0;

    case POST_MODIFY:
    case PRE_MODIFY:
      {
	rtx op0 = XEXP (x, 0);
	rtx op1 = XEXP (x, 1);
	enum rtx_code index_code;
	int regno;
	int reloadnum;

	if (GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)
	  return 0;

	/* Currently, we only support {PRE,POST}_MODIFY constructs
	   where a base register is {inc,dec}remented by the contents
	   of another register or by a constant value.  Thus, these
	   operands must match.  */
	gcc_assert (op0 == XEXP (op1, 0));

	/* Require index register (or constant).  Let's just handle the
	   register case in the meantime... If the target allows
	   auto-modify by a constant then we could try replacing a pseudo
	   register with its equivalent constant where applicable.

	   We also handle the case where the register was eliminated
	   resulting in a PLUS subexpression.

	   If we later decide to reload the whole PRE_MODIFY or
	   POST_MODIFY, inc_for_reload might clobber the reload register
	   before reading the index.  The index register might therefore
	   need to live longer than a TYPE reload normally would, so be
	   conservative and class it as RELOAD_OTHER.  */
	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, as, XEXP (op1, 1), 1, code, SCRATCH,
				  &XEXP (op1, 1), opnum, RELOAD_OTHER,
				  ind_levels, insn);

	gcc_assert (REG_P (XEXP (op1, 0)));

	regno = REGNO (XEXP (op1, 0));
	index_code = GET_CODE (XEXP (op1, 1));

	/* A register that is incremented cannot be constant!  */
	gcc_assert (regno < FIRST_PSEUDO_REGISTER
		    || reg_equiv_constant (regno) == 0);

	/* 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))
	  {
	    rtx tem = make_memloc (XEXP (x, 0), regno);

	    if (reg_equiv_address (regno)
		|| ! rtx_equal_p (tem, reg_equiv_mem (regno)))
	      {
		rtx orig = tem;

		/* First reload the memory location's address.
		    We can't use ADDR_TYPE (type) here, because we need to
		    write back the value after reading it, hence we actually
		    need two registers.  */
		find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
				      &XEXP (tem, 0), opnum,
				      RELOAD_OTHER,
				      ind_levels, insn);

		if (!rtx_equal_p (tem, orig))
		  push_reg_equiv_alt_mem (regno, tem);

		/* Then reload the memory location into a base
		   register.  */
		reloadnum = push_reload (tem, tem, &XEXP (x, 0),
					 &XEXP (op1, 0),
					 base_reg_class (mode, as,
							 code, index_code),
					 GET_MODE (x), GET_MODE (x), 0,
					 0, opnum, RELOAD_OTHER);

		update_auto_inc_notes (this_insn, regno, reloadnum);
		return 0;
	      }
	  }

	if (reg_renumber[regno] >= 0)
	  regno = reg_renumber[regno];

	/* We require a base register here...  */
	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),
				     base_reg_class (mode, as,
						     code, index_code),
				     GET_MODE (x), GET_MODE (x), 0, 0,
				     opnum, RELOAD_OTHER);

	    update_auto_inc_notes (this_insn, regno, reloadnum);
	    return 0;
	  }
      }
      return 0;

    case POST_INC:
    case POST_DEC:
    case PRE_INC:
    case PRE_DEC:
      if (REG_P (XEXP (x, 0)))
	{
	  int regno = REGNO (XEXP (x, 0));
	  int value = 0;
	  rtx x_orig = x;

	  /* A register that is incremented cannot be constant!  */
	  gcc_assert (regno < FIRST_PSEUDO_REGISTER
		      || reg_equiv_constant (regno) == 0);

	  /* 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))
	    {
	      rtx tem = make_memloc (XEXP (x, 0), regno);
	      if (reg_equiv_address (regno)
		  || ! rtx_equal_p (tem, reg_equiv_mem (regno)))
		{
		  rtx orig = tem;

		  /* First reload the memory location's address.
		     We can't use ADDR_TYPE (type) here, because we need to
		     write back the value after reading it, hence we actually
		     need two registers.  */
		  find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
					&XEXP (tem, 0), opnum, type,
					ind_levels, insn);
		  reloaded_inner_of_autoinc = true;
		  if (!rtx_equal_p (tem, orig))
		    push_reg_equiv_alt_mem (regno, tem);
		  /* Put this inside a new increment-expression.  */
		  x = gen_rtx_fmt_e (GET_CODE (x), GET_MODE (x), tem);
		  /* Proceed to reload that, as if it contained a register.  */
		}
	    }

	  /* If we have a hard register that is ok in this incdec context,
	     don't make a reload.  If the register isn't nice enough for
	     autoincdec, we can reload it.  But, if an autoincrement of a
	     register that we here verified as playing nice, still outside
	     isn't "valid", it must be that no autoincrement is "valid".
	     If that is true and something made an autoincrement anyway,
	     this must be a special context where one is allowed.
	     (For example, a "push" instruction.)
	     We can't improve this address, so leave it alone.  */

	  /* Otherwise, reload the autoincrement into a suitable hard reg
	     and record how much to increment by.  */

	  if (reg_renumber[regno] >= 0)
	    regno = reg_renumber[regno];
	  if (regno >= FIRST_PSEUDO_REGISTER
	      || !REG_OK_FOR_CONTEXT (context, regno, mode, as, code,
				      index_code))
	    {
	      int reloadnum;

	      /* If we can output the register afterwards, do so, this
		 saves the extra update.
		 We can do so if we have an INSN - i.e. no JUMP_INSN nor
		 CALL_INSN - and it does not set CC0.
		 But don't do this if we cannot directly address the
		 memory location, since this will make it harder to
		 reuse address reloads, and increases register pressure.
		 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));
	      enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
	      if (insn && NONJUMP_INSN_P (insn)
#if HAVE_cc0
		  && ! sets_cc0_p (PATTERN (insn))
#endif
		  && (regno < FIRST_PSEUDO_REGISTER
		      || (equiv
			  && memory_operand (equiv, GET_MODE (equiv))
			  && ! (icode != CODE_FOR_nothing
				&& insn_operand_matches (icode, 0, equiv)
				&& insn_operand_matches (icode, 1, equiv))))
		  /* Using RELOAD_OTHER means we emit this and the reload we
		     made earlier in the wrong order.  */
		  && !reloaded_inner_of_autoinc)
		{
		  /* We use the original pseudo for loc, so that
		     emit_reload_insns() knows which pseudo this
		     reload refers to and updates the pseudo rtx, not
		     its equivalent memory location, as well as the
		     corresponding entry in reg_last_reload_reg.  */
		  loc = &XEXP (x_orig, 0);
		  x = XEXP (x, 0);
		  reloadnum
		    = push_reload (x, x, loc, loc,
				   context_reg_class,
				   GET_MODE (x), GET_MODE (x), 0, 0,
				   opnum, RELOAD_OTHER);
		}
	      else
		{
		  reloadnum
		    = push_reload (x, x, loc, (rtx*) 0,
				   context_reg_class,
				   GET_MODE (x), GET_MODE (x), 0, 0,
				   opnum, type);
		  rld[reloadnum].inc
		    = find_inc_amount (PATTERN (this_insn), XEXP (x_orig, 0));

		  value = 1;
		}

	      update_auto_inc_notes (this_insn, REGNO (XEXP (x_orig, 0)),
				     reloadnum);
	    }
	  return value;
	}
      return 0;

    case TRUNCATE:
    case SIGN_EXTEND:
    case ZERO_EXTEND:
      /* Look for parts to reload in the inner expression and reload them
	 too, in addition to this operation.  Reloading all inner parts in
	 addition to this one shouldn't be necessary, but at this point,
	 we don't know if we can possibly omit any part that *can* be
	 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)), as, XEXP (x, 0),
			      context, code, SCRATCH, &XEXP (x, 0), opnum,
			      type, ind_levels, insn);
      push_reload (x, NULL_RTX, loc, (rtx*) 0,
		   context_reg_class,
		   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
      return 1;

    case MEM:
      /* This is probably the result of a substitution, by eliminate_regs, of
	 an equivalent address for a pseudo that was not allocated to a hard
	 register.  Verify that the specified address is valid and reload it
	 into a register.

	 Since we know we are going to reload this item, don't decrement for
	 the indirection level.

	 Note that this is actually conservative:  it would be slightly more
	 efficient to use the value of SPILL_INDIRECT_LEVELS from
	 reload1.c here.  */

      find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
			    opnum, ADDR_TYPE (type), ind_levels, insn);
      push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
		   context_reg_class,
		   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
      return 1;

    case REG:
      {
	int regno = REGNO (x);

	if (reg_equiv_constant (regno) != 0)
	  {
	    find_reloads_address_part (reg_equiv_constant (regno), loc,
				       context_reg_class,
				       GET_MODE (x), opnum, type, ind_levels);
	    return 1;
	  }

#if 0 /* This might screw code in reload1.c to delete prior output-reload
	 that feeds this insn.  */
	if (reg_equiv_mem (regno) != 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

	if (reg_equiv_memory_loc (regno)
	    && (reg_equiv_address (regno) != 0 || num_not_at_initial_offset))
	  {
	    rtx tem = make_memloc (x, 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),
				      &XEXP (x, 0), opnum, ADDR_TYPE (type),
				      ind_levels, insn);
		if (!rtx_equal_p (x, tem))
		  push_reg_equiv_alt_mem (regno, x);
	      }
	  }

	if (reg_renumber[regno] >= 0)
	  regno = reg_renumber[regno];

	if (regno >= FIRST_PSEUDO_REGISTER
	    || !REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code,
				    index_code))
	  {
	    push_reload (x, NULL_RTX, loc, (rtx*) 0,
			 context_reg_class,
			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
	    return 1;
	  }

	/* If a register appearing in an address is the subject of a CLOBBER
	   in this insn, reload it into some other register to be safe.
	   The CLOBBER is supposed to make the register unavailable
	   from before this insn to after it.  */
	if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
	  {
	    push_reload (x, NULL_RTX, loc, (rtx*) 0,
			 context_reg_class,
			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
	    return 1;
	  }
      }
      return 0;

    case SUBREG:
      if (REG_P (SUBREG_REG (x)))
	{
	  /* If this is a SUBREG of a hard register and the resulting register
	     is of the wrong class, reload the whole SUBREG.  This avoids
	     needless copies if SUBREG_REG is multi-word.  */
	  if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
	    {
	      int regno ATTRIBUTE_UNUSED = subreg_regno (x);

	      if (!REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code,
				       index_code))
		{
		  push_reload (x, NULL_RTX, loc, (rtx*) 0,
			       context_reg_class,
			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
		  return 1;
		}
	    }
	  /* If this is a SUBREG of a pseudo-register, and the pseudo-register
	     is larger than the class size, then reload the whole SUBREG.  */
	  else
	    {
	      enum reg_class rclass = context_reg_class;
	      if (ira_reg_class_max_nregs [rclass][GET_MODE (SUBREG_REG (x))]
		  > reg_class_size[(int) rclass])
		{
		  /* If the inner register will be replaced by a memory
		     reference, we can do this only if we can replace the
		     whole subreg by a (narrower) memory reference.  If
		     this is not possible, fall through and reload just
		     the inner register (including address reloads).  */
		  if (reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
		    {
		      rtx tem = find_reloads_subreg_address (x, opnum,
							     ADDR_TYPE (type),
							     ind_levels, insn,
							     NULL);
		      if (tem)
			{
			  push_reload (tem, NULL_RTX, loc, (rtx*) 0, rclass,
				       GET_MODE (tem), VOIDmode, 0, 0,
				       opnum, type);
			  return 1;
			}
		    }
		  else
		    {
		      push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
				   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
		      return 1;
		    }
		}
	    }
	}
      break;

    default:
      break;
    }

  {
    const char *fmt = GET_RTX_FORMAT (code);
    int i;

    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
	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, as, XEXP (x, i), context,
				  code, SCRATCH, &XEXP (x, i),
				  opnum, type, ind_levels, insn);
      }
  }

#undef REG_OK_FOR_CONTEXT
  return 0;
}

/* X, which is found at *LOC, is a part of an address that needs to be
   reloaded into a register of class RCLASS.  If X is a constant, or if
   X is a PLUS that contains a constant, check that the constant is a
   legitimate operand and that we are supposed to be able to load
   it into the register.

   If not, force the constant into memory and reload the MEM instead.

   MODE is the mode to use, in case X is an integer constant.

   OPNUM and TYPE describe the purpose of any reloads made.

   IND_LEVELS says how many levels of indirect addressing this machine
   supports.  */

static void
find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
			   machine_mode mode, int opnum,
			   enum reload_type type, int ind_levels)
{
  if (CONSTANT_P (x)
      && (!targetm.legitimate_constant_p (mode, x)
	  || targetm.preferred_reload_class (x, rclass) == NO_REGS))
    {
      x = force_const_mem (mode, x);
      find_reloads_address (mode, &x, XEXP (x, 0), &XEXP (x, 0),
			    opnum, type, ind_levels, 0);
    }

  else if (GET_CODE (x) == PLUS
	   && 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))
    {
      rtx tem;

      tem = force_const_mem (GET_MODE (x), XEXP (x, 1));
      x = gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), tem);
      find_reloads_address (mode, &XEXP (x, 1), XEXP (tem, 0), &XEXP (tem, 0),
			    opnum, type, ind_levels, 0);
    }

  push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
	       mode, VOIDmode, 0, 0, opnum, type);
}

/* X, a subreg of a pseudo, is a part of an address that needs to be
   reloaded, and the pseusdo is equivalent to a memory location.

   Attempt to replace the whole subreg by a (possibly narrower or wider)
   memory reference.  If this is possible, return this new memory
   reference, and push all required address reloads.  Otherwise,
   return NULL.

   OPNUM and TYPE identify the purpose of the reload.

   IND_LEVELS says how many levels of indirect addressing are
   supported at this point in the address.

   INSN, if nonzero, is the insn in which we do the reload.  It is used
   to determine where to put USEs for pseudos that we have to replace with
   stack slots.  */

static rtx
find_reloads_subreg_address (rtx x, int opnum, enum reload_type type,
			     int ind_levels, rtx_insn *insn,
			     int *address_reloaded)
{
  machine_mode outer_mode = GET_MODE (x);
  machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
  int regno = REGNO (SUBREG_REG (x));
  int reloaded = 0;
  rtx tem, orig;
  poly_int64 offset;

  gcc_assert (reg_equiv_memory_loc (regno) != 0);

  /* We cannot replace the subreg with a modified memory reference if:

     - we have a paradoxical subreg that implicitly acts as a zero or
       sign extension operation due to LOAD_EXTEND_OP;

     - we have a subreg that is implicitly supposed to act on the full
       register due to WORD_REGISTER_OPERATIONS (see also eliminate_regs);

     - the address of the equivalent memory location is mode-dependent;  or

     - we have a paradoxical subreg and the resulting memory is not
       sufficiently aligned to allow access in the wider mode.

    In addition, we choose not to perform the replacement for *any*
    paradoxical subreg, even if it were possible in principle.  This
    is to avoid generating wider memory references than necessary.

    This corresponds to how previous versions of reload used to handle
    paradoxical subregs where no address reload was required.  */

  if (paradoxical_subreg_p (x))
    return NULL;

  if (WORD_REGISTER_OPERATIONS
      && partial_subreg_p (outer_mode, inner_mode)
      && known_equal_after_align_down (GET_MODE_SIZE (outer_mode) - 1,
				       GET_MODE_SIZE (inner_mode) - 1,
				       UNITS_PER_WORD))
    return NULL;

  /* Since we don't attempt to handle paradoxical subregs, we can just
     call into simplify_subreg, which will handle all remaining checks
     for us.  */
  orig = make_memloc (SUBREG_REG (x), regno);
  offset = SUBREG_BYTE (x);
  tem = simplify_subreg (outer_mode, orig, inner_mode, offset);
  if (!tem || !MEM_P (tem))
    return NULL;

  /* Now push all required address reloads, if any.  */
  reloaded = find_reloads_address (GET_MODE (tem), &tem,
				   XEXP (tem, 0), &XEXP (tem, 0),
				   opnum, type, ind_levels, insn);
  /* ??? Do we need to handle nonzero offsets somehow?  */
  if (known_eq (offset, 0) && !rtx_equal_p (tem, orig))
    push_reg_equiv_alt_mem (regno, tem);

  /* For some processors an address may be valid in the original mode but
     not in a smaller mode.  For example, ARM accepts a scaled index register
     in SImode but not in HImode.  Note that this is only a problem if the
     address in reg_equiv_mem is already invalid in the new mode; other
     cases would be fixed by find_reloads_address as usual.

     ??? We attempt to handle such cases here by doing an additional reload
     of the full address after the usual processing by find_reloads_address.
     Note that this may not work in the general case, but it seems to cover
     the cases where this situation currently occurs.  A more general fix
     might be to reload the *value* instead of the address, but this would
     not be expected by the callers of this routine as-is.

     If find_reloads_address already completed replaced the address, there
     is nothing further to do.  */
  if (reloaded == 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))))
    {
      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 (replace_reloads && recog_data.operand[opnum] != x)
    /* We mark the USE with QImode so that we recognize it as one that
       can be safely deleted at the end of reload.  */
    PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, SUBREG_REG (x)), insn),
	      QImode);

  if (address_reloaded)
    *address_reloaded = reloaded;

  return tem;
}

/* Substitute into the current INSN the registers into which we have reloaded
   the things that need reloading.  The array `replacements'
   contains the locations of all pointers that must be changed
   and says what to replace them with.

   Return the rtx that X translates into; usually X, but modified.  */

void
subst_reloads (rtx_insn *insn)
{
  int i;

  for (i = 0; i < n_replacements; i++)
    {
      struct replacement *r = &replacements[i];
      rtx reloadreg = rld[r->what].reg_rtx;
      if (reloadreg)
	{
#ifdef DEBUG_RELOAD
	  /* This checking takes a very long time on some platforms
	     causing the gcc.c-torture/compile/limits-fnargs.c test
	     to time out during testing.  See PR 31850.

	     Internal consistency test.  Check that we don't modify
	     anything in the equivalence arrays.  Whenever something from
	     those arrays needs to be reloaded, it must be unshared before
	     being substituted into; the equivalence must not be modified.
	     Otherwise, if the equivalence is used after that, it will
	     have been modified, and the thing substituted (probably a
	     register) is likely overwritten and not a usable equivalence.  */
	  int check_regno;

	  for (check_regno = 0; check_regno < max_regno; check_regno++)
	    {
#define CHECK_MODF(ARRAY)						\
	      gcc_assert (!(*reg_equivs)[check_regno].ARRAY		\
			  || !loc_mentioned_in_p (r->where,		\
						  (*reg_equivs)[check_regno].ARRAY))

	      CHECK_MODF (constant);
	      CHECK_MODF (memory_loc);
	      CHECK_MODF (address);
	      CHECK_MODF (mem);
#undef CHECK_MODF
	    }
#endif /* DEBUG_RELOAD */

	  /* If we're replacing a LABEL_REF with a register, there must
	     already be an indication (to e.g. flow) which label this
	     register refers to.  */
	  gcc_assert (GET_CODE (*r->where) != LABEL_REF
		      || !JUMP_P (insn)
		      || find_reg_note (insn,
					REG_LABEL_OPERAND,
					XEXP (*r->where, 0))
		      || label_is_jump_target_p (XEXP (*r->where, 0), insn));

	  /* Encapsulate RELOADREG so its machine mode matches what
	     used to be there.  Note that gen_lowpart_common will
	     do the wrong thing if RELOADREG is multi-word.  RELOADREG
	     will always be a REG here.  */
	  if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
	    reloadreg = reload_adjust_reg_for_mode (reloadreg, r->mode);

	  *r->where = reloadreg;
	}
      /* If reload got no reg and isn't optional, something's wrong.  */
      else
	gcc_assert (rld[r->what].optional);
    }
}

/* Make a copy of any replacements being done into X and move those
   copies to locations in Y, a copy of X.  */

void
copy_replacements (rtx x, rtx y)
{
  copy_replacements_1 (&x, &y, n_replacements);
}

static void
copy_replacements_1 (rtx *px, rtx *py, int orig_replacements)
{
  int i, j;
  rtx x, y;
  struct replacement *r;
  enum rtx_code code;
  const char *fmt;

  for (j = 0; j < orig_replacements; j++)
    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;
  code = GET_CODE (x);
  fmt = GET_RTX_FORMAT (code);

  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	copy_replacements_1 (&XEXP (x, i), &XEXP (y, i), orig_replacements);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i); --j >= 0; )
	  copy_replacements_1 (&XVECEXP (x, i, j), &XVECEXP (y, i, j),
			       orig_replacements);
    }
}

/* Change any replacements being done to *X to be done to *Y.  */

void
move_replacements (rtx *x, rtx *y)
{
  int i;

  for (i = 0; i < n_replacements; i++)
    if (replacements[i].where == x)
      replacements[i].where = y;
}

/* If LOC was scheduled to be replaced by something, return the replacement.
   Otherwise, return *LOC.  */

rtx
find_replacement (rtx *loc)
{
  struct replacement *r;

  for (r = &replacements[0]; r < &replacements[n_replacements]; r++)
    {
      rtx reloadreg = rld[r->what].reg_rtx;

      if (reloadreg && r->where == loc)
	{
	  if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
	    reloadreg = reload_adjust_reg_for_mode (reloadreg, r->mode);

	  return reloadreg;
	}
      else if (reloadreg && GET_CODE (*loc) == SUBREG
	       && r->where == &SUBREG_REG (*loc))
	{
	  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));
	}
    }

  /* If *LOC is a PLUS, MINUS, or MULT, see if a replacement is scheduled for
     what's inside and make a new rtl if so.  */
  if (GET_CODE (*loc) == PLUS || GET_CODE (*loc) == MINUS
      || GET_CODE (*loc) == MULT)
    {
      rtx x = find_replacement (&XEXP (*loc, 0));
      rtx y = find_replacement (&XEXP (*loc, 1));

      if (x != XEXP (*loc, 0) || y != XEXP (*loc, 1))
	return gen_rtx_fmt_ee (GET_CODE (*loc), GET_MODE (*loc), x, y);
    }

  return *loc;
}

/* Return nonzero if register in range [REGNO, ENDREGNO)
   appears either explicitly or implicitly in X
   other than being stored into (except for earlyclobber operands).

   References contained within the substructure at LOC do not count.
   LOC may be zero, meaning don't ignore anything.

   This is similar to refers_to_regno_p in rtlanal.c except that we
   look at equivalences for pseudos that didn't get hard registers.  */

static int
refers_to_regno_for_reload_p (unsigned int regno, unsigned int endregno,
			      rtx x, rtx *loc)
{
  int i;
  unsigned int r;
  RTX_CODE code;
  const char *fmt;

  if (x == 0)
    return 0;

 repeat:
  code = GET_CODE (x);

  switch (code)
    {
    case REG:
      r = REGNO (x);

      /* If this is a pseudo, a hard register must not have been allocated.
	 X must therefore either be a constant or be in memory.  */
      if (r >= FIRST_PSEUDO_REGISTER)
	{
	  if (reg_equiv_memory_loc (r))
	    return refers_to_regno_for_reload_p (regno, endregno,
						 reg_equiv_memory_loc (r),
						 (rtx*) 0);

	  gcc_assert (reg_equiv_constant (r) || reg_equiv_invariant (r));
	  return 0;
	}

      return endregno > r && regno < END_REGNO (x);

    case SUBREG:
      /* If this is a SUBREG of a hard reg, we can see exactly which
	 registers are being modified.  Otherwise, handle normally.  */
      if (REG_P (SUBREG_REG (x))
	  && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
	{
	  unsigned int inner_regno = subreg_regno (x);
	  unsigned int inner_endregno
	    = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
			     ? subreg_nregs (x) : 1);

	  return endregno > inner_regno && regno < inner_endregno;
	}
      break;

    case CLOBBER:
    case SET:
      if (&SET_DEST (x) != loc
	  /* Note setting a SUBREG counts as referring to the REG it is in for
	     a pseudo but not for hard registers since we can
	     treat each word individually.  */
	  && ((GET_CODE (SET_DEST (x)) == SUBREG
	       && loc != &SUBREG_REG (SET_DEST (x))
	       && REG_P (SUBREG_REG (SET_DEST (x)))
	       && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
	       && refers_to_regno_for_reload_p (regno, endregno,
						SUBREG_REG (SET_DEST (x)),
						loc))
	      /* If the output is an earlyclobber operand, this is
		 a conflict.  */
	      || ((!REG_P (SET_DEST (x))
		   || earlyclobber_operand_p (SET_DEST (x)))
		  && refers_to_regno_for_reload_p (regno, endregno,
						   SET_DEST (x), loc))))
	return 1;

      if (code == CLOBBER || loc == &SET_SRC (x))
	return 0;
      x = SET_SRC (x);
      goto repeat;

    default:
      break;
    }

  /* X does not match, so try its subexpressions.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e' && loc != &XEXP (x, i))
	{
	  if (i == 0)
	    {
	      x = XEXP (x, 0);
	      goto repeat;
	    }
	  else
	    if (refers_to_regno_for_reload_p (regno, endregno,
					      XEXP (x, i), loc))
	      return 1;
	}
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    if (loc != &XVECEXP (x, i, j)
		&& refers_to_regno_for_reload_p (regno, endregno,
						 XVECEXP (x, i, j), loc))
	      return 1;
	}
    }
  return 0;
}

/* Nonzero if modifying X will affect IN.  If X is a register or a SUBREG,
   we check if any register number in X conflicts with the relevant register
   numbers.  If X is a constant, return 0.  If X is a MEM, return 1 iff IN
   contains a MEM (we don't bother checking for memory addresses that can't
   conflict because we expect this to be a rare case.

   This function is similar to reg_overlap_mentioned_p in rtlanal.c except
   that we look at equivalences for pseudos that didn't get hard registers.  */

int
reg_overlap_mentioned_for_reload_p (rtx x, rtx in)
{
  int regno, endregno;

  /* Overly conservative.  */
  if (GET_CODE (x) == STRICT_LOW_PART
      || GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
    x = XEXP (x, 0);

  /* If either argument is a constant, then modifying X cannot affect IN.  */
  if (CONSTANT_P (x) || CONSTANT_P (in))
    return 0;
  else if (GET_CODE (x) == SUBREG && MEM_P (SUBREG_REG (x)))
    return refers_to_mem_for_reload_p (in);
  else if (GET_CODE (x) == SUBREG)
    {
      regno = REGNO (SUBREG_REG (x));
      if (regno < FIRST_PSEUDO_REGISTER)
	regno += subreg_regno_offset (REGNO (SUBREG_REG (x)),
				      GET_MODE (SUBREG_REG (x)),
				      SUBREG_BYTE (x),
				      GET_MODE (x));
      endregno = regno + (regno < FIRST_PSEUDO_REGISTER
			  ? subreg_nregs (x) : 1);

      return refers_to_regno_for_reload_p (regno, endregno, in, (rtx*) 0);
    }
  else if (REG_P (x))
    {
      regno = REGNO (x);

      /* If this is a pseudo, it must not have been assigned a hard register.
	 Therefore, it must either be in memory or be a constant.  */

      if (regno >= FIRST_PSEUDO_REGISTER)
	{
	  if (reg_equiv_memory_loc (regno))
	    return refers_to_mem_for_reload_p (in);
	  gcc_assert (reg_equiv_constant (regno));
	  return 0;
	}

      endregno = END_REGNO (x);

      return refers_to_regno_for_reload_p (regno, endregno, in, (rtx*) 0);
    }
  else if (MEM_P (x))
    return refers_to_mem_for_reload_p (in);
  else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
	   || GET_CODE (x) == CC0)
    return reg_mentioned_p (x, in);
  else
    {
      gcc_assert (GET_CODE (x) == PLUS);

      /* We actually want to know if X is mentioned somewhere inside IN.
	 We must not say that (plus (sp) (const_int 124)) is in
	 (plus (sp) (const_int 64)), since that can lead to incorrect reload
	 allocation when spuriously changing a RELOAD_FOR_OUTPUT_ADDRESS
	 into a RELOAD_OTHER on behalf of another RELOAD_OTHER.  */
      while (MEM_P (in))
	in = XEXP (in, 0);
      if (REG_P (in))
	return 0;
      else if (GET_CODE (in) == PLUS)
	return (rtx_equal_p (x, in)
		|| reg_overlap_mentioned_for_reload_p (x, XEXP (in, 0))
		|| reg_overlap_mentioned_for_reload_p (x, XEXP (in, 1)));
      else return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
		   || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
    }

  gcc_unreachable ();
}

/* Return nonzero if anything in X contains a MEM.  Look also for pseudo
   registers.  */

static int
refers_to_mem_for_reload_p (rtx x)
{
  const char *fmt;
  int i;

  if (MEM_P (x))
    return 1;

  if (REG_P (x))
    return (REGNO (x) >= FIRST_PSEUDO_REGISTER
	    && reg_equiv_memory_loc (REGNO (x)));

  fmt = GET_RTX_FORMAT (GET_CODE (x));
  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
    if (fmt[i] == 'e'
	&& (MEM_P (XEXP (x, i))
	    || refers_to_mem_for_reload_p (XEXP (x, i))))
      return 1;

  return 0;
}

/* Check the insns before INSN to see if there is a suitable register
   containing the same value as GOAL.
   If OTHER is -1, look for a register in class RCLASS.
   Otherwise, just see if register number OTHER shares GOAL's value.

   Return an rtx for the register found, or zero if none is found.

   If RELOAD_REG_P is (short *)1,
   we reject any hard reg that appears in reload_reg_rtx
   because such a hard reg is also needed coming into this insn.

   If RELOAD_REG_P is any other nonzero value,
   it is a vector indexed by hard reg number
   and we reject any hard reg whose element in the vector is nonnegative
   as well as any that appears in reload_reg_rtx.

   If GOAL is zero, then GOALREG is a register number; we look
   for an equivalent for that register.

   MODE is the machine mode of the value we want an equivalence for.
   If GOAL is nonzero and not VOIDmode, then it must have mode MODE.

   This function is used by jump.c as well as in the reload pass.

   If GOAL is the sum of the stack pointer and a constant, we treat it
   as if it were a constant except that sp is required to be unchanging.  */

rtx
find_equiv_reg (rtx goal, rtx_insn *insn, enum reg_class rclass, int other,
		short *reload_reg_p, int goalreg, machine_mode mode)
{
  rtx_insn *p = insn;
  rtx goaltry, valtry, value;
  rtx_insn *where;
  rtx pat;
  int regno = -1;
  int valueno;
  int goal_mem = 0;
  int goal_const = 0;
  int goal_mem_addr_varies = 0;
  int need_stable_sp = 0;
  int nregs;
  int valuenregs;
  int num = 0;

  if (goal == 0)
    regno = goalreg;
  else if (REG_P (goal))
    regno = REGNO (goal);
  else if (MEM_P (goal))
    {
      enum rtx_code code = GET_CODE (XEXP (goal, 0));
      if (MEM_VOLATILE_P (goal))
	return 0;
      if (flag_float_store && SCALAR_FLOAT_MODE_P (GET_MODE (goal)))
	return 0;
      /* An address with side effects must be reexecuted.  */
      switch (code)
	{
	case POST_INC:
	case PRE_INC:
	case POST_DEC:
	case PRE_DEC:
	case POST_MODIFY:
	case PRE_MODIFY:
	  return 0;
	default:
	  break;
	}
      goal_mem = 1;
    }
  else if (CONSTANT_P (goal))
    goal_const = 1;
  else if (GET_CODE (goal) == PLUS
	   && XEXP (goal, 0) == stack_pointer_rtx
	   && CONSTANT_P (XEXP (goal, 1)))
    goal_const = need_stable_sp = 1;
  else if (GET_CODE (goal) == PLUS
	   && XEXP (goal, 0) == frame_pointer_rtx
	   && CONSTANT_P (XEXP (goal, 1)))
    goal_const = 1;
  else
    return 0;

  num = 0;
  /* Scan insns back from INSN, looking for one that copies
     a value into or out of GOAL.
     Stop and give up if we reach a label.  */

  while (1)
    {
      p = PREV_INSN (p);
      if (p && DEBUG_INSN_P (p))
	continue;
      num++;
      if (p == 0 || LABEL_P (p)
	  || 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
		 && reload_reg_p != (short *) HOST_WIDE_INT_1)
	      /* ... then ignore insns introduced by reload; they aren't
		 useful and can cause results in reload_as_needed to be
		 different from what they were when calculating the need for
		 spills.  If we notice an input-reload insn here, we will
		 reject it below, but it might hide a usable equivalent.
		 That makes bad code.  It may even fail: perhaps no reg was
		 spilled for this insn because it was assumed we would find
		 that equivalent.  */
	      || INSN_UID (p) < reload_first_uid))
	{
	  rtx tem;
	  pat = single_set (p);

	  /* First check for something that sets some reg equal to GOAL.  */
	  if (pat != 0
	      && ((regno >= 0
		   && true_regnum (SET_SRC (pat)) == regno
		   && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
		  ||
		  (regno >= 0
		   && true_regnum (SET_DEST (pat)) == regno
		   && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0)
		  ||
		  (goal_const && rtx_equal_p (SET_SRC (pat), goal)
		   /* When looking for stack pointer + const,
		      make sure we don't use a stack adjust.  */
		   && !reg_overlap_mentioned_for_reload_p (SET_DEST (pat), goal)
		   && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
		  || (goal_mem
		      && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0
		      && rtx_renumbered_equal_p (goal, SET_SRC (pat)))
		  || (goal_mem
		      && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0
		      && rtx_renumbered_equal_p (goal, SET_DEST (pat)))
		  /* If we are looking for a constant,
		     and something equivalent to that constant was copied
		     into a reg, we can use that reg.  */
		  || (goal_const && REG_NOTES (p) != 0
		      && (tem = find_reg_note (p, REG_EQUIV, NULL_RTX))
		      && ((rtx_equal_p (XEXP (tem, 0), goal)
			   && (valueno
			       = true_regnum (valtry = SET_DEST (pat))) >= 0)
			  || (REG_P (SET_DEST (pat))
			      && CONST_DOUBLE_AS_FLOAT_P (XEXP (tem, 0))
			      && SCALAR_FLOAT_MODE_P (GET_MODE (XEXP (tem, 0)))
			      && CONST_INT_P (goal)
			      && (goaltry = operand_subword (XEXP (tem, 0), 0,
							     0, VOIDmode)) != 0
			      && rtx_equal_p (goal, goaltry)
			      && (valtry
				  = operand_subword (SET_DEST (pat), 0, 0,
						     VOIDmode))
			      && (valueno = true_regnum (valtry)) >= 0)))
		  || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
							  NULL_RTX))
		      && REG_P (SET_DEST (pat))
		      && CONST_DOUBLE_AS_FLOAT_P (XEXP (tem, 0))
		      && SCALAR_FLOAT_MODE_P (GET_MODE (XEXP (tem, 0)))
		      && CONST_INT_P (goal)
		      && (goaltry = operand_subword (XEXP (tem, 0), 1, 0,
						     VOIDmode)) != 0
		      && rtx_equal_p (goal, goaltry)
		      && (valtry
			  = operand_subword (SET_DEST (pat), 1, 0, VOIDmode))
		      && (valueno = true_regnum (valtry)) >= 0)))
	    {
	      if (other >= 0)
		{
		  if (valueno != other)
		    continue;
		}
	      else if ((unsigned) valueno >= FIRST_PSEUDO_REGISTER)
		continue;
	      else if (!in_hard_reg_set_p (reg_class_contents[(int) rclass],
					  mode, valueno))
		continue;
	      value = valtry;
	      where = p;
	      break;
	    }
	}
    }

  /* We found a previous insn copying GOAL into a suitable other reg VALUE
     (or copying VALUE into GOAL, if GOAL is also a register).
     Now verify that VALUE is really valid.  */

  /* VALUENO is the register number of VALUE; a hard register.  */

  /* Don't try to re-use something that is killed in this insn.  We want
     to be able to trust REG_UNUSED notes.  */
  if (REG_NOTES (where) != 0 && find_reg_note (where, REG_UNUSED, value))
    return 0;

  /* If we propose to get the value from the stack pointer or if GOAL is
     a MEM based on the stack pointer, we need a stable SP.  */
  if (valueno == STACK_POINTER_REGNUM || regno == STACK_POINTER_REGNUM
      || (goal_mem && reg_overlap_mentioned_for_reload_p (stack_pointer_rtx,
							  goal)))
    need_stable_sp = 1;

  /* Reject VALUE if the copy-insn moved the wrong sort of datum.  */
  if (GET_MODE (value) != mode)
    return 0;

  /* Reject VALUE if it was loaded from GOAL
     and is also a register that appears in the address of GOAL.  */

  if (goal_mem && value == SET_DEST (single_set (where))
      && refers_to_regno_for_reload_p (valueno, end_hard_regno (mode, valueno),
				       goal, (rtx*) 0))
    return 0;

  /* Reject registers that overlap GOAL.  */

  if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
    nregs = hard_regno_nregs (regno, mode);
  else
    nregs = 1;
  valuenregs = hard_regno_nregs (valueno, mode);

  if (!goal_mem && !goal_const
      && regno + nregs > valueno && regno < valueno + valuenregs)
    return 0;

  /* Reject VALUE if it is one of the regs reserved for reloads.
     Reload1 knows how to reuse them anyway, and it would get
     confused if we allocated one without its knowledge.
     (Now that insns introduced by reload are ignored above,
     this case shouldn't happen, but I'm not positive.)  */

  if (reload_reg_p != 0 && reload_reg_p != (short *) HOST_WIDE_INT_1)
    {
      int i;
      for (i = 0; i < valuenregs; ++i)
	if (reload_reg_p[valueno + i] >= 0)
	  return 0;
    }

  /* Reject VALUE if it is a register being used for an input reload
     even if it is not one of those reserved.  */

  if (reload_reg_p != 0)
    {
      int i;
      for (i = 0; i < n_reloads; i++)
	if (rld[i].reg_rtx != 0
	    && rld[i].in
	    && (int) REGNO (rld[i].reg_rtx) < valueno + valuenregs
	    && (int) END_REGNO (rld[i].reg_rtx) > valueno)
	  return 0;
    }

  if (goal_mem)
    /* We must treat frame pointer as varying here,
       since it can vary--in a nonlocal goto as generated by expand_goto.  */
    goal_mem_addr_varies = !CONSTANT_ADDRESS_P (XEXP (goal, 0));

  /* Now verify that the values of GOAL and VALUE remain unaltered
     until INSN is reached.  */

  p = insn;
  while (1)
    {
      p = PREV_INSN (p);
      if (p == where)
	return value;

      /* Don't trust the conversion past a function call
	 if either of the two is in a call-clobbered register, or memory.  */
      if (CALL_P (p))
	{
	  int i;

	  if (goal_mem || need_stable_sp)
	    return 0;

	  if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
	    for (i = 0; i < nregs; ++i)
	      if (call_used_regs[regno + i]
		  || targetm.hard_regno_call_part_clobbered (NULL, regno + i,
							     mode))
		return 0;

	  if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER)
	    for (i = 0; i < valuenregs; ++i)
	      if (call_used_regs[valueno + i]
		  || targetm.hard_regno_call_part_clobbered (NULL, valueno + i,
							     mode))
		return 0;
	}

      if (INSN_P (p))
	{
	  pat = PATTERN (p);

	  /* Watch out for unspec_volatile, and volatile asms.  */
	  if (volatile_insn_p (pat))
	    return 0;

	  /* If this insn P stores in either GOAL or VALUE, return 0.
	     If GOAL is a memory ref and this insn writes memory, return 0.
	     If GOAL is a memory ref and its address is not constant,
	     and this insn P changes a register used in GOAL, return 0.  */

	  if (GET_CODE (pat) == COND_EXEC)
	    pat = COND_EXEC_CODE (pat);
	  if (GET_CODE (pat) == SET || GET_CODE (pat) == CLOBBER)
	    {
	      rtx dest = SET_DEST (pat);
	      while (GET_CODE (dest) == SUBREG
		     || GET_CODE (dest) == ZERO_EXTRACT
		     || GET_CODE (dest) == STRICT_LOW_PART)
		dest = XEXP (dest, 0);
	      if (REG_P (dest))
		{
		  int xregno = REGNO (dest);
		  int end_xregno = END_REGNO (dest);
		  if (xregno < regno + nregs && end_xregno > regno)
		    return 0;
		  if (xregno < valueno + valuenregs
		      && end_xregno > valueno)
		    return 0;
		  if (goal_mem_addr_varies
		      && reg_overlap_mentioned_for_reload_p (dest, goal))
		    return 0;
		  if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
		    return 0;
		}
	      else if (goal_mem && MEM_P (dest)
		       && ! push_operand (dest, GET_MODE (dest)))
		return 0;
	      else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
		       && reg_equiv_memory_loc (regno) != 0)
		return 0;
	      else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
		return 0;
	    }
	  else if (GET_CODE (pat) == PARALLEL)
	    {
	      int i;
	      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
		{
		  rtx v1 = XVECEXP (pat, 0, i);
		  if (GET_CODE (v1) == COND_EXEC)
		    v1 = COND_EXEC_CODE (v1);
		  if (GET_CODE (v1) == SET || GET_CODE (v1) == CLOBBER)
		    {
		      rtx dest = SET_DEST (v1);
		      while (GET_CODE (dest) == SUBREG
			     || GET_CODE (dest) == ZERO_EXTRACT
			     || GET_CODE (dest) == STRICT_LOW_PART)
			dest = XEXP (dest, 0);
		      if (REG_P (dest))
			{
			  int xregno = REGNO (dest);
			  int end_xregno = END_REGNO (dest);
			  if (xregno < regno + nregs
			      && end_xregno > regno)
			    return 0;
			  if (xregno < valueno + valuenregs
			      && end_xregno > valueno)
			    return 0;
			  if (goal_mem_addr_varies
			      && reg_overlap_mentioned_for_reload_p (dest,
								     goal))
			    return 0;
			  if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
			    return 0;
			}
		      else if (goal_mem && MEM_P (dest)
			       && ! push_operand (dest, GET_MODE (dest)))
			return 0;
		      else if (MEM_P (dest) && regno >= FIRST_PSEUDO_REGISTER
			       && reg_equiv_memory_loc (regno) != 0)
			return 0;
		      else if (need_stable_sp
			       && push_operand (dest, GET_MODE (dest)))
			return 0;
		    }
		}
	    }

	  if (CALL_P (p) && CALL_INSN_FUNCTION_USAGE (p))
	    {
	      rtx link;

	      for (link = CALL_INSN_FUNCTION_USAGE (p); XEXP (link, 1) != 0;
		   link = XEXP (link, 1))
		{
		  pat = XEXP (link, 0);
		  if (GET_CODE (pat) == CLOBBER)
		    {
		      rtx dest = SET_DEST (pat);

		      if (REG_P (dest))
			{
			  int xregno = REGNO (dest);
			  int end_xregno = END_REGNO (dest);

			  if (xregno < regno + nregs
			      && end_xregno > regno)
			    return 0;
			  else if (xregno < valueno + valuenregs
				   && end_xregno > valueno)
			    return 0;
			  else if (goal_mem_addr_varies
				   && reg_overlap_mentioned_for_reload_p (dest,
								     goal))
			    return 0;
			}

		      else if (goal_mem && MEM_P (dest)
			       && ! push_operand (dest, GET_MODE (dest)))
			return 0;
		      else if (need_stable_sp
			       && push_operand (dest, GET_MODE (dest)))
			return 0;
		    }
		}
	    }

#if AUTO_INC_DEC
	  /* If this insn auto-increments or auto-decrements
	     either regno or valueno, return 0 now.
	     If GOAL is a memory ref and its address is not constant,
	     and this insn P increments a register used in GOAL, return 0.  */
	  {
	    rtx link;

	    for (link = REG_NOTES (p); link; link = XEXP (link, 1))
	      if (REG_NOTE_KIND (link) == REG_INC
		  && REG_P (XEXP (link, 0)))
		{
		  int incno = REGNO (XEXP (link, 0));
		  if (incno < regno + nregs && incno >= regno)
		    return 0;
		  if (incno < valueno + valuenregs && incno >= valueno)
		    return 0;
		  if (goal_mem_addr_varies
		      && reg_overlap_mentioned_for_reload_p (XEXP (link, 0),
							     goal))
		    return 0;
		}
	  }
#endif
	}
    }
}

/* Find a place where INCED appears in an increment or decrement operator
   within X, and return the amount INCED is incremented or decremented by.
   The value is always positive.  */

static poly_int64
find_inc_amount (rtx x, rtx inced)
{
  enum rtx_code code = GET_CODE (x);
  const char *fmt;
  int i;

  if (code == MEM)
    {
      rtx addr = XEXP (x, 0);
      if ((GET_CODE (addr) == PRE_DEC
	   || GET_CODE (addr) == POST_DEC
	   || GET_CODE (addr) == PRE_INC
	   || GET_CODE (addr) == POST_INC)
	  && XEXP (addr, 0) == inced)
	return GET_MODE_SIZE (GET_MODE (x));
      else if ((GET_CODE (addr) == PRE_MODIFY
		|| GET_CODE (addr) == POST_MODIFY)
	       && GET_CODE (XEXP (addr, 1)) == PLUS
	       && XEXP (addr, 0) == XEXP (XEXP (addr, 1), 0)
	       && XEXP (addr, 0) == inced
	       && CONST_INT_P (XEXP (XEXP (addr, 1), 1)))
	{
	  i = INTVAL (XEXP (XEXP (addr, 1), 1));
	  return i < 0 ? -i : i;
	}
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  poly_int64 tem = find_inc_amount (XEXP (x, i), inced);
	  if (maybe_ne (tem, 0))
	    return tem;
	}
      if (fmt[i] == 'E')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    {
	      poly_int64 tem = find_inc_amount (XVECEXP (x, i, j), inced);
	      if (maybe_ne (tem, 0))
		return tem;
	    }
	}
    }

  return 0;
}

/* Return 1 if registers from REGNO to ENDREGNO are the subjects of a
   REG_INC note in insn INSN.  REGNO must refer to a hard register.  */

static int
reg_inc_found_and_valid_p (unsigned int regno, unsigned int endregno,
			   rtx insn)
{
  rtx link;

  if (!AUTO_INC_DEC)
    return 0;

  gcc_assert (insn);

  if (! INSN_P (insn))
    return 0;

  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
    if (REG_NOTE_KIND (link) == REG_INC)
      {
	unsigned int test = (int) REGNO (XEXP (link, 0));
	if (test >= regno && test < endregno)
	  return 1;
      }
  return 0;
}

/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
   If SETS is 1, also consider SETs.  If SETS is 2, enable checking
   REG_INC.  REGNO must refer to a hard register.  */

int
regno_clobbered_p (unsigned int regno, rtx_insn *insn, machine_mode mode,
		   int sets)
{
  /* regno must be a hard register.  */
  gcc_assert (regno < FIRST_PSEUDO_REGISTER);

  unsigned int endregno = end_hard_regno (mode, regno);

  if ((GET_CODE (PATTERN (insn)) == CLOBBER
       || (sets == 1 && GET_CODE (PATTERN (insn)) == SET))
      && REG_P (XEXP (PATTERN (insn), 0)))
    {
      unsigned int test = REGNO (XEXP (PATTERN (insn), 0));

      return test >= regno && test < endregno;
    }

  if (sets == 2 && reg_inc_found_and_valid_p (regno, endregno, insn))
    return 1;

  if (GET_CODE (PATTERN (insn)) == PARALLEL)
    {
      int i = XVECLEN (PATTERN (insn), 0) - 1;

      for (; i >= 0; i--)
	{
	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
	  if ((GET_CODE (elt) == CLOBBER
	       || (sets == 1 && GET_CODE (elt) == SET))
	      && REG_P (XEXP (elt, 0)))
	    {
	      unsigned int test = REGNO (XEXP (elt, 0));

	      if (test >= regno && test < endregno)
		return 1;
	    }
	  if (sets == 2
	      && reg_inc_found_and_valid_p (regno, endregno, elt))
	    return 1;
	}
    }

  return 0;
}

/* Find the low part, with mode MODE, of a hard regno RELOADREG.  */
rtx
reload_adjust_reg_for_mode (rtx reloadreg, machine_mode mode)
{
  int regno;

  if (GET_MODE (reloadreg) == mode)
    return reloadreg;

  regno = REGNO (reloadreg);

  if (REG_WORDS_BIG_ENDIAN)
    regno += ((int) REG_NREGS (reloadreg)
	      - (int) hard_regno_nregs (regno, mode));

  return gen_rtx_REG (mode, regno);
}

static const char *const reload_when_needed_name[] =
{
  "RELOAD_FOR_INPUT",
  "RELOAD_FOR_OUTPUT",
  "RELOAD_FOR_INSN",
  "RELOAD_FOR_INPUT_ADDRESS",
  "RELOAD_FOR_INPADDR_ADDRESS",
  "RELOAD_FOR_OUTPUT_ADDRESS",
  "RELOAD_FOR_OUTADDR_ADDRESS",
  "RELOAD_FOR_OPERAND_ADDRESS",
  "RELOAD_FOR_OPADDR_ADDR",
  "RELOAD_OTHER",
  "RELOAD_FOR_OTHER_ADDRESS"
};

/* These functions are used to print the variables set by 'find_reloads' */

DEBUG_FUNCTION void
debug_reload_to_stream (FILE *f)
{
  int r;
  const char *prefix;

  if (! f)
    f = stderr;
  for (r = 0; r < n_reloads; r++)
    {
      fprintf (f, "Reload %d: ", r);

      if (rld[r].in != 0)
	{
	  fprintf (f, "reload_in (%s) = ",
		   GET_MODE_NAME (rld[r].inmode));
	  print_inline_rtx (f, rld[r].in, 24);
	  fprintf (f, "\n\t");
	}

      if (rld[r].out != 0)
	{
	  fprintf (f, "reload_out (%s) = ",
		   GET_MODE_NAME (rld[r].outmode));
	  print_inline_rtx (f, rld[r].out, 24);
	  fprintf (f, "\n\t");
	}

      fprintf (f, "%s, ", reg_class_names[(int) rld[r].rclass]);

      fprintf (f, "%s (opnum = %d)",
	       reload_when_needed_name[(int) rld[r].when_needed],
	       rld[r].opnum);

      if (rld[r].optional)
	fprintf (f, ", optional");

      if (rld[r].nongroup)
	fprintf (f, ", nongroup");

      if (maybe_ne (rld[r].inc, 0))
	{
	  fprintf (f, ", inc by ");
	  print_dec (rld[r].inc, f, SIGNED);
	}

      if (rld[r].nocombine)
	fprintf (f, ", can't combine");

      if (rld[r].secondary_p)
	fprintf (f, ", secondary_reload_p");

      if (rld[r].in_reg != 0)
	{
	  fprintf (f, "\n\treload_in_reg: ");
	  print_inline_rtx (f, rld[r].in_reg, 24);
	}

      if (rld[r].out_reg != 0)
	{
	  fprintf (f, "\n\treload_out_reg: ");
	  print_inline_rtx (f, rld[r].out_reg, 24);
	}

      if (rld[r].reg_rtx != 0)
	{
	  fprintf (f, "\n\treload_reg_rtx: ");
	  print_inline_rtx (f, rld[r].reg_rtx, 24);
	}

      prefix = "\n\t";
      if (rld[r].secondary_in_reload != -1)
	{
	  fprintf (f, "%ssecondary_in_reload = %d",
		   prefix, rld[r].secondary_in_reload);
	  prefix = ", ";
	}

      if (rld[r].secondary_out_reload != -1)
	fprintf (f, "%ssecondary_out_reload = %d\n",
		 prefix, rld[r].secondary_out_reload);

      prefix = "\n\t";
      if (rld[r].secondary_in_icode != CODE_FOR_nothing)
	{
	  fprintf (f, "%ssecondary_in_icode = %s", prefix,
		   insn_data[rld[r].secondary_in_icode].name);
	  prefix = ", ";
	}

      if (rld[r].secondary_out_icode != CODE_FOR_nothing)
	fprintf (f, "%ssecondary_out_icode = %s", prefix,
		 insn_data[rld[r].secondary_out_icode].name);

      fprintf (f, "\n");
    }
}

DEBUG_FUNCTION void
debug_reload (void)
{
  debug_reload_to_stream (stderr);
}
