/* Search an insn for pseudo regs that must be in hard regs and are not.
   Copyright (C) 1987-2013 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 ENABLE_CHECKING, since it is awfully slow.  */
#undef DEBUG_RELOAD

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl-error.h"
#include "tm_p.h"
#include "insn-config.h"
#include "expr.h"
#include "optabs.h"
#include "recog.h"
#include "df.h"
#include "reload.h"
#include "regs.h"
#include "addresses.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "function.h"
#include "params.h"
#include "target.h"
#include "ira.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 */
  enum 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.  */
  HOST_WIDE_INT start;	/* Starting offset or register number.  */
  HOST_WIDE_INT end;	/* Ending offset or register number.  */
};

#ifdef SECONDARY_MEMORY_NEEDED

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

   We keep two versions, before and after register elimination.  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;
#endif

/* The instruction we are doing reloads for;
   so we can test whether a register dies in it.  */
static rtx 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,
				  enum machine_mode, enum reload_type,
				  enum insn_code *, secondary_reload_info *);
static enum reg_class find_valid_class (enum machine_mode, enum machine_mode,
					int, unsigned int);
static void push_replacement (rtx *, int, enum machine_mode);
static void dup_replacements (rtx *, rtx *);
static void combine_reloads (void);
static int find_reusable_reload (rtx *, rtx, enum reg_class,
				 enum reload_type, int, int);
static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode,
			      enum machine_mode, reg_class_t, int, int);
static int hard_reg_set_here_p (unsigned int, unsigned int, rtx);
static struct decomposition decompose (rtx);
static int immune_p (rtx, rtx, struct decomposition);
static bool alternative_allows_const_pool_ref (rtx, const char *, int);
static rtx find_reloads_toplev (rtx, int, enum reload_type, int, int, rtx,
				int *);
static rtx make_memloc (rtx, int);
static int maybe_memory_address_addr_space_p (enum machine_mode, rtx,
					      addr_space_t, rtx *);
static int find_reloads_address (enum machine_mode, rtx *, rtx, rtx *,
				 int, enum reload_type, int, rtx);
static rtx subst_reg_equivs (rtx, rtx);
static rtx subst_indexed_address (rtx);
static void update_auto_inc_notes (rtx, int, int);
static int find_reloads_address_1 (enum machine_mode, addr_space_t, rtx, int,
				   enum rtx_code, enum rtx_code, rtx *,
				   int, enum reload_type,int, rtx);
static void find_reloads_address_part (rtx, rtx *, enum reg_class,
				       enum machine_mode, int,
				       enum reload_type, int);
static rtx find_reloads_subreg_address (rtx, int, enum reload_type,
					int, rtx, int *);
static void copy_replacements_1 (rtx *, rtx *, int);
static int find_inc_amount (rtx, rtx);
static int refers_to_mem_for_reload_p (rtx);
static 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,
		       enum 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;
  enum 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;
  char letter;
  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++;
      letter = *scratch_constraint;
      scratch_class = (letter == 'r' ? GENERAL_REGS
		       : REG_CLASS_FROM_CONSTRAINT ((unsigned char) letter,
						   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
     can not 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)
    {
#ifdef SECONDARY_MEMORY_NEEDED
      /* 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
	  && SECONDARY_MEMORY_NEEDED (rclass, reload_class, mode))
	{
	  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;
	}
#endif

      /* 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++;

#ifdef SECONDARY_MEMORY_NEEDED
      if (! in_p && icode == CODE_FOR_nothing
	  && SECONDARY_MEMORY_NEEDED (reload_class, rclass, mode))
	get_secondary_mem (x, mode, opnum, type);
#endif
    }

  *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, enum 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;
  char scratch_letter;
  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++;
  scratch_letter = *scratch_constraint;
  if (scratch_letter == 'r')
    return GENERAL_REGS;
  rclass = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
				     scratch_constraint);
  gcc_assert (rclass != NO_REGS);
  return rclass;
}

#ifdef SECONDARY_MEMORY_NEEDED

/* Return a memory location that will be used to copy X in mode MODE.
   If we haven't already made a location for this mode in this insn,
   call find_reloads_address on the location being returned.  */

rtx
get_secondary_mem (rtx x ATTRIBUTE_UNUSED, enum 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).  */

#ifdef SECONDARY_MEMORY_NEEDED_MODE
  mode = SECONDARY_MEMORY_NEEDED_MODE (mode);
#else
  if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode))
    mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0);
#endif

  /* 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);
}
#endif /* SECONDARY_MEMORY_NEEDED */


/* 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 (enum machine_mode outer ATTRIBUTE_UNUSED,
		  enum 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 (HARD_REGNO_MODE_OK (regno, inner))
	      {
		good = 1;
		if (! TEST_HARD_REG_BIT (reg_class_contents[rclass], regno + n)
		    || ! 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 (enum machine_mode outer ATTRIBUTE_UNUSED,
		    enum 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++)
    {
      int bad = 0;
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER && !bad; regno++)
	{
	  if (in_hard_reg_set_p (reg_class_contents[rclass], mode, regno)
	      && !HARD_REGNO_MODE_OK (regno, mode))
	    bad = 1;
	}
      
      if (bad)
	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);

#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 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, enum 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 (!HARD_REGNO_MODE_OK (subreg_regno (x), mode))
    return true;

  /* If this is for an output, and the outer part is a word or smaller,
     INNER is larger than a word and the number of registers in INNER is
     not the same as the number of words in INNER, then INNER will need
     reloading (with an in-out reload).  */
  return (output
	  && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
	  && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD
	  && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD)
	      != (int) hard_regno_nregs[REGNO (inner)][GET_MODE (inner)]));
}

/* 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, enum machine_mode mode)
{
  rtx dst, test_insn;
  int r = 0;
  struct recog_data 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 (VOIDmode, dst, in));
  save_recog_data = recog_data;
  if (recog_memoized (test_insn) >= 0)
    {
      extract_insn (test_insn);
      r = constrain_operands (1);
    }
  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, enum machine_mode inmode,
	     enum 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.  */

  if (in != 0 && GET_CODE (in) == SUBREG
      && (subreg_lowpart_p (in) || strict_low)
#ifdef CANNOT_CHANGE_MODE_CLASS
      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
#endif
      && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (in))]
      && (CONSTANT_P (SUBREG_REG (in))
	  || GET_CODE (SUBREG_REG (in)) == PLUS
	  || strict_low
	  || (((REG_P (SUBREG_REG (in))
		&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
	       || MEM_P (SUBREG_REG (in)))
	      && ((GET_MODE_PRECISION (inmode)
		   > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
#ifdef LOAD_EXTEND_OP
		  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
		      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
			  <= UNITS_PER_WORD)
		      && (GET_MODE_PRECISION (inmode)
			  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
		      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
		      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
#endif
#ifdef WORD_REGISTER_OPERATIONS
		  || ((GET_MODE_PRECISION (inmode)
		       < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
		      && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
			   / UNITS_PER_WORD)))
#endif
		  ))
	  || (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))
	      && ((GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
		   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
		       > UNITS_PER_WORD)
		   && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
			/ UNITS_PER_WORD)
		       != (int) hard_regno_nregs[REGNO (SUBREG_REG (in))]
						[GET_MODE (SUBREG_REG (in))]))
		  || ! HARD_REGNO_MODE_OK (subreg_regno (in), inmode)))
	  || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
	      && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)),
					  SUBREG_REG (in))
		  == NO_REGS))
#ifdef CANNOT_CHANGE_MODE_CLASS
	  || (REG_P (SUBREG_REG (in))
	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
	      && REG_CANNOT_CHANGE_MODE_P
	      (REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)), inmode))
#endif
	  ))
    {
#ifdef LIMIT_RELOAD_CLASS
      in_subreg_loc = inloc;
#endif
      inloc = &SUBREG_REG (in);
      in = *inloc;
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
      if (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 (GET_MODE_SIZE (GET_MODE (in)) <= GET_MODE_SIZE (inmode));
#endif
      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 (GET_CODE (SUBREG_REG (in)) == SYMBOL_REF)
	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)
#ifdef CANNOT_CHANGE_MODE_CLASS
      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, rclass)
#endif
      && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (out))]
      && (CONSTANT_P (SUBREG_REG (out))
	  || strict_low
	  || (((REG_P (SUBREG_REG (out))
		&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
	       || MEM_P (SUBREG_REG (out)))
	      && ((GET_MODE_PRECISION (outmode)
		   > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
#ifdef WORD_REGISTER_OPERATIONS
		  || ((GET_MODE_PRECISION (outmode)
		       < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
		      && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
			   / UNITS_PER_WORD)))
#endif
		  ))
	  || (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.  */
	      && ! (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
		    && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
		        > UNITS_PER_WORD))
	      && ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode))
	  || (secondary_reload_class (0, rclass, outmode, out) != NO_REGS
	      && (secondary_reload_class (0, rclass, GET_MODE (SUBREG_REG (out)),
					  SUBREG_REG (out))
		  == NO_REGS))
#ifdef CANNOT_CHANGE_MODE_CLASS
	  || (REG_P (SUBREG_REG (out))
	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
	      && REG_CANNOT_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
					   GET_MODE (SUBREG_REG (out)),
					   outmode))
#endif
	  ))
    {
#ifdef LIMIT_RELOAD_CLASS
      out_subreg_loc = outloc;
#endif
      outloc = &SUBREG_REG (out);
      out = *outloc;
#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
      gcc_assert (!MEM_P (out)
		  || GET_MODE_SIZE (GET_MODE (out))
		     <= GET_MODE_SIZE (outmode));
#endif
      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)
    {
      enum machine_mode mode;
      if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (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 (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.  */

#ifdef SECONDARY_MEMORY_NEEDED
      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
	  && SECONDARY_MEMORY_NEEDED (subreg_in_class, rclass, inmode))
	get_secondary_mem (in, inmode, opnum, type);
#endif

      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++;

#ifdef SECONDARY_MEMORY_NEEDED
      if (out != 0
          && (REG_P (out)
	      || (GET_CODE (out) == SUBREG && REG_P (SUBREG_REG (out))))
	  && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
	  && SECONDARY_MEMORY_NEEDED (rclass,
				      REGNO_REG_CLASS (reg_or_subregno (out)),
				      outmode))
	get_secondary_mem (out, outmode, opnum, type);
#endif
    }
  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
	  && GET_MODE_SIZE (inmode) > GET_MODE_SIZE (rld[i].inmode))
	rld[i].inmode = inmode;
      if (outmode != VOIDmode
	  && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (rld[i].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
	      || GET_MODE_SIZE (GET_MODE (in))
	           > GET_MODE_SIZE (GET_MODE (rld[i].in)))
	    rld[i].in = in;
	  if (!rld[i].in_reg
	      || (in_reg
		  && GET_MODE_SIZE (GET_MODE (in_reg))
	             > GET_MODE_SIZE (GET_MODE (rld[i].in_reg))))
	    rld[i].in_reg = in_reg;
	}
      if (out != 0)
	{
	  if (!rld[i].out
	      || (out
		  && GET_MODE_SIZE (GET_MODE (out))
	             > GET_MODE_SIZE (GET_MODE (rld[i].out))))
	    rld[i].out = out;
	  if (outloc
	      && (!rld[i].out_reg
		  || GET_MODE_SIZE (GET_MODE (*outloc))
		     > GET_MODE_SIZE (GET_MODE (rld[i].out_reg))))
	    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))
	  && 0 != find_equiv_reg (in, this_insn, NO_REGS, REGNO (out),
				  static_reload_reg_p, i, inmode))
	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;
      enum machine_mode rel_mode = inmode;

      if (out && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (inmode))
	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),
				    ORIGINAL_REGNO (XEXP (note, 0)))
		    && hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] == 1))
	    && ! refers_to_regno_for_reload_p (regno,
					       end_hard_regno (rel_mode,
							       regno),
					       PATTERN (this_insn), inloc)
	    /* 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
		    && (((GET_MODE_SIZE (GET_MODE (in)) + (UNITS_PER_WORD - 1))
			 / UNITS_PER_WORD)
			== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
			     + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
	    /* Make sure the operand fits in the reg that dies.  */
	    && (GET_MODE_SIZE (rel_mode)
		<= GET_MODE_SIZE (GET_MODE (XEXP (note, 0))))
	    && HARD_REGNO_MODE_OK (regno, inmode)
	    && 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, enum 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])
	&& rld[i].inc == 0
	&& rld[i].reg_rtx == 0
#ifdef SECONDARY_MEMORY_NEEDED
	/* 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]))
#endif
	&& (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;
	  }

#ifdef SECONDARY_MEMORY_NEEDED
	/* 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];
#endif
	/* 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
	&& 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]
	    <= hard_regno_nregs[regno][GET_MODE (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),
			       ORIGINAL_REGNO (XEXP (note, 0)))
		&& hard_regno_nregs[regno][GET_MODE (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,
		   enum machine_mode inmode, enum 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 (GET_MODE_SIZE (outmode) != GET_MODE_SIZE (inmode)
      && (GET_MODE_SIZE (outmode) > UNITS_PER_WORD
	  || 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
	  && 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)]
      && 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),
			     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.  */
	      && hard_regno_nregs[REGNO (in)][GET_MODE (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 (enum 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.  */
      if (REG_WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
	  && SCALAR_INT_MODE_P (GET_MODE (x))
	  && i < FIRST_PSEUDO_REGISTER)
	i += hard_regno_nregs[i][GET_MODE (x)] - 1;
      if (REG_WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
	  && SCALAR_INT_MODE_P (GET_MODE (y))
	  && j < FIRST_PSEUDO_REGISTER)
	j += hard_regno_nregs[j][GET_MODE (y)] - 1;

      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 XEXP (x, 0) == XEXP (y, 0);
    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 '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;

  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;
      val.start = true_regnum (x);
      if (val.start < 0 || val.start >= FIRST_PSEUDO_REGISTER)
	{
	  /* A pseudo with no hard reg.  */
	  val.start = REGNO (x);
	  val.end = val.start + 1;
	}
      else
	/* A hard reg.  */
	val.end = end_hard_regno (GET_MODE (x), val.start);
      break;

    case SUBREG:
      if (!REG_P (SUBREG_REG (x)))
	/* This could be more precise, but it's good enough.  */
	return decompose (SUBREG_REG (x));
      val.reg_flag = 1;
      val.start = true_regnum (x);
      if (val.start < 0 || val.start >= FIRST_PSEUDO_REGISTER)
	return decompose (SUBREG_REG (x));
      else
	/* A hard reg.  */
	val.end = val.start + 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)
    return !refers_to_regno_for_reload_p (ydata.start, ydata.end, 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 (xdata.start >= ydata.end || 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, 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;
  enum 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;

#ifdef HAVE_cc0
  if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
    no_input_reloads = 1;
  if (reg_set_p (cc0_rtx, PATTERN (insn)))
    no_output_reloads = 1;
#endif

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

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

  /* 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 (enum 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 (constraints[i][0] == 'p'
	       || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], 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)
	      && (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.  */

  for (this_alternative_number = 0;
       this_alternative_number < n_alternatives;
       this_alternative_number++)
    {
      int swapped;

      if (!recog_data.alternative_enabled_p[this_alternative_number])
	{
	  int i;

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

	  continue;
	}

      /* 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)
	    {
	      enum reg_class tclass;
	      int t;

	      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]];

	      tclass = preferred_class[commutative];
	      preferred_class[commutative] = preferred_class[commutative + 1];
	      preferred_class[commutative + 1] = tclass;

	      t = pref_or_nothing[commutative];
	      pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
	      pref_or_nothing[commutative + 1] = t;

	      t = address_reloaded[commutative];
	      address_reloaded[commutative] = address_reloaded[commutative + 1];
	      address_reloaded[commutative + 1] = t;
	    }

	  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;

	      /* 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.  */
		  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))
#ifndef WORD_REGISTER_OPERATIONS
			  && (((GET_MODE_BITSIZE (GET_MODE (operand))
				< BIGGEST_ALIGNMENT)
			       && (GET_MODE_SIZE (operand_mode[i])
				   > GET_MODE_SIZE (GET_MODE (operand))))
			      || BYTES_BIG_ENDIAN
#ifdef LOAD_EXTEND_OP
			      || (GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
				  && (GET_MODE_SIZE (GET_MODE (operand))
				      <= UNITS_PER_WORD)
				  && (GET_MODE_SIZE (operand_mode[i])
				      > GET_MODE_SIZE (GET_MODE (operand)))
				  && INTEGRAL_MODE_P (GET_MODE (operand))
				  && LOAD_EXTEND_OP (GET_MODE (operand)) != UNKNOWN)
#endif
			      )
#endif
			  )
		      )
		    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 '=':  case '+':  case '*':
		    break;

		  case '%':
		    /* We only support one commutative marker, the first
		       one.  We already set commutative above.  */
		    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;

		  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 'E':
		  case 'F':
		    if (CONST_DOUBLE_AS_FLOAT_P (operand)
			|| (GET_CODE (operand) == CONST_VECTOR
			    && (GET_MODE_CLASS (GET_MODE (operand))
				== MODE_VECTOR_FLOAT)))
		      win = 1;
		    break;

		  case 'G':
		  case 'H':
		    if (CONST_DOUBLE_AS_FLOAT_P (operand)
			&& CONST_DOUBLE_OK_FOR_CONSTRAINT_P (operand, c, p))
		      win = 1;
		    break;

		  case 's':
		    if (CONST_SCALAR_INT_P (operand))
		      break;
		  case 'i':
		    if (CONSTANT_P (operand)
			&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand)))
		      win = 1;
		    break;

		  case 'n':
		    if (CONST_SCALAR_INT_P (operand))
		      win = 1;
		    break;

		  case 'I':
		  case 'J':
		  case 'K':
		  case 'L':
		  case 'M':
		  case 'N':
		  case 'O':
		  case 'P':
		    if (CONST_INT_P (operand)
			&& CONST_OK_FOR_CONSTRAINT_P (INTVAL (operand), c, p))
		      win = 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;
		    /* Drop through into 'r' case.  */

		  case 'r':
		    this_alternative[i]
		      = reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS];
		    goto reg;

		  default:
		    if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
		      {
#ifdef EXTRA_CONSTRAINT_STR
			if (EXTRA_MEMORY_CONSTRAINT (c, p))
			  {
			    if (force_reload)
			      break;
			    if (EXTRA_CONSTRAINT_STR (operand, c, p))
			      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
					  && EXTRA_CONSTRAINT_STR (reg_equiv_mem (REGNO (operand)), c, p))
					 || (reg_equiv_address (REGNO (operand)) != 0)))
			      win = 1;

			    /* If we didn't already win, we can reload
			       constants via force_const_mem, and other
			       MEMs by reloading the address like for 'o'.  */
			    if (CONST_POOL_OK_P (operand_mode[i], operand)
				|| MEM_P (operand))
			      badop = 0;
			    constmemok = 1;
			    offmemok = 1;
			    break;
			  }
			if (EXTRA_ADDRESS_CONSTRAINT (c, p))
			  {
			    if (EXTRA_CONSTRAINT_STR (operand, c, p))
			      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;
			  }

			if (EXTRA_CONSTRAINT_STR (operand, c, p))
			  win = 1;
#endif
			break;
		      }

		    this_alternative[i]
		      = (reg_class_subunion
			 [this_alternative[i]]
			 [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]);
		  reg:
		    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
		  && 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)
	    {
	      enum reg_class tclass;
	      int t;

	      /* 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.  */
	      tclass = preferred_class[commutative];
	      preferred_class[commutative] = preferred_class[commutative + 1];
	      preferred_class[commutative + 1] = tclass;

	      t = pref_or_nothing[commutative];
	      pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
	      pref_or_nothing[commutative + 1] = t;

	      t = address_reloaded[commutative];
	      address_reloaded[commutative] = address_reloaded[commutative + 1];
	      address_reloaded[commutative + 1] = t;
	    }
	}
    }

  /* 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)
    {
      rtx tem;

      tem = substed_operand[commutative];
      substed_operand[commutative] = substed_operand[commutative + 1];
      substed_operand[commutative + 1] = tem;
      tem = recog_data.operand[commutative];
      recog_data.operand[commutative] = recog_data.operand[commutative + 1];
      recog_data.operand[commutative + 1] = tem;
      tem = *recog_data.operand_loc[commutative];
      *recog_data.operand_loc[commutative]
	= *recog_data.operand_loc[commutative + 1];
      *recog_data.operand_loc[commutative + 1] = tem;

      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;
	enum 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 == 0
						      ? 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]);
	    enum 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_FOR_INPUT);
	    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_INPUT_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_INPUT_ADDRESS;
			else if (rld[j].when_needed
				 == RELOAD_FOR_OUTADDR_ADDRESS)
			  rld[j].when_needed = RELOAD_FOR_INPADDR_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,
				 XEXP (substitution, 0))
	      /* 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 (XEXP (substitution, 0),
					      insn)))
	    {
	      add_reg_note (insn, REG_LABEL_OPERAND, XEXP (substitution, 0));
	      if (LABEL_P (XEXP (substitution, 0)))
		++LABEL_NUSES (XEXP (substitution, 0));
	    }

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

  /* 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;
	  }

#ifdef HAVE_cc0
  /* 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 (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);
#endif

  /* Compute reload_mode and reload_nregs.  */
  for (i = 0; i < n_reloads; i++)
    {
      rld[i].mode
	= (rld[i].inmode == VOIDmode
	   || (GET_MODE_SIZE (rld[i].outmode)
	       > GET_MODE_SIZE (rld[i].inmode)))
	  ? rld[i].outmode : rld[i].inmode;

      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)
	    && 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;

	    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 it didn't need any reloads, 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))
    {
      if (c == TARGET_MEM_CONSTRAINT || c == 'o')
	return true;
#ifdef EXTRA_CONSTRAINT_STR
      if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
	  && (mem == NULL || EXTRA_CONSTRAINT_STR (mem, c, constraint)))
	return true;
#endif
    }
  return false;
}

/* 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,
		     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 (enum 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 (enum machine_mode mode, rtx *memrefloc, rtx ad,
		      rtx *loc, int opnum, enum reload_type type,
		      int ind_levels, rtx 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
	  && 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
#if !HARD_FRAME_POINTER_IS_FRAME_POINTER
	   || operand == hard_frame_pointer_rtx
#endif
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	   || operand == arg_pointer_rtx
#endif
	   || 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))
    {
      enum 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)
{
  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 (enum 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 ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
		       int reloadnum ATTRIBUTE_UNUSED)
{
#ifdef AUTO_INC_DEC
  rtx link;

  for (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);
#endif
}

/* 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 (enum machine_mode mode, addr_space_t as,
			rtx x, int context,
			enum rtx_code outer_code, enum rtx_code index_code,
			rtx *loc, int opnum, enum reload_type type,
			int ind_levels, rtx insn)
{
#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);

  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);
		  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) && equiv
		  && memory_operand (equiv, GET_MODE (equiv))
#ifdef HAVE_cc0
		  && ! sets_cc0_p (PATTERN (insn))
#endif
		  && ! (icode != CODE_FOR_nothing
			&& insn_operand_matches (icode, 0, equiv)
			&& insn_operand_matches (icode, 1, equiv)))
		{
		  /* We use the original pseudo for loc, so that
		     emit_reload_insns() knows which pseudo this
		     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,
			   enum 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, int *address_reloaded)
{
  enum machine_mode outer_mode = GET_MODE (x);
  enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
  int regno = REGNO (SUBREG_REG (x));
  int reloaded = 0;
  rtx tem, orig;
  int 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;

#ifdef WORD_REGISTER_OPERATIONS
  if (GET_MODE_SIZE (outer_mode) < GET_MODE_SIZE (inner_mode)
      && ((GET_MODE_SIZE (outer_mode) - 1) / UNITS_PER_WORD
          == (GET_MODE_SIZE (inner_mode) - 1) / UNITS_PER_WORD))
    return NULL;
#endif

  /* 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 (!offset && !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)
{
  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 < r + (r < FIRST_PSEUDO_REGISTER
			      ? hard_regno_nregs[r][GET_MODE (x)]
			      : 1));

    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 can not 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_HARD_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, enum reg_class rclass, int other,
		short *reload_reg_p, int goalreg, enum machine_mode mode)
{
  rtx p = insn;
  rtx goaltry, valtry, value, 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)
			      && 0 != (goaltry
				       = operand_subword (XEXP (tem, 0), 0, 0,
							  VOIDmode))
			      && 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)
		      && 0 != (goaltry = operand_subword (XEXP (tem, 0), 1, 0,
							  VOIDmode))
		      && 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 regno1 = REGNO (rld[i].reg_rtx);
	    int nregs1 = hard_regno_nregs[regno1]
					 [GET_MODE (rld[i].reg_rtx)];
	    if (regno1 < valueno + valuenregs
		&& regno1 + nregs1 > 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]
		  || HARD_REGNO_CALL_PART_CLOBBERED (regno + i, mode))
		return 0;

	  if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER)
	    for (i = 0; i < valuenregs; ++i)
	      if (call_used_regs[valueno + i]
		  || HARD_REGNO_CALL_PART_CLOBBERED (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 xnregs;
		  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
		    xnregs = hard_regno_nregs[xregno][GET_MODE (dest)];
		  else
		    xnregs = 1;
		  if (xregno < regno + nregs && xregno + xnregs > regno)
		    return 0;
		  if (xregno < valueno + valuenregs
		      && xregno + xnregs > 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 xnregs;
			  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
			    xnregs = hard_regno_nregs[xregno][GET_MODE (dest)];
			  else
			    xnregs = 1;
			  if (xregno < regno + nregs
			      && xregno + xnregs > regno)
			    return 0;
			  if (xregno < valueno + valuenregs
			      && xregno + xnregs > 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 xnregs
			    = hard_regno_nregs[xregno][GET_MODE (dest)];

			  if (xregno < regno + nregs
			      && xregno + xnregs > regno)
			    return 0;
			  else if (xregno < valueno + valuenregs
				   && xregno + xnregs > 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;
		    }
		}
	    }

#ifdef 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 int
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')
	{
	  int tem = find_inc_amount (XEXP (x, i), inced);
	  if (tem != 0)
	    return tem;
	}
      if (fmt[i] == 'E')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    {
	      int tem = find_inc_amount (XVECEXP (x, i, j), inced);
	      if (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.  */

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

  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;
}
#else

#define reg_inc_found_and_valid_p(regno,endregno,insn) 0

#endif

/* 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, enum machine_mode mode,
		   int sets)
{
  unsigned int nregs, endregno;

  /* regno must be a hard register.  */
  gcc_assert (regno < FIRST_PSEUDO_REGISTER);

  nregs = hard_regno_nregs[regno][mode];
  endregno = regno + nregs;

  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, enum machine_mode mode)
{
  int regno;

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

  regno = REGNO (reloadreg);

  if (REG_WORDS_BIG_ENDIAN)
    regno += (int) hard_regno_nregs[regno][GET_MODE (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 (rld[r].inc != 0)
	fprintf (f, ", inc by %d", rld[r].inc);

      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);
}
