reload.c revision 102798
118334Speter/* Search an insn for pseudo regs that must be in hard regs and are not.
290285Sobrien   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
390285Sobrien   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
418334Speter
590285SobrienThis file is part of GCC.
618334Speter
790285SobrienGCC is free software; you can redistribute it and/or modify it under
890285Sobrienthe terms of the GNU General Public License as published by the Free
990285SobrienSoftware Foundation; either version 2, or (at your option) any later
1090285Sobrienversion.
1118334Speter
1290285SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390285SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490285SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590285Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890285Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1990285SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2090285Sobrien02111-1307, USA.  */
2118334Speter
2290285Sobrien
2352557Sobrien/* $FreeBSD: head/contrib/gcc/reload.c 102798 2002-09-01 21:08:29Z kan $ */
2418334Speter
2552557Sobrien
2618334Speter/* This file contains subroutines used only from the file reload1.c.
2718334Speter   It knows how to scan one insn for operands and values
2818334Speter   that need to be copied into registers to make valid code.
2918334Speter   It also finds other operands and values which are valid
3018334Speter   but for which equivalent values in registers exist and
3118334Speter   ought to be used instead.
3218334Speter
3318334Speter   Before processing the first insn of the function, call `init_reload'.
3418334Speter
3518334Speter   To scan an insn, call `find_reloads'.  This does two things:
3618334Speter   1. sets up tables describing which values must be reloaded
3718334Speter   for this insn, and what kind of hard regs they must be reloaded into;
3818334Speter   2. optionally record the locations where those values appear in
3918334Speter   the data, so they can be replaced properly later.
4018334Speter   This is done only if the second arg to `find_reloads' is nonzero.
4118334Speter
4218334Speter   The third arg to `find_reloads' specifies the number of levels
4318334Speter   of indirect addressing supported by the machine.  If it is zero,
4418334Speter   indirect addressing is not valid.  If it is one, (MEM (REG n))
4518334Speter   is valid even if (REG n) did not get a hard register; if it is two,
4618334Speter   (MEM (MEM (REG n))) is also valid even if (REG n) did not get a
4718334Speter   hard register, and similarly for higher values.
4818334Speter
4918334Speter   Then you must choose the hard regs to reload those pseudo regs into,
5018334Speter   and generate appropriate load insns before this insn and perhaps
5118334Speter   also store insns after this insn.  Set up the array `reload_reg_rtx'
5218334Speter   to contain the REG rtx's for the registers you used.  In some
5318334Speter   cases `find_reloads' will return a nonzero value in `reload_reg_rtx'
5418334Speter   for certain reloads.  Then that tells you which register to use,
5518334Speter   so you do not need to allocate one.  But you still do need to add extra
5618334Speter   instructions to copy the value into and out of that register.
5718334Speter
5818334Speter   Finally you must call `subst_reloads' to substitute the reload reg rtx's
5918334Speter   into the locations already recorded.
6018334Speter
6118334SpeterNOTE SIDE EFFECTS:
6218334Speter
6318334Speter   find_reloads can alter the operands of the instruction it is called on.
6418334Speter
6518334Speter   1. Two operands of any sort may be interchanged, if they are in a
6618334Speter   commutative instruction.
6718334Speter   This happens only if find_reloads thinks the instruction will compile
6818334Speter   better that way.
6918334Speter
7018334Speter   2. Pseudo-registers that are equivalent to constants are replaced
7118334Speter   with those constants if they are not in hard registers.
7218334Speter
7318334Speter1 happens every time find_reloads is called.
7418334Speter2 happens only when REPLACE is 1, which is only when
7518334Speteractually doing the reloads, not when just counting them.
7618334Speter
7718334SpeterUsing a reload register for several reloads in one insn:
7818334Speter
7918334SpeterWhen an insn has reloads, it is considered as having three parts:
8018334Speterthe input reloads, the insn itself after reloading, and the output reloads.
8118334SpeterReloads of values used in memory addresses are often needed for only one part.
8218334Speter
8318334SpeterWhen this is so, reload_when_needed records which part needs the reload.
8418334SpeterTwo reloads for different parts of the insn can share the same reload
8518334Speterregister.
8618334Speter
8718334SpeterWhen a reload is used for addresses in multiple parts, or when it is
8818334Speteran ordinary operand, it is classified as RELOAD_OTHER, and cannot share
8918334Spetera register with any other reload.  */
9018334Speter
9118334Speter#define REG_OK_STRICT
9218334Speter
9318334Speter#include "config.h"
9450605Sobrien#include "system.h"
9518334Speter#include "rtl.h"
9690285Sobrien#include "tm_p.h"
9718334Speter#include "insn-config.h"
9890285Sobrien#include "expr.h"
9990285Sobrien#include "optabs.h"
10018334Speter#include "recog.h"
10118334Speter#include "reload.h"
10218334Speter#include "regs.h"
10318334Speter#include "hard-reg-set.h"
10418334Speter#include "flags.h"
10518334Speter#include "real.h"
10618334Speter#include "output.h"
10790285Sobrien#include "function.h"
10850605Sobrien#include "toplev.h"
10918334Speter
11018334Speter#ifndef REGISTER_MOVE_COST
11190285Sobrien#define REGISTER_MOVE_COST(m, x, y) 2
11218334Speter#endif
11350605Sobrien
11450605Sobrien#ifndef REGNO_MODE_OK_FOR_BASE_P
11550605Sobrien#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
11650605Sobrien#endif
11750605Sobrien
11850605Sobrien#ifndef REG_MODE_OK_FOR_BASE_P
11950605Sobrien#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
12050605Sobrien#endif
12118334Speter
12290285Sobrien/* All reloads of the current insn are recorded here.  See reload.h for
12390285Sobrien   comments.  */
12418334Speterint n_reloads;
12590285Sobrienstruct reload rld[MAX_RELOADS];
12618334Speter
12718334Speter/* All the "earlyclobber" operands of the current insn
12818334Speter   are recorded here.  */
12918334Speterint n_earlyclobbers;
13018334Speterrtx reload_earlyclobbers[MAX_RECOG_OPERANDS];
13118334Speter
13218334Speterint reload_n_operands;
13318334Speter
13418334Speter/* Replacing reloads.
13518334Speter
13618334Speter   If `replace_reloads' is nonzero, then as each reload is recorded
13718334Speter   an entry is made for it in the table `replacements'.
13818334Speter   Then later `subst_reloads' can look through that table and
13918334Speter   perform all the replacements needed.  */
14018334Speter
14118334Speter/* Nonzero means record the places to replace.  */
14218334Speterstatic int replace_reloads;
14318334Speter
14418334Speter/* Each replacement is recorded with a structure like this.  */
14518334Speterstruct replacement
14618334Speter{
14718334Speter  rtx *where;			/* Location to store in */
14818334Speter  rtx *subreg_loc;		/* Location of SUBREG if WHERE is inside
14918334Speter				   a SUBREG; 0 otherwise.  */
15018334Speter  int what;			/* which reload this is for */
15118334Speter  enum machine_mode mode;	/* mode it must have */
15218334Speter};
15318334Speter
15418334Speterstatic struct replacement replacements[MAX_RECOG_OPERANDS * ((MAX_REGS_PER_ADDRESS * 2) + 1)];
15518334Speter
15618334Speter/* Number of replacements currently recorded.  */
15718334Speterstatic int n_replacements;
15818334Speter
15918334Speter/* Used to track what is modified by an operand.  */
16018334Speterstruct decomposition
16118334Speter{
16250605Sobrien  int reg_flag;		/* Nonzero if referencing a register.  */
16350605Sobrien  int safe;		/* Nonzero if this can't conflict with anything.  */
16450605Sobrien  rtx base;		/* Base address for MEM.  */
16550605Sobrien  HOST_WIDE_INT start;	/* Starting offset or register number.  */
16618334Speter  HOST_WIDE_INT end;	/* Ending offset or register number.  */
16718334Speter};
16818334Speter
16918334Speter#ifdef SECONDARY_MEMORY_NEEDED
17018334Speter
17118334Speter/* Save MEMs needed to copy from one class of registers to another.  One MEM
17290285Sobrien   is used per mode, but normally only one or two modes are ever used.
17318334Speter
17490285Sobrien   We keep two versions, before and after register elimination.  The one
17518334Speter   after register elimination is record separately for each operand.  This
17618334Speter   is done in case the address is not valid to be sure that we separately
17718334Speter   reload each.  */
17818334Speter
17918334Speterstatic rtx secondary_memlocs[NUM_MACHINE_MODES];
18018334Speterstatic rtx secondary_memlocs_elim[NUM_MACHINE_MODES][MAX_RECOG_OPERANDS];
18118334Speter#endif
18218334Speter
18318334Speter/* The instruction we are doing reloads for;
18418334Speter   so we can test whether a register dies in it.  */
18518334Speterstatic rtx this_insn;
18618334Speter
18718334Speter/* Nonzero if this instruction is a user-specified asm with operands.  */
18818334Speterstatic int this_insn_is_asm;
18918334Speter
19018334Speter/* If hard_regs_live_known is nonzero,
19118334Speter   we can tell which hard regs are currently live,
19218334Speter   at least enough to succeed in choosing dummy reloads.  */
19318334Speterstatic int hard_regs_live_known;
19418334Speter
19518334Speter/* Indexed by hard reg number,
19650605Sobrien   element is nonnegative if hard reg has been spilled.
19718334Speter   This vector is passed to `find_reloads' as an argument
19818334Speter   and is not changed here.  */
19918334Speterstatic short *static_reload_reg_p;
20018334Speter
20118334Speter/* Set to 1 in subst_reg_equivs if it changes anything.  */
20218334Speterstatic int subst_reg_equivs_changed;
20318334Speter
20418334Speter/* On return from push_reload, holds the reload-number for the OUT
20518334Speter   operand, which can be different for that from the input operand.  */
20618334Speterstatic int output_reloadnum;
20718334Speter
20818334Speter  /* Compare two RTX's.  */
20918334Speter#define MATCHES(x, y) \
21018334Speter (x == y || (x != 0 && (GET_CODE (x) == REG				\
21118334Speter			? GET_CODE (y) == REG && REGNO (x) == REGNO (y)	\
21218334Speter			: rtx_equal_p (x, y) && ! side_effects_p (x))))
21318334Speter
21418334Speter  /* Indicates if two reloads purposes are for similar enough things that we
21518334Speter     can merge their reloads.  */
21618334Speter#define MERGABLE_RELOADS(when1, when2, op1, op2) \
21718334Speter  ((when1) == RELOAD_OTHER || (when2) == RELOAD_OTHER	\
21818334Speter   || ((when1) == (when2) && (op1) == (op2))		\
21918334Speter   || ((when1) == RELOAD_FOR_INPUT && (when2) == RELOAD_FOR_INPUT) \
22018334Speter   || ((when1) == RELOAD_FOR_OPERAND_ADDRESS		\
22118334Speter       && (when2) == RELOAD_FOR_OPERAND_ADDRESS)	\
22218334Speter   || ((when1) == RELOAD_FOR_OTHER_ADDRESS		\
22318334Speter       && (when2) == RELOAD_FOR_OTHER_ADDRESS))
22418334Speter
22518334Speter  /* Nonzero if these two reload purposes produce RELOAD_OTHER when merged.  */
22618334Speter#define MERGE_TO_OTHER(when1, when2, op1, op2) \
22718334Speter  ((when1) != (when2)					\
22818334Speter   || ! ((op1) == (op2)					\
22918334Speter	 || (when1) == RELOAD_FOR_INPUT			\
23018334Speter	 || (when1) == RELOAD_FOR_OPERAND_ADDRESS	\
23118334Speter	 || (when1) == RELOAD_FOR_OTHER_ADDRESS))
23218334Speter
23350605Sobrien  /* If we are going to reload an address, compute the reload type to
23450605Sobrien     use.  */
23550605Sobrien#define ADDR_TYPE(type)					\
23650605Sobrien  ((type) == RELOAD_FOR_INPUT_ADDRESS			\
23750605Sobrien   ? RELOAD_FOR_INPADDR_ADDRESS				\
23850605Sobrien   : ((type) == RELOAD_FOR_OUTPUT_ADDRESS		\
23950605Sobrien      ? RELOAD_FOR_OUTADDR_ADDRESS			\
24050605Sobrien      : (type)))
24150605Sobrien
24250605Sobrien#ifdef HAVE_SECONDARY_RELOADS
24390285Sobrienstatic int push_secondary_reload PARAMS ((int, rtx, int, int, enum reg_class,
24418334Speter					enum machine_mode, enum reload_type,
24518334Speter					enum insn_code *));
24650605Sobrien#endif
247102798Skanstatic enum reg_class find_valid_class PARAMS ((enum machine_mode, int,
248102798Skan						unsigned int));
24990285Sobrienstatic int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode));
25090285Sobrienstatic void push_replacement	PARAMS ((rtx *, int, enum machine_mode));
25190285Sobrienstatic void combine_reloads	PARAMS ((void));
25290285Sobrienstatic int find_reusable_reload	PARAMS ((rtx *, rtx, enum reg_class,
25352557Sobrien				       enum reload_type, int, int));
25490285Sobrienstatic rtx find_dummy_reload	PARAMS ((rtx, rtx, rtx *, rtx *,
25518334Speter				       enum machine_mode, enum machine_mode,
25650605Sobrien				       enum reg_class, int, int));
25790285Sobrienstatic int hard_reg_set_here_p	PARAMS ((unsigned int, unsigned int, rtx));
25890285Sobrienstatic struct decomposition decompose PARAMS ((rtx));
25990285Sobrienstatic int immune_p		PARAMS ((rtx, rtx, struct decomposition));
26090285Sobrienstatic int alternative_allows_memconst PARAMS ((const char *, int));
26190285Sobrienstatic rtx find_reloads_toplev	PARAMS ((rtx, int, enum reload_type, int,
26290285Sobrien					 int, rtx, int *));
26390285Sobrienstatic rtx make_memloc		PARAMS ((rtx, int));
26490285Sobrienstatic int find_reloads_address	PARAMS ((enum machine_mode, rtx *, rtx, rtx *,
26550605Sobrien				       int, enum reload_type, int, rtx));
26690285Sobrienstatic rtx subst_reg_equivs	PARAMS ((rtx, rtx));
26790285Sobrienstatic rtx subst_indexed_address PARAMS ((rtx));
26890285Sobrienstatic void update_auto_inc_notes PARAMS ((rtx, int, int));
26990285Sobrienstatic int find_reloads_address_1 PARAMS ((enum machine_mode, rtx, int, rtx *,
27050605Sobrien					 int, enum reload_type,int, rtx));
27190285Sobrienstatic void find_reloads_address_part PARAMS ((rtx, rtx *, enum reg_class,
27218334Speter					     enum machine_mode, int,
27318334Speter					     enum reload_type, int));
27496288Sobrienstatic rtx find_reloads_subreg_address PARAMS ((rtx, int, int,
27596288Sobrien						enum reload_type, int, rtx));
27696288Sobrienstatic void copy_replacements_1 PARAMS ((rtx *, rtx *, int));
27790285Sobrienstatic int find_inc_amount	PARAMS ((rtx, rtx));
27818334Speter
27918334Speter#ifdef HAVE_SECONDARY_RELOADS
28018334Speter
28118334Speter/* Determine if any secondary reloads are needed for loading (if IN_P is
28218334Speter   non-zero) or storing (if IN_P is zero) X to or from a reload register of
28318334Speter   register class RELOAD_CLASS in mode RELOAD_MODE.  If secondary reloads
28418334Speter   are needed, push them.
28518334Speter
28618334Speter   Return the reload number of the secondary reload we made, or -1 if
28718334Speter   we didn't need one.  *PICODE is set to the insn_code to use if we do
28818334Speter   need a secondary reload.  */
28918334Speter
29018334Speterstatic int
29118334Speterpush_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
29218334Speter		       type, picode)
29318334Speter     int in_p;
29418334Speter     rtx x;
29518334Speter     int opnum;
29618334Speter     int optional;
29718334Speter     enum reg_class reload_class;
29818334Speter     enum machine_mode reload_mode;
29918334Speter     enum reload_type type;
30018334Speter     enum insn_code *picode;
30118334Speter{
30218334Speter  enum reg_class class = NO_REGS;
30318334Speter  enum machine_mode mode = reload_mode;
30418334Speter  enum insn_code icode = CODE_FOR_nothing;
30518334Speter  enum reg_class t_class = NO_REGS;
30618334Speter  enum machine_mode t_mode = VOIDmode;
30718334Speter  enum insn_code t_icode = CODE_FOR_nothing;
30818334Speter  enum reload_type secondary_type;
30918334Speter  int s_reload, t_reload = -1;
31018334Speter
31150605Sobrien  if (type == RELOAD_FOR_INPUT_ADDRESS
31250605Sobrien      || type == RELOAD_FOR_OUTPUT_ADDRESS
31350605Sobrien      || type == RELOAD_FOR_INPADDR_ADDRESS
31450605Sobrien      || type == RELOAD_FOR_OUTADDR_ADDRESS)
31518334Speter    secondary_type = type;
31618334Speter  else
31718334Speter    secondary_type = in_p ? RELOAD_FOR_INPUT_ADDRESS : RELOAD_FOR_OUTPUT_ADDRESS;
31818334Speter
31918334Speter  *picode = CODE_FOR_nothing;
32018334Speter
32118334Speter  /* If X is a paradoxical SUBREG, use the inner value to determine both the
32218334Speter     mode and object being reloaded.  */
32318334Speter  if (GET_CODE (x) == SUBREG
32418334Speter      && (GET_MODE_SIZE (GET_MODE (x))
32518334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
32618334Speter    {
32718334Speter      x = SUBREG_REG (x);
32818334Speter      reload_mode = GET_MODE (x);
32918334Speter    }
33018334Speter
33118334Speter  /* If X is a pseudo-register that has an equivalent MEM (actually, if it
33218334Speter     is still a pseudo-register by now, it *must* have an equivalent MEM
33318334Speter     but we don't want to assume that), use that equivalent when seeing if
33418334Speter     a secondary reload is needed since whether or not a reload is needed
33518334Speter     might be sensitive to the form of the MEM.  */
33618334Speter
33718334Speter  if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
33818334Speter      && reg_equiv_mem[REGNO (x)] != 0)
33918334Speter    x = reg_equiv_mem[REGNO (x)];
34018334Speter
34118334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
34218334Speter  if (in_p)
34318334Speter    class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
34418334Speter#endif
34518334Speter
34618334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
34718334Speter  if (! in_p)
34818334Speter    class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
34918334Speter#endif
35018334Speter
35118334Speter  /* If we don't need any secondary registers, done.  */
35218334Speter  if (class == NO_REGS)
35318334Speter    return -1;
35418334Speter
35518334Speter  /* Get a possible insn to use.  If the predicate doesn't accept X, don't
35618334Speter     use the insn.  */
35718334Speter
35818334Speter  icode = (in_p ? reload_in_optab[(int) reload_mode]
35918334Speter	   : reload_out_optab[(int) reload_mode]);
36018334Speter
36118334Speter  if (icode != CODE_FOR_nothing
36290285Sobrien      && insn_data[(int) icode].operand[in_p].predicate
36390285Sobrien      && (! (insn_data[(int) icode].operand[in_p].predicate) (x, reload_mode)))
36418334Speter    icode = CODE_FOR_nothing;
36518334Speter
36618334Speter  /* If we will be using an insn, see if it can directly handle the reload
36718334Speter     register we will be using.  If it can, the secondary reload is for a
36818334Speter     scratch register.  If it can't, we will use the secondary reload for
36918334Speter     an intermediate register and require a tertiary reload for the scratch
37018334Speter     register.  */
37118334Speter
37218334Speter  if (icode != CODE_FOR_nothing)
37318334Speter    {
37490285Sobrien      /* If IN_P is non-zero, the reload register will be the output in
37518334Speter	 operand 0.  If IN_P is zero, the reload register will be the input
37618334Speter	 in operand 1.  Outputs should have an initial "=", which we must
37718334Speter	 skip.  */
37818334Speter
37990285Sobrien      enum reg_class insn_class;
38018334Speter
38190285Sobrien      if (insn_data[(int) icode].operand[!in_p].constraint[0] == 0)
38290285Sobrien	insn_class = ALL_REGS;
38390285Sobrien      else
38490285Sobrien	{
38590285Sobrien	  char insn_letter
38690285Sobrien	    = insn_data[(int) icode].operand[!in_p].constraint[in_p];
38790285Sobrien	  insn_class
38890285Sobrien	    = (insn_letter == 'r' ? GENERAL_REGS
38990285Sobrien	       : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
39090285Sobrien
39190285Sobrien          if (insn_class == NO_REGS)
39290285Sobrien	    abort ();
39390285Sobrien	  if (in_p
39490285Sobrien	      && insn_data[(int) icode].operand[!in_p].constraint[0] != '=')
39590285Sobrien	    abort ();
39690285Sobrien	}
39790285Sobrien
39890285Sobrien      /* The scratch register's constraint must start with "=&".  */
39990285Sobrien      if (insn_data[(int) icode].operand[2].constraint[0] != '='
40090285Sobrien	  || insn_data[(int) icode].operand[2].constraint[1] != '&')
40118334Speter	abort ();
40218334Speter
40318334Speter      if (reg_class_subset_p (reload_class, insn_class))
40490285Sobrien	mode = insn_data[(int) icode].operand[2].mode;
40518334Speter      else
40618334Speter	{
40790285Sobrien	  char t_letter = insn_data[(int) icode].operand[2].constraint[2];
40818334Speter	  class = insn_class;
40990285Sobrien	  t_mode = insn_data[(int) icode].operand[2].mode;
41018334Speter	  t_class = (t_letter == 'r' ? GENERAL_REGS
41152557Sobrien		     : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
41218334Speter	  t_icode = icode;
41318334Speter	  icode = CODE_FOR_nothing;
41418334Speter	}
41518334Speter    }
41618334Speter
41718334Speter  /* This case isn't valid, so fail.  Reload is allowed to use the same
41818334Speter     register for RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_INPUT reloads, but
41918334Speter     in the case of a secondary register, we actually need two different
42018334Speter     registers for correct code.  We fail here to prevent the possibility of
42118334Speter     silently generating incorrect code later.
42218334Speter
42318334Speter     The convention is that secondary input reloads are valid only if the
42418334Speter     secondary_class is different from class.  If you have such a case, you
42518334Speter     can not use secondary reloads, you must work around the problem some
42618334Speter     other way.
42718334Speter
42890285Sobrien     Allow this when a reload_in/out pattern is being used.  I.e. assume
42990285Sobrien     that the generated code handles this case.  */
43018334Speter
43190285Sobrien  if (in_p && class == reload_class && icode == CODE_FOR_nothing
43290285Sobrien      && t_icode == CODE_FOR_nothing)
43318334Speter    abort ();
43418334Speter
43518334Speter  /* If we need a tertiary reload, see if we have one we can reuse or else
43618334Speter     make a new one.  */
43718334Speter
43818334Speter  if (t_class != NO_REGS)
43918334Speter    {
44018334Speter      for (t_reload = 0; t_reload < n_reloads; t_reload++)
44190285Sobrien	if (rld[t_reload].secondary_p
44290285Sobrien	    && (reg_class_subset_p (t_class, rld[t_reload].class)
44390285Sobrien		|| reg_class_subset_p (rld[t_reload].class, t_class))
44490285Sobrien	    && ((in_p && rld[t_reload].inmode == t_mode)
44590285Sobrien		|| (! in_p && rld[t_reload].outmode == t_mode))
44690285Sobrien	    && ((in_p && (rld[t_reload].secondary_in_icode
44718334Speter			  == CODE_FOR_nothing))
44890285Sobrien		|| (! in_p &&(rld[t_reload].secondary_out_icode
44918334Speter			      == CODE_FOR_nothing)))
45050605Sobrien	    && (reg_class_size[(int) t_class] == 1 || SMALL_REGISTER_CLASSES)
45118334Speter	    && MERGABLE_RELOADS (secondary_type,
45290285Sobrien				 rld[t_reload].when_needed,
45390285Sobrien				 opnum, rld[t_reload].opnum))
45418334Speter	  {
45518334Speter	    if (in_p)
45690285Sobrien	      rld[t_reload].inmode = t_mode;
45718334Speter	    if (! in_p)
45890285Sobrien	      rld[t_reload].outmode = t_mode;
45918334Speter
46090285Sobrien	    if (reg_class_subset_p (t_class, rld[t_reload].class))
46190285Sobrien	      rld[t_reload].class = t_class;
46218334Speter
46390285Sobrien	    rld[t_reload].opnum = MIN (rld[t_reload].opnum, opnum);
46490285Sobrien	    rld[t_reload].optional &= optional;
46590285Sobrien	    rld[t_reload].secondary_p = 1;
46690285Sobrien	    if (MERGE_TO_OTHER (secondary_type, rld[t_reload].when_needed,
46790285Sobrien				opnum, rld[t_reload].opnum))
46890285Sobrien	      rld[t_reload].when_needed = RELOAD_OTHER;
46918334Speter	  }
47018334Speter
47118334Speter      if (t_reload == n_reloads)
47218334Speter	{
47318334Speter	  /* We need to make a new tertiary reload for this register class.  */
47490285Sobrien	  rld[t_reload].in = rld[t_reload].out = 0;
47590285Sobrien	  rld[t_reload].class = t_class;
47690285Sobrien	  rld[t_reload].inmode = in_p ? t_mode : VOIDmode;
47790285Sobrien	  rld[t_reload].outmode = ! in_p ? t_mode : VOIDmode;
47890285Sobrien	  rld[t_reload].reg_rtx = 0;
47990285Sobrien	  rld[t_reload].optional = optional;
48090285Sobrien	  rld[t_reload].inc = 0;
48118334Speter	  /* Maybe we could combine these, but it seems too tricky.  */
48290285Sobrien	  rld[t_reload].nocombine = 1;
48390285Sobrien	  rld[t_reload].in_reg = 0;
48490285Sobrien	  rld[t_reload].out_reg = 0;
48590285Sobrien	  rld[t_reload].opnum = opnum;
48690285Sobrien	  rld[t_reload].when_needed = secondary_type;
48790285Sobrien	  rld[t_reload].secondary_in_reload = -1;
48890285Sobrien	  rld[t_reload].secondary_out_reload = -1;
48990285Sobrien	  rld[t_reload].secondary_in_icode = CODE_FOR_nothing;
49090285Sobrien	  rld[t_reload].secondary_out_icode = CODE_FOR_nothing;
49190285Sobrien	  rld[t_reload].secondary_p = 1;
49218334Speter
49318334Speter	  n_reloads++;
49418334Speter	}
49518334Speter    }
49618334Speter
49718334Speter  /* See if we can reuse an existing secondary reload.  */
49818334Speter  for (s_reload = 0; s_reload < n_reloads; s_reload++)
49990285Sobrien    if (rld[s_reload].secondary_p
50090285Sobrien	&& (reg_class_subset_p (class, rld[s_reload].class)
50190285Sobrien	    || reg_class_subset_p (rld[s_reload].class, class))
50290285Sobrien	&& ((in_p && rld[s_reload].inmode == mode)
50390285Sobrien	    || (! in_p && rld[s_reload].outmode == mode))
50490285Sobrien	&& ((in_p && rld[s_reload].secondary_in_reload == t_reload)
50590285Sobrien	    || (! in_p && rld[s_reload].secondary_out_reload == t_reload))
50690285Sobrien	&& ((in_p && rld[s_reload].secondary_in_icode == t_icode)
50790285Sobrien	    || (! in_p && rld[s_reload].secondary_out_icode == t_icode))
50850605Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
50990285Sobrien	&& MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
51090285Sobrien			     opnum, rld[s_reload].opnum))
51118334Speter      {
51218334Speter	if (in_p)
51390285Sobrien	  rld[s_reload].inmode = mode;
51418334Speter	if (! in_p)
51590285Sobrien	  rld[s_reload].outmode = mode;
51618334Speter
51790285Sobrien	if (reg_class_subset_p (class, rld[s_reload].class))
51890285Sobrien	  rld[s_reload].class = class;
51918334Speter
52090285Sobrien	rld[s_reload].opnum = MIN (rld[s_reload].opnum, opnum);
52190285Sobrien	rld[s_reload].optional &= optional;
52290285Sobrien	rld[s_reload].secondary_p = 1;
52390285Sobrien	if (MERGE_TO_OTHER (secondary_type, rld[s_reload].when_needed,
52490285Sobrien			    opnum, rld[s_reload].opnum))
52590285Sobrien	  rld[s_reload].when_needed = RELOAD_OTHER;
52618334Speter      }
52718334Speter
52818334Speter  if (s_reload == n_reloads)
52918334Speter    {
53050605Sobrien#ifdef SECONDARY_MEMORY_NEEDED
53150605Sobrien      /* If we need a memory location to copy between the two reload regs,
53250605Sobrien	 set it up now.  Note that we do the input case before making
53390285Sobrien	 the reload and the output case after.  This is due to the
53450605Sobrien	 way reloads are output.  */
53550605Sobrien
53650605Sobrien      if (in_p && icode == CODE_FOR_nothing
53750605Sobrien	  && SECONDARY_MEMORY_NEEDED (class, reload_class, mode))
53870639Sobrien	{
53970639Sobrien	  get_secondary_mem (x, reload_mode, opnum, type);
54070639Sobrien
54170639Sobrien	  /* We may have just added new reloads.  Make sure we add
54270639Sobrien	     the new reload at the end.  */
54370639Sobrien	  s_reload = n_reloads;
54470639Sobrien	}
54550605Sobrien#endif
54650605Sobrien
54718334Speter      /* We need to make a new secondary reload for this register class.  */
54890285Sobrien      rld[s_reload].in = rld[s_reload].out = 0;
54990285Sobrien      rld[s_reload].class = class;
55018334Speter
55190285Sobrien      rld[s_reload].inmode = in_p ? mode : VOIDmode;
55290285Sobrien      rld[s_reload].outmode = ! in_p ? mode : VOIDmode;
55390285Sobrien      rld[s_reload].reg_rtx = 0;
55490285Sobrien      rld[s_reload].optional = optional;
55590285Sobrien      rld[s_reload].inc = 0;
55618334Speter      /* Maybe we could combine these, but it seems too tricky.  */
55790285Sobrien      rld[s_reload].nocombine = 1;
55890285Sobrien      rld[s_reload].in_reg = 0;
55990285Sobrien      rld[s_reload].out_reg = 0;
56090285Sobrien      rld[s_reload].opnum = opnum;
56190285Sobrien      rld[s_reload].when_needed = secondary_type;
56290285Sobrien      rld[s_reload].secondary_in_reload = in_p ? t_reload : -1;
56390285Sobrien      rld[s_reload].secondary_out_reload = ! in_p ? t_reload : -1;
56490285Sobrien      rld[s_reload].secondary_in_icode = in_p ? t_icode : CODE_FOR_nothing;
56590285Sobrien      rld[s_reload].secondary_out_icode
56618334Speter	= ! in_p ? t_icode : CODE_FOR_nothing;
56790285Sobrien      rld[s_reload].secondary_p = 1;
56818334Speter
56918334Speter      n_reloads++;
57018334Speter
57118334Speter#ifdef SECONDARY_MEMORY_NEEDED
57218334Speter      if (! in_p && icode == CODE_FOR_nothing
57350605Sobrien	  && SECONDARY_MEMORY_NEEDED (reload_class, class, mode))
57450605Sobrien	get_secondary_mem (x, mode, opnum, type);
57518334Speter#endif
57618334Speter    }
57718334Speter
57818334Speter  *picode = icode;
57918334Speter  return s_reload;
58018334Speter}
58118334Speter#endif /* HAVE_SECONDARY_RELOADS */
58218334Speter
58318334Speter#ifdef SECONDARY_MEMORY_NEEDED
58418334Speter
58590285Sobrien/* Return a memory location that will be used to copy X in mode MODE.
58618334Speter   If we haven't already made a location for this mode in this insn,
58718334Speter   call find_reloads_address on the location being returned.  */
58818334Speter
58918334Speterrtx
59018334Speterget_secondary_mem (x, mode, opnum, type)
59190285Sobrien     rtx x ATTRIBUTE_UNUSED;
59218334Speter     enum machine_mode mode;
59318334Speter     int opnum;
59418334Speter     enum reload_type type;
59518334Speter{
59618334Speter  rtx loc;
59718334Speter  int mem_valid;
59818334Speter
59918334Speter  /* By default, if MODE is narrower than a word, widen it to a word.
60018334Speter     This is required because most machines that require these memory
60118334Speter     locations do not support short load and stores from all registers
60218334Speter     (e.g., FP registers).  */
60318334Speter
60418334Speter#ifdef SECONDARY_MEMORY_NEEDED_MODE
60518334Speter  mode = SECONDARY_MEMORY_NEEDED_MODE (mode);
60618334Speter#else
60790285Sobrien  if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode))
60818334Speter    mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0);
60918334Speter#endif
61018334Speter
61118334Speter  /* If we already have made a MEM for this operand in MODE, return it.  */
61218334Speter  if (secondary_memlocs_elim[(int) mode][opnum] != 0)
61318334Speter    return secondary_memlocs_elim[(int) mode][opnum];
61418334Speter
61590285Sobrien  /* If this is the first time we've tried to get a MEM for this mode,
61618334Speter     allocate a new one.  `something_changed' in reload will get set
61718334Speter     by noticing that the frame size has changed.  */
61818334Speter
61918334Speter  if (secondary_memlocs[(int) mode] == 0)
62018334Speter    {
62118334Speter#ifdef SECONDARY_MEMORY_NEEDED_RTX
62218334Speter      secondary_memlocs[(int) mode] = SECONDARY_MEMORY_NEEDED_RTX (mode);
62318334Speter#else
62418334Speter      secondary_memlocs[(int) mode]
62518334Speter	= assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
62618334Speter#endif
62718334Speter    }
62818334Speter
62918334Speter  /* Get a version of the address doing any eliminations needed.  If that
63018334Speter     didn't give us a new MEM, make a new one if it isn't valid.  */
63118334Speter
63218334Speter  loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX);
63318334Speter  mem_valid = strict_memory_address_p (mode, XEXP (loc, 0));
63418334Speter
63518334Speter  if (! mem_valid && loc == secondary_memlocs[(int) mode])
63618334Speter    loc = copy_rtx (loc);
63718334Speter
63818334Speter  /* The only time the call below will do anything is if the stack
63918334Speter     offset is too large.  In that case IND_LEVELS doesn't matter, so we
64018334Speter     can just pass a zero.  Adjust the type to be the address of the
64118334Speter     corresponding object.  If the address was valid, save the eliminated
64218334Speter     address.  If it wasn't valid, we need to make a reload each time, so
64318334Speter     don't save it.  */
64418334Speter
64518334Speter  if (! mem_valid)
64618334Speter    {
64718334Speter      type =  (type == RELOAD_FOR_INPUT ? RELOAD_FOR_INPUT_ADDRESS
64818334Speter	       : type == RELOAD_FOR_OUTPUT ? RELOAD_FOR_OUTPUT_ADDRESS
64918334Speter	       : RELOAD_OTHER);
65018334Speter
65190285Sobrien      find_reloads_address (mode, (rtx*) 0, XEXP (loc, 0), &XEXP (loc, 0),
65250605Sobrien			    opnum, type, 0, 0);
65318334Speter    }
65418334Speter
65518334Speter  secondary_memlocs_elim[(int) mode][opnum] = loc;
65618334Speter  return loc;
65718334Speter}
65818334Speter
65918334Speter/* Clear any secondary memory locations we've made.  */
66018334Speter
66118334Spetervoid
66218334Speterclear_secondary_mem ()
66318334Speter{
66490285Sobrien  memset ((char *) secondary_memlocs, 0, sizeof secondary_memlocs);
66518334Speter}
66618334Speter#endif /* SECONDARY_MEMORY_NEEDED */
66718334Speter
66850605Sobrien/* Find the largest class for which every register number plus N is valid in
669102798Skan   M1 (if in range) and is cheap to move into REGNO.
670102798Skan   Abort if no such class exists.  */
67150605Sobrien
67250605Sobrienstatic enum reg_class
673102798Skanfind_valid_class (m1, n, dest_regno)
67490285Sobrien     enum machine_mode m1 ATTRIBUTE_UNUSED;
67550605Sobrien     int n;
676102798Skan     unsigned int dest_regno;
67750605Sobrien{
678102798Skan  int best_cost = -1;
67950605Sobrien  int class;
68050605Sobrien  int regno;
68190285Sobrien  enum reg_class best_class = NO_REGS;
682102798Skan  enum reg_class dest_class = REGNO_REG_CLASS (dest_regno);
68390285Sobrien  unsigned int best_size = 0;
684102798Skan  int cost;
68550605Sobrien
68650605Sobrien  for (class = 1; class < N_REG_CLASSES; class++)
68750605Sobrien    {
68850605Sobrien      int bad = 0;
68950605Sobrien      for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++)
69050605Sobrien	if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
69150605Sobrien	    && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
69250605Sobrien	    && ! HARD_REGNO_MODE_OK (regno + n, m1))
69350605Sobrien	  bad = 1;
69450605Sobrien
695102798Skan      if (bad)
696102798Skan	continue;
697102798Skan      cost = REGISTER_MOVE_COST (m1, class, dest_class);
698102798Skan
699102798Skan      if ((reg_class_size[class] > best_size
700102798Skan	   && (best_cost < 0 || best_cost >= cost))
701102798Skan	  || best_cost > cost)
702102798Skan	{
703102798Skan	  best_class = class;
704102798Skan	  best_size = reg_class_size[class];
705102798Skan	  best_cost = REGISTER_MOVE_COST (m1, class, dest_class);
706102798Skan	}
70750605Sobrien    }
70850605Sobrien
70950605Sobrien  if (best_size == 0)
71050605Sobrien    abort ();
71150605Sobrien
71250605Sobrien  return best_class;
71350605Sobrien}
71450605Sobrien
71552557Sobrien/* Return the number of a previously made reload that can be combined with
71652557Sobrien   a new one, or n_reloads if none of the existing reloads can be used.
71752557Sobrien   OUT, CLASS, TYPE and OPNUM are the same arguments as passed to
71852557Sobrien   push_reload, they determine the kind of the new reload that we try to
71952557Sobrien   combine.  P_IN points to the corresponding value of IN, which can be
72052557Sobrien   modified by this function.
72152557Sobrien   DONT_SHARE is nonzero if we can't share any input-only reload for IN.  */
72290285Sobrien
72352557Sobrienstatic int
72452557Sobrienfind_reusable_reload (p_in, out, class, type, opnum, dont_share)
72552557Sobrien     rtx *p_in, out;
72652557Sobrien     enum reg_class class;
72752557Sobrien     enum reload_type type;
72852557Sobrien     int opnum, dont_share;
72952557Sobrien{
73052557Sobrien  rtx in = *p_in;
73152557Sobrien  int i;
73252557Sobrien  /* We can't merge two reloads if the output of either one is
73352557Sobrien     earlyclobbered.  */
73452557Sobrien
73552557Sobrien  if (earlyclobber_operand_p (out))
73652557Sobrien    return n_reloads;
73752557Sobrien
73852557Sobrien  /* We can use an existing reload if the class is right
73952557Sobrien     and at least one of IN and OUT is a match
74052557Sobrien     and the other is at worst neutral.
74190285Sobrien     (A zero compared against anything is neutral.)
74252557Sobrien
74352557Sobrien     If SMALL_REGISTER_CLASSES, don't use existing reloads unless they are
74452557Sobrien     for the same thing since that can cause us to need more reload registers
74552557Sobrien     than we otherwise would.  */
74690285Sobrien
74752557Sobrien  for (i = 0; i < n_reloads; i++)
74890285Sobrien    if ((reg_class_subset_p (class, rld[i].class)
74990285Sobrien	 || reg_class_subset_p (rld[i].class, class))
75052557Sobrien	/* If the existing reload has a register, it must fit our class.  */
75190285Sobrien	&& (rld[i].reg_rtx == 0
75252557Sobrien	    || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
75390285Sobrien				  true_regnum (rld[i].reg_rtx)))
75490285Sobrien	&& ((in != 0 && MATCHES (rld[i].in, in) && ! dont_share
75590285Sobrien	     && (out == 0 || rld[i].out == 0 || MATCHES (rld[i].out, out)))
75690285Sobrien	    || (out != 0 && MATCHES (rld[i].out, out)
75790285Sobrien		&& (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
75890285Sobrien	&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
75952557Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
76090285Sobrien	&& MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
76152557Sobrien      return i;
76252557Sobrien
76352557Sobrien  /* Reloading a plain reg for input can match a reload to postincrement
76452557Sobrien     that reg, since the postincrement's value is the right value.
76552557Sobrien     Likewise, it can match a preincrement reload, since we regard
76652557Sobrien     the preincrementation as happening before any ref in this insn
76752557Sobrien     to that register.  */
76852557Sobrien  for (i = 0; i < n_reloads; i++)
76990285Sobrien    if ((reg_class_subset_p (class, rld[i].class)
77090285Sobrien	 || reg_class_subset_p (rld[i].class, class))
77152557Sobrien	/* If the existing reload has a register, it must fit our
77252557Sobrien	   class.  */
77390285Sobrien	&& (rld[i].reg_rtx == 0
77452557Sobrien	    || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
77590285Sobrien				  true_regnum (rld[i].reg_rtx)))
77690285Sobrien	&& out == 0 && rld[i].out == 0 && rld[i].in != 0
77752557Sobrien	&& ((GET_CODE (in) == REG
77890285Sobrien	     && GET_RTX_CLASS (GET_CODE (rld[i].in)) == 'a'
77990285Sobrien	     && MATCHES (XEXP (rld[i].in, 0), in))
78090285Sobrien	    || (GET_CODE (rld[i].in) == REG
78190285Sobrien		&& GET_RTX_CLASS (GET_CODE (in)) == 'a'
78290285Sobrien		&& MATCHES (XEXP (in, 0), rld[i].in)))
78390285Sobrien	&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
78452557Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
78590285Sobrien	&& MERGABLE_RELOADS (type, rld[i].when_needed,
78690285Sobrien			     opnum, rld[i].opnum))
78752557Sobrien      {
78852557Sobrien	/* Make sure reload_in ultimately has the increment,
78952557Sobrien	   not the plain register.  */
79052557Sobrien	if (GET_CODE (in) == REG)
79190285Sobrien	  *p_in = rld[i].in;
79252557Sobrien	return i;
79352557Sobrien      }
79452557Sobrien  return n_reloads;
79552557Sobrien}
79652557Sobrien
79790285Sobrien/* Return nonzero if X is a SUBREG which will require reloading of its
79890285Sobrien   SUBREG_REG expression.  */
79990285Sobrien
80090285Sobrienstatic int
80190285Sobrienreload_inner_reg_of_subreg (x, mode)
80290285Sobrien     rtx x;
80390285Sobrien     enum machine_mode mode;
80490285Sobrien{
80590285Sobrien  rtx inner;
80690285Sobrien
80790285Sobrien  /* Only SUBREGs are problematical.  */
80890285Sobrien  if (GET_CODE (x) != SUBREG)
80990285Sobrien    return 0;
81090285Sobrien
81190285Sobrien  inner = SUBREG_REG (x);
81290285Sobrien
81390285Sobrien  /* If INNER is a constant or PLUS, then INNER must be reloaded.  */
81490285Sobrien  if (CONSTANT_P (inner) || GET_CODE (inner) == PLUS)
81590285Sobrien    return 1;
81690285Sobrien
81790285Sobrien  /* If INNER is not a hard register, then INNER will not need to
81890285Sobrien     be reloaded.  */
81990285Sobrien  if (GET_CODE (inner) != REG
82090285Sobrien      || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
82190285Sobrien    return 0;
82290285Sobrien
82390285Sobrien  /* If INNER is not ok for MODE, then INNER will need reloading.  */
82490285Sobrien  if (! HARD_REGNO_MODE_OK (subreg_regno (x), mode))
82590285Sobrien    return 1;
82690285Sobrien
82790285Sobrien  /* If the outer part is a word or smaller, INNER larger than a
82890285Sobrien     word and the number of regs for INNER is not the same as the
82990285Sobrien     number of words in INNER, then INNER will need reloading.  */
83090285Sobrien  return (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
83190285Sobrien	  && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD
83290285Sobrien	  && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD)
83390285Sobrien	      != HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))));
83490285Sobrien}
83590285Sobrien
83618334Speter/* Record one reload that needs to be performed.
83718334Speter   IN is an rtx saying where the data are to be found before this instruction.
83818334Speter   OUT says where they must be stored after the instruction.
83918334Speter   (IN is zero for data not read, and OUT is zero for data not written.)
84018334Speter   INLOC and OUTLOC point to the places in the instructions where
84118334Speter   IN and OUT were found.
84218334Speter   If IN and OUT are both non-zero, it means the same register must be used
84318334Speter   to reload both IN and OUT.
84418334Speter
84518334Speter   CLASS is a register class required for the reloaded data.
84618334Speter   INMODE is the machine mode that the instruction requires
84718334Speter   for the reg that replaces IN and OUTMODE is likewise for OUT.
84818334Speter
84918334Speter   If IN is zero, then OUT's location and mode should be passed as
85018334Speter   INLOC and INMODE.
85118334Speter
85218334Speter   STRICT_LOW is the 1 if there is a containing STRICT_LOW_PART rtx.
85318334Speter
85418334Speter   OPTIONAL nonzero means this reload does not need to be performed:
85518334Speter   it can be discarded if that is more convenient.
85618334Speter
85718334Speter   OPNUM and TYPE say what the purpose of this reload is.
85818334Speter
85918334Speter   The return value is the reload-number for this reload.
86018334Speter
86118334Speter   If both IN and OUT are nonzero, in some rare cases we might
86218334Speter   want to make two separate reloads.  (Actually we never do this now.)
86318334Speter   Therefore, the reload-number for OUT is stored in
86418334Speter   output_reloadnum when we return; the return value applies to IN.
86518334Speter   Usually (presently always), when IN and OUT are nonzero,
86618334Speter   the two reload-numbers are equal, but the caller should be careful to
86718334Speter   distinguish them.  */
86818334Speter
86990285Sobrienint
87018334Speterpush_reload (in, out, inloc, outloc, class,
87118334Speter	     inmode, outmode, strict_low, optional, opnum, type)
87252557Sobrien     rtx in, out;
87318334Speter     rtx *inloc, *outloc;
87418334Speter     enum reg_class class;
87518334Speter     enum machine_mode inmode, outmode;
87618334Speter     int strict_low;
87718334Speter     int optional;
87818334Speter     int opnum;
87918334Speter     enum reload_type type;
88018334Speter{
88190285Sobrien  int i;
88218334Speter  int dont_share = 0;
88318334Speter  int dont_remove_subreg = 0;
88418334Speter  rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
88518334Speter  int secondary_in_reload = -1, secondary_out_reload = -1;
88618334Speter  enum insn_code secondary_in_icode = CODE_FOR_nothing;
88718334Speter  enum insn_code secondary_out_icode = CODE_FOR_nothing;
88818334Speter
88918334Speter  /* INMODE and/or OUTMODE could be VOIDmode if no mode
89018334Speter     has been specified for the operand.  In that case,
89118334Speter     use the operand's mode as the mode to reload.  */
89218334Speter  if (inmode == VOIDmode && in != 0)
89318334Speter    inmode = GET_MODE (in);
89418334Speter  if (outmode == VOIDmode && out != 0)
89518334Speter    outmode = GET_MODE (out);
89618334Speter
89790285Sobrien  /* If IN is a pseudo register everywhere-equivalent to a constant, and
89818334Speter     it is not in a hard register, reload straight from the constant,
89918334Speter     since we want to get rid of such pseudo registers.
90018334Speter     Often this is done earlier, but not always in find_reloads_address.  */
90118334Speter  if (in != 0 && GET_CODE (in) == REG)
90218334Speter    {
90390285Sobrien      int regno = REGNO (in);
90418334Speter
90518334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
90618334Speter	  && reg_equiv_constant[regno] != 0)
90718334Speter	in = reg_equiv_constant[regno];
90818334Speter    }
90918334Speter
91018334Speter  /* Likewise for OUT.  Of course, OUT will never be equivalent to
91118334Speter     an actual constant, but it might be equivalent to a memory location
91218334Speter     (in the case of a parameter).  */
91318334Speter  if (out != 0 && GET_CODE (out) == REG)
91418334Speter    {
91590285Sobrien      int regno = REGNO (out);
91618334Speter
91718334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
91818334Speter	  && reg_equiv_constant[regno] != 0)
91918334Speter	out = reg_equiv_constant[regno];
92018334Speter    }
92118334Speter
92218334Speter  /* If we have a read-write operand with an address side-effect,
92318334Speter     change either IN or OUT so the side-effect happens only once.  */
92418334Speter  if (in != 0 && out != 0 && GET_CODE (in) == MEM && rtx_equal_p (in, out))
92590285Sobrien    switch (GET_CODE (XEXP (in, 0)))
92690285Sobrien      {
92790285Sobrien      case POST_INC: case POST_DEC:   case POST_MODIFY:
92890285Sobrien	in = replace_equiv_address_nv (in, XEXP (XEXP (in, 0), 0));
92990285Sobrien	break;
93018334Speter
93190285Sobrien      case PRE_INC: case PRE_DEC: case PRE_MODIFY:
93290285Sobrien	out = replace_equiv_address_nv (out, XEXP (XEXP (out, 0), 0));
93390285Sobrien	break;
93490285Sobrien
93590285Sobrien      default:
93690285Sobrien	break;
93790285Sobrien      }
93890285Sobrien
93918334Speter  /* If we are reloading a (SUBREG constant ...), really reload just the
94018334Speter     inside expression in its own mode.  Similarly for (SUBREG (PLUS ...)).
94118334Speter     If we have (SUBREG:M1 (MEM:M2 ...) ...) (or an inner REG that is still
94218334Speter     a pseudo and hence will become a MEM) with M1 wider than M2 and the
94318334Speter     register is a pseudo, also reload the inside expression.
94418334Speter     For machines that extend byte loads, do this for any SUBREG of a pseudo
94518334Speter     where both M1 and M2 are a word or smaller, M1 is wider than M2, and
94618334Speter     M2 is an integral mode that gets extended when loaded.
94718334Speter     Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
94818334Speter     either M1 is not valid for R or M2 is wider than a word but we only
94918334Speter     need one word to store an M2-sized quantity in R.
95018334Speter     (However, if OUT is nonzero, we need to reload the reg *and*
95118334Speter     the subreg, so do nothing here, and let following statement handle it.)
95218334Speter
95318334Speter     Note that the case of (SUBREG (CONST_INT...)...) is handled elsewhere;
95418334Speter     we can't handle it here because CONST_INT does not indicate a mode.
95518334Speter
95618334Speter     Similarly, we must reload the inside expression if we have a
95718334Speter     STRICT_LOW_PART (presumably, in == out in the cas).
95818334Speter
95918334Speter     Also reload the inner expression if it does not require a secondary
96018334Speter     reload but the SUBREG does.
96118334Speter
96218334Speter     Finally, reload the inner expression if it is a register that is in
96318334Speter     the class whose registers cannot be referenced in a different size
96490285Sobrien     and M1 is not the same size as M2.  If subreg_lowpart_p is false, we
96518334Speter     cannot reload just the inside since we might end up with the wrong
96652557Sobrien     register class.  But if it is inside a STRICT_LOW_PART, we have
96752557Sobrien     no choice, so we hope we do get the right register class there.  */
96818334Speter
96952557Sobrien  if (in != 0 && GET_CODE (in) == SUBREG
97090285Sobrien      && (subreg_lowpart_p (in) || strict_low)
97190285Sobrien#ifdef CLASS_CANNOT_CHANGE_MODE
97290285Sobrien      && (class != CLASS_CANNOT_CHANGE_MODE
97390285Sobrien	  || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)), inmode))
97418334Speter#endif
97518334Speter      && (CONSTANT_P (SUBREG_REG (in))
97618334Speter	  || GET_CODE (SUBREG_REG (in)) == PLUS
97718334Speter	  || strict_low
97818334Speter	  || (((GET_CODE (SUBREG_REG (in)) == REG
97918334Speter		&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
98018334Speter	       || GET_CODE (SUBREG_REG (in)) == MEM)
98118334Speter	      && ((GET_MODE_SIZE (inmode)
98218334Speter		   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
98318334Speter#ifdef LOAD_EXTEND_OP
98418334Speter		  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
98518334Speter		      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
98618334Speter			  <= UNITS_PER_WORD)
98718334Speter		      && (GET_MODE_SIZE (inmode)
98818334Speter			  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
98918334Speter		      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
99018334Speter		      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != NIL)
99118334Speter#endif
99250605Sobrien#ifdef WORD_REGISTER_OPERATIONS
99350605Sobrien		  || ((GET_MODE_SIZE (inmode)
99450605Sobrien		       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
99550605Sobrien		      && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
99650605Sobrien			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
99750605Sobrien			   / UNITS_PER_WORD)))
99850605Sobrien#endif
99918334Speter		  ))
100018334Speter	  || (GET_CODE (SUBREG_REG (in)) == REG
100118334Speter	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
100218334Speter	      /* The case where out is nonzero
100318334Speter		 is handled differently in the following statement.  */
100490285Sobrien	      && (out == 0 || subreg_lowpart_p (in))
100518334Speter	      && ((GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
100618334Speter		   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
100718334Speter		       > UNITS_PER_WORD)
100818334Speter		   && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
100918334Speter			/ UNITS_PER_WORD)
101018334Speter		       != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
101118334Speter					    GET_MODE (SUBREG_REG (in)))))
101290285Sobrien		  || ! HARD_REGNO_MODE_OK (subreg_regno (in), inmode)))
101318334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
101418334Speter	  || (SECONDARY_INPUT_RELOAD_CLASS (class, inmode, in) != NO_REGS
101518334Speter	      && (SECONDARY_INPUT_RELOAD_CLASS (class,
101618334Speter						GET_MODE (SUBREG_REG (in)),
101718334Speter						SUBREG_REG (in))
101818334Speter		  == NO_REGS))
101918334Speter#endif
102090285Sobrien#ifdef CLASS_CANNOT_CHANGE_MODE
102118334Speter	  || (GET_CODE (SUBREG_REG (in)) == REG
102218334Speter	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
102318334Speter	      && (TEST_HARD_REG_BIT
102490285Sobrien		  (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
102518334Speter		   REGNO (SUBREG_REG (in))))
102690285Sobrien	      && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)),
102790285Sobrien					     inmode))
102818334Speter#endif
102918334Speter	  ))
103018334Speter    {
103118334Speter      in_subreg_loc = inloc;
103218334Speter      inloc = &SUBREG_REG (in);
103318334Speter      in = *inloc;
103450605Sobrien#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
103518334Speter      if (GET_CODE (in) == MEM)
103618334Speter	/* This is supposed to happen only for paradoxical subregs made by
103718334Speter	   combine.c.  (SUBREG (MEM)) isn't supposed to occur other ways.  */
103818334Speter	if (GET_MODE_SIZE (GET_MODE (in)) > GET_MODE_SIZE (inmode))
103918334Speter	  abort ();
104018334Speter#endif
104118334Speter      inmode = GET_MODE (in);
104218334Speter    }
104318334Speter
104418334Speter  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
104518334Speter     either M1 is not valid for R or M2 is wider than a word but we only
104618334Speter     need one word to store an M2-sized quantity in R.
104718334Speter
104818334Speter     However, we must reload the inner reg *as well as* the subreg in
104918334Speter     that case.  */
105018334Speter
105150605Sobrien  /* Similar issue for (SUBREG constant ...) if it was not handled by the
105290285Sobrien     code above.  This can happen if SUBREG_BYTE != 0.  */
105350605Sobrien
105490285Sobrien  if (in != 0 && reload_inner_reg_of_subreg (in, inmode))
105518334Speter    {
105690285Sobrien      enum reg_class in_class = class;
105790285Sobrien
105890285Sobrien      if (GET_CODE (SUBREG_REG (in)) == REG)
105990285Sobrien	in_class
106090285Sobrien	  = find_valid_class (inmode,
106190285Sobrien			      subreg_regno_offset (REGNO (SUBREG_REG (in)),
106290285Sobrien						   GET_MODE (SUBREG_REG (in)),
106390285Sobrien						   SUBREG_BYTE (in),
1064102798Skan						   GET_MODE (in)),
1065102798Skan			      REGNO (SUBREG_REG (in)));
106690285Sobrien
106718334Speter      /* This relies on the fact that emit_reload_insns outputs the
106818334Speter	 instructions for input reloads of type RELOAD_OTHER in the same
106918334Speter	 order as the reloads.  Thus if the outer reload is also of type
107018334Speter	 RELOAD_OTHER, we are guaranteed that this inner reload will be
107118334Speter	 output before the outer reload.  */
107290285Sobrien      push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), (rtx *) 0,
107390285Sobrien		   in_class, VOIDmode, VOIDmode, 0, 0, opnum, type);
107418334Speter      dont_remove_subreg = 1;
107518334Speter    }
107618334Speter
107718334Speter  /* Similarly for paradoxical and problematical SUBREGs on the output.
107818334Speter     Note that there is no reason we need worry about the previous value
107918334Speter     of SUBREG_REG (out); even if wider than out,
108018334Speter     storing in a subreg is entitled to clobber it all
108118334Speter     (except in the case of STRICT_LOW_PART,
108218334Speter     and in that case the constraint should label it input-output.)  */
108352557Sobrien  if (out != 0 && GET_CODE (out) == SUBREG
108490285Sobrien      && (subreg_lowpart_p (out) || strict_low)
108590285Sobrien#ifdef CLASS_CANNOT_CHANGE_MODE
108690285Sobrien      && (class != CLASS_CANNOT_CHANGE_MODE
108790285Sobrien	  || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
108890285Sobrien					   outmode))
108918334Speter#endif
109018334Speter      && (CONSTANT_P (SUBREG_REG (out))
109118334Speter	  || strict_low
109218334Speter	  || (((GET_CODE (SUBREG_REG (out)) == REG
109318334Speter		&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
109418334Speter	       || GET_CODE (SUBREG_REG (out)) == MEM)
109518334Speter	      && ((GET_MODE_SIZE (outmode)
109650605Sobrien		   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
109750605Sobrien#ifdef WORD_REGISTER_OPERATIONS
109850605Sobrien		  || ((GET_MODE_SIZE (outmode)
109950605Sobrien		       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
110050605Sobrien		      && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
110150605Sobrien			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
110250605Sobrien			   / UNITS_PER_WORD)))
110350605Sobrien#endif
110490285Sobrien		  ))
110518334Speter	  || (GET_CODE (SUBREG_REG (out)) == REG
110618334Speter	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
110718334Speter	      && ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
110818334Speter		   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
110918334Speter		       > UNITS_PER_WORD)
111018334Speter		   && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
111118334Speter			/ UNITS_PER_WORD)
111218334Speter		       != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
111318334Speter					    GET_MODE (SUBREG_REG (out)))))
111490285Sobrien		  || ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode)))
111518334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
111618334Speter	  || (SECONDARY_OUTPUT_RELOAD_CLASS (class, outmode, out) != NO_REGS
111718334Speter	      && (SECONDARY_OUTPUT_RELOAD_CLASS (class,
111818334Speter						 GET_MODE (SUBREG_REG (out)),
111918334Speter						 SUBREG_REG (out))
112018334Speter		  == NO_REGS))
112118334Speter#endif
112290285Sobrien#ifdef CLASS_CANNOT_CHANGE_MODE
112318334Speter	  || (GET_CODE (SUBREG_REG (out)) == REG
112418334Speter	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
112518334Speter	      && (TEST_HARD_REG_BIT
112690285Sobrien		  (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
112718334Speter		   REGNO (SUBREG_REG (out))))
112890285Sobrien	      && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
112990285Sobrien					     outmode))
113018334Speter#endif
113118334Speter	  ))
113218334Speter    {
113318334Speter      out_subreg_loc = outloc;
113418334Speter      outloc = &SUBREG_REG (out);
113590285Sobrien      out = *outloc;
113650605Sobrien#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
113790285Sobrien      if (GET_CODE (out) == MEM
113818334Speter	  && GET_MODE_SIZE (GET_MODE (out)) > GET_MODE_SIZE (outmode))
113918334Speter	abort ();
114018334Speter#endif
114118334Speter      outmode = GET_MODE (out);
114218334Speter    }
114318334Speter
114418334Speter  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
114518334Speter     either M1 is not valid for R or M2 is wider than a word but we only
114618334Speter     need one word to store an M2-sized quantity in R.
114718334Speter
114818334Speter     However, we must reload the inner reg *as well as* the subreg in
114918334Speter     that case.  In this case, the inner reg is an in-out reload.  */
115018334Speter
115190285Sobrien  if (out != 0 && reload_inner_reg_of_subreg (out, outmode))
115218334Speter    {
115318334Speter      /* This relies on the fact that emit_reload_insns outputs the
115418334Speter	 instructions for output reloads of type RELOAD_OTHER in reverse
115518334Speter	 order of the reloads.  Thus if the outer reload is also of type
115618334Speter	 RELOAD_OTHER, we are guaranteed that this inner reload will be
115718334Speter	 output after the outer reload.  */
115818334Speter      dont_remove_subreg = 1;
115918334Speter      push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
116050605Sobrien		   &SUBREG_REG (out),
116190285Sobrien		   find_valid_class (outmode,
116290285Sobrien				     subreg_regno_offset (REGNO (SUBREG_REG (out)),
116390285Sobrien							  GET_MODE (SUBREG_REG (out)),
116490285Sobrien							  SUBREG_BYTE (out),
1165102798Skan							  GET_MODE (out)),
1166102798Skan				     REGNO (SUBREG_REG (out))),
116750605Sobrien		   VOIDmode, VOIDmode, 0, 0,
116818334Speter		   opnum, RELOAD_OTHER);
116918334Speter    }
117018334Speter
117118334Speter  /* If IN appears in OUT, we can't share any input-only reload for IN.  */
117218334Speter  if (in != 0 && out != 0 && GET_CODE (out) == MEM
117318334Speter      && (GET_CODE (in) == REG || GET_CODE (in) == MEM)
117418334Speter      && reg_overlap_mentioned_for_reload_p (in, XEXP (out, 0)))
117518334Speter    dont_share = 1;
117618334Speter
117718334Speter  /* If IN is a SUBREG of a hard register, make a new REG.  This
117818334Speter     simplifies some of the cases below.  */
117918334Speter
118018334Speter  if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
118118334Speter      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
118218334Speter      && ! dont_remove_subreg)
118390285Sobrien    in = gen_rtx_REG (GET_MODE (in), subreg_regno (in));
118418334Speter
118518334Speter  /* Similarly for OUT.  */
118618334Speter  if (out != 0 && GET_CODE (out) == SUBREG
118718334Speter      && GET_CODE (SUBREG_REG (out)) == REG
118818334Speter      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
118918334Speter      && ! dont_remove_subreg)
119090285Sobrien    out = gen_rtx_REG (GET_MODE (out), subreg_regno (out));
119118334Speter
119218334Speter  /* Narrow down the class of register wanted if that is
119318334Speter     desirable on this machine for efficiency.  */
119418334Speter  if (in != 0)
119518334Speter    class = PREFERRED_RELOAD_CLASS (in, class);
119618334Speter
119718334Speter  /* Output reloads may need analogous treatment, different in detail.  */
119818334Speter#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
119918334Speter  if (out != 0)
120018334Speter    class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class);
120118334Speter#endif
120218334Speter
120318334Speter  /* Make sure we use a class that can handle the actual pseudo
120418334Speter     inside any subreg.  For example, on the 386, QImode regs
120518334Speter     can appear within SImode subregs.  Although GENERAL_REGS
120618334Speter     can handle SImode, QImode needs a smaller class.  */
120718334Speter#ifdef LIMIT_RELOAD_CLASS
120818334Speter  if (in_subreg_loc)
120918334Speter    class = LIMIT_RELOAD_CLASS (inmode, class);
121018334Speter  else if (in != 0 && GET_CODE (in) == SUBREG)
121118334Speter    class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), class);
121218334Speter
121318334Speter  if (out_subreg_loc)
121418334Speter    class = LIMIT_RELOAD_CLASS (outmode, class);
121518334Speter  if (out != 0 && GET_CODE (out) == SUBREG)
121618334Speter    class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), class);
121718334Speter#endif
121818334Speter
121918334Speter  /* Verify that this class is at least possible for the mode that
122018334Speter     is specified.  */
122118334Speter  if (this_insn_is_asm)
122218334Speter    {
122318334Speter      enum machine_mode mode;
122418334Speter      if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
122518334Speter	mode = inmode;
122618334Speter      else
122718334Speter	mode = outmode;
122818334Speter      if (mode == VOIDmode)
122918334Speter	{
123018334Speter	  error_for_asm (this_insn, "cannot reload integer constant operand in `asm'");
123118334Speter	  mode = word_mode;
123218334Speter	  if (in != 0)
123318334Speter	    inmode = word_mode;
123418334Speter	  if (out != 0)
123518334Speter	    outmode = word_mode;
123618334Speter	}
123718334Speter      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
123818334Speter	if (HARD_REGNO_MODE_OK (i, mode)
123918334Speter	    && TEST_HARD_REG_BIT (reg_class_contents[(int) class], i))
124018334Speter	  {
124118334Speter	    int nregs = HARD_REGNO_NREGS (i, mode);
124218334Speter
124318334Speter	    int j;
124418334Speter	    for (j = 1; j < nregs; j++)
124518334Speter	      if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class], i + j))
124618334Speter		break;
124718334Speter	    if (j == nregs)
124818334Speter	      break;
124918334Speter	  }
125018334Speter      if (i == FIRST_PSEUDO_REGISTER)
125118334Speter	{
125218334Speter	  error_for_asm (this_insn, "impossible register constraint in `asm'");
125318334Speter	  class = ALL_REGS;
125418334Speter	}
125518334Speter    }
125618334Speter
125752557Sobrien  /* Optional output reloads are always OK even if we have no register class,
125852557Sobrien     since the function of these reloads is only to have spill_reg_store etc.
125952557Sobrien     set, so that the storing insn can be deleted later.  */
126052557Sobrien  if (class == NO_REGS
126152557Sobrien      && (optional == 0 || type != RELOAD_FOR_OUTPUT))
126218334Speter    abort ();
126318334Speter
126452557Sobrien  i = find_reusable_reload (&in, out, class, type, opnum, dont_share);
126518334Speter
126618334Speter  if (i == n_reloads)
126718334Speter    {
126818334Speter      /* See if we need a secondary reload register to move between CLASS
126918334Speter	 and IN or CLASS and OUT.  Get the icode and push any required reloads
127018334Speter	 needed for each of them if so.  */
127118334Speter
127218334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
127318334Speter      if (in != 0)
127418334Speter	secondary_in_reload
127518334Speter	  = push_secondary_reload (1, in, opnum, optional, class, inmode, type,
127618334Speter				   &secondary_in_icode);
127718334Speter#endif
127818334Speter
127918334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
128018334Speter      if (out != 0 && GET_CODE (out) != SCRATCH)
128118334Speter	secondary_out_reload
128218334Speter	  = push_secondary_reload (0, out, opnum, optional, class, outmode,
128318334Speter				   type, &secondary_out_icode);
128418334Speter#endif
128518334Speter
128618334Speter      /* We found no existing reload suitable for re-use.
128718334Speter	 So add an additional reload.  */
128818334Speter
128950605Sobrien#ifdef SECONDARY_MEMORY_NEEDED
129050605Sobrien      /* If a memory location is needed for the copy, make one.  */
129150605Sobrien      if (in != 0 && GET_CODE (in) == REG
129250605Sobrien	  && REGNO (in) < FIRST_PSEUDO_REGISTER
129350605Sobrien	  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
129490285Sobrien				      class, inmode))
129550605Sobrien	get_secondary_mem (in, inmode, opnum, type);
129650605Sobrien#endif
129750605Sobrien
129818334Speter      i = n_reloads;
129990285Sobrien      rld[i].in = in;
130090285Sobrien      rld[i].out = out;
130190285Sobrien      rld[i].class = class;
130290285Sobrien      rld[i].inmode = inmode;
130390285Sobrien      rld[i].outmode = outmode;
130490285Sobrien      rld[i].reg_rtx = 0;
130590285Sobrien      rld[i].optional = optional;
130690285Sobrien      rld[i].inc = 0;
130790285Sobrien      rld[i].nocombine = 0;
130890285Sobrien      rld[i].in_reg = inloc ? *inloc : 0;
130990285Sobrien      rld[i].out_reg = outloc ? *outloc : 0;
131090285Sobrien      rld[i].opnum = opnum;
131190285Sobrien      rld[i].when_needed = type;
131290285Sobrien      rld[i].secondary_in_reload = secondary_in_reload;
131390285Sobrien      rld[i].secondary_out_reload = secondary_out_reload;
131490285Sobrien      rld[i].secondary_in_icode = secondary_in_icode;
131590285Sobrien      rld[i].secondary_out_icode = secondary_out_icode;
131690285Sobrien      rld[i].secondary_p = 0;
131718334Speter
131818334Speter      n_reloads++;
131918334Speter
132018334Speter#ifdef SECONDARY_MEMORY_NEEDED
132118334Speter      if (out != 0 && GET_CODE (out) == REG
132218334Speter	  && REGNO (out) < FIRST_PSEUDO_REGISTER
132318334Speter	  && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (REGNO (out)),
132418334Speter				      outmode))
132518334Speter	get_secondary_mem (out, outmode, opnum, type);
132618334Speter#endif
132718334Speter    }
132818334Speter  else
132918334Speter    {
133018334Speter      /* We are reusing an existing reload,
133118334Speter	 but we may have additional information for it.
133218334Speter	 For example, we may now have both IN and OUT
133318334Speter	 while the old one may have just one of them.  */
133418334Speter
133550605Sobrien      /* The modes can be different.  If they are, we want to reload in
133650605Sobrien	 the larger mode, so that the value is valid for both modes.  */
133750605Sobrien      if (inmode != VOIDmode
133890285Sobrien	  && GET_MODE_SIZE (inmode) > GET_MODE_SIZE (rld[i].inmode))
133990285Sobrien	rld[i].inmode = inmode;
134050605Sobrien      if (outmode != VOIDmode
134190285Sobrien	  && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (rld[i].outmode))
134290285Sobrien	rld[i].outmode = outmode;
134318334Speter      if (in != 0)
134452557Sobrien	{
134552557Sobrien	  rtx in_reg = inloc ? *inloc : 0;
134652557Sobrien	  /* If we merge reloads for two distinct rtl expressions that
134752557Sobrien	     are identical in content, there might be duplicate address
134852557Sobrien	     reloads.  Remove the extra set now, so that if we later find
134952557Sobrien	     that we can inherit this reload, we can get rid of the
135052557Sobrien	     address reloads altogether.
135152557Sobrien
135252557Sobrien	     Do not do this if both reloads are optional since the result
135352557Sobrien	     would be an optional reload which could potentially leave
135452557Sobrien	     unresolved address replacements.
135552557Sobrien
135652557Sobrien	     It is not sufficient to call transfer_replacements since
135752557Sobrien	     choose_reload_regs will remove the replacements for address
135852557Sobrien	     reloads of inherited reloads which results in the same
135952557Sobrien	     problem.  */
136090285Sobrien	  if (rld[i].in != in && rtx_equal_p (in, rld[i].in)
136190285Sobrien	      && ! (rld[i].optional && optional))
136252557Sobrien	    {
136352557Sobrien	      /* We must keep the address reload with the lower operand
136452557Sobrien		 number alive.  */
136590285Sobrien	      if (opnum > rld[i].opnum)
136652557Sobrien		{
136752557Sobrien		  remove_address_replacements (in);
136890285Sobrien		  in = rld[i].in;
136990285Sobrien		  in_reg = rld[i].in_reg;
137052557Sobrien		}
137152557Sobrien	      else
137290285Sobrien		remove_address_replacements (rld[i].in);
137352557Sobrien	    }
137490285Sobrien	  rld[i].in = in;
137590285Sobrien	  rld[i].in_reg = in_reg;
137652557Sobrien	}
137718334Speter      if (out != 0)
137852557Sobrien	{
137990285Sobrien	  rld[i].out = out;
138090285Sobrien	  rld[i].out_reg = outloc ? *outloc : 0;
138152557Sobrien	}
138290285Sobrien      if (reg_class_subset_p (class, rld[i].class))
138390285Sobrien	rld[i].class = class;
138490285Sobrien      rld[i].optional &= optional;
138590285Sobrien      if (MERGE_TO_OTHER (type, rld[i].when_needed,
138690285Sobrien			  opnum, rld[i].opnum))
138790285Sobrien	rld[i].when_needed = RELOAD_OTHER;
138890285Sobrien      rld[i].opnum = MIN (rld[i].opnum, opnum);
138918334Speter    }
139018334Speter
139190285Sobrien  /* If the ostensible rtx being reloaded differs from the rtx found
139218334Speter     in the location to substitute, this reload is not safe to combine
139318334Speter     because we cannot reliably tell whether it appears in the insn.  */
139418334Speter
139518334Speter  if (in != 0 && in != *inloc)
139690285Sobrien    rld[i].nocombine = 1;
139718334Speter
139818334Speter#if 0
139918334Speter  /* This was replaced by changes in find_reloads_address_1 and the new
140018334Speter     function inc_for_reload, which go with a new meaning of reload_inc.  */
140118334Speter
140218334Speter  /* If this is an IN/OUT reload in an insn that sets the CC,
140318334Speter     it must be for an autoincrement.  It doesn't work to store
140418334Speter     the incremented value after the insn because that would clobber the CC.
140518334Speter     So we must do the increment of the value reloaded from,
140618334Speter     increment it, store it back, then decrement again.  */
140718334Speter  if (out != 0 && sets_cc0_p (PATTERN (this_insn)))
140818334Speter    {
140918334Speter      out = 0;
141090285Sobrien      rld[i].out = 0;
141190285Sobrien      rld[i].inc = find_inc_amount (PATTERN (this_insn), in);
141218334Speter      /* If we did not find a nonzero amount-to-increment-by,
141318334Speter	 that contradicts the belief that IN is being incremented
141418334Speter	 in an address in this insn.  */
141590285Sobrien      if (rld[i].inc == 0)
141618334Speter	abort ();
141718334Speter    }
141818334Speter#endif
141918334Speter
142018334Speter  /* If we will replace IN and OUT with the reload-reg,
142118334Speter     record where they are located so that substitution need
142218334Speter     not do a tree walk.  */
142318334Speter
142418334Speter  if (replace_reloads)
142518334Speter    {
142618334Speter      if (inloc != 0)
142718334Speter	{
142890285Sobrien	  struct replacement *r = &replacements[n_replacements++];
142918334Speter	  r->what = i;
143018334Speter	  r->subreg_loc = in_subreg_loc;
143118334Speter	  r->where = inloc;
143218334Speter	  r->mode = inmode;
143318334Speter	}
143418334Speter      if (outloc != 0 && outloc != inloc)
143518334Speter	{
143690285Sobrien	  struct replacement *r = &replacements[n_replacements++];
143718334Speter	  r->what = i;
143818334Speter	  r->where = outloc;
143918334Speter	  r->subreg_loc = out_subreg_loc;
144018334Speter	  r->mode = outmode;
144118334Speter	}
144218334Speter    }
144318334Speter
144418334Speter  /* If this reload is just being introduced and it has both
144518334Speter     an incoming quantity and an outgoing quantity that are
144618334Speter     supposed to be made to match, see if either one of the two
144718334Speter     can serve as the place to reload into.
144818334Speter
144990285Sobrien     If one of them is acceptable, set rld[i].reg_rtx
145018334Speter     to that one.  */
145118334Speter
145290285Sobrien  if (in != 0 && out != 0 && in != out && rld[i].reg_rtx == 0)
145318334Speter    {
145490285Sobrien      rld[i].reg_rtx = find_dummy_reload (in, out, inloc, outloc,
145590285Sobrien					  inmode, outmode,
145690285Sobrien					  rld[i].class, i,
145790285Sobrien					  earlyclobber_operand_p (out));
145818334Speter
145918334Speter      /* If the outgoing register already contains the same value
146018334Speter	 as the incoming one, we can dispense with loading it.
146118334Speter	 The easiest way to tell the caller that is to give a phony
146218334Speter	 value for the incoming operand (same as outgoing one).  */
146390285Sobrien      if (rld[i].reg_rtx == out
146418334Speter	  && (GET_CODE (in) == REG || CONSTANT_P (in))
146518334Speter	  && 0 != find_equiv_reg (in, this_insn, 0, REGNO (out),
146618334Speter				  static_reload_reg_p, i, inmode))
146790285Sobrien	rld[i].in = out;
146818334Speter    }
146918334Speter
147018334Speter  /* If this is an input reload and the operand contains a register that
147118334Speter     dies in this insn and is used nowhere else, see if it is the right class
147218334Speter     to be used for this reload.  Use it if so.  (This occurs most commonly
147318334Speter     in the case of paradoxical SUBREGs and in-out reloads).  We cannot do
147418334Speter     this if it is also an output reload that mentions the register unless
147518334Speter     the output is a SUBREG that clobbers an entire register.
147618334Speter
147718334Speter     Note that the operand might be one of the spill regs, if it is a
147818334Speter     pseudo reg and we are in a block where spilling has not taken place.
147918334Speter     But if there is no spilling in this block, that is OK.
148018334Speter     An explicitly used hard reg cannot be a spill reg.  */
148118334Speter
148290285Sobrien  if (rld[i].reg_rtx == 0 && in != 0)
148318334Speter    {
148418334Speter      rtx note;
148518334Speter      int regno;
148690285Sobrien      enum machine_mode rel_mode = inmode;
148718334Speter
148890285Sobrien      if (out && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (inmode))
148990285Sobrien	rel_mode = outmode;
149090285Sobrien
149118334Speter      for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
149218334Speter	if (REG_NOTE_KIND (note) == REG_DEAD
149318334Speter	    && GET_CODE (XEXP (note, 0)) == REG
149418334Speter	    && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
149518334Speter	    && reg_mentioned_p (XEXP (note, 0), in)
149618334Speter	    && ! refers_to_regno_for_reload_p (regno,
149718334Speter					       (regno
149818334Speter						+ HARD_REGNO_NREGS (regno,
149990285Sobrien								    rel_mode)),
150018334Speter					       PATTERN (this_insn), inloc)
150118334Speter	    /* If this is also an output reload, IN cannot be used as
150218334Speter	       the reload register if it is set in this insn unless IN
150318334Speter	       is also OUT.  */
150418334Speter	    && (out == 0 || in == out
150518334Speter		|| ! hard_reg_set_here_p (regno,
150618334Speter					  (regno
150718334Speter					   + HARD_REGNO_NREGS (regno,
150890285Sobrien							       rel_mode)),
150918334Speter					  PATTERN (this_insn)))
151018334Speter	    /* ??? Why is this code so different from the previous?
151118334Speter	       Is there any simple coherent way to describe the two together?
151218334Speter	       What's going on here.  */
151318334Speter	    && (in != out
151418334Speter		|| (GET_CODE (in) == SUBREG
151518334Speter		    && (((GET_MODE_SIZE (GET_MODE (in)) + (UNITS_PER_WORD - 1))
151618334Speter			 / UNITS_PER_WORD)
151718334Speter			== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
151818334Speter			     + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
151918334Speter	    /* Make sure the operand fits in the reg that dies.  */
152090285Sobrien	    && (GET_MODE_SIZE (rel_mode)
152190285Sobrien		<= GET_MODE_SIZE (GET_MODE (XEXP (note, 0))))
152218334Speter	    && HARD_REGNO_MODE_OK (regno, inmode)
152370639Sobrien	    && HARD_REGNO_MODE_OK (regno, outmode))
152418334Speter	  {
152570639Sobrien	    unsigned int offs;
152670639Sobrien	    unsigned int nregs = MAX (HARD_REGNO_NREGS (regno, inmode),
152770639Sobrien				      HARD_REGNO_NREGS (regno, outmode));
152870639Sobrien
152970639Sobrien	    for (offs = 0; offs < nregs; offs++)
153070639Sobrien	      if (fixed_regs[regno + offs]
153170639Sobrien		  || ! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
153270639Sobrien					  regno + offs))
153370639Sobrien		break;
153470639Sobrien
153570639Sobrien	    if (offs == nregs)
153670639Sobrien	      {
153790285Sobrien		rld[i].reg_rtx = gen_rtx_REG (rel_mode, regno);
153870639Sobrien		break;
153970639Sobrien	      }
154018334Speter	  }
154118334Speter    }
154218334Speter
154318334Speter  if (out)
154418334Speter    output_reloadnum = i;
154518334Speter
154618334Speter  return i;
154718334Speter}
154818334Speter
154918334Speter/* Record an additional place we must replace a value
155018334Speter   for which we have already recorded a reload.
155118334Speter   RELOADNUM is the value returned by push_reload
155218334Speter   when the reload was recorded.
155318334Speter   This is used in insn patterns that use match_dup.  */
155418334Speter
155518334Speterstatic void
155618334Speterpush_replacement (loc, reloadnum, mode)
155718334Speter     rtx *loc;
155818334Speter     int reloadnum;
155918334Speter     enum machine_mode mode;
156018334Speter{
156118334Speter  if (replace_reloads)
156218334Speter    {
156390285Sobrien      struct replacement *r = &replacements[n_replacements++];
156418334Speter      r->what = reloadnum;
156518334Speter      r->where = loc;
156618334Speter      r->subreg_loc = 0;
156718334Speter      r->mode = mode;
156818334Speter    }
156918334Speter}
157018334Speter
157118334Speter/* Transfer all replacements that used to be in reload FROM to be in
157218334Speter   reload TO.  */
157318334Speter
157418334Spetervoid
157518334Spetertransfer_replacements (to, from)
157618334Speter     int to, from;
157718334Speter{
157818334Speter  int i;
157918334Speter
158018334Speter  for (i = 0; i < n_replacements; i++)
158118334Speter    if (replacements[i].what == from)
158218334Speter      replacements[i].what = to;
158318334Speter}
158418334Speter
158552557Sobrien/* IN_RTX is the value loaded by a reload that we now decided to inherit,
158652557Sobrien   or a subpart of it.  If we have any replacements registered for IN_RTX,
158752557Sobrien   cancel the reloads that were supposed to load them.
158852557Sobrien   Return non-zero if we canceled any reloads.  */
158952557Sobrienint
159052557Sobrienremove_address_replacements (in_rtx)
159152557Sobrien     rtx in_rtx;
159250605Sobrien{
159350605Sobrien  int i, j;
159452557Sobrien  char reload_flags[MAX_RELOADS];
159552557Sobrien  int something_changed = 0;
159650605Sobrien
159790285Sobrien  memset (reload_flags, 0, sizeof reload_flags);
159850605Sobrien  for (i = 0, j = 0; i < n_replacements; i++)
159950605Sobrien    {
160052557Sobrien      if (loc_mentioned_in_p (replacements[i].where, in_rtx))
160152557Sobrien	reload_flags[replacements[i].what] |= 1;
160252557Sobrien      else
160352557Sobrien	{
160452557Sobrien	  replacements[j++] = replacements[i];
160552557Sobrien	  reload_flags[replacements[i].what] |= 2;
160652557Sobrien	}
160750605Sobrien    }
160852557Sobrien  /* Note that the following store must be done before the recursive calls.  */
160952557Sobrien  n_replacements = j;
161052557Sobrien
161152557Sobrien  for (i = n_reloads - 1; i >= 0; i--)
161252557Sobrien    {
161352557Sobrien      if (reload_flags[i] == 1)
161452557Sobrien	{
161552557Sobrien	  deallocate_reload_reg (i);
161690285Sobrien	  remove_address_replacements (rld[i].in);
161790285Sobrien	  rld[i].in = 0;
161852557Sobrien	  something_changed = 1;
161952557Sobrien	}
162052557Sobrien    }
162152557Sobrien  return something_changed;
162250605Sobrien}
162350605Sobrien
162418334Speter/* If there is only one output reload, and it is not for an earlyclobber
162518334Speter   operand, try to combine it with a (logically unrelated) input reload
162618334Speter   to reduce the number of reload registers needed.
162718334Speter
162818334Speter   This is safe if the input reload does not appear in
162918334Speter   the value being output-reloaded, because this implies
163018334Speter   it is not needed any more once the original insn completes.
163118334Speter
163218334Speter   If that doesn't work, see we can use any of the registers that
163318334Speter   die in this insn as a reload register.  We can if it is of the right
163418334Speter   class and does not appear in the value being output-reloaded.  */
163518334Speter
163618334Speterstatic void
163718334Spetercombine_reloads ()
163818334Speter{
163918334Speter  int i;
164018334Speter  int output_reload = -1;
164118334Speter  int secondary_out = -1;
164218334Speter  rtx note;
164318334Speter
164418334Speter  /* Find the output reload; return unless there is exactly one
164518334Speter     and that one is mandatory.  */
164618334Speter
164718334Speter  for (i = 0; i < n_reloads; i++)
164890285Sobrien    if (rld[i].out != 0)
164918334Speter      {
165018334Speter	if (output_reload >= 0)
165118334Speter	  return;
165218334Speter	output_reload = i;
165318334Speter      }
165418334Speter
165590285Sobrien  if (output_reload < 0 || rld[output_reload].optional)
165618334Speter    return;
165718334Speter
165818334Speter  /* An input-output reload isn't combinable.  */
165918334Speter
166090285Sobrien  if (rld[output_reload].in != 0)
166118334Speter    return;
166218334Speter
166318334Speter  /* If this reload is for an earlyclobber operand, we can't do anything.  */
166490285Sobrien  if (earlyclobber_operand_p (rld[output_reload].out))
166518334Speter    return;
166618334Speter
166790285Sobrien  /* If there is a reload for part of the address of this operand, we would
166890285Sobrien     need to chnage it to RELOAD_FOR_OTHER_ADDRESS.  But that would extend
166990285Sobrien     its life to the point where doing this combine would not lower the
167090285Sobrien     number of spill registers needed.  */
167190285Sobrien  for (i = 0; i < n_reloads; i++)
167290285Sobrien    if ((rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
167390285Sobrien	 || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
167490285Sobrien	&& rld[i].opnum == rld[output_reload].opnum)
167590285Sobrien      return;
167690285Sobrien
167718334Speter  /* Check each input reload; can we combine it?  */
167818334Speter
167918334Speter  for (i = 0; i < n_reloads; i++)
168090285Sobrien    if (rld[i].in && ! rld[i].optional && ! rld[i].nocombine
168118334Speter	/* Life span of this reload must not extend past main insn.  */
168290285Sobrien	&& rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS
168390285Sobrien	&& rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
168490285Sobrien	&& rld[i].when_needed != RELOAD_OTHER
168590285Sobrien	&& (CLASS_MAX_NREGS (rld[i].class, rld[i].inmode)
168690285Sobrien	    == CLASS_MAX_NREGS (rld[output_reload].class,
168790285Sobrien				rld[output_reload].outmode))
168890285Sobrien	&& rld[i].inc == 0
168990285Sobrien	&& rld[i].reg_rtx == 0
169018334Speter#ifdef SECONDARY_MEMORY_NEEDED
169118334Speter	/* Don't combine two reloads with different secondary
169218334Speter	   memory locations.  */
169390285Sobrien	&& (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum] == 0
169490285Sobrien	    || secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] == 0
169590285Sobrien	    || rtx_equal_p (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum],
169690285Sobrien			    secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
169718334Speter#endif
169850605Sobrien	&& (SMALL_REGISTER_CLASSES
169990285Sobrien	    ? (rld[i].class == rld[output_reload].class)
170090285Sobrien	    : (reg_class_subset_p (rld[i].class,
170190285Sobrien				   rld[output_reload].class)
170290285Sobrien	       || reg_class_subset_p (rld[output_reload].class,
170390285Sobrien				      rld[i].class)))
170490285Sobrien	&& (MATCHES (rld[i].in, rld[output_reload].out)
170518334Speter	    /* Args reversed because the first arg seems to be
170618334Speter	       the one that we imagine being modified
170718334Speter	       while the second is the one that might be affected.  */
170890285Sobrien	    || (! reg_overlap_mentioned_for_reload_p (rld[output_reload].out,
170990285Sobrien						      rld[i].in)
171018334Speter		/* However, if the input is a register that appears inside
171118334Speter		   the output, then we also can't share.
171218334Speter		   Imagine (set (mem (reg 69)) (plus (reg 69) ...)).
171318334Speter		   If the same reload reg is used for both reg 69 and the
171418334Speter		   result to be stored in memory, then that result
171518334Speter		   will clobber the address of the memory ref.  */
171690285Sobrien		&& ! (GET_CODE (rld[i].in) == REG
171790285Sobrien		      && reg_overlap_mentioned_for_reload_p (rld[i].in,
171890285Sobrien							     rld[output_reload].out))))
171990285Sobrien	&& ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode)
172090285Sobrien	&& (reg_class_size[(int) rld[i].class]
172150605Sobrien	    || SMALL_REGISTER_CLASSES)
172218334Speter	/* We will allow making things slightly worse by combining an
172318334Speter	   input and an output, but no worse than that.  */
172490285Sobrien	&& (rld[i].when_needed == RELOAD_FOR_INPUT
172590285Sobrien	    || rld[i].when_needed == RELOAD_FOR_OUTPUT))
172618334Speter      {
172718334Speter	int j;
172818334Speter
172918334Speter	/* We have found a reload to combine with!  */
173090285Sobrien	rld[i].out = rld[output_reload].out;
173190285Sobrien	rld[i].out_reg = rld[output_reload].out_reg;
173290285Sobrien	rld[i].outmode = rld[output_reload].outmode;
173318334Speter	/* Mark the old output reload as inoperative.  */
173490285Sobrien	rld[output_reload].out = 0;
173518334Speter	/* The combined reload is needed for the entire insn.  */
173690285Sobrien	rld[i].when_needed = RELOAD_OTHER;
173750605Sobrien	/* If the output reload had a secondary reload, copy it.  */
173890285Sobrien	if (rld[output_reload].secondary_out_reload != -1)
173918334Speter	  {
174090285Sobrien	    rld[i].secondary_out_reload
174190285Sobrien	      = rld[output_reload].secondary_out_reload;
174290285Sobrien	    rld[i].secondary_out_icode
174390285Sobrien	      = rld[output_reload].secondary_out_icode;
174418334Speter	  }
174518334Speter
174618334Speter#ifdef SECONDARY_MEMORY_NEEDED
174718334Speter	/* Copy any secondary MEM.  */
174890285Sobrien	if (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] != 0)
174990285Sobrien	  secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum]
175090285Sobrien	    = secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum];
175118334Speter#endif
175250605Sobrien	/* If required, minimize the register class.  */
175390285Sobrien	if (reg_class_subset_p (rld[output_reload].class,
175490285Sobrien				rld[i].class))
175590285Sobrien	  rld[i].class = rld[output_reload].class;
175618334Speter
175718334Speter	/* Transfer all replacements from the old reload to the combined.  */
175818334Speter	for (j = 0; j < n_replacements; j++)
175918334Speter	  if (replacements[j].what == output_reload)
176018334Speter	    replacements[j].what = i;
176118334Speter
176218334Speter	return;
176318334Speter      }
176418334Speter
176518334Speter  /* If this insn has only one operand that is modified or written (assumed
176618334Speter     to be the first),  it must be the one corresponding to this reload.  It
176718334Speter     is safe to use anything that dies in this insn for that output provided
176818334Speter     that it does not occur in the output (we already know it isn't an
176918334Speter     earlyclobber.  If this is an asm insn, give up.  */
177018334Speter
177118334Speter  if (INSN_CODE (this_insn) == -1)
177218334Speter    return;
177318334Speter
177490285Sobrien  for (i = 1; i < insn_data[INSN_CODE (this_insn)].n_operands; i++)
177590285Sobrien    if (insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '='
177690285Sobrien	|| insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '+')
177718334Speter      return;
177818334Speter
177918334Speter  /* See if some hard register that dies in this insn and is not used in
178018334Speter     the output is the right class.  Only works if the register we pick
178118334Speter     up can fully hold our output reload.  */
178218334Speter  for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
178318334Speter    if (REG_NOTE_KIND (note) == REG_DEAD
178418334Speter	&& GET_CODE (XEXP (note, 0)) == REG
178518334Speter	&& ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
178690285Sobrien						 rld[output_reload].out)
178718334Speter	&& REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
178890285Sobrien	&& HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
178990285Sobrien	&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
179018334Speter			      REGNO (XEXP (note, 0)))
179190285Sobrien	&& (HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
179218334Speter	    <= HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), GET_MODE (XEXP (note, 0))))
179318334Speter	/* Ensure that a secondary or tertiary reload for this output
179418334Speter	   won't want this register.  */
179590285Sobrien	&& ((secondary_out = rld[output_reload].secondary_out_reload) == -1
179690285Sobrien	    || (! (TEST_HARD_REG_BIT
179790285Sobrien		   (reg_class_contents[(int) rld[secondary_out].class],
179890285Sobrien		    REGNO (XEXP (note, 0))))
179990285Sobrien		&& ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
180018334Speter		    ||  ! (TEST_HARD_REG_BIT
180190285Sobrien			   (reg_class_contents[(int) rld[secondary_out].class],
180218334Speter			    REGNO (XEXP (note, 0)))))))
180318334Speter	&& ! fixed_regs[REGNO (XEXP (note, 0))])
180418334Speter      {
180590285Sobrien	rld[output_reload].reg_rtx
180690285Sobrien	  = gen_rtx_REG (rld[output_reload].outmode,
180750605Sobrien			 REGNO (XEXP (note, 0)));
180818334Speter	return;
180918334Speter      }
181018334Speter}
181118334Speter
181218334Speter/* Try to find a reload register for an in-out reload (expressions IN and OUT).
181318334Speter   See if one of IN and OUT is a register that may be used;
181418334Speter   this is desirable since a spill-register won't be needed.
181518334Speter   If so, return the register rtx that proves acceptable.
181618334Speter
181718334Speter   INLOC and OUTLOC are locations where IN and OUT appear in the insn.
181818334Speter   CLASS is the register class required for the reload.
181918334Speter
182018334Speter   If FOR_REAL is >= 0, it is the number of the reload,
182118334Speter   and in some cases when it can be discovered that OUT doesn't need
182290285Sobrien   to be computed, clear out rld[FOR_REAL].out.
182318334Speter
182418334Speter   If FOR_REAL is -1, this should not be done, because this call
182550605Sobrien   is just to see if a register can be found, not to find and install it.
182618334Speter
182750605Sobrien   EARLYCLOBBER is non-zero if OUT is an earlyclobber operand.  This
182850605Sobrien   puts an additional constraint on being able to use IN for OUT since
182950605Sobrien   IN must not appear elsewhere in the insn (it is assumed that IN itself
183050605Sobrien   is safe from the earlyclobber).  */
183150605Sobrien
183218334Speterstatic rtx
183318334Speterfind_dummy_reload (real_in, real_out, inloc, outloc,
183450605Sobrien		   inmode, outmode, class, for_real, earlyclobber)
183518334Speter     rtx real_in, real_out;
183618334Speter     rtx *inloc, *outloc;
183718334Speter     enum machine_mode inmode, outmode;
183818334Speter     enum reg_class class;
183918334Speter     int for_real;
184050605Sobrien     int earlyclobber;
184118334Speter{
184218334Speter  rtx in = real_in;
184318334Speter  rtx out = real_out;
184418334Speter  int in_offset = 0;
184518334Speter  int out_offset = 0;
184618334Speter  rtx value = 0;
184718334Speter
184818334Speter  /* If operands exceed a word, we can't use either of them
184918334Speter     unless they have the same size.  */
185018334Speter  if (GET_MODE_SIZE (outmode) != GET_MODE_SIZE (inmode)
185118334Speter      && (GET_MODE_SIZE (outmode) > UNITS_PER_WORD
185218334Speter	  || GET_MODE_SIZE (inmode) > UNITS_PER_WORD))
185318334Speter    return 0;
185418334Speter
185590285Sobrien  /* Note that {in,out}_offset are needed only when 'in' or 'out'
185690285Sobrien     respectively refers to a hard register.  */
185790285Sobrien
185818334Speter  /* Find the inside of any subregs.  */
185918334Speter  while (GET_CODE (out) == SUBREG)
186018334Speter    {
186190285Sobrien      if (GET_CODE (SUBREG_REG (out)) == REG
186290285Sobrien	  && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER)
186390285Sobrien	out_offset += subreg_regno_offset (REGNO (SUBREG_REG (out)),
186490285Sobrien					   GET_MODE (SUBREG_REG (out)),
186590285Sobrien					   SUBREG_BYTE (out),
186690285Sobrien					   GET_MODE (out));
186718334Speter      out = SUBREG_REG (out);
186818334Speter    }
186918334Speter  while (GET_CODE (in) == SUBREG)
187018334Speter    {
187190285Sobrien      if (GET_CODE (SUBREG_REG (in)) == REG
187290285Sobrien	  && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER)
187390285Sobrien	in_offset += subreg_regno_offset (REGNO (SUBREG_REG (in)),
187490285Sobrien					  GET_MODE (SUBREG_REG (in)),
187590285Sobrien					  SUBREG_BYTE (in),
187690285Sobrien					  GET_MODE (in));
187718334Speter      in = SUBREG_REG (in);
187818334Speter    }
187918334Speter
188018334Speter  /* Narrow down the reg class, the same way push_reload will;
188118334Speter     otherwise we might find a dummy now, but push_reload won't.  */
188218334Speter  class = PREFERRED_RELOAD_CLASS (in, class);
188318334Speter
188418334Speter  /* See if OUT will do.  */
188518334Speter  if (GET_CODE (out) == REG
188618334Speter      && REGNO (out) < FIRST_PSEUDO_REGISTER)
188718334Speter    {
188890285Sobrien      unsigned int regno = REGNO (out) + out_offset;
188990285Sobrien      unsigned int nwords = HARD_REGNO_NREGS (regno, outmode);
189018334Speter      rtx saved_rtx;
189118334Speter
189218334Speter      /* When we consider whether the insn uses OUT,
189318334Speter	 ignore references within IN.  They don't prevent us
189418334Speter	 from copying IN into OUT, because those refs would
189518334Speter	 move into the insn that reloads IN.
189618334Speter
189718334Speter	 However, we only ignore IN in its role as this reload.
189818334Speter	 If the insn uses IN elsewhere and it contains OUT,
189918334Speter	 that counts.  We can't be sure it's the "same" operand
190018334Speter	 so it might not go through this reload.  */
190118334Speter      saved_rtx = *inloc;
190218334Speter      *inloc = const0_rtx;
190318334Speter
190418334Speter      if (regno < FIRST_PSEUDO_REGISTER
190596288Sobrien	  && HARD_REGNO_MODE_OK (regno, outmode)
190618334Speter	  && ! refers_to_regno_for_reload_p (regno, regno + nwords,
190718334Speter					     PATTERN (this_insn), outloc))
190818334Speter	{
190990285Sobrien	  unsigned int i;
191090285Sobrien
191118334Speter	  for (i = 0; i < nwords; i++)
191218334Speter	    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
191318334Speter				     regno + i))
191418334Speter	      break;
191518334Speter
191618334Speter	  if (i == nwords)
191718334Speter	    {
191818334Speter	      if (GET_CODE (real_out) == REG)
191918334Speter		value = real_out;
192018334Speter	      else
192150605Sobrien		value = gen_rtx_REG (outmode, regno);
192218334Speter	    }
192318334Speter	}
192418334Speter
192518334Speter      *inloc = saved_rtx;
192618334Speter    }
192718334Speter
192818334Speter  /* Consider using IN if OUT was not acceptable
192918334Speter     or if OUT dies in this insn (like the quotient in a divmod insn).
193018334Speter     We can't use IN unless it is dies in this insn,
193118334Speter     which means we must know accurately which hard regs are live.
193250605Sobrien     Also, the result can't go in IN if IN is used within OUT,
193350605Sobrien     or if OUT is an earlyclobber and IN appears elsewhere in the insn.  */
193418334Speter  if (hard_regs_live_known
193518334Speter      && GET_CODE (in) == REG
193618334Speter      && REGNO (in) < FIRST_PSEUDO_REGISTER
193718334Speter      && (value == 0
193818334Speter	  || find_reg_note (this_insn, REG_UNUSED, real_out))
193918334Speter      && find_reg_note (this_insn, REG_DEAD, real_in)
194018334Speter      && !fixed_regs[REGNO (in)]
194118334Speter      && HARD_REGNO_MODE_OK (REGNO (in),
194218334Speter			     /* The only case where out and real_out might
194318334Speter				have different modes is where real_out
194418334Speter				is a subreg, and in that case, out
194518334Speter				has a real mode.  */
194618334Speter			     (GET_MODE (out) != VOIDmode
194718334Speter			      ? GET_MODE (out) : outmode)))
194818334Speter    {
194990285Sobrien      unsigned int regno = REGNO (in) + in_offset;
195090285Sobrien      unsigned int nwords = HARD_REGNO_NREGS (regno, inmode);
195118334Speter
195290285Sobrien      if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, (rtx*) 0)
195318334Speter	  && ! hard_reg_set_here_p (regno, regno + nwords,
195450605Sobrien				    PATTERN (this_insn))
195550605Sobrien	  && (! earlyclobber
195650605Sobrien	      || ! refers_to_regno_for_reload_p (regno, regno + nwords,
195750605Sobrien						 PATTERN (this_insn), inloc)))
195818334Speter	{
195990285Sobrien	  unsigned int i;
196090285Sobrien
196118334Speter	  for (i = 0; i < nwords; i++)
196218334Speter	    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
196318334Speter				     regno + i))
196418334Speter	      break;
196518334Speter
196618334Speter	  if (i == nwords)
196718334Speter	    {
196818334Speter	      /* If we were going to use OUT as the reload reg
196918334Speter		 and changed our mind, it means OUT is a dummy that
197018334Speter		 dies here.  So don't bother copying value to it.  */
197118334Speter	      if (for_real >= 0 && value == real_out)
197290285Sobrien		rld[for_real].out = 0;
197318334Speter	      if (GET_CODE (real_in) == REG)
197418334Speter		value = real_in;
197518334Speter	      else
197650605Sobrien		value = gen_rtx_REG (inmode, regno);
197718334Speter	    }
197818334Speter	}
197918334Speter    }
198018334Speter
198118334Speter  return value;
198218334Speter}
198318334Speter
198418334Speter/* This page contains subroutines used mainly for determining
198518334Speter   whether the IN or an OUT of a reload can serve as the
198618334Speter   reload register.  */
198718334Speter
198818334Speter/* Return 1 if X is an operand of an insn that is being earlyclobbered.  */
198918334Speter
199070639Sobrienint
199118334Speterearlyclobber_operand_p (x)
199218334Speter     rtx x;
199318334Speter{
199418334Speter  int i;
199518334Speter
199618334Speter  for (i = 0; i < n_earlyclobbers; i++)
199718334Speter    if (reload_earlyclobbers[i] == x)
199818334Speter      return 1;
199918334Speter
200018334Speter  return 0;
200118334Speter}
200218334Speter
200318334Speter/* Return 1 if expression X alters a hard reg in the range
200418334Speter   from BEG_REGNO (inclusive) to END_REGNO (exclusive),
200518334Speter   either explicitly or in the guise of a pseudo-reg allocated to REGNO.
200618334Speter   X should be the body of an instruction.  */
200718334Speter
200818334Speterstatic int
200918334Speterhard_reg_set_here_p (beg_regno, end_regno, x)
201090285Sobrien     unsigned int beg_regno, end_regno;
201118334Speter     rtx x;
201218334Speter{
201318334Speter  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
201418334Speter    {
201590285Sobrien      rtx op0 = SET_DEST (x);
201690285Sobrien
201718334Speter      while (GET_CODE (op0) == SUBREG)
201818334Speter	op0 = SUBREG_REG (op0);
201918334Speter      if (GET_CODE (op0) == REG)
202018334Speter	{
202190285Sobrien	  unsigned int r = REGNO (op0);
202290285Sobrien
202318334Speter	  /* See if this reg overlaps range under consideration.  */
202418334Speter	  if (r < end_regno
202518334Speter	      && r + HARD_REGNO_NREGS (r, GET_MODE (op0)) > beg_regno)
202618334Speter	    return 1;
202718334Speter	}
202818334Speter    }
202918334Speter  else if (GET_CODE (x) == PARALLEL)
203018334Speter    {
203190285Sobrien      int i = XVECLEN (x, 0) - 1;
203290285Sobrien
203318334Speter      for (; i >= 0; i--)
203418334Speter	if (hard_reg_set_here_p (beg_regno, end_regno, XVECEXP (x, 0, i)))
203518334Speter	  return 1;
203618334Speter    }
203718334Speter
203818334Speter  return 0;
203918334Speter}
204018334Speter
204118334Speter/* Return 1 if ADDR is a valid memory address for mode MODE,
204218334Speter   and check that each pseudo reg has the proper kind of
204318334Speter   hard reg.  */
204418334Speter
204518334Speterint
204618334Speterstrict_memory_address_p (mode, addr)
204790285Sobrien     enum machine_mode mode ATTRIBUTE_UNUSED;
204890285Sobrien     rtx addr;
204918334Speter{
205018334Speter  GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
205118334Speter  return 0;
205218334Speter
205318334Speter win:
205418334Speter  return 1;
205518334Speter}
205618334Speter
205718334Speter/* Like rtx_equal_p except that it allows a REG and a SUBREG to match
205818334Speter   if they are the same hard reg, and has special hacks for
205918334Speter   autoincrement and autodecrement.
206018334Speter   This is specifically intended for find_reloads to use
206118334Speter   in determining whether two operands match.
206218334Speter   X is the operand whose number is the lower of the two.
206318334Speter
206418334Speter   The value is 2 if Y contains a pre-increment that matches
206518334Speter   a non-incrementing address in X.  */
206618334Speter
206718334Speter/* ??? To be completely correct, we should arrange to pass
206818334Speter   for X the output operand and for Y the input operand.
206918334Speter   For now, we assume that the output operand has the lower number
207018334Speter   because that is natural in (SET output (... input ...)).  */
207118334Speter
207218334Speterint
207318334Speteroperands_match_p (x, y)
207490285Sobrien     rtx x, y;
207518334Speter{
207690285Sobrien  int i;
207790285Sobrien  RTX_CODE code = GET_CODE (x);
207890285Sobrien  const char *fmt;
207918334Speter  int success_2;
208090285Sobrien
208118334Speter  if (x == y)
208218334Speter    return 1;
208318334Speter  if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
208418334Speter      && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
208518334Speter				  && GET_CODE (SUBREG_REG (y)) == REG)))
208618334Speter    {
208790285Sobrien      int j;
208818334Speter
208918334Speter      if (code == SUBREG)
209018334Speter	{
209118334Speter	  i = REGNO (SUBREG_REG (x));
209218334Speter	  if (i >= FIRST_PSEUDO_REGISTER)
209318334Speter	    goto slow;
209490285Sobrien	  i += subreg_regno_offset (REGNO (SUBREG_REG (x)),
209590285Sobrien				    GET_MODE (SUBREG_REG (x)),
209690285Sobrien				    SUBREG_BYTE (x),
209790285Sobrien				    GET_MODE (x));
209818334Speter	}
209918334Speter      else
210018334Speter	i = REGNO (x);
210118334Speter
210218334Speter      if (GET_CODE (y) == SUBREG)
210318334Speter	{
210418334Speter	  j = REGNO (SUBREG_REG (y));
210518334Speter	  if (j >= FIRST_PSEUDO_REGISTER)
210618334Speter	    goto slow;
210790285Sobrien	  j += subreg_regno_offset (REGNO (SUBREG_REG (y)),
210890285Sobrien				    GET_MODE (SUBREG_REG (y)),
210990285Sobrien				    SUBREG_BYTE (y),
211090285Sobrien				    GET_MODE (y));
211118334Speter	}
211218334Speter      else
211318334Speter	j = REGNO (y);
211418334Speter
211518334Speter      /* On a WORDS_BIG_ENDIAN machine, point to the last register of a
211618334Speter	 multiple hard register group, so that for example (reg:DI 0) and
211718334Speter	 (reg:SI 1) will be considered the same register.  */
211818334Speter      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
211918334Speter	  && i < FIRST_PSEUDO_REGISTER)
212018334Speter	i += (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD) - 1;
212118334Speter      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
212218334Speter	  && j < FIRST_PSEUDO_REGISTER)
212318334Speter	j += (GET_MODE_SIZE (GET_MODE (y)) / UNITS_PER_WORD) - 1;
212418334Speter
212518334Speter      return i == j;
212618334Speter    }
212718334Speter  /* If two operands must match, because they are really a single
212818334Speter     operand of an assembler insn, then two postincrements are invalid
212918334Speter     because the assembler insn would increment only once.
213018334Speter     On the other hand, an postincrement matches ordinary indexing
213118334Speter     if the postincrement is the output operand.  */
213290285Sobrien  if (code == POST_DEC || code == POST_INC || code == POST_MODIFY)
213318334Speter    return operands_match_p (XEXP (x, 0), y);
213418334Speter  /* Two preincrements are invalid
213518334Speter     because the assembler insn would increment only once.
213618334Speter     On the other hand, an preincrement matches ordinary indexing
213718334Speter     if the preincrement is the input operand.
213818334Speter     In this case, return 2, since some callers need to do special
213918334Speter     things when this happens.  */
214090285Sobrien  if (GET_CODE (y) == PRE_DEC || GET_CODE (y) == PRE_INC
214190285Sobrien      || GET_CODE (y) == PRE_MODIFY)
214218334Speter    return operands_match_p (x, XEXP (y, 0)) ? 2 : 0;
214318334Speter
214418334Speter slow:
214518334Speter
214690285Sobrien  /* Now we have disposed of all the cases
214718334Speter     in which different rtx codes can match.  */
214818334Speter  if (code != GET_CODE (y))
214918334Speter    return 0;
215018334Speter  if (code == LABEL_REF)
215118334Speter    return XEXP (x, 0) == XEXP (y, 0);
215218334Speter  if (code == SYMBOL_REF)
215318334Speter    return XSTR (x, 0) == XSTR (y, 0);
215418334Speter
215518334Speter  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
215618334Speter
215718334Speter  if (GET_MODE (x) != GET_MODE (y))
215818334Speter    return 0;
215918334Speter
216018334Speter  /* Compare the elements.  If any pair of corresponding elements
216118334Speter     fail to match, return 0 for the whole things.  */
216218334Speter
216318334Speter  success_2 = 0;
216418334Speter  fmt = GET_RTX_FORMAT (code);
216518334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
216618334Speter    {
216752557Sobrien      int val, j;
216818334Speter      switch (fmt[i])
216918334Speter	{
217018334Speter	case 'w':
217118334Speter	  if (XWINT (x, i) != XWINT (y, i))
217218334Speter	    return 0;
217318334Speter	  break;
217418334Speter
217518334Speter	case 'i':
217618334Speter	  if (XINT (x, i) != XINT (y, i))
217718334Speter	    return 0;
217818334Speter	  break;
217918334Speter
218018334Speter	case 'e':
218118334Speter	  val = operands_match_p (XEXP (x, i), XEXP (y, i));
218218334Speter	  if (val == 0)
218318334Speter	    return 0;
218418334Speter	  /* If any subexpression returns 2,
218518334Speter	     we should return 2 if we are successful.  */
218618334Speter	  if (val == 2)
218718334Speter	    success_2 = 1;
218818334Speter	  break;
218918334Speter
219018334Speter	case '0':
219118334Speter	  break;
219218334Speter
219352557Sobrien	case 'E':
219452557Sobrien	  if (XVECLEN (x, i) != XVECLEN (y, i))
219552557Sobrien	    return 0;
219652557Sobrien	  for (j = XVECLEN (x, i) - 1; j >= 0; --j)
219752557Sobrien	    {
219852557Sobrien	      val = operands_match_p (XVECEXP (x, i, j), XVECEXP (y, i, j));
219952557Sobrien	      if (val == 0)
220052557Sobrien		return 0;
220152557Sobrien	      if (val == 2)
220252557Sobrien		success_2 = 1;
220352557Sobrien	    }
220452557Sobrien	  break;
220552557Sobrien
220618334Speter	  /* It is believed that rtx's at this level will never
220718334Speter	     contain anything but integers and other rtx's,
220818334Speter	     except for within LABEL_REFs and SYMBOL_REFs.  */
220918334Speter	default:
221018334Speter	  abort ();
221118334Speter	}
221218334Speter    }
221318334Speter  return 1 + success_2;
221418334Speter}
221518334Speter
221618334Speter/* Describe the range of registers or memory referenced by X.
221790285Sobrien   If X is a register, set REG_FLAG and put the first register
221818334Speter   number into START and the last plus one into END.
221990285Sobrien   If X is a memory reference, put a base address into BASE
222018334Speter   and a range of integer offsets into START and END.
222190285Sobrien   If X is pushing on the stack, we can assume it causes no trouble,
222218334Speter   so we set the SAFE field.  */
222318334Speter
222418334Speterstatic struct decomposition
222518334Speterdecompose (x)
222618334Speter     rtx x;
222718334Speter{
222818334Speter  struct decomposition val;
222918334Speter  int all_const = 0;
223018334Speter
223118334Speter  val.reg_flag = 0;
223218334Speter  val.safe = 0;
223350605Sobrien  val.base = 0;
223418334Speter  if (GET_CODE (x) == MEM)
223518334Speter    {
223690285Sobrien      rtx base = NULL_RTX, offset = 0;
223718334Speter      rtx addr = XEXP (x, 0);
223818334Speter
223918334Speter      if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
224018334Speter	  || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
224118334Speter	{
224218334Speter	  val.base = XEXP (addr, 0);
224390285Sobrien	  val.start = -GET_MODE_SIZE (GET_MODE (x));
224418334Speter	  val.end = GET_MODE_SIZE (GET_MODE (x));
224518334Speter	  val.safe = REGNO (val.base) == STACK_POINTER_REGNUM;
224618334Speter	  return val;
224718334Speter	}
224818334Speter
224990285Sobrien      if (GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
225090285Sobrien	{
225190285Sobrien	  if (GET_CODE (XEXP (addr, 1)) == PLUS
225290285Sobrien	      && XEXP (addr, 0) == XEXP (XEXP (addr, 1), 0)
225390285Sobrien	      && CONSTANT_P (XEXP (XEXP (addr, 1), 1)))
225490285Sobrien	    {
225590285Sobrien	      val.base  = XEXP (addr, 0);
225690285Sobrien	      val.start = -INTVAL (XEXP (XEXP (addr, 1), 1));
225790285Sobrien	      val.end   = INTVAL (XEXP (XEXP (addr, 1), 1));
225890285Sobrien	      val.safe  = REGNO (val.base) == STACK_POINTER_REGNUM;
225990285Sobrien	      return val;
226090285Sobrien	    }
226190285Sobrien	}
226290285Sobrien
226318334Speter      if (GET_CODE (addr) == CONST)
226418334Speter	{
226518334Speter	  addr = XEXP (addr, 0);
226618334Speter	  all_const = 1;
226718334Speter	}
226818334Speter      if (GET_CODE (addr) == PLUS)
226918334Speter	{
227018334Speter	  if (CONSTANT_P (XEXP (addr, 0)))
227118334Speter	    {
227218334Speter	      base = XEXP (addr, 1);
227318334Speter	      offset = XEXP (addr, 0);
227418334Speter	    }
227518334Speter	  else if (CONSTANT_P (XEXP (addr, 1)))
227618334Speter	    {
227718334Speter	      base = XEXP (addr, 0);
227818334Speter	      offset = XEXP (addr, 1);
227918334Speter	    }
228018334Speter	}
228118334Speter
228218334Speter      if (offset == 0)
228318334Speter	{
228418334Speter	  base = addr;
228518334Speter	  offset = const0_rtx;
228690285Sobrien	}
228718334Speter      if (GET_CODE (offset) == CONST)
228818334Speter	offset = XEXP (offset, 0);
228918334Speter      if (GET_CODE (offset) == PLUS)
229018334Speter	{
229118334Speter	  if (GET_CODE (XEXP (offset, 0)) == CONST_INT)
229218334Speter	    {
229350605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 1));
229418334Speter	      offset = XEXP (offset, 0);
229518334Speter	    }
229618334Speter	  else if (GET_CODE (XEXP (offset, 1)) == CONST_INT)
229718334Speter	    {
229850605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 0));
229918334Speter	      offset = XEXP (offset, 1);
230018334Speter	    }
230118334Speter	  else
230218334Speter	    {
230350605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, offset);
230418334Speter	      offset = const0_rtx;
230518334Speter	    }
230618334Speter	}
230718334Speter      else if (GET_CODE (offset) != CONST_INT)
230818334Speter	{
230950605Sobrien	  base = gen_rtx_PLUS (GET_MODE (base), base, offset);
231018334Speter	  offset = const0_rtx;
231118334Speter	}
231218334Speter
231318334Speter      if (all_const && GET_CODE (base) == PLUS)
231450605Sobrien	base = gen_rtx_CONST (GET_MODE (base), base);
231518334Speter
231618334Speter      if (GET_CODE (offset) != CONST_INT)
231718334Speter	abort ();
231818334Speter
231918334Speter      val.start = INTVAL (offset);
232018334Speter      val.end = val.start + GET_MODE_SIZE (GET_MODE (x));
232118334Speter      val.base = base;
232218334Speter      return val;
232318334Speter    }
232418334Speter  else if (GET_CODE (x) == REG)
232518334Speter    {
232618334Speter      val.reg_flag = 1;
232790285Sobrien      val.start = true_regnum (x);
232818334Speter      if (val.start < 0)
232918334Speter	{
233018334Speter	  /* A pseudo with no hard reg.  */
233118334Speter	  val.start = REGNO (x);
233218334Speter	  val.end = val.start + 1;
233318334Speter	}
233418334Speter      else
233518334Speter	/* A hard reg.  */
233618334Speter	val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
233718334Speter    }
233818334Speter  else if (GET_CODE (x) == SUBREG)
233918334Speter    {
234018334Speter      if (GET_CODE (SUBREG_REG (x)) != REG)
234118334Speter	/* This could be more precise, but it's good enough.  */
234218334Speter	return decompose (SUBREG_REG (x));
234318334Speter      val.reg_flag = 1;
234490285Sobrien      val.start = true_regnum (x);
234518334Speter      if (val.start < 0)
234618334Speter	return decompose (SUBREG_REG (x));
234718334Speter      else
234818334Speter	/* A hard reg.  */
234918334Speter	val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
235018334Speter    }
235118334Speter  else if (CONSTANT_P (x)
235218334Speter	   /* This hasn't been assigned yet, so it can't conflict yet.  */
235318334Speter	   || GET_CODE (x) == SCRATCH)
235418334Speter    val.safe = 1;
235518334Speter  else
235618334Speter    abort ();
235718334Speter  return val;
235818334Speter}
235918334Speter
236018334Speter/* Return 1 if altering Y will not modify the value of X.
236118334Speter   Y is also described by YDATA, which should be decompose (Y).  */
236218334Speter
236318334Speterstatic int
236418334Speterimmune_p (x, y, ydata)
236518334Speter     rtx x, y;
236618334Speter     struct decomposition ydata;
236718334Speter{
236818334Speter  struct decomposition xdata;
236918334Speter
237018334Speter  if (ydata.reg_flag)
237190285Sobrien    return !refers_to_regno_for_reload_p (ydata.start, ydata.end, x, (rtx*) 0);
237218334Speter  if (ydata.safe)
237318334Speter    return 1;
237418334Speter
237518334Speter  if (GET_CODE (y) != MEM)
237618334Speter    abort ();
237718334Speter  /* If Y is memory and X is not, Y can't affect X.  */
237818334Speter  if (GET_CODE (x) != MEM)
237918334Speter    return 1;
238018334Speter
238190285Sobrien  xdata = decompose (x);
238218334Speter
238318334Speter  if (! rtx_equal_p (xdata.base, ydata.base))
238418334Speter    {
238518334Speter      /* If bases are distinct symbolic constants, there is no overlap.  */
238618334Speter      if (CONSTANT_P (xdata.base) && CONSTANT_P (ydata.base))
238718334Speter	return 1;
238818334Speter      /* Constants and stack slots never overlap.  */
238918334Speter      if (CONSTANT_P (xdata.base)
239018334Speter	  && (ydata.base == frame_pointer_rtx
239118334Speter	      || ydata.base == hard_frame_pointer_rtx
239218334Speter	      || ydata.base == stack_pointer_rtx))
239318334Speter	return 1;
239418334Speter      if (CONSTANT_P (ydata.base)
239518334Speter	  && (xdata.base == frame_pointer_rtx
239618334Speter	      || xdata.base == hard_frame_pointer_rtx
239718334Speter	      || xdata.base == stack_pointer_rtx))
239818334Speter	return 1;
239918334Speter      /* If either base is variable, we don't know anything.  */
240018334Speter      return 0;
240118334Speter    }
240218334Speter
240318334Speter  return (xdata.start >= ydata.end || ydata.start >= xdata.end);
240418334Speter}
240518334Speter
240618334Speter/* Similar, but calls decompose.  */
240718334Speter
240818334Speterint
240918334Spetersafe_from_earlyclobber (op, clobber)
241018334Speter     rtx op, clobber;
241118334Speter{
241218334Speter  struct decomposition early_data;
241318334Speter
241418334Speter  early_data = decompose (clobber);
241518334Speter  return immune_p (op, clobber, early_data);
241618334Speter}
241718334Speter
241818334Speter/* Main entry point of this file: search the body of INSN
241918334Speter   for values that need reloading and record them with push_reload.
242018334Speter   REPLACE nonzero means record also where the values occur
242118334Speter   so that subst_reloads can be used.
242218334Speter
242318334Speter   IND_LEVELS says how many levels of indirection are supported by this
242418334Speter   machine; a value of zero means that a memory reference is not a valid
242518334Speter   memory address.
242618334Speter
242718334Speter   LIVE_KNOWN says we have valid information about which hard
242818334Speter   regs are live at each point in the program; this is true when
242918334Speter   we are called from global_alloc but false when stupid register
243018334Speter   allocation has been done.
243118334Speter
243218334Speter   RELOAD_REG_P if nonzero is a vector indexed by hard reg number
243318334Speter   which is nonnegative if the reg has been commandeered for reloading into.
243418334Speter   It is copied into STATIC_RELOAD_REG_P and referenced from there
243552557Sobrien   by various subroutines.
243618334Speter
243752557Sobrien   Return TRUE if some operands need to be changed, because of swapping
243852557Sobrien   commutative operands, reg_equiv_address substitution, or whatever.  */
243952557Sobrien
244052557Sobrienint
244118334Speterfind_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
244218334Speter     rtx insn;
244318334Speter     int replace, ind_levels;
244418334Speter     int live_known;
244518334Speter     short *reload_reg_p;
244618334Speter{
244790285Sobrien  int insn_code_number;
244890285Sobrien  int i, j;
244918334Speter  int noperands;
245018334Speter  /* These start out as the constraints for the insn
245118334Speter     and they are chewed up as we consider alternatives.  */
245218334Speter  char *constraints[MAX_RECOG_OPERANDS];
245318334Speter  /* These are the preferred classes for an operand, or NO_REGS if it isn't
245418334Speter     a register.  */
245518334Speter  enum reg_class preferred_class[MAX_RECOG_OPERANDS];
245618334Speter  char pref_or_nothing[MAX_RECOG_OPERANDS];
245718334Speter  /* Nonzero for a MEM operand whose entire address needs a reload.  */
245818334Speter  int address_reloaded[MAX_RECOG_OPERANDS];
245918334Speter  /* Value of enum reload_type to use for operand.  */
246018334Speter  enum reload_type operand_type[MAX_RECOG_OPERANDS];
246118334Speter  /* Value of enum reload_type to use within address of operand.  */
246218334Speter  enum reload_type address_type[MAX_RECOG_OPERANDS];
246318334Speter  /* Save the usage of each operand.  */
246418334Speter  enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS];
246518334Speter  int no_input_reloads = 0, no_output_reloads = 0;
246618334Speter  int n_alternatives;
246718334Speter  int this_alternative[MAX_RECOG_OPERANDS];
246890285Sobrien  char this_alternative_match_win[MAX_RECOG_OPERANDS];
246918334Speter  char this_alternative_win[MAX_RECOG_OPERANDS];
247018334Speter  char this_alternative_offmemok[MAX_RECOG_OPERANDS];
247118334Speter  char this_alternative_earlyclobber[MAX_RECOG_OPERANDS];
247218334Speter  int this_alternative_matches[MAX_RECOG_OPERANDS];
247318334Speter  int swapped;
247418334Speter  int goal_alternative[MAX_RECOG_OPERANDS];
247518334Speter  int this_alternative_number;
247690285Sobrien  int goal_alternative_number = 0;
247718334Speter  int operand_reloadnum[MAX_RECOG_OPERANDS];
247818334Speter  int goal_alternative_matches[MAX_RECOG_OPERANDS];
247918334Speter  int goal_alternative_matched[MAX_RECOG_OPERANDS];
248090285Sobrien  char goal_alternative_match_win[MAX_RECOG_OPERANDS];
248118334Speter  char goal_alternative_win[MAX_RECOG_OPERANDS];
248218334Speter  char goal_alternative_offmemok[MAX_RECOG_OPERANDS];
248318334Speter  char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
248418334Speter  int goal_alternative_swapped;
248518334Speter  int best;
248618334Speter  int commutative;
248718334Speter  char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
248818334Speter  rtx substed_operand[MAX_RECOG_OPERANDS];
248918334Speter  rtx body = PATTERN (insn);
249018334Speter  rtx set = single_set (insn);
249190285Sobrien  int goal_earlyclobber = 0, this_earlyclobber;
249218334Speter  enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
249352557Sobrien  int retval = 0;
249418334Speter
249518334Speter  this_insn = insn;
249618334Speter  n_reloads = 0;
249718334Speter  n_replacements = 0;
249818334Speter  n_earlyclobbers = 0;
249918334Speter  replace_reloads = replace;
250018334Speter  hard_regs_live_known = live_known;
250118334Speter  static_reload_reg_p = reload_reg_p;
250218334Speter
250318334Speter  /* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
250418334Speter     neither are insns that SET cc0.  Insns that use CC0 are not allowed
250518334Speter     to have any input reloads.  */
250618334Speter  if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)
250718334Speter    no_output_reloads = 1;
250818334Speter
250918334Speter#ifdef HAVE_cc0
251018334Speter  if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
251118334Speter    no_input_reloads = 1;
251218334Speter  if (reg_set_p (cc0_rtx, PATTERN (insn)))
251318334Speter    no_output_reloads = 1;
251418334Speter#endif
251590285Sobrien
251618334Speter#ifdef SECONDARY_MEMORY_NEEDED
251718334Speter  /* The eliminated forms of any secondary memory locations are per-insn, so
251818334Speter     clear them out here.  */
251918334Speter
252090285Sobrien  memset ((char *) secondary_memlocs_elim, 0, sizeof secondary_memlocs_elim);
252118334Speter#endif
252218334Speter
252352557Sobrien  /* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
252452557Sobrien     is cheap to move between them.  If it is not, there may not be an insn
252552557Sobrien     to do the copy, so we may need a reload.  */
252652557Sobrien  if (GET_CODE (body) == SET
252752557Sobrien      && GET_CODE (SET_DEST (body)) == REG
252852557Sobrien      && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
252952557Sobrien      && GET_CODE (SET_SRC (body)) == REG
253052557Sobrien      && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
253190285Sobrien      && REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)),
253290285Sobrien			     REGNO_REG_CLASS (REGNO (SET_SRC (body))),
253352557Sobrien			     REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
253452557Sobrien    return 0;
253518334Speter
253652557Sobrien  extract_insn (insn);
253718334Speter
253890285Sobrien  noperands = reload_n_operands = recog_data.n_operands;
253990285Sobrien  n_alternatives = recog_data.n_alternatives;
254018334Speter
254152557Sobrien  /* Just return "no reloads" if insn has no operands with constraints.  */
254252557Sobrien  if (noperands == 0 || n_alternatives == 0)
254352557Sobrien    return 0;
254418334Speter
254552557Sobrien  insn_code_number = INSN_CODE (insn);
254652557Sobrien  this_insn_is_asm = insn_code_number < 0;
254718334Speter
254890285Sobrien  memcpy (operand_mode, recog_data.operand_mode,
254990285Sobrien	  noperands * sizeof (enum machine_mode));
255090285Sobrien  memcpy (constraints, recog_data.constraints, noperands * sizeof (char *));
255118334Speter
255218334Speter  commutative = -1;
255318334Speter
255418334Speter  /* If we will need to know, later, whether some pair of operands
255518334Speter     are the same, we must compare them now and save the result.
255618334Speter     Reloading the base and index registers will clobber them
255718334Speter     and afterward they will fail to match.  */
255818334Speter
255918334Speter  for (i = 0; i < noperands; i++)
256018334Speter    {
256190285Sobrien      char *p;
256290285Sobrien      int c;
256318334Speter
256490285Sobrien      substed_operand[i] = recog_data.operand[i];
256518334Speter      p = constraints[i];
256618334Speter
256718334Speter      modified[i] = RELOAD_READ;
256818334Speter
256990285Sobrien      /* Scan this operand's constraint to see if it is an output operand,
257018334Speter	 an in-out operand, is commutative, or should match another.  */
257118334Speter
257250605Sobrien      while ((c = *p++))
257318334Speter	{
257418334Speter	  if (c == '=')
257518334Speter	    modified[i] = RELOAD_WRITE;
257618334Speter	  else if (c == '+')
257718334Speter	    modified[i] = RELOAD_READ_WRITE;
257818334Speter	  else if (c == '%')
257918334Speter	    {
258018334Speter	      /* The last operand should not be marked commutative.  */
258118334Speter	      if (i == noperands - 1)
258252557Sobrien		abort ();
258352557Sobrien
258452557Sobrien	      commutative = i;
258518334Speter	    }
258690285Sobrien	  else if (ISDIGIT (c))
258718334Speter	    {
258890285Sobrien	      c = strtoul (p - 1, &p, 10);
258990285Sobrien
259018334Speter	      operands_match[c][i]
259190285Sobrien		= operands_match_p (recog_data.operand[c],
259290285Sobrien				    recog_data.operand[i]);
259318334Speter
259418334Speter	      /* An operand may not match itself.  */
259518334Speter	      if (c == i)
259652557Sobrien		abort ();
259718334Speter
259818334Speter	      /* If C can be commuted with C+1, and C might need to match I,
259918334Speter		 then C+1 might also need to match I.  */
260018334Speter	      if (commutative >= 0)
260118334Speter		{
260218334Speter		  if (c == commutative || c == commutative + 1)
260318334Speter		    {
260418334Speter		      int other = c + (c == commutative ? 1 : -1);
260518334Speter		      operands_match[other][i]
260690285Sobrien			= operands_match_p (recog_data.operand[other],
260790285Sobrien					    recog_data.operand[i]);
260818334Speter		    }
260918334Speter		  if (i == commutative || i == commutative + 1)
261018334Speter		    {
261118334Speter		      int other = i + (i == commutative ? 1 : -1);
261218334Speter		      operands_match[c][other]
261390285Sobrien			= operands_match_p (recog_data.operand[c],
261490285Sobrien					    recog_data.operand[other]);
261518334Speter		    }
261618334Speter		  /* Note that C is supposed to be less than I.
261718334Speter		     No need to consider altering both C and I because in
261818334Speter		     that case we would alter one into the other.  */
261918334Speter		}
262018334Speter	    }
262118334Speter	}
262218334Speter    }
262318334Speter
262418334Speter  /* Examine each operand that is a memory reference or memory address
262518334Speter     and reload parts of the addresses into index registers.
262618334Speter     Also here any references to pseudo regs that didn't get hard regs
262718334Speter     but are equivalent to constants get replaced in the insn itself
262890285Sobrien     with those constants.  Nobody will ever see them again.
262918334Speter
263018334Speter     Finally, set up the preferred classes of each operand.  */
263118334Speter
263218334Speter  for (i = 0; i < noperands; i++)
263318334Speter    {
263490285Sobrien      RTX_CODE code = GET_CODE (recog_data.operand[i]);
263518334Speter
263618334Speter      address_reloaded[i] = 0;
263718334Speter      operand_type[i] = (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT
263818334Speter			 : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT
263918334Speter			 : RELOAD_OTHER);
264018334Speter      address_type[i]
264118334Speter	= (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT_ADDRESS
264218334Speter	   : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT_ADDRESS
264318334Speter	   : RELOAD_OTHER);
264418334Speter
264518334Speter      if (*constraints[i] == 0)
264618334Speter	/* Ignore things like match_operator operands.  */
264718334Speter	;
264818334Speter      else if (constraints[i][0] == 'p')
264918334Speter	{
265090285Sobrien	  find_reloads_address (VOIDmode, (rtx*) 0,
265190285Sobrien				recog_data.operand[i],
265290285Sobrien				recog_data.operand_loc[i],
265350605Sobrien				i, operand_type[i], ind_levels, insn);
265450605Sobrien
265590285Sobrien	  /* If we now have a simple operand where we used to have a
265650605Sobrien	     PLUS or MULT, re-recognize and try again.  */
265790285Sobrien	  if ((GET_RTX_CLASS (GET_CODE (*recog_data.operand_loc[i])) == 'o'
265890285Sobrien	       || GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
265990285Sobrien	      && (GET_CODE (recog_data.operand[i]) == MULT
266090285Sobrien		  || GET_CODE (recog_data.operand[i]) == PLUS))
266150605Sobrien	    {
266250605Sobrien	      INSN_CODE (insn) = -1;
266352557Sobrien	      retval = find_reloads (insn, replace, ind_levels, live_known,
266452557Sobrien				     reload_reg_p);
266552557Sobrien	      return retval;
266650605Sobrien	    }
266750605Sobrien
266890285Sobrien	  recog_data.operand[i] = *recog_data.operand_loc[i];
266990285Sobrien	  substed_operand[i] = recog_data.operand[i];
267018334Speter	}
267118334Speter      else if (code == MEM)
267218334Speter	{
267352557Sobrien	  address_reloaded[i]
267490285Sobrien	    = find_reloads_address (GET_MODE (recog_data.operand[i]),
267590285Sobrien				    recog_data.operand_loc[i],
267690285Sobrien				    XEXP (recog_data.operand[i], 0),
267790285Sobrien				    &XEXP (recog_data.operand[i], 0),
267852557Sobrien				    i, address_type[i], ind_levels, insn);
267990285Sobrien	  recog_data.operand[i] = *recog_data.operand_loc[i];
268090285Sobrien	  substed_operand[i] = recog_data.operand[i];
268118334Speter	}
268218334Speter      else if (code == SUBREG)
268350605Sobrien	{
268490285Sobrien	  rtx reg = SUBREG_REG (recog_data.operand[i]);
268550605Sobrien	  rtx op
268690285Sobrien	    = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
268750605Sobrien				   ind_levels,
268850605Sobrien				   set != 0
268990285Sobrien				   && &SET_DEST (set) == recog_data.operand_loc[i],
269090285Sobrien				   insn,
269190285Sobrien				   &address_reloaded[i]);
269250605Sobrien
269350605Sobrien	  /* If we made a MEM to load (a part of) the stackslot of a pseudo
269450605Sobrien	     that didn't get a hard register, emit a USE with a REG_EQUAL
269550605Sobrien	     note in front so that we might inherit a previous, possibly
269650605Sobrien	     wider reload.  */
269790285Sobrien
269852557Sobrien	  if (replace
269952557Sobrien	      && GET_CODE (op) == MEM
270050605Sobrien	      && GET_CODE (reg) == REG
270150605Sobrien	      && (GET_MODE_SIZE (GET_MODE (reg))
270250605Sobrien		  >= GET_MODE_SIZE (GET_MODE (op))))
270390285Sobrien	    set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
270490285Sobrien						   insn),
270590285Sobrien				 REG_EQUAL, reg_equiv_memory_loc[REGNO (reg)]);
270650605Sobrien
270790285Sobrien	  substed_operand[i] = recog_data.operand[i] = op;
270850605Sobrien	}
270950605Sobrien      else if (code == PLUS || GET_RTX_CLASS (code) == '1')
271050605Sobrien	/* We can get a PLUS as an "operand" as a result of register
271150605Sobrien	   elimination.  See eliminate_regs and gen_reload.  We handle
271250605Sobrien	   a unary operator by reloading the operand.  */
271390285Sobrien	substed_operand[i] = recog_data.operand[i]
271490285Sobrien	  = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
271590285Sobrien				 ind_levels, 0, insn,
271690285Sobrien				 &address_reloaded[i]);
271718334Speter      else if (code == REG)
271818334Speter	{
271918334Speter	  /* This is equivalent to calling find_reloads_toplev.
272018334Speter	     The code is duplicated for speed.
272118334Speter	     When we find a pseudo always equivalent to a constant,
272218334Speter	     we replace it by the constant.  We must be sure, however,
272318334Speter	     that we don't try to replace it in the insn in which it
272490285Sobrien	     is being set.  */
272590285Sobrien	  int regno = REGNO (recog_data.operand[i]);
272618334Speter	  if (reg_equiv_constant[regno] != 0
272790285Sobrien	      && (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i]))
272850605Sobrien	    {
272950605Sobrien	      /* Record the existing mode so that the check if constants are
273090285Sobrien		 allowed will work when operand_mode isn't specified.  */
273150605Sobrien
273250605Sobrien	      if (operand_mode[i] == VOIDmode)
273390285Sobrien		operand_mode[i] = GET_MODE (recog_data.operand[i]);
273450605Sobrien
273590285Sobrien	      substed_operand[i] = recog_data.operand[i]
273690285Sobrien		= reg_equiv_constant[regno];
273750605Sobrien	    }
273852557Sobrien	  if (reg_equiv_memory_loc[regno] != 0
273952557Sobrien	      && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
274052557Sobrien	    /* We need not give a valid is_set_dest argument since the case
274152557Sobrien	       of a constant equivalence was checked above.  */
274290285Sobrien	    substed_operand[i] = recog_data.operand[i]
274390285Sobrien	      = find_reloads_toplev (recog_data.operand[i], i, address_type[i],
274490285Sobrien				     ind_levels, 0, insn,
274590285Sobrien				     &address_reloaded[i]);
274618334Speter	}
274718334Speter      /* If the operand is still a register (we didn't replace it with an
274818334Speter	 equivalent), get the preferred class to reload it into.  */
274990285Sobrien      code = GET_CODE (recog_data.operand[i]);
275018334Speter      preferred_class[i]
275190285Sobrien	= ((code == REG && REGNO (recog_data.operand[i])
275290285Sobrien	    >= FIRST_PSEUDO_REGISTER)
275390285Sobrien	   ? reg_preferred_class (REGNO (recog_data.operand[i]))
275490285Sobrien	   : NO_REGS);
275518334Speter      pref_or_nothing[i]
275690285Sobrien	= (code == REG
275790285Sobrien	   && REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER
275890285Sobrien	   && reg_alternate_class (REGNO (recog_data.operand[i])) == NO_REGS);
275918334Speter    }
276018334Speter
276118334Speter  /* If this is simply a copy from operand 1 to operand 0, merge the
276218334Speter     preferred classes for the operands.  */
276390285Sobrien  if (set != 0 && noperands >= 2 && recog_data.operand[0] == SET_DEST (set)
276490285Sobrien      && recog_data.operand[1] == SET_SRC (set))
276518334Speter    {
276618334Speter      preferred_class[0] = preferred_class[1]
276718334Speter	= reg_class_subunion[(int) preferred_class[0]][(int) preferred_class[1]];
276818334Speter      pref_or_nothing[0] |= pref_or_nothing[1];
276918334Speter      pref_or_nothing[1] |= pref_or_nothing[0];
277018334Speter    }
277118334Speter
277218334Speter  /* Now see what we need for pseudo-regs that didn't get hard regs
277318334Speter     or got the wrong kind of hard reg.  For this, we must consider
277418334Speter     all the operands together against the register constraints.  */
277518334Speter
277650605Sobrien  best = MAX_RECOG_OPERANDS * 2 + 600;
277718334Speter
277818334Speter  swapped = 0;
277918334Speter  goal_alternative_swapped = 0;
278018334Speter try_swapped:
278118334Speter
278218334Speter  /* The constraints are made of several alternatives.
278318334Speter     Each operand's constraint looks like foo,bar,... with commas
278418334Speter     separating the alternatives.  The first alternatives for all
278518334Speter     operands go together, the second alternatives go together, etc.
278618334Speter
278718334Speter     First loop over alternatives.  */
278818334Speter
278918334Speter  for (this_alternative_number = 0;
279018334Speter       this_alternative_number < n_alternatives;
279118334Speter       this_alternative_number++)
279218334Speter    {
279318334Speter      /* Loop over operands for one constraint alternative.  */
279418334Speter      /* LOSERS counts those that don't fit this alternative
279518334Speter	 and would require loading.  */
279618334Speter      int losers = 0;
279718334Speter      /* BAD is set to 1 if it some operand can't fit this alternative
279818334Speter	 even after reloading.  */
279918334Speter      int bad = 0;
280018334Speter      /* REJECT is a count of how undesirable this alternative says it is
280118334Speter	 if any reloading is required.  If the alternative matches exactly
280218334Speter	 then REJECT is ignored, but otherwise it gets this much
280390285Sobrien	 counted against it in addition to the reloading needed.  Each
280418334Speter	 ? counts three times here since we want the disparaging caused by
280518334Speter	 a bad register class to only count 1/3 as much.  */
280618334Speter      int reject = 0;
280718334Speter
280818334Speter      this_earlyclobber = 0;
280918334Speter
281018334Speter      for (i = 0; i < noperands; i++)
281118334Speter	{
281290285Sobrien	  char *p = constraints[i];
281390285Sobrien	  int win = 0;
281490285Sobrien	  int did_match = 0;
281590285Sobrien	  /* 0 => this operand can be reloaded somehow for this alternative.  */
281618334Speter	  int badop = 1;
281718334Speter	  /* 0 => this operand can be reloaded if the alternative allows regs.  */
281818334Speter	  int winreg = 0;
281918334Speter	  int c;
282090285Sobrien	  rtx operand = recog_data.operand[i];
282118334Speter	  int offset = 0;
282218334Speter	  /* Nonzero means this is a MEM that must be reloaded into a reg
282318334Speter	     regardless of what the constraint says.  */
282418334Speter	  int force_reload = 0;
282518334Speter	  int offmemok = 0;
282618334Speter	  /* Nonzero if a constant forced into memory would be OK for this
282718334Speter	     operand.  */
282818334Speter	  int constmemok = 0;
282918334Speter	  int earlyclobber = 0;
283018334Speter
283150605Sobrien	  /* If the predicate accepts a unary operator, it means that
283290285Sobrien	     we need to reload the operand, but do not do this for
283350605Sobrien	     match_operator and friends.  */
283450605Sobrien	  if (GET_RTX_CLASS (GET_CODE (operand)) == '1' && *p != 0)
283550605Sobrien	    operand = XEXP (operand, 0);
283650605Sobrien
283718334Speter	  /* If the operand is a SUBREG, extract
283818334Speter	     the REG or MEM (or maybe even a constant) within.
283918334Speter	     (Constants can occur as a result of reg_equiv_constant.)  */
284018334Speter
284118334Speter	  while (GET_CODE (operand) == SUBREG)
284218334Speter	    {
284390285Sobrien	      /* Offset only matters when operand is a REG and
284490285Sobrien		 it is a hard reg.  This is because it is passed
284590285Sobrien		 to reg_fits_class_p if it is a REG and all pseudos
284690285Sobrien		 return 0 from that function.  */
284790285Sobrien	      if (GET_CODE (SUBREG_REG (operand)) == REG
284890285Sobrien		  && REGNO (SUBREG_REG (operand)) < FIRST_PSEUDO_REGISTER)
284990285Sobrien		{
285090285Sobrien		  offset += subreg_regno_offset (REGNO (SUBREG_REG (operand)),
285190285Sobrien						 GET_MODE (SUBREG_REG (operand)),
285290285Sobrien						 SUBREG_BYTE (operand),
285390285Sobrien						 GET_MODE (operand));
285490285Sobrien		}
285518334Speter	      operand = SUBREG_REG (operand);
285650605Sobrien	      /* Force reload if this is a constant or PLUS or if there may
285718334Speter		 be a problem accessing OPERAND in the outer mode.  */
285818334Speter	      if (CONSTANT_P (operand)
285918334Speter		  || GET_CODE (operand) == PLUS
286018334Speter		  /* We must force a reload of paradoxical SUBREGs
286118334Speter		     of a MEM because the alignment of the inner value
286218334Speter		     may not be enough to do the outer reference.  On
286318334Speter		     big-endian machines, it may also reference outside
286418334Speter		     the object.
286518334Speter
286618334Speter		     On machines that extend byte operations and we have a
286718334Speter		     SUBREG where both the inner and outer modes are no wider
286818334Speter		     than a word and the inner mode is narrower, is integral,
286918334Speter		     and gets extended when loaded from memory, combine.c has
287018334Speter		     made assumptions about the behavior of the machine in such
287118334Speter		     register access.  If the data is, in fact, in memory we
287218334Speter		     must always load using the size assumed to be in the
287390285Sobrien		     register and let the insn do the different-sized
287450605Sobrien		     accesses.
287550605Sobrien
287690285Sobrien		     This is doubly true if WORD_REGISTER_OPERATIONS.  In
287750605Sobrien		     this case eliminate_regs has left non-paradoxical
287850605Sobrien		     subregs for push_reloads to see.  Make sure it does
287950605Sobrien		     by forcing the reload.
288050605Sobrien
288150605Sobrien		     ??? When is it right at this stage to have a subreg
288250605Sobrien		     of a mem that is _not_ to be handled specialy?  IMO
288350605Sobrien		     those should have been reduced to just a mem.  */
288418334Speter		  || ((GET_CODE (operand) == MEM
288518334Speter		       || (GET_CODE (operand)== REG
288618334Speter			   && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
288750605Sobrien#ifndef WORD_REGISTER_OPERATIONS
288818334Speter		      && (((GET_MODE_BITSIZE (GET_MODE (operand))
288918334Speter			    < BIGGEST_ALIGNMENT)
289018334Speter			   && (GET_MODE_SIZE (operand_mode[i])
289118334Speter			       > GET_MODE_SIZE (GET_MODE (operand))))
289218334Speter			  || (GET_CODE (operand) == MEM && BYTES_BIG_ENDIAN)
289318334Speter#ifdef LOAD_EXTEND_OP
289418334Speter			  || (GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
289518334Speter			      && (GET_MODE_SIZE (GET_MODE (operand))
289618334Speter				  <= UNITS_PER_WORD)
289718334Speter			      && (GET_MODE_SIZE (operand_mode[i])
289818334Speter				  > GET_MODE_SIZE (GET_MODE (operand)))
289918334Speter			      && INTEGRAL_MODE_P (GET_MODE (operand))
290018334Speter			      && LOAD_EXTEND_OP (GET_MODE (operand)) != NIL)
290118334Speter#endif
290250605Sobrien			  )
290350605Sobrien#endif
290450605Sobrien		      )
290590285Sobrien		  /* This following hunk of code should no longer be
290690285Sobrien		     needed at all with SUBREG_BYTE.  If you need this
290790285Sobrien		     code back, please explain to me why so I can
290890285Sobrien		     fix the real problem.  -DaveM */
290990285Sobrien#if 0
291018334Speter		  /* Subreg of a hard reg which can't handle the subreg's mode
291118334Speter		     or which would handle that mode in the wrong number of
291218334Speter		     registers for subregging to work.  */
291318334Speter		  || (GET_CODE (operand) == REG
291418334Speter		      && REGNO (operand) < FIRST_PSEUDO_REGISTER
291518334Speter		      && ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
291618334Speter			   && (GET_MODE_SIZE (GET_MODE (operand))
291718334Speter			       > UNITS_PER_WORD)
291818334Speter			   && ((GET_MODE_SIZE (GET_MODE (operand))
291918334Speter				/ UNITS_PER_WORD)
292018334Speter			       != HARD_REGNO_NREGS (REGNO (operand),
292118334Speter						    GET_MODE (operand))))
292218334Speter			  || ! HARD_REGNO_MODE_OK (REGNO (operand) + offset,
292390285Sobrien						   operand_mode[i])))
292490285Sobrien#endif
292590285Sobrien		  )
292618334Speter		force_reload = 1;
292718334Speter	    }
292818334Speter
292918334Speter	  this_alternative[i] = (int) NO_REGS;
293018334Speter	  this_alternative_win[i] = 0;
293190285Sobrien	  this_alternative_match_win[i] = 0;
293218334Speter	  this_alternative_offmemok[i] = 0;
293318334Speter	  this_alternative_earlyclobber[i] = 0;
293418334Speter	  this_alternative_matches[i] = -1;
293518334Speter
293618334Speter	  /* An empty constraint or empty alternative
293718334Speter	     allows anything which matched the pattern.  */
293818334Speter	  if (*p == 0 || *p == ',')
293918334Speter	    win = 1, badop = 0;
294018334Speter
294118334Speter	  /* Scan this alternative's specs for this operand;
294218334Speter	     set WIN if the operand fits any letter in this alternative.
294318334Speter	     Otherwise, clear BADOP if this operand could
294418334Speter	     fit some letter after reloads,
294518334Speter	     or set WINREG if this operand could fit after reloads
294618334Speter	     provided the constraint allows some registers.  */
294718334Speter
294818334Speter	  while (*p && (c = *p++) != ',')
294918334Speter	    switch (c)
295018334Speter	      {
295190285Sobrien	      case '=':  case '+':  case '*':
295218334Speter		break;
295318334Speter
295418334Speter	      case '%':
295518334Speter		/* The last operand should not be marked commutative.  */
295618334Speter		if (i != noperands - 1)
295718334Speter		  commutative = i;
295818334Speter		break;
295918334Speter
296018334Speter	      case '?':
296150605Sobrien		reject += 6;
296218334Speter		break;
296318334Speter
296418334Speter	      case '!':
296550605Sobrien		reject = 600;
296618334Speter		break;
296718334Speter
296818334Speter	      case '#':
296918334Speter		/* Ignore rest of this alternative as far as
297018334Speter		   reloading is concerned.  */
297190285Sobrien		while (*p && *p != ',')
297290285Sobrien		  p++;
297318334Speter		break;
297418334Speter
297590285Sobrien	      case '0':  case '1':  case '2':  case '3':  case '4':
297690285Sobrien	      case '5':  case '6':  case '7':  case '8':  case '9':
297790285Sobrien		c = strtoul (p - 1, &p, 10);
297890285Sobrien
297918334Speter		this_alternative_matches[i] = c;
298018334Speter		/* We are supposed to match a previous operand.
298118334Speter		   If we do, we win if that one did.
298218334Speter		   If we do not, count both of the operands as losers.
298318334Speter		   (This is too conservative, since most of the time
298418334Speter		   only a single reload insn will be needed to make
298518334Speter		   the two operands win.  As a result, this alternative
298618334Speter		   may be rejected when it is actually desirable.)  */
298718334Speter		if ((swapped && (c != commutative || i != commutative + 1))
298818334Speter		    /* If we are matching as if two operands were swapped,
298918334Speter		       also pretend that operands_match had been computed
299018334Speter		       with swapped.
299118334Speter		       But if I is the second of those and C is the first,
299218334Speter		       don't exchange them, because operands_match is valid
299318334Speter		       only on one side of its diagonal.  */
299418334Speter		    ? (operands_match
299590285Sobrien		       [(c == commutative || c == commutative + 1)
299690285Sobrien		       ? 2 * commutative + 1 - c : c]
299790285Sobrien		       [(i == commutative || i == commutative + 1)
299890285Sobrien		       ? 2 * commutative + 1 - i : i])
299918334Speter		    : operands_match[c][i])
300050605Sobrien		  {
300150605Sobrien		    /* If we are matching a non-offsettable address where an
300250605Sobrien		       offsettable address was expected, then we must reject
300350605Sobrien		       this combination, because we can't reload it.  */
300450605Sobrien		    if (this_alternative_offmemok[c]
300590285Sobrien			&& GET_CODE (recog_data.operand[c]) == MEM
300650605Sobrien			&& this_alternative[c] == (int) NO_REGS
300750605Sobrien			&& ! this_alternative_win[c])
300850605Sobrien		      bad = 1;
300950605Sobrien
301090285Sobrien		    did_match = this_alternative_win[c];
301150605Sobrien		  }
301218334Speter		else
301318334Speter		  {
301418334Speter		    /* Operands don't match.  */
301518334Speter		    rtx value;
301618334Speter		    /* Retroactively mark the operand we had to match
301718334Speter		       as a loser, if it wasn't already.  */
301818334Speter		    if (this_alternative_win[c])
301918334Speter		      losers++;
302018334Speter		    this_alternative_win[c] = 0;
302118334Speter		    if (this_alternative[c] == (int) NO_REGS)
302218334Speter		      bad = 1;
302318334Speter		    /* But count the pair only once in the total badness of
302418334Speter		       this alternative, if the pair can be a dummy reload.  */
302518334Speter		    value
302690285Sobrien		      = find_dummy_reload (recog_data.operand[i],
302790285Sobrien					   recog_data.operand[c],
302890285Sobrien					   recog_data.operand_loc[i],
302990285Sobrien					   recog_data.operand_loc[c],
303018334Speter					   operand_mode[i], operand_mode[c],
303150605Sobrien					   this_alternative[c], -1,
303250605Sobrien					   this_alternative_earlyclobber[c]);
303318334Speter
303418334Speter		    if (value != 0)
303518334Speter		      losers--;
303618334Speter		  }
303718334Speter		/* This can be fixed with reloads if the operand
303818334Speter		   we are supposed to match can be fixed with reloads.  */
303918334Speter		badop = 0;
304018334Speter		this_alternative[i] = this_alternative[c];
304118334Speter
304218334Speter		/* If we have to reload this operand and some previous
304318334Speter		   operand also had to match the same thing as this
304418334Speter		   operand, we don't know how to do that.  So reject this
304518334Speter		   alternative.  */
304690285Sobrien		if (! did_match || force_reload)
304718334Speter		  for (j = 0; j < i; j++)
304818334Speter		    if (this_alternative_matches[j]
304918334Speter			== this_alternative_matches[i])
305018334Speter		      badop = 1;
305118334Speter		break;
305218334Speter
305318334Speter	      case 'p':
305418334Speter		/* All necessary reloads for an address_operand
305518334Speter		   were handled in find_reloads_address.  */
305690285Sobrien		this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
305718334Speter		win = 1;
305896288Sobrien		badop = 0;
305918334Speter		break;
306018334Speter
306118334Speter	      case 'm':
306218334Speter		if (force_reload)
306318334Speter		  break;
306418334Speter		if (GET_CODE (operand) == MEM
306518334Speter		    || (GET_CODE (operand) == REG
306618334Speter			&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
306718334Speter			&& reg_renumber[REGNO (operand)] < 0))
306818334Speter		  win = 1;
306950605Sobrien		if (CONSTANT_P (operand)
307050605Sobrien		    /* force_const_mem does not accept HIGH.  */
307150605Sobrien		    && GET_CODE (operand) != HIGH)
307218334Speter		  badop = 0;
307318334Speter		constmemok = 1;
307418334Speter		break;
307518334Speter
307618334Speter	      case '<':
307718334Speter		if (GET_CODE (operand) == MEM
307818334Speter		    && ! address_reloaded[i]
307918334Speter		    && (GET_CODE (XEXP (operand, 0)) == PRE_DEC
308018334Speter			|| GET_CODE (XEXP (operand, 0)) == POST_DEC))
308118334Speter		  win = 1;
308218334Speter		break;
308318334Speter
308418334Speter	      case '>':
308518334Speter		if (GET_CODE (operand) == MEM
308618334Speter		    && ! address_reloaded[i]
308718334Speter		    && (GET_CODE (XEXP (operand, 0)) == PRE_INC
308818334Speter			|| GET_CODE (XEXP (operand, 0)) == POST_INC))
308918334Speter		  win = 1;
309018334Speter		break;
309118334Speter
309218334Speter		/* Memory operand whose address is not offsettable.  */
309318334Speter	      case 'V':
309418334Speter		if (force_reload)
309518334Speter		  break;
309618334Speter		if (GET_CODE (operand) == MEM
309718334Speter		    && ! (ind_levels ? offsettable_memref_p (operand)
309818334Speter			  : offsettable_nonstrict_memref_p (operand))
309918334Speter		    /* Certain mem addresses will become offsettable
310018334Speter		       after they themselves are reloaded.  This is important;
310118334Speter		       we don't want our own handling of unoffsettables
310218334Speter		       to override the handling of reg_equiv_address.  */
310318334Speter		    && !(GET_CODE (XEXP (operand, 0)) == REG
310418334Speter			 && (ind_levels == 0
310518334Speter			     || reg_equiv_address[REGNO (XEXP (operand, 0))] != 0)))
310618334Speter		  win = 1;
310718334Speter		break;
310818334Speter
310918334Speter		/* Memory operand whose address is offsettable.  */
311018334Speter	      case 'o':
311118334Speter		if (force_reload)
311218334Speter		  break;
311318334Speter		if ((GET_CODE (operand) == MEM
311418334Speter		     /* If IND_LEVELS, find_reloads_address won't reload a
311518334Speter			pseudo that didn't get a hard reg, so we have to
311618334Speter			reject that case.  */
311752557Sobrien		     && ((ind_levels ? offsettable_memref_p (operand)
311852557Sobrien			  : offsettable_nonstrict_memref_p (operand))
311952557Sobrien			 /* A reloaded address is offsettable because it is now
312052557Sobrien			    just a simple register indirect.  */
312152557Sobrien			 || address_reloaded[i]))
312218334Speter		    || (GET_CODE (operand) == REG
312318334Speter			&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
312418334Speter			&& reg_renumber[REGNO (operand)] < 0
312518334Speter			/* If reg_equiv_address is nonzero, we will be
312618334Speter			   loading it into a register; hence it will be
312718334Speter			   offsettable, but we cannot say that reg_equiv_mem
312818334Speter			   is offsettable without checking.  */
312918334Speter			&& ((reg_equiv_mem[REGNO (operand)] != 0
313018334Speter			     && offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
313118334Speter			    || (reg_equiv_address[REGNO (operand)] != 0))))
313218334Speter		  win = 1;
313350605Sobrien		/* force_const_mem does not accept HIGH.  */
313450605Sobrien		if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
313550605Sobrien		    || GET_CODE (operand) == MEM)
313618334Speter		  badop = 0;
313718334Speter		constmemok = 1;
313818334Speter		offmemok = 1;
313918334Speter		break;
314018334Speter
314118334Speter	      case '&':
314218334Speter		/* Output operand that is stored before the need for the
314318334Speter		   input operands (and their index registers) is over.  */
314418334Speter		earlyclobber = 1, this_earlyclobber = 1;
314518334Speter		break;
314618334Speter
314718334Speter	      case 'E':
314818334Speter#ifndef REAL_ARITHMETIC
314918334Speter		/* Match any floating double constant, but only if
315018334Speter		   we can examine the bits of it reliably.  */
315118334Speter		if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
315218334Speter		     || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
315318334Speter		    && GET_MODE (operand) != VOIDmode && ! flag_pretend_float)
315418334Speter		  break;
315518334Speter#endif
315618334Speter		if (GET_CODE (operand) == CONST_DOUBLE)
315718334Speter		  win = 1;
315818334Speter		break;
315918334Speter
316018334Speter	      case 'F':
316118334Speter		if (GET_CODE (operand) == CONST_DOUBLE)
316218334Speter		  win = 1;
316318334Speter		break;
316418334Speter
316518334Speter	      case 'G':
316618334Speter	      case 'H':
316718334Speter		if (GET_CODE (operand) == CONST_DOUBLE
316818334Speter		    && CONST_DOUBLE_OK_FOR_LETTER_P (operand, c))
316918334Speter		  win = 1;
317018334Speter		break;
317118334Speter
317218334Speter	      case 's':
317318334Speter		if (GET_CODE (operand) == CONST_INT
317418334Speter		    || (GET_CODE (operand) == CONST_DOUBLE
317518334Speter			&& GET_MODE (operand) == VOIDmode))
317618334Speter		  break;
317718334Speter	      case 'i':
317818334Speter		if (CONSTANT_P (operand)
317918334Speter#ifdef LEGITIMATE_PIC_OPERAND_P
318018334Speter		    && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand))
318118334Speter#endif
318218334Speter		    )
318318334Speter		  win = 1;
318418334Speter		break;
318518334Speter
318618334Speter	      case 'n':
318718334Speter		if (GET_CODE (operand) == CONST_INT
318818334Speter		    || (GET_CODE (operand) == CONST_DOUBLE
318918334Speter			&& GET_MODE (operand) == VOIDmode))
319018334Speter		  win = 1;
319118334Speter		break;
319218334Speter
319318334Speter	      case 'I':
319418334Speter	      case 'J':
319518334Speter	      case 'K':
319618334Speter	      case 'L':
319718334Speter	      case 'M':
319818334Speter	      case 'N':
319918334Speter	      case 'O':
320018334Speter	      case 'P':
320118334Speter		if (GET_CODE (operand) == CONST_INT
320218334Speter		    && CONST_OK_FOR_LETTER_P (INTVAL (operand), c))
320318334Speter		  win = 1;
320418334Speter		break;
320518334Speter
320618334Speter	      case 'X':
320718334Speter		win = 1;
320818334Speter		break;
320918334Speter
321018334Speter	      case 'g':
321118334Speter		if (! force_reload
321218334Speter		    /* A PLUS is never a valid operand, but reload can make
321318334Speter		       it from a register when eliminating registers.  */
321418334Speter		    && GET_CODE (operand) != PLUS
321518334Speter		    /* A SCRATCH is not a valid operand.  */
321618334Speter		    && GET_CODE (operand) != SCRATCH
321718334Speter#ifdef LEGITIMATE_PIC_OPERAND_P
321890285Sobrien		    && (! CONSTANT_P (operand)
321990285Sobrien			|| ! flag_pic
322018334Speter			|| LEGITIMATE_PIC_OPERAND_P (operand))
322118334Speter#endif
322218334Speter		    && (GENERAL_REGS == ALL_REGS
322318334Speter			|| GET_CODE (operand) != REG
322418334Speter			|| (REGNO (operand) >= FIRST_PSEUDO_REGISTER
322518334Speter			    && reg_renumber[REGNO (operand)] < 0)))
322618334Speter		  win = 1;
322790285Sobrien		/* Drop through into 'r' case.  */
322818334Speter
322918334Speter	      case 'r':
323018334Speter		this_alternative[i]
323118334Speter		  = (int) reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS];
323218334Speter		goto reg;
323318334Speter
323490285Sobrien	      default:
323590285Sobrien		if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
323690285Sobrien		  {
323718334Speter#ifdef EXTRA_CONSTRAINT
323890285Sobrien		    if (EXTRA_CONSTRAINT (operand, c))
323990285Sobrien		      win = 1;
324018334Speter#endif
324190285Sobrien		    break;
324290285Sobrien		  }
324390285Sobrien
324418334Speter		this_alternative[i]
324518334Speter		  = (int) reg_class_subunion[this_alternative[i]][(int) REG_CLASS_FROM_LETTER (c)];
324618334Speter	      reg:
324718334Speter		if (GET_MODE (operand) == BLKmode)
324818334Speter		  break;
324918334Speter		winreg = 1;
325018334Speter		if (GET_CODE (operand) == REG
325118334Speter		    && reg_fits_class_p (operand, this_alternative[i],
325290285Sobrien					 offset, GET_MODE (recog_data.operand[i])))
325318334Speter		  win = 1;
325418334Speter		break;
325518334Speter	      }
325618334Speter
325718334Speter	  constraints[i] = p;
325818334Speter
325918334Speter	  /* If this operand could be handled with a reg,
326018334Speter	     and some reg is allowed, then this operand can be handled.  */
326118334Speter	  if (winreg && this_alternative[i] != (int) NO_REGS)
326218334Speter	    badop = 0;
326318334Speter
326418334Speter	  /* Record which operands fit this alternative.  */
326518334Speter	  this_alternative_earlyclobber[i] = earlyclobber;
326618334Speter	  if (win && ! force_reload)
326718334Speter	    this_alternative_win[i] = 1;
326890285Sobrien	  else if (did_match && ! force_reload)
326990285Sobrien	    this_alternative_match_win[i] = 1;
327018334Speter	  else
327118334Speter	    {
327218334Speter	      int const_to_mem = 0;
327318334Speter
327418334Speter	      this_alternative_offmemok[i] = offmemok;
327518334Speter	      losers++;
327618334Speter	      if (badop)
327718334Speter		bad = 1;
327818334Speter	      /* Alternative loses if it has no regs for a reg operand.  */
327918334Speter	      if (GET_CODE (operand) == REG
328018334Speter		  && this_alternative[i] == (int) NO_REGS
328118334Speter		  && this_alternative_matches[i] < 0)
328218334Speter		bad = 1;
328318334Speter
328418334Speter	      /* If this is a constant that is reloaded into the desired
328518334Speter		 class by copying it to memory first, count that as another
328618334Speter		 reload.  This is consistent with other code and is
328718334Speter		 required to avoid choosing another alternative when
328818334Speter		 the constant is moved into memory by this function on
328990285Sobrien		 an early reload pass.  Note that the test here is
329018334Speter		 precisely the same as in the code below that calls
329118334Speter		 force_const_mem.  */
329218334Speter	      if (CONSTANT_P (operand)
329318334Speter		  /* force_const_mem does not accept HIGH.  */
329418334Speter		  && GET_CODE (operand) != HIGH
329550605Sobrien		  && ((PREFERRED_RELOAD_CLASS (operand,
329690285Sobrien					       (enum reg_class) this_alternative[i])
329750605Sobrien		       == NO_REGS)
329850605Sobrien		      || no_input_reloads)
329918334Speter		  && operand_mode[i] != VOIDmode)
330018334Speter		{
330118334Speter		  const_to_mem = 1;
330218334Speter		  if (this_alternative[i] != (int) NO_REGS)
330318334Speter		    losers++;
330418334Speter		}
330518334Speter
330618334Speter	      /* If we can't reload this value at all, reject this
330718334Speter		 alternative.  Note that we could also lose due to
330818334Speter		 LIMIT_RELOAD_RELOAD_CLASS, but we don't check that
330918334Speter		 here.  */
331018334Speter
331118334Speter	      if (! CONSTANT_P (operand)
331218334Speter		  && (enum reg_class) this_alternative[i] != NO_REGS
331318334Speter		  && (PREFERRED_RELOAD_CLASS (operand,
331418334Speter					      (enum reg_class) this_alternative[i])
331518334Speter		      == NO_REGS))
331618334Speter		bad = 1;
331718334Speter
331850605Sobrien	      /* Alternative loses if it requires a type of reload not
331950605Sobrien		 permitted for this insn.  We can always reload SCRATCH
332050605Sobrien		 and objects with a REG_UNUSED note.  */
332150605Sobrien	      else if (GET_CODE (operand) != SCRATCH
332290285Sobrien		       && modified[i] != RELOAD_READ && no_output_reloads
332390285Sobrien		       && ! find_reg_note (insn, REG_UNUSED, operand))
332450605Sobrien		bad = 1;
332550605Sobrien	      else if (modified[i] != RELOAD_WRITE && no_input_reloads
332650605Sobrien		       && ! const_to_mem)
332750605Sobrien		bad = 1;
332850605Sobrien
332918334Speter	      /* We prefer to reload pseudos over reloading other things,
333018334Speter		 since such reloads may be able to be eliminated later.
333118334Speter		 If we are reloading a SCRATCH, we won't be generating any
333290285Sobrien		 insns, just using a register, so it is also preferred.
333318334Speter		 So bump REJECT in other cases.  Don't do this in the
333418334Speter		 case where we are forcing a constant into memory and
333518334Speter		 it will then win since we don't want to have a different
333618334Speter		 alternative match then.  */
333718334Speter	      if (! (GET_CODE (operand) == REG
333818334Speter		     && REGNO (operand) >= FIRST_PSEUDO_REGISTER)
333918334Speter		  && GET_CODE (operand) != SCRATCH
334018334Speter		  && ! (const_to_mem && constmemok))
334150605Sobrien		reject += 2;
334250605Sobrien
334350605Sobrien	      /* Input reloads can be inherited more often than output
334450605Sobrien		 reloads can be removed, so penalize output reloads.  */
334550605Sobrien	      if (operand_type[i] != RELOAD_FOR_INPUT
334650605Sobrien		  && GET_CODE (operand) != SCRATCH)
334718334Speter		reject++;
334818334Speter	    }
334918334Speter
335090285Sobrien	  /* If this operand is a pseudo register that didn't get a hard
335118334Speter	     reg and this alternative accepts some register, see if the
335218334Speter	     class that we want is a subset of the preferred class for this
335318334Speter	     register.  If not, but it intersects that class, use the
335418334Speter	     preferred class instead.  If it does not intersect the preferred
335518334Speter	     class, show that usage of this alternative should be discouraged;
335618334Speter	     it will be discouraged more still if the register is `preferred
335718334Speter	     or nothing'.  We do this because it increases the chance of
335818334Speter	     reusing our spill register in a later insn and avoiding a pair
335918334Speter	     of memory stores and loads.
336018334Speter
336118334Speter	     Don't bother with this if this alternative will accept this
336218334Speter	     operand.
336318334Speter
336418334Speter	     Don't do this for a multiword operand, since it is only a
336518334Speter	     small win and has the risk of requiring more spill registers,
336618334Speter	     which could cause a large loss.
336718334Speter
336818334Speter	     Don't do this if the preferred class has only one register
336918334Speter	     because we might otherwise exhaust the class.  */
337018334Speter
337190285Sobrien	  if (! win && ! did_match
337290285Sobrien	      && this_alternative[i] != (int) NO_REGS
337318334Speter	      && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
337418334Speter	      && reg_class_size[(int) preferred_class[i]] > 1)
337518334Speter	    {
337618334Speter	      if (! reg_class_subset_p (this_alternative[i],
337718334Speter					preferred_class[i]))
337818334Speter		{
337918334Speter		  /* Since we don't have a way of forming the intersection,
338018334Speter		     we just do something special if the preferred class
338190285Sobrien		     is a subset of the class we have; that's the most
338218334Speter		     common case anyway.  */
338318334Speter		  if (reg_class_subset_p (preferred_class[i],
338418334Speter					  this_alternative[i]))
338518334Speter		    this_alternative[i] = (int) preferred_class[i];
338618334Speter		  else
338750605Sobrien		    reject += (2 + 2 * pref_or_nothing[i]);
338818334Speter		}
338918334Speter	    }
339018334Speter	}
339118334Speter
339218334Speter      /* Now see if any output operands that are marked "earlyclobber"
339318334Speter	 in this alternative conflict with any input operands
339418334Speter	 or any memory addresses.  */
339518334Speter
339618334Speter      for (i = 0; i < noperands; i++)
339718334Speter	if (this_alternative_earlyclobber[i]
339890285Sobrien	    && (this_alternative_win[i] || this_alternative_match_win[i]))
339918334Speter	  {
340090285Sobrien	    struct decomposition early_data;
340118334Speter
340290285Sobrien	    early_data = decompose (recog_data.operand[i]);
340318334Speter
340418334Speter	    if (modified[i] == RELOAD_READ)
340552557Sobrien	      abort ();
340690285Sobrien
340718334Speter	    if (this_alternative[i] == NO_REGS)
340818334Speter	      {
340918334Speter		this_alternative_earlyclobber[i] = 0;
341018334Speter		if (this_insn_is_asm)
341118334Speter		  error_for_asm (this_insn,
341218334Speter				 "`&' constraint used with no register class");
341318334Speter		else
341418334Speter		  abort ();
341518334Speter	      }
341618334Speter
341718334Speter	    for (j = 0; j < noperands; j++)
341818334Speter	      /* Is this an input operand or a memory ref?  */
341990285Sobrien	      if ((GET_CODE (recog_data.operand[j]) == MEM
342018334Speter		   || modified[j] != RELOAD_WRITE)
342118334Speter		  && j != i
342218334Speter		  /* Ignore things like match_operator operands.  */
342390285Sobrien		  && *recog_data.constraints[j] != 0
342418334Speter		  /* Don't count an input operand that is constrained to match
342518334Speter		     the early clobber operand.  */
342618334Speter		  && ! (this_alternative_matches[j] == i
342790285Sobrien			&& rtx_equal_p (recog_data.operand[i],
342890285Sobrien					recog_data.operand[j]))
342918334Speter		  /* Is it altered by storing the earlyclobber operand?  */
343090285Sobrien		  && !immune_p (recog_data.operand[j], recog_data.operand[i],
343190285Sobrien				early_data))
343218334Speter		{
343318334Speter		  /* If the output is in a single-reg class,
343418334Speter		     it's costly to reload it, so reload the input instead.  */
343518334Speter		  if (reg_class_size[this_alternative[i]] == 1
343690285Sobrien		      && (GET_CODE (recog_data.operand[j]) == REG
343790285Sobrien			  || GET_CODE (recog_data.operand[j]) == SUBREG))
343818334Speter		    {
343918334Speter		      losers++;
344018334Speter		      this_alternative_win[j] = 0;
344190285Sobrien		      this_alternative_match_win[j] = 0;
344218334Speter		    }
344318334Speter		  else
344418334Speter		    break;
344518334Speter		}
344618334Speter	    /* If an earlyclobber operand conflicts with something,
344718334Speter	       it must be reloaded, so request this and count the cost.  */
344818334Speter	    if (j != noperands)
344918334Speter	      {
345018334Speter		losers++;
345118334Speter		this_alternative_win[i] = 0;
345290285Sobrien		this_alternative_match_win[j] = 0;
345318334Speter		for (j = 0; j < noperands; j++)
345418334Speter		  if (this_alternative_matches[j] == i
345590285Sobrien		      && this_alternative_match_win[j])
345618334Speter		    {
345718334Speter		      this_alternative_win[j] = 0;
345890285Sobrien		      this_alternative_match_win[j] = 0;
345918334Speter		      losers++;
346018334Speter		    }
346118334Speter	      }
346218334Speter	  }
346318334Speter
346418334Speter      /* If one alternative accepts all the operands, no reload required,
346518334Speter	 choose that alternative; don't consider the remaining ones.  */
346618334Speter      if (losers == 0)
346718334Speter	{
346818334Speter	  /* Unswap these so that they are never swapped at `finish'.  */
346918334Speter	  if (commutative >= 0)
347018334Speter	    {
347190285Sobrien	      recog_data.operand[commutative] = substed_operand[commutative];
347290285Sobrien	      recog_data.operand[commutative + 1]
347318334Speter		= substed_operand[commutative + 1];
347418334Speter	    }
347518334Speter	  for (i = 0; i < noperands; i++)
347618334Speter	    {
347790285Sobrien	      goal_alternative_win[i] = this_alternative_win[i];
347890285Sobrien	      goal_alternative_match_win[i] = this_alternative_match_win[i];
347918334Speter	      goal_alternative[i] = this_alternative[i];
348018334Speter	      goal_alternative_offmemok[i] = this_alternative_offmemok[i];
348118334Speter	      goal_alternative_matches[i] = this_alternative_matches[i];
348218334Speter	      goal_alternative_earlyclobber[i]
348318334Speter		= this_alternative_earlyclobber[i];
348418334Speter	    }
348518334Speter	  goal_alternative_number = this_alternative_number;
348618334Speter	  goal_alternative_swapped = swapped;
348718334Speter	  goal_earlyclobber = this_earlyclobber;
348818334Speter	  goto finish;
348918334Speter	}
349018334Speter
349118334Speter      /* REJECT, set by the ! and ? constraint characters and when a register
349218334Speter	 would be reloaded into a non-preferred class, discourages the use of
349350605Sobrien	 this alternative for a reload goal.  REJECT is incremented by six
349450605Sobrien	 for each ? and two for each non-preferred class.  */
349550605Sobrien      losers = losers * 6 + reject;
349618334Speter
349718334Speter      /* If this alternative can be made to work by reloading,
349818334Speter	 and it needs less reloading than the others checked so far,
349918334Speter	 record it as the chosen goal for reloading.  */
350018334Speter      if (! bad && best > losers)
350118334Speter	{
350218334Speter	  for (i = 0; i < noperands; i++)
350318334Speter	    {
350418334Speter	      goal_alternative[i] = this_alternative[i];
350518334Speter	      goal_alternative_win[i] = this_alternative_win[i];
350690285Sobrien	      goal_alternative_match_win[i] = this_alternative_match_win[i];
350718334Speter	      goal_alternative_offmemok[i] = this_alternative_offmemok[i];
350818334Speter	      goal_alternative_matches[i] = this_alternative_matches[i];
350918334Speter	      goal_alternative_earlyclobber[i]
351018334Speter		= this_alternative_earlyclobber[i];
351118334Speter	    }
351218334Speter	  goal_alternative_swapped = swapped;
351318334Speter	  best = losers;
351418334Speter	  goal_alternative_number = this_alternative_number;
351518334Speter	  goal_earlyclobber = this_earlyclobber;
351618334Speter	}
351718334Speter    }
351818334Speter
351918334Speter  /* If insn is commutative (it's safe to exchange a certain pair of operands)
352018334Speter     then we need to try each alternative twice,
352118334Speter     the second time matching those two operands
352218334Speter     as if we had exchanged them.
352318334Speter     To do this, really exchange them in operands.
352418334Speter
352518334Speter     If we have just tried the alternatives the second time,
352618334Speter     return operands to normal and drop through.  */
352718334Speter
352818334Speter  if (commutative >= 0)
352918334Speter    {
353018334Speter      swapped = !swapped;
353118334Speter      if (swapped)
353218334Speter	{
353390285Sobrien	  enum reg_class tclass;
353490285Sobrien	  int t;
353518334Speter
353690285Sobrien	  recog_data.operand[commutative] = substed_operand[commutative + 1];
353790285Sobrien	  recog_data.operand[commutative + 1] = substed_operand[commutative];
353890285Sobrien	  /* Swap the duplicates too.  */
353990285Sobrien	  for (i = 0; i < recog_data.n_dups; i++)
354090285Sobrien	    if (recog_data.dup_num[i] == commutative
354190285Sobrien		|| recog_data.dup_num[i] == commutative + 1)
354290285Sobrien	      *recog_data.dup_loc[i]
354390285Sobrien		 = recog_data.operand[(int) recog_data.dup_num[i]];
354418334Speter
354518334Speter	  tclass = preferred_class[commutative];
354618334Speter	  preferred_class[commutative] = preferred_class[commutative + 1];
354718334Speter	  preferred_class[commutative + 1] = tclass;
354818334Speter
354918334Speter	  t = pref_or_nothing[commutative];
355018334Speter	  pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
355118334Speter	  pref_or_nothing[commutative + 1] = t;
355218334Speter
355390285Sobrien	  memcpy (constraints, recog_data.constraints,
355490285Sobrien		  noperands * sizeof (char *));
355518334Speter	  goto try_swapped;
355618334Speter	}
355718334Speter      else
355818334Speter	{
355990285Sobrien	  recog_data.operand[commutative] = substed_operand[commutative];
356090285Sobrien	  recog_data.operand[commutative + 1]
356190285Sobrien	    = substed_operand[commutative + 1];
356290285Sobrien	  /* Unswap the duplicates too.  */
356390285Sobrien	  for (i = 0; i < recog_data.n_dups; i++)
356490285Sobrien	    if (recog_data.dup_num[i] == commutative
356590285Sobrien		|| recog_data.dup_num[i] == commutative + 1)
356690285Sobrien	      *recog_data.dup_loc[i]
356790285Sobrien		 = recog_data.operand[(int) recog_data.dup_num[i]];
356818334Speter	}
356918334Speter    }
357018334Speter
357118334Speter  /* The operands don't meet the constraints.
357218334Speter     goal_alternative describes the alternative
357318334Speter     that we could reach by reloading the fewest operands.
357418334Speter     Reload so as to fit it.  */
357518334Speter
357650605Sobrien  if (best == MAX_RECOG_OPERANDS * 2 + 600)
357718334Speter    {
357818334Speter      /* No alternative works with reloads??  */
357918334Speter      if (insn_code_number >= 0)
358090285Sobrien	fatal_insn ("unable to generate reloads for:", insn);
358118334Speter      error_for_asm (insn, "inconsistent operand constraints in an `asm'");
358218334Speter      /* Avoid further trouble with this insn.  */
358350605Sobrien      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
358418334Speter      n_reloads = 0;
358552557Sobrien      return 0;
358618334Speter    }
358718334Speter
358818334Speter  /* Jump to `finish' from above if all operands are valid already.
358918334Speter     In that case, goal_alternative_win is all 1.  */
359018334Speter finish:
359118334Speter
359218334Speter  /* Right now, for any pair of operands I and J that are required to match,
359318334Speter     with I < J,
359418334Speter     goal_alternative_matches[J] is I.
359518334Speter     Set up goal_alternative_matched as the inverse function:
359618334Speter     goal_alternative_matched[I] = J.  */
359718334Speter
359818334Speter  for (i = 0; i < noperands; i++)
359918334Speter    goal_alternative_matched[i] = -1;
360090285Sobrien
360118334Speter  for (i = 0; i < noperands; i++)
360218334Speter    if (! goal_alternative_win[i]
360318334Speter	&& goal_alternative_matches[i] >= 0)
360418334Speter      goal_alternative_matched[goal_alternative_matches[i]] = i;
360518334Speter
360690285Sobrien  for (i = 0; i < noperands; i++)
360790285Sobrien    goal_alternative_win[i] |= goal_alternative_match_win[i];
360890285Sobrien
360918334Speter  /* If the best alternative is with operands 1 and 2 swapped,
361018334Speter     consider them swapped before reporting the reloads.  Update the
361118334Speter     operand numbers of any reloads already pushed.  */
361218334Speter
361318334Speter  if (goal_alternative_swapped)
361418334Speter    {
361590285Sobrien      rtx tem;
361618334Speter
361718334Speter      tem = substed_operand[commutative];
361818334Speter      substed_operand[commutative] = substed_operand[commutative + 1];
361918334Speter      substed_operand[commutative + 1] = tem;
362090285Sobrien      tem = recog_data.operand[commutative];
362190285Sobrien      recog_data.operand[commutative] = recog_data.operand[commutative + 1];
362290285Sobrien      recog_data.operand[commutative + 1] = tem;
362390285Sobrien      tem = *recog_data.operand_loc[commutative];
362490285Sobrien      *recog_data.operand_loc[commutative]
362590285Sobrien	= *recog_data.operand_loc[commutative + 1];
362690285Sobrien      *recog_data.operand_loc[commutative + 1] = tem;
362718334Speter
362818334Speter      for (i = 0; i < n_reloads; i++)
362918334Speter	{
363090285Sobrien	  if (rld[i].opnum == commutative)
363190285Sobrien	    rld[i].opnum = commutative + 1;
363290285Sobrien	  else if (rld[i].opnum == commutative + 1)
363390285Sobrien	    rld[i].opnum = commutative;
363418334Speter	}
363518334Speter    }
363618334Speter
363718334Speter  for (i = 0; i < noperands; i++)
363818334Speter    {
363918334Speter      operand_reloadnum[i] = -1;
364018334Speter
364118334Speter      /* If this is an earlyclobber operand, we need to widen the scope.
364218334Speter	 The reload must remain valid from the start of the insn being
364318334Speter	 reloaded until after the operand is stored into its destination.
364418334Speter	 We approximate this with RELOAD_OTHER even though we know that we
364518334Speter	 do not conflict with RELOAD_FOR_INPUT_ADDRESS reloads.
364618334Speter
364718334Speter	 One special case that is worth checking is when we have an
364818334Speter	 output that is earlyclobber but isn't used past the insn (typically
364990285Sobrien	 a SCRATCH).  In this case, we only need have the reload live
365018334Speter	 through the insn itself, but not for any of our input or output
365190285Sobrien	 reloads.
365250605Sobrien	 But we must not accidentally narrow the scope of an existing
365350605Sobrien	 RELOAD_OTHER reload - leave these alone.
365418334Speter
365518334Speter	 In any case, anything needed to address this operand can remain
365618334Speter	 however they were previously categorized.  */
365718334Speter
365850605Sobrien      if (goal_alternative_earlyclobber[i] && operand_type[i] != RELOAD_OTHER)
365918334Speter	operand_type[i]
366090285Sobrien	  = (find_reg_note (insn, REG_UNUSED, recog_data.operand[i])
366118334Speter	     ? RELOAD_FOR_INSN : RELOAD_OTHER);
366218334Speter    }
366318334Speter
366418334Speter  /* Any constants that aren't allowed and can't be reloaded
366518334Speter     into registers are here changed into memory references.  */
366618334Speter  for (i = 0; i < noperands; i++)
366718334Speter    if (! goal_alternative_win[i]
366890285Sobrien	&& CONSTANT_P (recog_data.operand[i])
366918334Speter	/* force_const_mem does not accept HIGH.  */
367090285Sobrien	&& GET_CODE (recog_data.operand[i]) != HIGH
367190285Sobrien	&& ((PREFERRED_RELOAD_CLASS (recog_data.operand[i],
367290285Sobrien				     (enum reg_class) goal_alternative[i])
367350605Sobrien	     == NO_REGS)
367450605Sobrien	    || no_input_reloads)
367518334Speter	&& operand_mode[i] != VOIDmode)
367618334Speter      {
367790285Sobrien	substed_operand[i] = recog_data.operand[i]
367818334Speter	  = find_reloads_toplev (force_const_mem (operand_mode[i],
367990285Sobrien						  recog_data.operand[i]),
368090285Sobrien				 i, address_type[i], ind_levels, 0, insn,
368190285Sobrien				 NULL);
368290285Sobrien	if (alternative_allows_memconst (recog_data.constraints[i],
368318334Speter					 goal_alternative_number))
368418334Speter	  goal_alternative_win[i] = 1;
368518334Speter      }
368618334Speter
368718334Speter  /* Record the values of the earlyclobber operands for the caller.  */
368818334Speter  if (goal_earlyclobber)
368918334Speter    for (i = 0; i < noperands; i++)
369018334Speter      if (goal_alternative_earlyclobber[i])
369190285Sobrien	reload_earlyclobbers[n_earlyclobbers++] = recog_data.operand[i];
369218334Speter
369318334Speter  /* Now record reloads for all the operands that need them.  */
369418334Speter  for (i = 0; i < noperands; i++)
369518334Speter    if (! goal_alternative_win[i])
369618334Speter      {
369718334Speter	/* Operands that match previous ones have already been handled.  */
369818334Speter	if (goal_alternative_matches[i] >= 0)
369918334Speter	  ;
370018334Speter	/* Handle an operand with a nonoffsettable address
370118334Speter	   appearing where an offsettable address will do
370218334Speter	   by reloading the address into a base register.
370318334Speter
370418334Speter	   ??? We can also do this when the operand is a register and
370518334Speter	   reg_equiv_mem is not offsettable, but this is a bit tricky,
370618334Speter	   so we don't bother with it.  It may not be worth doing.  */
370718334Speter	else if (goal_alternative_matched[i] == -1
370818334Speter		 && goal_alternative_offmemok[i]
370990285Sobrien		 && GET_CODE (recog_data.operand[i]) == MEM)
371018334Speter	  {
371118334Speter	    operand_reloadnum[i]
371290285Sobrien	      = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
371390285Sobrien			     &XEXP (recog_data.operand[i], 0), (rtx*) 0,
371490285Sobrien			     MODE_BASE_REG_CLASS (VOIDmode),
371590285Sobrien			     GET_MODE (XEXP (recog_data.operand[i], 0)),
371618334Speter			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
371790285Sobrien	    rld[operand_reloadnum[i]].inc
371890285Sobrien	      = GET_MODE_SIZE (GET_MODE (recog_data.operand[i]));
371918334Speter
372018334Speter	    /* If this operand is an output, we will have made any
372118334Speter	       reloads for its address as RELOAD_FOR_OUTPUT_ADDRESS, but
372218334Speter	       now we are treating part of the operand as an input, so
372318334Speter	       we must change these to RELOAD_FOR_INPUT_ADDRESS.  */
372418334Speter
372518334Speter	    if (modified[i] == RELOAD_WRITE)
372650605Sobrien	      {
372750605Sobrien		for (j = 0; j < n_reloads; j++)
372850605Sobrien		  {
372990285Sobrien		    if (rld[j].opnum == i)
373050605Sobrien		      {
373190285Sobrien			if (rld[j].when_needed == RELOAD_FOR_OUTPUT_ADDRESS)
373290285Sobrien			  rld[j].when_needed = RELOAD_FOR_INPUT_ADDRESS;
373390285Sobrien			else if (rld[j].when_needed
373450605Sobrien				 == RELOAD_FOR_OUTADDR_ADDRESS)
373590285Sobrien			  rld[j].when_needed = RELOAD_FOR_INPADDR_ADDRESS;
373650605Sobrien		      }
373750605Sobrien		  }
373850605Sobrien	      }
373918334Speter	  }
374018334Speter	else if (goal_alternative_matched[i] == -1)
374150605Sobrien	  {
374250605Sobrien	    operand_reloadnum[i]
374350605Sobrien	      = push_reload ((modified[i] != RELOAD_WRITE
374490285Sobrien			      ? recog_data.operand[i] : 0),
374590285Sobrien			     (modified[i] != RELOAD_READ
374690285Sobrien			      ? recog_data.operand[i] : 0),
374750605Sobrien			     (modified[i] != RELOAD_WRITE
374890285Sobrien			      ? recog_data.operand_loc[i] : 0),
374950605Sobrien			     (modified[i] != RELOAD_READ
375090285Sobrien			      ? recog_data.operand_loc[i] : 0),
375150605Sobrien			     (enum reg_class) goal_alternative[i],
375250605Sobrien			     (modified[i] == RELOAD_WRITE
375350605Sobrien			      ? VOIDmode : operand_mode[i]),
375450605Sobrien			     (modified[i] == RELOAD_READ
375550605Sobrien			      ? VOIDmode : operand_mode[i]),
375650605Sobrien			     (insn_code_number < 0 ? 0
375790285Sobrien			      : insn_data[insn_code_number].operand[i].strict_low),
375850605Sobrien			     0, i, operand_type[i]);
375950605Sobrien	  }
376018334Speter	/* In a matching pair of operands, one must be input only
376118334Speter	   and the other must be output only.
376218334Speter	   Pass the input operand as IN and the other as OUT.  */
376318334Speter	else if (modified[i] == RELOAD_READ
376418334Speter		 && modified[goal_alternative_matched[i]] == RELOAD_WRITE)
376518334Speter	  {
376618334Speter	    operand_reloadnum[i]
376790285Sobrien	      = push_reload (recog_data.operand[i],
376890285Sobrien			     recog_data.operand[goal_alternative_matched[i]],
376990285Sobrien			     recog_data.operand_loc[i],
377090285Sobrien			     recog_data.operand_loc[goal_alternative_matched[i]],
377118334Speter			     (enum reg_class) goal_alternative[i],
377218334Speter			     operand_mode[i],
377318334Speter			     operand_mode[goal_alternative_matched[i]],
377418334Speter			     0, 0, i, RELOAD_OTHER);
377518334Speter	    operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
377618334Speter	  }
377718334Speter	else if (modified[i] == RELOAD_WRITE
377818334Speter		 && modified[goal_alternative_matched[i]] == RELOAD_READ)
377918334Speter	  {
378018334Speter	    operand_reloadnum[goal_alternative_matched[i]]
378190285Sobrien	      = push_reload (recog_data.operand[goal_alternative_matched[i]],
378290285Sobrien			     recog_data.operand[i],
378390285Sobrien			     recog_data.operand_loc[goal_alternative_matched[i]],
378490285Sobrien			     recog_data.operand_loc[i],
378518334Speter			     (enum reg_class) goal_alternative[i],
378618334Speter			     operand_mode[goal_alternative_matched[i]],
378718334Speter			     operand_mode[i],
378818334Speter			     0, 0, i, RELOAD_OTHER);
378918334Speter	    operand_reloadnum[i] = output_reloadnum;
379018334Speter	  }
379118334Speter	else if (insn_code_number >= 0)
379218334Speter	  abort ();
379318334Speter	else
379418334Speter	  {
379518334Speter	    error_for_asm (insn, "inconsistent operand constraints in an `asm'");
379618334Speter	    /* Avoid further trouble with this insn.  */
379750605Sobrien	    PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
379818334Speter	    n_reloads = 0;
379952557Sobrien	    return 0;
380018334Speter	  }
380118334Speter      }
380218334Speter    else if (goal_alternative_matched[i] < 0
380318334Speter	     && goal_alternative_matches[i] < 0
380418334Speter	     && optimize)
380518334Speter      {
380690285Sobrien	/* For each non-matching operand that's a MEM or a pseudo-register
380718334Speter	   that didn't get a hard register, make an optional reload.
380818334Speter	   This may get done even if the insn needs no reloads otherwise.  */
380918334Speter
381090285Sobrien	rtx operand = recog_data.operand[i];
381118334Speter
381218334Speter	while (GET_CODE (operand) == SUBREG)
381390285Sobrien	  operand = SUBREG_REG (operand);
381418334Speter	if ((GET_CODE (operand) == MEM
381518334Speter	     || (GET_CODE (operand) == REG
381618334Speter		 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
381752557Sobrien	    /* If this is only for an output, the optional reload would not
381852557Sobrien	       actually cause us to use a register now, just note that
381952557Sobrien	       something is stored here.  */
382052557Sobrien	    && ((enum reg_class) goal_alternative[i] != NO_REGS
382152557Sobrien		|| modified[i] == RELOAD_WRITE)
382218334Speter	    && ! no_input_reloads
382352557Sobrien	    /* An optional output reload might allow to delete INSN later.
382452557Sobrien	       We mustn't make in-out reloads on insns that are not permitted
382552557Sobrien	       output reloads.
382652557Sobrien	       If this is an asm, we can't delete it; we must not even call
382752557Sobrien	       push_reload for an optional output reload in this case,
382852557Sobrien	       because we can't be sure that the constraint allows a register,
382952557Sobrien	       and push_reload verifies the constraints for asms.  */
383018334Speter	    && (modified[i] == RELOAD_READ
383152557Sobrien		|| (! no_output_reloads && ! this_insn_is_asm)))
383218334Speter	  operand_reloadnum[i]
383390285Sobrien	    = push_reload ((modified[i] != RELOAD_WRITE
383490285Sobrien			    ? recog_data.operand[i] : 0),
383590285Sobrien			   (modified[i] != RELOAD_READ
383690285Sobrien			    ? recog_data.operand[i] : 0),
383718334Speter			   (modified[i] != RELOAD_WRITE
383890285Sobrien			    ? recog_data.operand_loc[i] : 0),
383918334Speter			   (modified[i] != RELOAD_READ
384090285Sobrien			    ? recog_data.operand_loc[i] : 0),
384118334Speter			   (enum reg_class) goal_alternative[i],
384218334Speter			   (modified[i] == RELOAD_WRITE
384318334Speter			    ? VOIDmode : operand_mode[i]),
384418334Speter			   (modified[i] == RELOAD_READ
384518334Speter			    ? VOIDmode : operand_mode[i]),
384618334Speter			   (insn_code_number < 0 ? 0
384790285Sobrien			    : insn_data[insn_code_number].operand[i].strict_low),
384818334Speter			   1, i, operand_type[i]);
384952557Sobrien	/* If a memory reference remains (either as a MEM or a pseudo that
385052557Sobrien	   did not get a hard register), yet we can't make an optional
385152557Sobrien	   reload, check if this is actually a pseudo register reference;
385252557Sobrien	   we then need to emit a USE and/or a CLOBBER so that reload
385352557Sobrien	   inheritance will do the right thing.  */
385452557Sobrien	else if (replace
385552557Sobrien		 && (GET_CODE (operand) == MEM
385652557Sobrien		     || (GET_CODE (operand) == REG
385752557Sobrien			 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
385852557Sobrien			 && reg_renumber [REGNO (operand)] < 0)))
385952557Sobrien	  {
386090285Sobrien	    operand = *recog_data.operand_loc[i];
386152557Sobrien
386252557Sobrien	    while (GET_CODE (operand) == SUBREG)
386390285Sobrien	      operand = SUBREG_REG (operand);
386452557Sobrien	    if (GET_CODE (operand) == REG)
386552557Sobrien	      {
386652557Sobrien		if (modified[i] != RELOAD_WRITE)
386790285Sobrien		  /* We mark the USE with QImode so that we recognize
386890285Sobrien		     it as one that can be safely deleted at the end
386990285Sobrien		     of reload.  */
387090285Sobrien		  PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, operand),
387190285Sobrien					      insn), QImode);
387252557Sobrien		if (modified[i] != RELOAD_READ)
387352557Sobrien		  emit_insn_after (gen_rtx_CLOBBER (VOIDmode, operand), insn);
387452557Sobrien	      }
387552557Sobrien	  }
387618334Speter      }
387718334Speter    else if (goal_alternative_matches[i] >= 0
387818334Speter	     && goal_alternative_win[goal_alternative_matches[i]]
387918334Speter	     && modified[i] == RELOAD_READ
388018334Speter	     && modified[goal_alternative_matches[i]] == RELOAD_WRITE
388118334Speter	     && ! no_input_reloads && ! no_output_reloads
388218334Speter	     && optimize)
388318334Speter      {
388418334Speter	/* Similarly, make an optional reload for a pair of matching
388518334Speter	   objects that are in MEM or a pseudo that didn't get a hard reg.  */
388618334Speter
388790285Sobrien	rtx operand = recog_data.operand[i];
388818334Speter
388918334Speter	while (GET_CODE (operand) == SUBREG)
389090285Sobrien	  operand = SUBREG_REG (operand);
389118334Speter	if ((GET_CODE (operand) == MEM
389218334Speter	     || (GET_CODE (operand) == REG
389318334Speter		 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
389418334Speter	    && ((enum reg_class) goal_alternative[goal_alternative_matches[i]]
389518334Speter		!= NO_REGS))
389618334Speter	  operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]]
389790285Sobrien	    = push_reload (recog_data.operand[goal_alternative_matches[i]],
389890285Sobrien			   recog_data.operand[i],
389990285Sobrien			   recog_data.operand_loc[goal_alternative_matches[i]],
390090285Sobrien			   recog_data.operand_loc[i],
390118334Speter			   (enum reg_class) goal_alternative[goal_alternative_matches[i]],
390218334Speter			   operand_mode[goal_alternative_matches[i]],
390318334Speter			   operand_mode[i],
390418334Speter			   0, 1, goal_alternative_matches[i], RELOAD_OTHER);
390518334Speter      }
390690285Sobrien
390752557Sobrien  /* Perform whatever substitutions on the operands we are supposed
390852557Sobrien     to make due to commutativity or replacement of registers
390952557Sobrien     with equivalent constants or memory slots.  */
391052557Sobrien
391152557Sobrien  for (i = 0; i < noperands; i++)
391252557Sobrien    {
391352557Sobrien      /* We only do this on the last pass through reload, because it is
391490285Sobrien	 possible for some data (like reg_equiv_address) to be changed during
391590285Sobrien	 later passes.  Moreover, we loose the opportunity to get a useful
391690285Sobrien	 reload_{in,out}_reg when we do these replacements.  */
391752557Sobrien
391852557Sobrien      if (replace)
391952557Sobrien	{
392052557Sobrien	  rtx substitution = substed_operand[i];
392152557Sobrien
392290285Sobrien	  *recog_data.operand_loc[i] = substitution;
392352557Sobrien
392452557Sobrien	  /* If we're replacing an operand with a LABEL_REF, we need
392552557Sobrien	     to make sure that there's a REG_LABEL note attached to
392652557Sobrien	     this instruction.  */
392752557Sobrien	  if (GET_CODE (insn) != JUMP_INSN
392852557Sobrien	      && GET_CODE (substitution) == LABEL_REF
392952557Sobrien	      && !find_reg_note (insn, REG_LABEL, XEXP (substitution, 0)))
393090285Sobrien	    REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
393152557Sobrien						  XEXP (substitution, 0),
393252557Sobrien						  REG_NOTES (insn));
393352557Sobrien	}
393452557Sobrien      else
393590285Sobrien	retval |= (substed_operand[i] != *recog_data.operand_loc[i]);
393652557Sobrien    }
393752557Sobrien
393818334Speter  /* If this insn pattern contains any MATCH_DUP's, make sure that
393918334Speter     they will be substituted if the operands they match are substituted.
394018334Speter     Also do now any substitutions we already did on the operands.
394118334Speter
394218334Speter     Don't do this if we aren't making replacements because we might be
394318334Speter     propagating things allocated by frame pointer elimination into places
394418334Speter     it doesn't expect.  */
394518334Speter
394618334Speter  if (insn_code_number >= 0 && replace)
394790285Sobrien    for (i = insn_data[insn_code_number].n_dups - 1; i >= 0; i--)
394818334Speter      {
394990285Sobrien	int opno = recog_data.dup_num[i];
395090285Sobrien	*recog_data.dup_loc[i] = *recog_data.operand_loc[opno];
395118334Speter	if (operand_reloadnum[opno] >= 0)
395290285Sobrien	  push_replacement (recog_data.dup_loc[i], operand_reloadnum[opno],
395390285Sobrien			    insn_data[insn_code_number].operand[opno].mode);
395418334Speter      }
395518334Speter
395618334Speter#if 0
395718334Speter  /* This loses because reloading of prior insns can invalidate the equivalence
395818334Speter     (or at least find_equiv_reg isn't smart enough to find it any more),
395918334Speter     causing this insn to need more reload regs than it needed before.
396018334Speter     It may be too late to make the reload regs available.
396118334Speter     Now this optimization is done safely in choose_reload_regs.  */
396218334Speter
396318334Speter  /* For each reload of a reg into some other class of reg,
396418334Speter     search for an existing equivalent reg (same value now) in the right class.
396518334Speter     We can use it as long as we don't need to change its contents.  */
396618334Speter  for (i = 0; i < n_reloads; i++)
396790285Sobrien    if (rld[i].reg_rtx == 0
396890285Sobrien	&& rld[i].in != 0
396990285Sobrien	&& GET_CODE (rld[i].in) == REG
397090285Sobrien	&& rld[i].out == 0)
397118334Speter      {
397290285Sobrien	rld[i].reg_rtx
397390285Sobrien	  = find_equiv_reg (rld[i].in, insn, rld[i].class, -1,
397490285Sobrien			    static_reload_reg_p, 0, rld[i].inmode);
397518334Speter	/* Prevent generation of insn to load the value
397618334Speter	   because the one we found already has the value.  */
397790285Sobrien	if (rld[i].reg_rtx)
397890285Sobrien	  rld[i].in = rld[i].reg_rtx;
397918334Speter      }
398018334Speter#endif
398118334Speter
398218334Speter  /* Perhaps an output reload can be combined with another
398318334Speter     to reduce needs by one.  */
398418334Speter  if (!goal_earlyclobber)
398518334Speter    combine_reloads ();
398618334Speter
398718334Speter  /* If we have a pair of reloads for parts of an address, they are reloading
398818334Speter     the same object, the operands themselves were not reloaded, and they
398918334Speter     are for two operands that are supposed to match, merge the reloads and
399050605Sobrien     change the type of the surviving reload to RELOAD_FOR_OPERAND_ADDRESS.  */
399118334Speter
399218334Speter  for (i = 0; i < n_reloads; i++)
399318334Speter    {
399418334Speter      int k;
399518334Speter
399618334Speter      for (j = i + 1; j < n_reloads; j++)
399790285Sobrien	if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
399890285Sobrien	     || rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
399990285Sobrien	     || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
400090285Sobrien	     || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
400190285Sobrien	    && (rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
400290285Sobrien		|| rld[j].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
400390285Sobrien		|| rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS
400490285Sobrien		|| rld[j].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
400590285Sobrien	    && rtx_equal_p (rld[i].in, rld[j].in)
400690285Sobrien	    && (operand_reloadnum[rld[i].opnum] < 0
400790285Sobrien		|| rld[operand_reloadnum[rld[i].opnum]].optional)
400890285Sobrien	    && (operand_reloadnum[rld[j].opnum] < 0
400990285Sobrien		|| rld[operand_reloadnum[rld[j].opnum]].optional)
401090285Sobrien	    && (goal_alternative_matches[rld[i].opnum] == rld[j].opnum
401190285Sobrien		|| (goal_alternative_matches[rld[j].opnum]
401290285Sobrien		    == rld[i].opnum)))
401318334Speter	  {
401418334Speter	    for (k = 0; k < n_replacements; k++)
401518334Speter	      if (replacements[k].what == j)
401618334Speter		replacements[k].what = i;
401718334Speter
401890285Sobrien	    if (rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
401990285Sobrien		|| rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
402090285Sobrien	      rld[i].when_needed = RELOAD_FOR_OPADDR_ADDR;
402150605Sobrien	    else
402290285Sobrien	      rld[i].when_needed = RELOAD_FOR_OPERAND_ADDRESS;
402390285Sobrien	    rld[j].in = 0;
402418334Speter	  }
402518334Speter    }
402618334Speter
402790285Sobrien  /* Scan all the reloads and update their type.
402818334Speter     If a reload is for the address of an operand and we didn't reload
402918334Speter     that operand, change the type.  Similarly, change the operand number
403018334Speter     of a reload when two operands match.  If a reload is optional, treat it
403118334Speter     as though the operand isn't reloaded.
403218334Speter
403318334Speter     ??? This latter case is somewhat odd because if we do the optional
403418334Speter     reload, it means the object is hanging around.  Thus we need only
403518334Speter     do the address reload if the optional reload was NOT done.
403618334Speter
403718334Speter     Change secondary reloads to be the address type of their operand, not
403818334Speter     the normal type.
403918334Speter
404018334Speter     If an operand's reload is now RELOAD_OTHER, change any
404118334Speter     RELOAD_FOR_INPUT_ADDRESS reloads of that operand to
404218334Speter     RELOAD_FOR_OTHER_ADDRESS.  */
404318334Speter
404418334Speter  for (i = 0; i < n_reloads; i++)
404518334Speter    {
404690285Sobrien      if (rld[i].secondary_p
404790285Sobrien	  && rld[i].when_needed == operand_type[rld[i].opnum])
404890285Sobrien	rld[i].when_needed = address_type[rld[i].opnum];
404918334Speter
405090285Sobrien      if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
405190285Sobrien	   || rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
405290285Sobrien	   || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
405390285Sobrien	   || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
405490285Sobrien	  && (operand_reloadnum[rld[i].opnum] < 0
405590285Sobrien	      || rld[operand_reloadnum[rld[i].opnum]].optional))
405618334Speter	{
405718334Speter	  /* If we have a secondary reload to go along with this reload,
405850605Sobrien	     change its type to RELOAD_FOR_OPADDR_ADDR.  */
405918334Speter
406090285Sobrien	  if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
406190285Sobrien	       || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
406290285Sobrien	      && rld[i].secondary_in_reload != -1)
406318334Speter	    {
406490285Sobrien	      int secondary_in_reload = rld[i].secondary_in_reload;
406518334Speter
406690285Sobrien	      rld[secondary_in_reload].when_needed = RELOAD_FOR_OPADDR_ADDR;
406718334Speter
406850605Sobrien	      /* If there's a tertiary reload we have to change it also.  */
406918334Speter	      if (secondary_in_reload > 0
407090285Sobrien		  && rld[secondary_in_reload].secondary_in_reload != -1)
407190285Sobrien		rld[rld[secondary_in_reload].secondary_in_reload].when_needed
407218334Speter		  = RELOAD_FOR_OPADDR_ADDR;
407318334Speter	    }
407418334Speter
407590285Sobrien	  if ((rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
407690285Sobrien	       || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
407790285Sobrien	      && rld[i].secondary_out_reload != -1)
407818334Speter	    {
407990285Sobrien	      int secondary_out_reload = rld[i].secondary_out_reload;
408018334Speter
408190285Sobrien	      rld[secondary_out_reload].when_needed = RELOAD_FOR_OPADDR_ADDR;
408218334Speter
408350605Sobrien	      /* If there's a tertiary reload we have to change it also.  */
408418334Speter	      if (secondary_out_reload
408590285Sobrien		  && rld[secondary_out_reload].secondary_out_reload != -1)
408690285Sobrien		rld[rld[secondary_out_reload].secondary_out_reload].when_needed
408718334Speter		  = RELOAD_FOR_OPADDR_ADDR;
408818334Speter	    }
408950605Sobrien
409090285Sobrien	  if (rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
409190285Sobrien	      || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
409290285Sobrien	    rld[i].when_needed = RELOAD_FOR_OPADDR_ADDR;
409352557Sobrien	  else
409490285Sobrien	    rld[i].when_needed = RELOAD_FOR_OPERAND_ADDRESS;
409518334Speter	}
409618334Speter
409790285Sobrien      if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
409890285Sobrien	   || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
409990285Sobrien	  && operand_reloadnum[rld[i].opnum] >= 0
410090285Sobrien	  && (rld[operand_reloadnum[rld[i].opnum]].when_needed
410118334Speter	      == RELOAD_OTHER))
410290285Sobrien	rld[i].when_needed = RELOAD_FOR_OTHER_ADDRESS;
410318334Speter
410490285Sobrien      if (goal_alternative_matches[rld[i].opnum] >= 0)
410590285Sobrien	rld[i].opnum = goal_alternative_matches[rld[i].opnum];
410618334Speter    }
410718334Speter
410850605Sobrien  /* Scan all the reloads, and check for RELOAD_FOR_OPERAND_ADDRESS reloads.
410950605Sobrien     If we have more than one, then convert all RELOAD_FOR_OPADDR_ADDR
411050605Sobrien     reloads to RELOAD_FOR_OPERAND_ADDRESS reloads.
411150605Sobrien
411250605Sobrien     choose_reload_regs assumes that RELOAD_FOR_OPADDR_ADDR reloads never
411350605Sobrien     conflict with RELOAD_FOR_OPERAND_ADDRESS reloads.  This is true for a
411450605Sobrien     single pair of RELOAD_FOR_OPADDR_ADDR/RELOAD_FOR_OPERAND_ADDRESS reloads.
411550605Sobrien     However, if there is more than one RELOAD_FOR_OPERAND_ADDRESS reload,
411650605Sobrien     then a RELOAD_FOR_OPADDR_ADDR reload conflicts with all
411750605Sobrien     RELOAD_FOR_OPERAND_ADDRESS reloads other than the one that uses it.
411850605Sobrien     This is complicated by the fact that a single operand can have more
411950605Sobrien     than one RELOAD_FOR_OPERAND_ADDRESS reload.  It is very difficult to fix
412050605Sobrien     choose_reload_regs without affecting code quality, and cases that
412150605Sobrien     actually fail are extremely rare, so it turns out to be better to fix
412250605Sobrien     the problem here by not generating cases that choose_reload_regs will
412350605Sobrien     fail for.  */
412452557Sobrien  /* There is a similar problem with RELOAD_FOR_INPUT_ADDRESS /
412550605Sobrien     RELOAD_FOR_OUTPUT_ADDRESS when there is more than one of a kind for
412650605Sobrien     a single operand.
412750605Sobrien     We can reduce the register pressure by exploiting that a
412850605Sobrien     RELOAD_FOR_X_ADDR_ADDR that precedes all RELOAD_FOR_X_ADDRESS reloads
412952557Sobrien     does not conflict with any of them, if it is only used for the first of
413052557Sobrien     the RELOAD_FOR_X_ADDRESS reloads.  */
413150605Sobrien  {
413250605Sobrien    int first_op_addr_num = -2;
413350605Sobrien    int first_inpaddr_num[MAX_RECOG_OPERANDS];
413450605Sobrien    int first_outpaddr_num[MAX_RECOG_OPERANDS];
413590285Sobrien    int need_change = 0;
413650605Sobrien    /* We use last_op_addr_reload and the contents of the above arrays
413750605Sobrien       first as flags - -2 means no instance encountered, -1 means exactly
413850605Sobrien       one instance encountered.
413950605Sobrien       If more than one instance has been encountered, we store the reload
414050605Sobrien       number of the first reload of the kind in question; reload numbers
414150605Sobrien       are known to be non-negative.  */
414250605Sobrien    for (i = 0; i < noperands; i++)
414350605Sobrien      first_inpaddr_num[i] = first_outpaddr_num[i] = -2;
414450605Sobrien    for (i = n_reloads - 1; i >= 0; i--)
414550605Sobrien      {
414690285Sobrien	switch (rld[i].when_needed)
414750605Sobrien	  {
414850605Sobrien	  case RELOAD_FOR_OPERAND_ADDRESS:
414952557Sobrien	    if (++first_op_addr_num >= 0)
415050605Sobrien	      {
415152557Sobrien		first_op_addr_num = i;
415250605Sobrien		need_change = 1;
415350605Sobrien	      }
415450605Sobrien	    break;
415550605Sobrien	  case RELOAD_FOR_INPUT_ADDRESS:
415690285Sobrien	    if (++first_inpaddr_num[rld[i].opnum] >= 0)
415750605Sobrien	      {
415890285Sobrien		first_inpaddr_num[rld[i].opnum] = i;
415950605Sobrien		need_change = 1;
416050605Sobrien	      }
416150605Sobrien	    break;
416250605Sobrien	  case RELOAD_FOR_OUTPUT_ADDRESS:
416390285Sobrien	    if (++first_outpaddr_num[rld[i].opnum] >= 0)
416450605Sobrien	      {
416590285Sobrien		first_outpaddr_num[rld[i].opnum] = i;
416650605Sobrien		need_change = 1;
416750605Sobrien	      }
416850605Sobrien	    break;
416950605Sobrien	  default:
417050605Sobrien	    break;
417150605Sobrien	  }
417250605Sobrien      }
417350605Sobrien
417450605Sobrien    if (need_change)
417550605Sobrien      {
417650605Sobrien	for (i = 0; i < n_reloads; i++)
417750605Sobrien	  {
417890285Sobrien	    int first_num;
417990285Sobrien	    enum reload_type type;
418050605Sobrien
418190285Sobrien	    switch (rld[i].when_needed)
418250605Sobrien	      {
418350605Sobrien	      case RELOAD_FOR_OPADDR_ADDR:
418450605Sobrien		first_num = first_op_addr_num;
418550605Sobrien		type = RELOAD_FOR_OPERAND_ADDRESS;
418650605Sobrien		break;
418750605Sobrien	      case RELOAD_FOR_INPADDR_ADDRESS:
418890285Sobrien		first_num = first_inpaddr_num[rld[i].opnum];
418950605Sobrien		type = RELOAD_FOR_INPUT_ADDRESS;
419050605Sobrien		break;
419150605Sobrien	      case RELOAD_FOR_OUTADDR_ADDRESS:
419290285Sobrien		first_num = first_outpaddr_num[rld[i].opnum];
419350605Sobrien		type = RELOAD_FOR_OUTPUT_ADDRESS;
419450605Sobrien		break;
419550605Sobrien	      default:
419650605Sobrien		continue;
419750605Sobrien	      }
419852557Sobrien	    if (first_num < 0)
419952557Sobrien	      continue;
420052557Sobrien	    else if (i > first_num)
420190285Sobrien	      rld[i].when_needed = type;
420252557Sobrien	    else
420352557Sobrien	      {
420452557Sobrien		/* Check if the only TYPE reload that uses reload I is
420552557Sobrien		   reload FIRST_NUM.  */
420652557Sobrien		for (j = n_reloads - 1; j > first_num; j--)
420752557Sobrien		  {
420890285Sobrien		    if (rld[j].when_needed == type
420990285Sobrien			&& (rld[i].secondary_p
421090285Sobrien			    ? rld[j].secondary_in_reload == i
421190285Sobrien			    : reg_mentioned_p (rld[i].in, rld[j].in)))
421252557Sobrien		      {
421390285Sobrien			rld[i].when_needed = type;
421452557Sobrien			break;
421552557Sobrien		      }
421652557Sobrien		  }
421752557Sobrien	      }
421850605Sobrien	  }
421950605Sobrien      }
422050605Sobrien  }
422150605Sobrien
422218334Speter  /* See if we have any reloads that are now allowed to be merged
422318334Speter     because we've changed when the reload is needed to
422418334Speter     RELOAD_FOR_OPERAND_ADDRESS or RELOAD_FOR_OTHER_ADDRESS.  Only
422518334Speter     check for the most common cases.  */
422618334Speter
422718334Speter  for (i = 0; i < n_reloads; i++)
422890285Sobrien    if (rld[i].in != 0 && rld[i].out == 0
422990285Sobrien	&& (rld[i].when_needed == RELOAD_FOR_OPERAND_ADDRESS
423090285Sobrien	    || rld[i].when_needed == RELOAD_FOR_OPADDR_ADDR
423190285Sobrien	    || rld[i].when_needed == RELOAD_FOR_OTHER_ADDRESS))
423218334Speter      for (j = 0; j < n_reloads; j++)
423390285Sobrien	if (i != j && rld[j].in != 0 && rld[j].out == 0
423490285Sobrien	    && rld[j].when_needed == rld[i].when_needed
423590285Sobrien	    && MATCHES (rld[i].in, rld[j].in)
423690285Sobrien	    && rld[i].class == rld[j].class
423790285Sobrien	    && !rld[i].nocombine && !rld[j].nocombine
423890285Sobrien	    && rld[i].reg_rtx == rld[j].reg_rtx)
423918334Speter	  {
424090285Sobrien	    rld[i].opnum = MIN (rld[i].opnum, rld[j].opnum);
424118334Speter	    transfer_replacements (i, j);
424290285Sobrien	    rld[j].in = 0;
424318334Speter	  }
424418334Speter
424590285Sobrien#ifdef HAVE_cc0
424690285Sobrien  /* If we made any reloads for addresses, see if they violate a
424790285Sobrien     "no input reloads" requirement for this insn.  But loads that we
424890285Sobrien     do after the insn (such as for output addresses) are fine.  */
424990285Sobrien  if (no_input_reloads)
425090285Sobrien    for (i = 0; i < n_reloads; i++)
425190285Sobrien      if (rld[i].in != 0
425290285Sobrien	  && rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
425390285Sobrien	  && rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS)
425490285Sobrien	abort ();
425590285Sobrien#endif
425650605Sobrien
425790285Sobrien  /* Compute reload_mode and reload_nregs.  */
425850605Sobrien  for (i = 0; i < n_reloads; i++)
425950605Sobrien    {
426090285Sobrien      rld[i].mode
426190285Sobrien	= (rld[i].inmode == VOIDmode
426290285Sobrien	   || (GET_MODE_SIZE (rld[i].outmode)
426390285Sobrien	       > GET_MODE_SIZE (rld[i].inmode)))
426490285Sobrien	  ? rld[i].outmode : rld[i].inmode;
426550605Sobrien
426690285Sobrien      rld[i].nregs = CLASS_MAX_NREGS (rld[i].class, rld[i].mode);
426750605Sobrien    }
426850605Sobrien
426990285Sobrien  /* Special case a simple move with an input reload and a
427090285Sobrien     destination of a hard reg, if the hard reg is ok, use it.  */
427190285Sobrien  for (i = 0; i < n_reloads; i++)
427290285Sobrien    if (rld[i].when_needed == RELOAD_FOR_INPUT
427390285Sobrien	&& GET_CODE (PATTERN (insn)) == SET
427490285Sobrien 	&& GET_CODE (SET_DEST (PATTERN (insn))) == REG
427590285Sobrien 	&& SET_SRC (PATTERN (insn)) == rld[i].in)
427690285Sobrien      {
427790285Sobrien 	rtx dest = SET_DEST (PATTERN (insn));
427890285Sobrien	unsigned int regno = REGNO (dest);
427950605Sobrien
428090285Sobrien 	if (regno < FIRST_PSEUDO_REGISTER
428190285Sobrien 	    && TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno)
428290285Sobrien 	    && HARD_REGNO_MODE_OK (regno, rld[i].mode))
428390285Sobrien 	  rld[i].reg_rtx = dest;
428490285Sobrien      }
428550605Sobrien
428652557Sobrien  return retval;
428718334Speter}
428818334Speter
428918334Speter/* Return 1 if alternative number ALTNUM in constraint-string CONSTRAINT
429018334Speter   accepts a memory operand with constant address.  */
429118334Speter
429218334Speterstatic int
429318334Speteralternative_allows_memconst (constraint, altnum)
429452557Sobrien     const char *constraint;
429518334Speter     int altnum;
429618334Speter{
429790285Sobrien  int c;
429818334Speter  /* Skip alternatives before the one requested.  */
429918334Speter  while (altnum > 0)
430018334Speter    {
430118334Speter      while (*constraint++ != ',');
430218334Speter      altnum--;
430318334Speter    }
430418334Speter  /* Scan the requested alternative for 'm' or 'o'.
430518334Speter     If one of them is present, this alternative accepts memory constants.  */
430618334Speter  while ((c = *constraint++) && c != ',' && c != '#')
430718334Speter    if (c == 'm' || c == 'o')
430818334Speter      return 1;
430918334Speter  return 0;
431018334Speter}
431118334Speter
431218334Speter/* Scan X for memory references and scan the addresses for reloading.
431318334Speter   Also checks for references to "constant" regs that we want to eliminate
431418334Speter   and replaces them with the values they stand for.
431518334Speter   We may alter X destructively if it contains a reference to such.
431618334Speter   If X is just a constant reg, we return the equivalent value
431718334Speter   instead of X.
431818334Speter
431918334Speter   IND_LEVELS says how many levels of indirect addressing this machine
432018334Speter   supports.
432118334Speter
432218334Speter   OPNUM and TYPE identify the purpose of the reload.
432318334Speter
432418334Speter   IS_SET_DEST is true if X is the destination of a SET, which is not
432552557Sobrien   appropriate to be replaced by a constant.
432618334Speter
432752557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
432852557Sobrien   to determine if we may generate output reloads, and where to put USEs
432990285Sobrien   for pseudos that we have to replace with stack slots.
433052557Sobrien
433190285Sobrien   ADDRESS_RELOADED.  If nonzero, is a pointer to where we put the
433290285Sobrien   result of find_reloads_address.  */
433390285Sobrien
433418334Speterstatic rtx
433590285Sobrienfind_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn,
433690285Sobrien		     address_reloaded)
433718334Speter     rtx x;
433818334Speter     int opnum;
433918334Speter     enum reload_type type;
434018334Speter     int ind_levels;
434118334Speter     int is_set_dest;
434252557Sobrien     rtx insn;
434390285Sobrien     int *address_reloaded;
434418334Speter{
434590285Sobrien  RTX_CODE code = GET_CODE (x);
434618334Speter
434790285Sobrien  const char *fmt = GET_RTX_FORMAT (code);
434890285Sobrien  int i;
434952557Sobrien  int copied;
435018334Speter
435118334Speter  if (code == REG)
435218334Speter    {
435318334Speter      /* This code is duplicated for speed in find_reloads.  */
435490285Sobrien      int regno = REGNO (x);
435518334Speter      if (reg_equiv_constant[regno] != 0 && !is_set_dest)
435618334Speter	x = reg_equiv_constant[regno];
435718334Speter#if 0
435890285Sobrien      /*  This creates (subreg (mem...)) which would cause an unnecessary
435990285Sobrien	  reload of the mem.  */
436018334Speter      else if (reg_equiv_mem[regno] != 0)
436118334Speter	x = reg_equiv_mem[regno];
436218334Speter#endif
436352557Sobrien      else if (reg_equiv_memory_loc[regno]
436452557Sobrien	       && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
436518334Speter	{
436652557Sobrien	  rtx mem = make_memloc (x, regno);
436752557Sobrien	  if (reg_equiv_address[regno]
436852557Sobrien	      || ! rtx_equal_p (mem, reg_equiv_mem[regno]))
436952557Sobrien	    {
437052557Sobrien	      /* If this is not a toplevel operand, find_reloads doesn't see
437152557Sobrien		 this substitution.  We have to emit a USE of the pseudo so
437252557Sobrien		 that delete_output_reload can see it.  */
437390285Sobrien	      if (replace_reloads && recog_data.operand[opnum] != x)
437490285Sobrien		/* We mark the USE with QImode so that we recognize it
437590285Sobrien		   as one that can be safely deleted at the end of
437690285Sobrien		   reload.  */
437790285Sobrien		PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, x), insn),
437890285Sobrien			  QImode);
437952557Sobrien	      x = mem;
438090285Sobrien	      i = find_reloads_address (GET_MODE (x), &x, XEXP (x, 0), &XEXP (x, 0),
438190285Sobrien					opnum, type, ind_levels, insn);
438290285Sobrien	      if (address_reloaded)
438390285Sobrien		*address_reloaded = i;
438452557Sobrien	    }
438518334Speter	}
438618334Speter      return x;
438718334Speter    }
438818334Speter  if (code == MEM)
438918334Speter    {
439018334Speter      rtx tem = x;
439190285Sobrien
439290285Sobrien      i = find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0),
439390285Sobrien				opnum, type, ind_levels, insn);
439490285Sobrien      if (address_reloaded)
439590285Sobrien	*address_reloaded = i;
439690285Sobrien
439718334Speter      return tem;
439818334Speter    }
439918334Speter
440018334Speter  if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)
440118334Speter    {
440290285Sobrien      /* Check for SUBREG containing a REG that's equivalent to a constant.
440318334Speter	 If the constant has a known value, truncate it right now.
440418334Speter	 Similarly if we are extracting a single-word of a multi-word
440518334Speter	 constant.  If the constant is symbolic, allow it to be substituted
440618334Speter	 normally.  push_reload will strip the subreg later.  If the
440718334Speter	 constant is VOIDmode, abort because we will lose the mode of
440818334Speter	 the register (this should never happen because one of the cases
440918334Speter	 above should handle it).  */
441018334Speter
441190285Sobrien      int regno = REGNO (SUBREG_REG (x));
441218334Speter      rtx tem;
441318334Speter
441418334Speter      if (subreg_lowpart_p (x)
441518334Speter	  && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
441618334Speter	  && reg_equiv_constant[regno] != 0
441718334Speter	  && (tem = gen_lowpart_common (GET_MODE (x),
441818334Speter					reg_equiv_constant[regno])) != 0)
441918334Speter	return tem;
442018334Speter
442118334Speter      if (GET_MODE_BITSIZE (GET_MODE (x)) == BITS_PER_WORD
442218334Speter	  && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
442318334Speter	  && reg_equiv_constant[regno] != 0
442418334Speter	  && (tem = operand_subword (reg_equiv_constant[regno],
442590285Sobrien				     SUBREG_BYTE (x) / UNITS_PER_WORD, 0,
442618334Speter				     GET_MODE (SUBREG_REG (x)))) != 0)
442750605Sobrien	{
442850605Sobrien	  /* TEM is now a word sized constant for the bits from X that
442950605Sobrien	     we wanted.  However, TEM may be the wrong representation.
443018334Speter
443150605Sobrien	     Use gen_lowpart_common to convert a CONST_INT into a
443250605Sobrien	     CONST_DOUBLE and vice versa as needed according to by the mode
443350605Sobrien	     of the SUBREG.  */
443450605Sobrien	  tem = gen_lowpart_common (GET_MODE (x), tem);
443550605Sobrien	  if (!tem)
443650605Sobrien	    abort ();
443750605Sobrien	  return tem;
443850605Sobrien	}
443950605Sobrien
444050605Sobrien      /* If the SUBREG is wider than a word, the above test will fail.
444150605Sobrien	 For example, we might have a SImode SUBREG of a DImode SUBREG_REG
444250605Sobrien	 for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
444350605Sobrien	 a 32 bit target.  We still can - and have to - handle this
444450605Sobrien	 for non-paradoxical subregs of CONST_INTs.  */
444518334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
444618334Speter	  && reg_equiv_constant[regno] != 0
444750605Sobrien	  && GET_CODE (reg_equiv_constant[regno]) == CONST_INT
444850605Sobrien	  && (GET_MODE_SIZE (GET_MODE (x))
444950605Sobrien	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
445090285Sobrien	{
445190285Sobrien	  int shift = SUBREG_BYTE (x) * BITS_PER_UNIT;
445290285Sobrien	  if (WORDS_BIG_ENDIAN)
445390285Sobrien	    shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
445490285Sobrien		     - GET_MODE_BITSIZE (GET_MODE (x))
445590285Sobrien		     - shift);
445690285Sobrien	  /* Here we use the knowledge that CONST_INTs have a
445790285Sobrien	     HOST_WIDE_INT field.  */
445890285Sobrien	  if (shift >= HOST_BITS_PER_WIDE_INT)
445990285Sobrien	    shift = HOST_BITS_PER_WIDE_INT - 1;
446090285Sobrien	  return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
446190285Sobrien	}
446250605Sobrien
446350605Sobrien      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
446450605Sobrien	  && reg_equiv_constant[regno] != 0
446518334Speter	  && GET_MODE (reg_equiv_constant[regno]) == VOIDmode)
446618334Speter	abort ();
446718334Speter
446818334Speter      /* If the subreg contains a reg that will be converted to a mem,
446918334Speter	 convert the subreg to a narrower memref now.
447018334Speter	 Otherwise, we would get (subreg (mem ...) ...),
447118334Speter	 which would force reload of the mem.
447218334Speter
447318334Speter	 We also need to do this if there is an equivalent MEM that is
447418334Speter	 not offsettable.  In that case, alter_subreg would produce an
447518334Speter	 invalid address on big-endian machines.
447618334Speter
447718334Speter	 For machines that extend byte loads, we must not reload using
447818334Speter	 a wider mode if we have a paradoxical SUBREG.  find_reloads will
447918334Speter	 force a reload in that case.  So we should not do anything here.  */
448018334Speter
448118334Speter      else if (regno >= FIRST_PSEUDO_REGISTER
448218334Speter#ifdef LOAD_EXTEND_OP
448318334Speter	       && (GET_MODE_SIZE (GET_MODE (x))
448418334Speter		   <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
448518334Speter#endif
448618334Speter	       && (reg_equiv_address[regno] != 0
448718334Speter		   || (reg_equiv_mem[regno] != 0
448890285Sobrien		       && (! strict_memory_address_p (GET_MODE (x),
448918334Speter						      XEXP (reg_equiv_mem[regno], 0))
449052557Sobrien			   || ! offsettable_memref_p (reg_equiv_mem[regno])
449152557Sobrien			   || num_not_at_initial_offset))))
449252557Sobrien	x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
449352557Sobrien					 insn);
449452557Sobrien    }
449552557Sobrien
449652557Sobrien  for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
449752557Sobrien    {
449852557Sobrien      if (fmt[i] == 'e')
449918334Speter	{
450052557Sobrien	  rtx new_part = find_reloads_toplev (XEXP (x, i), opnum, type,
450190285Sobrien					      ind_levels, is_set_dest, insn,
450290285Sobrien					      address_reloaded);
450352557Sobrien	  /* If we have replaced a reg with it's equivalent memory loc -
450452557Sobrien	     that can still be handled here e.g. if it's in a paradoxical
450552557Sobrien	     subreg - we must make the change in a copy, rather than using
450652557Sobrien	     a destructive change.  This way, find_reloads can still elect
450752557Sobrien	     not to do the change.  */
450852557Sobrien	  if (new_part != XEXP (x, i) && ! CONSTANT_P (new_part) && ! copied)
450918334Speter	    {
451052557Sobrien	      x = shallow_copy_rtx (x);
451152557Sobrien	      copied = 1;
451218334Speter	    }
451352557Sobrien	  XEXP (x, i) = new_part;
451418334Speter	}
451518334Speter    }
451618334Speter  return x;
451718334Speter}
451818334Speter
451918334Speter/* Return a mem ref for the memory equivalent of reg REGNO.
452018334Speter   This mem ref is not shared with anything.  */
452118334Speter
452218334Speterstatic rtx
452318334Spetermake_memloc (ad, regno)
452418334Speter     rtx ad;
452518334Speter     int regno;
452618334Speter{
452718334Speter  /* We must rerun eliminate_regs, in case the elimination
452818334Speter     offsets have changed.  */
452952557Sobrien  rtx tem
453052557Sobrien    = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0, NULL_RTX), 0);
453118334Speter
453218334Speter  /* If TEM might contain a pseudo, we must copy it to avoid
453318334Speter     modifying it when we do the substitution for the reload.  */
453490285Sobrien  if (rtx_varies_p (tem, 0))
453518334Speter    tem = copy_rtx (tem);
453618334Speter
453790285Sobrien  tem = replace_equiv_address_nv (reg_equiv_memory_loc[regno], tem);
453890285Sobrien  tem = adjust_address_nv (tem, GET_MODE (ad), 0);
453990285Sobrien
454090285Sobrien  /* Copy the result if it's still the same as the equivalence, to avoid
454190285Sobrien     modifying it when we do the substitution for the reload.  */
454290285Sobrien  if (tem == reg_equiv_memory_loc[regno])
454390285Sobrien    tem = copy_rtx (tem);
454418334Speter  return tem;
454518334Speter}
454618334Speter
454718334Speter/* Record all reloads needed for handling memory address AD
454818334Speter   which appears in *LOC in a memory reference to mode MODE
454918334Speter   which itself is found in location  *MEMREFLOC.
455018334Speter   Note that we take shortcuts assuming that no multi-reg machine mode
455118334Speter   occurs as part of an address.
455218334Speter
455318334Speter   OPNUM and TYPE specify the purpose of this reload.
455418334Speter
455518334Speter   IND_LEVELS says how many levels of indirect addressing this machine
455618334Speter   supports.
455718334Speter
455850605Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
455952557Sobrien   to determine if we may generate output reloads, and where to put USEs
456052557Sobrien   for pseudos that we have to replace with stack slots.
456150605Sobrien
456218334Speter   Value is nonzero if this address is reloaded or replaced as a whole.
456318334Speter   This is interesting to the caller if the address is an autoincrement.
456418334Speter
456518334Speter   Note that there is no verification that the address will be valid after
456618334Speter   this routine does its work.  Instead, we rely on the fact that the address
456718334Speter   was valid when reload started.  So we need only undo things that reload
456818334Speter   could have broken.  These are wrong register types, pseudos not allocated
456918334Speter   to a hard register, and frame pointer elimination.  */
457018334Speter
457118334Speterstatic int
457250605Sobrienfind_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
457318334Speter     enum machine_mode mode;
457418334Speter     rtx *memrefloc;
457518334Speter     rtx ad;
457618334Speter     rtx *loc;
457718334Speter     int opnum;
457818334Speter     enum reload_type type;
457918334Speter     int ind_levels;
458050605Sobrien     rtx insn;
458118334Speter{
458290285Sobrien  int regno;
458352557Sobrien  int removed_and = 0;
458418334Speter  rtx tem;
458518334Speter
458618334Speter  /* If the address is a register, see if it is a legitimate address and
458718334Speter     reload if not.  We first handle the cases where we need not reload
458818334Speter     or where we must reload in a non-standard way.  */
458918334Speter
459018334Speter  if (GET_CODE (ad) == REG)
459118334Speter    {
459218334Speter      regno = REGNO (ad);
459318334Speter
459490285Sobrien      /* If the register is equivalent to an invariant expression, substitute
459590285Sobrien	 the invariant, and eliminate any eliminable register references.  */
459690285Sobrien      tem = reg_equiv_constant[regno];
459790285Sobrien      if (tem != 0
459890285Sobrien	  && (tem = eliminate_regs (tem, mode, insn))
459990285Sobrien	  && strict_memory_address_p (mode, tem))
460018334Speter	{
460190285Sobrien	  *loc = ad = tem;
460252557Sobrien	  return 0;
460318334Speter	}
460418334Speter
460552557Sobrien      tem = reg_equiv_memory_loc[regno];
460652557Sobrien      if (tem != 0)
460718334Speter	{
460852557Sobrien	  if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
460952557Sobrien	    {
461052557Sobrien	      tem = make_memloc (ad, regno);
461152557Sobrien	      if (! strict_memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
461252557Sobrien		{
461390285Sobrien		  find_reloads_address (GET_MODE (tem), (rtx*) 0, XEXP (tem, 0),
461452557Sobrien					&XEXP (tem, 0), opnum, ADDR_TYPE (type),
461552557Sobrien					ind_levels, insn);
461652557Sobrien		}
461752557Sobrien	      /* We can avoid a reload if the register's equivalent memory
461852557Sobrien		 expression is valid as an indirect memory address.
461952557Sobrien		 But not all addresses are valid in a mem used as an indirect
462052557Sobrien		 address: only reg or reg+constant.  */
462152557Sobrien
462252557Sobrien	      if (ind_levels > 0
462352557Sobrien		  && strict_memory_address_p (mode, tem)
462452557Sobrien		  && (GET_CODE (XEXP (tem, 0)) == REG
462552557Sobrien		      || (GET_CODE (XEXP (tem, 0)) == PLUS
462652557Sobrien			  && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
462752557Sobrien			  && CONSTANT_P (XEXP (XEXP (tem, 0), 1)))))
462852557Sobrien		{
462952557Sobrien		  /* TEM is not the same as what we'll be replacing the
463052557Sobrien		     pseudo with after reload, put a USE in front of INSN
463152557Sobrien		     in the final reload pass.  */
463252557Sobrien		  if (replace_reloads
463352557Sobrien		      && num_not_at_initial_offset
463452557Sobrien		      && ! rtx_equal_p (tem, reg_equiv_mem[regno]))
463552557Sobrien		    {
463652557Sobrien		      *loc = tem;
463790285Sobrien		      /* We mark the USE with QImode so that we
463890285Sobrien			 recognize it as one that can be safely
463990285Sobrien			 deleted at the end of reload.  */
464090285Sobrien		      PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, ad),
464190285Sobrien						  insn), QImode);
464290285Sobrien
464352557Sobrien		      /* This doesn't really count as replacing the address
464452557Sobrien			 as a whole, since it is still a memory access.  */
464552557Sobrien		    }
464652557Sobrien		  return 0;
464752557Sobrien		}
464852557Sobrien	      ad = tem;
464952557Sobrien	    }
465018334Speter	}
465118334Speter
465218334Speter      /* The only remaining case where we can avoid a reload is if this is a
465318334Speter	 hard register that is valid as a base register and which is not the
465418334Speter	 subject of a CLOBBER in this insn.  */
465518334Speter
465650605Sobrien      else if (regno < FIRST_PSEUDO_REGISTER
465750605Sobrien	       && REGNO_MODE_OK_FOR_BASE_P (regno, mode)
465890285Sobrien	       && ! regno_clobbered_p (regno, this_insn, mode, 0))
465918334Speter	return 0;
466018334Speter
466118334Speter      /* If we do not have one of the cases above, we must do the reload.  */
466290285Sobrien      push_reload (ad, NULL_RTX, loc, (rtx*) 0, MODE_BASE_REG_CLASS (mode),
466318334Speter		   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
466418334Speter      return 1;
466518334Speter    }
466618334Speter
466718334Speter  if (strict_memory_address_p (mode, ad))
466818334Speter    {
466918334Speter      /* The address appears valid, so reloads are not needed.
467018334Speter	 But the address may contain an eliminable register.
467118334Speter	 This can happen because a machine with indirect addressing
467218334Speter	 may consider a pseudo register by itself a valid address even when
467318334Speter	 it has failed to get a hard reg.
467418334Speter	 So do a tree-walk to find and eliminate all such regs.  */
467518334Speter
467618334Speter      /* But first quickly dispose of a common case.  */
467718334Speter      if (GET_CODE (ad) == PLUS
467818334Speter	  && GET_CODE (XEXP (ad, 1)) == CONST_INT
467918334Speter	  && GET_CODE (XEXP (ad, 0)) == REG
468018334Speter	  && reg_equiv_constant[REGNO (XEXP (ad, 0))] == 0)
468118334Speter	return 0;
468218334Speter
468318334Speter      subst_reg_equivs_changed = 0;
468452557Sobrien      *loc = subst_reg_equivs (ad, insn);
468518334Speter
468618334Speter      if (! subst_reg_equivs_changed)
468718334Speter	return 0;
468818334Speter
468918334Speter      /* Check result for validity after substitution.  */
469018334Speter      if (strict_memory_address_p (mode, ad))
469118334Speter	return 0;
469218334Speter    }
469318334Speter
469450605Sobrien#ifdef LEGITIMIZE_RELOAD_ADDRESS
469550605Sobrien  do
469650605Sobrien    {
469750605Sobrien      if (memrefloc)
469850605Sobrien	{
469950605Sobrien	  LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
470050605Sobrien				     ind_levels, win);
470150605Sobrien	}
470250605Sobrien      break;
470350605Sobrien    win:
470450605Sobrien      *memrefloc = copy_rtx (*memrefloc);
470550605Sobrien      XEXP (*memrefloc, 0) = ad;
470650605Sobrien      move_replacements (&ad, &XEXP (*memrefloc, 0));
470750605Sobrien      return 1;
470850605Sobrien    }
470950605Sobrien  while (0);
471050605Sobrien#endif
471150605Sobrien
471252557Sobrien  /* The address is not valid.  We have to figure out why.  First see if
471352557Sobrien     we have an outer AND and remove it if so.  Then analyze what's inside.  */
471452557Sobrien
471552557Sobrien  if (GET_CODE (ad) == AND)
471652557Sobrien    {
471752557Sobrien      removed_and = 1;
471852557Sobrien      loc = &XEXP (ad, 0);
471952557Sobrien      ad = *loc;
472052557Sobrien    }
472152557Sobrien
472252557Sobrien  /* One possibility for why the address is invalid is that it is itself
472352557Sobrien     a MEM.  This can happen when the frame pointer is being eliminated, a
472452557Sobrien     pseudo is not allocated to a hard register, and the offset between the
472552557Sobrien     frame and stack pointers is not its initial value.  In that case the
472652557Sobrien     pseudo will have been replaced by a MEM referring to the
472752557Sobrien     stack pointer.  */
472818334Speter  if (GET_CODE (ad) == MEM)
472918334Speter    {
473018334Speter      /* First ensure that the address in this MEM is valid.  Then, unless
473118334Speter	 indirect addresses are valid, reload the MEM into a register.  */
473218334Speter      tem = ad;
473318334Speter      find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0),
473450605Sobrien			    opnum, ADDR_TYPE (type),
473550605Sobrien			    ind_levels == 0 ? 0 : ind_levels - 1, insn);
473618334Speter
473718334Speter      /* If tem was changed, then we must create a new memory reference to
473818334Speter	 hold it and store it back into memrefloc.  */
473918334Speter      if (tem != ad && memrefloc)
474018334Speter	{
474118334Speter	  *memrefloc = copy_rtx (*memrefloc);
474218334Speter	  copy_replacements (tem, XEXP (*memrefloc, 0));
474318334Speter	  loc = &XEXP (*memrefloc, 0);
474452557Sobrien	  if (removed_and)
474552557Sobrien	    loc = &XEXP (*loc, 0);
474618334Speter	}
474718334Speter
474818334Speter      /* Check similar cases as for indirect addresses as above except
474918334Speter	 that we can allow pseudos and a MEM since they should have been
475018334Speter	 taken care of above.  */
475118334Speter
475218334Speter      if (ind_levels == 0
475318334Speter	  || (GET_CODE (XEXP (tem, 0)) == SYMBOL_REF && ! indirect_symref_ok)
475418334Speter	  || GET_CODE (XEXP (tem, 0)) == MEM
475518334Speter	  || ! (GET_CODE (XEXP (tem, 0)) == REG
475618334Speter		|| (GET_CODE (XEXP (tem, 0)) == PLUS
475718334Speter		    && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
475818334Speter		    && GET_CODE (XEXP (XEXP (tem, 0), 1)) == CONST_INT)))
475918334Speter	{
476018334Speter	  /* Must use TEM here, not AD, since it is the one that will
476118334Speter	     have any subexpressions reloaded, if needed.  */
476290285Sobrien	  push_reload (tem, NULL_RTX, loc, (rtx*) 0,
476390285Sobrien		       MODE_BASE_REG_CLASS (mode), GET_MODE (tem),
476450605Sobrien		       VOIDmode, 0,
476518334Speter		       0, opnum, type);
476652557Sobrien	  return ! removed_and;
476718334Speter	}
476818334Speter      else
476918334Speter	return 0;
477018334Speter    }
477118334Speter
477218334Speter  /* If we have address of a stack slot but it's not valid because the
477318334Speter     displacement is too large, compute the sum in a register.
477418334Speter     Handle all base registers here, not just fp/ap/sp, because on some
477518334Speter     targets (namely SH) we can also get too large displacements from
477618334Speter     big-endian corrections.  */
477718334Speter  else if (GET_CODE (ad) == PLUS
477818334Speter	   && GET_CODE (XEXP (ad, 0)) == REG
477918334Speter	   && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
478050605Sobrien	   && REG_MODE_OK_FOR_BASE_P (XEXP (ad, 0), mode)
478118334Speter	   && GET_CODE (XEXP (ad, 1)) == CONST_INT)
478218334Speter    {
478318334Speter      /* Unshare the MEM rtx so we can safely alter it.  */
478418334Speter      if (memrefloc)
478518334Speter	{
478618334Speter	  *memrefloc = copy_rtx (*memrefloc);
478718334Speter	  loc = &XEXP (*memrefloc, 0);
478852557Sobrien	  if (removed_and)
478952557Sobrien	    loc = &XEXP (*loc, 0);
479018334Speter	}
479152557Sobrien
479218334Speter      if (double_reg_address_ok)
479318334Speter	{
479418334Speter	  /* Unshare the sum as well.  */
479518334Speter	  *loc = ad = copy_rtx (ad);
479652557Sobrien
479718334Speter	  /* Reload the displacement into an index reg.
479818334Speter	     We assume the frame pointer or arg pointer is a base reg.  */
479918334Speter	  find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
480052557Sobrien				     INDEX_REG_CLASS, GET_MODE (ad), opnum,
480152557Sobrien				     type, ind_levels);
480252557Sobrien	  return 0;
480318334Speter	}
480418334Speter      else
480518334Speter	{
480618334Speter	  /* If the sum of two regs is not necessarily valid,
480718334Speter	     reload the sum into a base reg.
480818334Speter	     That will at least work.  */
480990285Sobrien	  find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
481050605Sobrien				     Pmode, opnum, type, ind_levels);
481118334Speter	}
481252557Sobrien      return ! removed_and;
481318334Speter    }
481418334Speter
481518334Speter  /* If we have an indexed stack slot, there are three possible reasons why
481618334Speter     it might be invalid: The index might need to be reloaded, the address
481718334Speter     might have been made by frame pointer elimination and hence have a
481890285Sobrien     constant out of range, or both reasons might apply.
481918334Speter
482018334Speter     We can easily check for an index needing reload, but even if that is the
482118334Speter     case, we might also have an invalid constant.  To avoid making the
482218334Speter     conservative assumption and requiring two reloads, we see if this address
482318334Speter     is valid when not interpreted strictly.  If it is, the only problem is
482418334Speter     that the index needs a reload and find_reloads_address_1 will take care
482518334Speter     of it.
482618334Speter
482718334Speter     If we decide to do something here, it must be that
482818334Speter     `double_reg_address_ok' is true and that this address rtl was made by
482918334Speter     eliminate_regs.  We generate a reload of the fp/sp/ap + constant and
483018334Speter     rework the sum so that the reload register will be added to the index.
483118334Speter     This is safe because we know the address isn't shared.
483218334Speter
483318334Speter     We check for fp/ap/sp as both the first and second operand of the
483418334Speter     innermost PLUS.  */
483518334Speter
483618334Speter  else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
483718334Speter	   && GET_CODE (XEXP (ad, 0)) == PLUS
483818334Speter	   && (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
483918334Speter#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
484018334Speter	       || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
484118334Speter#endif
484218334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
484318334Speter	       || XEXP (XEXP (ad, 0), 0) == arg_pointer_rtx
484418334Speter#endif
484518334Speter	       || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
484618334Speter	   && ! memory_address_p (mode, ad))
484718334Speter    {
484850605Sobrien      *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
484950605Sobrien				plus_constant (XEXP (XEXP (ad, 0), 0),
485050605Sobrien					       INTVAL (XEXP (ad, 1))),
485190285Sobrien				XEXP (XEXP (ad, 0), 1));
485290285Sobrien      find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0),
485390285Sobrien				 MODE_BASE_REG_CLASS (mode),
485418334Speter				 GET_MODE (ad), opnum, type, ind_levels);
485550605Sobrien      find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
485650605Sobrien			      type, 0, insn);
485718334Speter
485852557Sobrien      return 0;
485918334Speter    }
486090285Sobrien
486118334Speter  else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
486218334Speter	   && GET_CODE (XEXP (ad, 0)) == PLUS
486318334Speter	   && (XEXP (XEXP (ad, 0), 1) == frame_pointer_rtx
486418334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
486518334Speter	       || XEXP (XEXP (ad, 0), 1) == hard_frame_pointer_rtx
486618334Speter#endif
486718334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
486818334Speter	       || XEXP (XEXP (ad, 0), 1) == arg_pointer_rtx
486918334Speter#endif
487018334Speter	       || XEXP (XEXP (ad, 0), 1) == stack_pointer_rtx)
487118334Speter	   && ! memory_address_p (mode, ad))
487218334Speter    {
487350605Sobrien      *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
487450605Sobrien				XEXP (XEXP (ad, 0), 0),
487550605Sobrien				plus_constant (XEXP (XEXP (ad, 0), 1),
487650605Sobrien					       INTVAL (XEXP (ad, 1))));
487790285Sobrien      find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
487890285Sobrien				 MODE_BASE_REG_CLASS (mode),
487918334Speter				 GET_MODE (ad), opnum, type, ind_levels);
488050605Sobrien      find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
488150605Sobrien			      type, 0, insn);
488218334Speter
488352557Sobrien      return 0;
488418334Speter    }
488590285Sobrien
488618334Speter  /* See if address becomes valid when an eliminable register
488718334Speter     in a sum is replaced.  */
488818334Speter
488918334Speter  tem = ad;
489018334Speter  if (GET_CODE (ad) == PLUS)
489118334Speter    tem = subst_indexed_address (ad);
489218334Speter  if (tem != ad && strict_memory_address_p (mode, tem))
489318334Speter    {
489418334Speter      /* Ok, we win that way.  Replace any additional eliminable
489518334Speter	 registers.  */
489618334Speter
489718334Speter      subst_reg_equivs_changed = 0;
489852557Sobrien      tem = subst_reg_equivs (tem, insn);
489918334Speter
490018334Speter      /* Make sure that didn't make the address invalid again.  */
490118334Speter
490218334Speter      if (! subst_reg_equivs_changed || strict_memory_address_p (mode, tem))
490318334Speter	{
490418334Speter	  *loc = tem;
490518334Speter	  return 0;
490618334Speter	}
490718334Speter    }
490818334Speter
490918334Speter  /* If constants aren't valid addresses, reload the constant address
491018334Speter     into a register.  */
491118334Speter  if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
491218334Speter    {
491390285Sobrien      /* If AD is an address in the constant pool, the MEM rtx may be shared.
491418334Speter	 Unshare it so we can safely alter it.  */
491518334Speter      if (memrefloc && GET_CODE (ad) == SYMBOL_REF
491618334Speter	  && CONSTANT_POOL_ADDRESS_P (ad))
491718334Speter	{
491818334Speter	  *memrefloc = copy_rtx (*memrefloc);
491918334Speter	  loc = &XEXP (*memrefloc, 0);
492052557Sobrien	  if (removed_and)
492152557Sobrien	    loc = &XEXP (*loc, 0);
492218334Speter	}
492318334Speter
492490285Sobrien      find_reloads_address_part (ad, loc, MODE_BASE_REG_CLASS (mode),
492590285Sobrien				 Pmode, opnum, type, ind_levels);
492652557Sobrien      return ! removed_and;
492718334Speter    }
492818334Speter
492950605Sobrien  return find_reloads_address_1 (mode, ad, 0, loc, opnum, type, ind_levels,
493050605Sobrien				 insn);
493118334Speter}
493218334Speter
493318334Speter/* Find all pseudo regs appearing in AD
493418334Speter   that are eliminable in favor of equivalent values
493552557Sobrien   and do not have hard regs; replace them by their equivalents.
493652557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  We put USEs in
493752557Sobrien   front of it for pseudos that we have to replace with stack slots.  */
493818334Speter
493918334Speterstatic rtx
494052557Sobriensubst_reg_equivs (ad, insn)
494118334Speter     rtx ad;
494252557Sobrien     rtx insn;
494318334Speter{
494490285Sobrien  RTX_CODE code = GET_CODE (ad);
494590285Sobrien  int i;
494690285Sobrien  const char *fmt;
494718334Speter
494818334Speter  switch (code)
494918334Speter    {
495018334Speter    case HIGH:
495118334Speter    case CONST_INT:
495218334Speter    case CONST:
495318334Speter    case CONST_DOUBLE:
495496288Sobrien    case CONST_VECTOR:
495518334Speter    case SYMBOL_REF:
495618334Speter    case LABEL_REF:
495718334Speter    case PC:
495818334Speter    case CC0:
495918334Speter      return ad;
496018334Speter
496118334Speter    case REG:
496218334Speter      {
496390285Sobrien	int regno = REGNO (ad);
496418334Speter
496518334Speter	if (reg_equiv_constant[regno] != 0)
496618334Speter	  {
496718334Speter	    subst_reg_equivs_changed = 1;
496818334Speter	    return reg_equiv_constant[regno];
496918334Speter	  }
497052557Sobrien	if (reg_equiv_memory_loc[regno] && num_not_at_initial_offset)
497152557Sobrien	  {
497252557Sobrien	    rtx mem = make_memloc (ad, regno);
497352557Sobrien	    if (! rtx_equal_p (mem, reg_equiv_mem[regno]))
497452557Sobrien	      {
497552557Sobrien		subst_reg_equivs_changed = 1;
497690285Sobrien		/* We mark the USE with QImode so that we recognize it
497790285Sobrien		   as one that can be safely deleted at the end of
497890285Sobrien		   reload.  */
497990285Sobrien		PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn),
498090285Sobrien			  QImode);
498152557Sobrien		return mem;
498252557Sobrien	      }
498352557Sobrien	  }
498418334Speter      }
498518334Speter      return ad;
498618334Speter
498718334Speter    case PLUS:
498818334Speter      /* Quickly dispose of a common case.  */
498918334Speter      if (XEXP (ad, 0) == frame_pointer_rtx
499018334Speter	  && GET_CODE (XEXP (ad, 1)) == CONST_INT)
499118334Speter	return ad;
499250605Sobrien      break;
499390285Sobrien
499450605Sobrien    default:
499550605Sobrien      break;
499618334Speter    }
499718334Speter
499818334Speter  fmt = GET_RTX_FORMAT (code);
499918334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
500018334Speter    if (fmt[i] == 'e')
500152557Sobrien      XEXP (ad, i) = subst_reg_equivs (XEXP (ad, i), insn);
500218334Speter  return ad;
500318334Speter}
500418334Speter
500518334Speter/* Compute the sum of X and Y, making canonicalizations assumed in an
500618334Speter   address, namely: sum constant integers, surround the sum of two
500718334Speter   constants with a CONST, put the constant as the second operand, and
500818334Speter   group the constant on the outermost sum.
500918334Speter
501018334Speter   This routine assumes both inputs are already in canonical form.  */
501118334Speter
501218334Speterrtx
501318334Speterform_sum (x, y)
501418334Speter     rtx x, y;
501518334Speter{
501618334Speter  rtx tem;
501718334Speter  enum machine_mode mode = GET_MODE (x);
501818334Speter
501918334Speter  if (mode == VOIDmode)
502018334Speter    mode = GET_MODE (y);
502118334Speter
502218334Speter  if (mode == VOIDmode)
502318334Speter    mode = Pmode;
502418334Speter
502518334Speter  if (GET_CODE (x) == CONST_INT)
502618334Speter    return plus_constant (y, INTVAL (x));
502718334Speter  else if (GET_CODE (y) == CONST_INT)
502818334Speter    return plus_constant (x, INTVAL (y));
502918334Speter  else if (CONSTANT_P (x))
503018334Speter    tem = x, x = y, y = tem;
503118334Speter
503218334Speter  if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
503318334Speter    return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
503418334Speter
503518334Speter  /* Note that if the operands of Y are specified in the opposite
503618334Speter     order in the recursive calls below, infinite recursion will occur.  */
503718334Speter  if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
503818334Speter    return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
503918334Speter
504018334Speter  /* If both constant, encapsulate sum.  Otherwise, just form sum.  A
504118334Speter     constant will have been placed second.  */
504218334Speter  if (CONSTANT_P (x) && CONSTANT_P (y))
504318334Speter    {
504418334Speter      if (GET_CODE (x) == CONST)
504518334Speter	x = XEXP (x, 0);
504618334Speter      if (GET_CODE (y) == CONST)
504718334Speter	y = XEXP (y, 0);
504818334Speter
504950605Sobrien      return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y));
505018334Speter    }
505118334Speter
505250605Sobrien  return gen_rtx_PLUS (mode, x, y);
505318334Speter}
505418334Speter
505518334Speter/* If ADDR is a sum containing a pseudo register that should be
505618334Speter   replaced with a constant (from reg_equiv_constant),
505718334Speter   return the result of doing so, and also apply the associative
505818334Speter   law so that the result is more likely to be a valid address.
505918334Speter   (But it is not guaranteed to be one.)
506018334Speter
506118334Speter   Note that at most one register is replaced, even if more are
506218334Speter   replaceable.  Also, we try to put the result into a canonical form
506318334Speter   so it is more likely to be a valid address.
506418334Speter
506518334Speter   In all other cases, return ADDR.  */
506618334Speter
506718334Speterstatic rtx
506818334Spetersubst_indexed_address (addr)
506918334Speter     rtx addr;
507018334Speter{
507118334Speter  rtx op0 = 0, op1 = 0, op2 = 0;
507218334Speter  rtx tem;
507318334Speter  int regno;
507418334Speter
507518334Speter  if (GET_CODE (addr) == PLUS)
507618334Speter    {
507718334Speter      /* Try to find a register to replace.  */
507818334Speter      op0 = XEXP (addr, 0), op1 = XEXP (addr, 1), op2 = 0;
507918334Speter      if (GET_CODE (op0) == REG
508018334Speter	  && (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
508118334Speter	  && reg_renumber[regno] < 0
508218334Speter	  && reg_equiv_constant[regno] != 0)
508318334Speter	op0 = reg_equiv_constant[regno];
508418334Speter      else if (GET_CODE (op1) == REG
508590285Sobrien	       && (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
508690285Sobrien	       && reg_renumber[regno] < 0
508790285Sobrien	       && reg_equiv_constant[regno] != 0)
508818334Speter	op1 = reg_equiv_constant[regno];
508918334Speter      else if (GET_CODE (op0) == PLUS
509018334Speter	       && (tem = subst_indexed_address (op0)) != op0)
509118334Speter	op0 = tem;
509218334Speter      else if (GET_CODE (op1) == PLUS
509318334Speter	       && (tem = subst_indexed_address (op1)) != op1)
509418334Speter	op1 = tem;
509518334Speter      else
509618334Speter	return addr;
509718334Speter
509818334Speter      /* Pick out up to three things to add.  */
509918334Speter      if (GET_CODE (op1) == PLUS)
510018334Speter	op2 = XEXP (op1, 1), op1 = XEXP (op1, 0);
510118334Speter      else if (GET_CODE (op0) == PLUS)
510218334Speter	op2 = op1, op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
510318334Speter
510418334Speter      /* Compute the sum.  */
510518334Speter      if (op2 != 0)
510618334Speter	op1 = form_sum (op1, op2);
510718334Speter      if (op1 != 0)
510818334Speter	op0 = form_sum (op0, op1);
510918334Speter
511018334Speter      return op0;
511118334Speter    }
511218334Speter  return addr;
511318334Speter}
511418334Speter
511590285Sobrien/* Update the REG_INC notes for an insn.  It updates all REG_INC
511690285Sobrien   notes for the instruction which refer to REGNO the to refer
511790285Sobrien   to the reload number.
511890285Sobrien
511990285Sobrien   INSN is the insn for which any REG_INC notes need updating.
512090285Sobrien
512190285Sobrien   REGNO is the register number which has been reloaded.
512290285Sobrien
512390285Sobrien   RELOADNUM is the reload number.  */
512490285Sobrien
512590285Sobrienstatic void
512690285Sobrienupdate_auto_inc_notes (insn, regno, reloadnum)
512790285Sobrien     rtx insn ATTRIBUTE_UNUSED;
512890285Sobrien     int regno ATTRIBUTE_UNUSED;
512990285Sobrien     int reloadnum ATTRIBUTE_UNUSED;
513090285Sobrien{
513190285Sobrien#ifdef AUTO_INC_DEC
513290285Sobrien  rtx link;
513390285Sobrien
513490285Sobrien  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
513590285Sobrien    if (REG_NOTE_KIND (link) == REG_INC
513690285Sobrien        && REGNO (XEXP (link, 0)) == regno)
513790285Sobrien      push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
513890285Sobrien#endif
513990285Sobrien}
514090285Sobrien
514150605Sobrien/* Record the pseudo registers we must reload into hard registers in a
514250605Sobrien   subexpression of a would-be memory address, X referring to a value
514350605Sobrien   in mode MODE.  (This function is not called if the address we find
514450605Sobrien   is strictly valid.)
514550605Sobrien
514618334Speter   CONTEXT = 1 means we are considering regs as index regs,
514718334Speter   = 0 means we are considering them as base regs.
514818334Speter
514918334Speter   OPNUM and TYPE specify the purpose of any reloads made.
515018334Speter
515118334Speter   IND_LEVELS says how many levels of indirect addressing are
515218334Speter   supported at this point in the address.
515318334Speter
515450605Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
515550605Sobrien   to determine if we may generate output reloads.
515650605Sobrien
515718334Speter   We return nonzero if X, as a whole, is reloaded or replaced.  */
515818334Speter
515918334Speter/* Note that we take shortcuts assuming that no multi-reg machine mode
516018334Speter   occurs as part of an address.
516118334Speter   Also, this is not fully machine-customizable; it works for machines
516290285Sobrien   such as VAXen and 68000's and 32000's, but other possible machines
516318334Speter   could have addressing modes that this does not handle right.  */
516418334Speter
516518334Speterstatic int
516650605Sobrienfind_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
516750605Sobrien     enum machine_mode mode;
516818334Speter     rtx x;
516918334Speter     int context;
517018334Speter     rtx *loc;
517118334Speter     int opnum;
517218334Speter     enum reload_type type;
517318334Speter     int ind_levels;
517450605Sobrien     rtx insn;
517518334Speter{
517690285Sobrien  RTX_CODE code = GET_CODE (x);
517718334Speter
517818334Speter  switch (code)
517918334Speter    {
518018334Speter    case PLUS:
518118334Speter      {
518290285Sobrien	rtx orig_op0 = XEXP (x, 0);
518390285Sobrien	rtx orig_op1 = XEXP (x, 1);
518490285Sobrien	RTX_CODE code0 = GET_CODE (orig_op0);
518590285Sobrien	RTX_CODE code1 = GET_CODE (orig_op1);
518690285Sobrien	rtx op0 = orig_op0;
518790285Sobrien	rtx op1 = orig_op1;
518818334Speter
518918334Speter	if (GET_CODE (op0) == SUBREG)
519018334Speter	  {
519118334Speter	    op0 = SUBREG_REG (op0);
519218334Speter	    code0 = GET_CODE (op0);
519318334Speter	    if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
519450605Sobrien	      op0 = gen_rtx_REG (word_mode,
519590285Sobrien				 (REGNO (op0) +
519690285Sobrien				  subreg_regno_offset (REGNO (SUBREG_REG (orig_op0)),
519790285Sobrien						       GET_MODE (SUBREG_REG (orig_op0)),
519890285Sobrien						       SUBREG_BYTE (orig_op0),
519990285Sobrien						       GET_MODE (orig_op0))));
520018334Speter	  }
520118334Speter
520218334Speter	if (GET_CODE (op1) == SUBREG)
520318334Speter	  {
520418334Speter	    op1 = SUBREG_REG (op1);
520518334Speter	    code1 = GET_CODE (op1);
520618334Speter	    if (code1 == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER)
520790285Sobrien	      /* ??? Why is this given op1's mode and above for
520890285Sobrien		 ??? op0 SUBREGs we use word_mode?  */
520950605Sobrien	      op1 = gen_rtx_REG (GET_MODE (op1),
521090285Sobrien				 (REGNO (op1) +
521190285Sobrien				  subreg_regno_offset (REGNO (SUBREG_REG (orig_op1)),
521290285Sobrien						       GET_MODE (SUBREG_REG (orig_op1)),
521390285Sobrien						       SUBREG_BYTE (orig_op1),
521490285Sobrien						       GET_MODE (orig_op1))));
521518334Speter	  }
521618334Speter
521790285Sobrien	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
521818334Speter	    || code0 == ZERO_EXTEND || code1 == MEM)
521918334Speter	  {
522050605Sobrien	    find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
522150605Sobrien				    type, ind_levels, insn);
522250605Sobrien	    find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
522350605Sobrien				    type, ind_levels, insn);
522418334Speter	  }
522518334Speter
522618334Speter	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
522718334Speter		 || code1 == ZERO_EXTEND || code0 == MEM)
522818334Speter	  {
522950605Sobrien	    find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
523050605Sobrien				    type, ind_levels, insn);
523150605Sobrien	    find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
523250605Sobrien				    type, ind_levels, insn);
523318334Speter	  }
523418334Speter
523518334Speter	else if (code0 == CONST_INT || code0 == CONST
523618334Speter		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
523750605Sobrien	  find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
523850605Sobrien				  type, ind_levels, insn);
523918334Speter
524018334Speter	else if (code1 == CONST_INT || code1 == CONST
524118334Speter		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
524250605Sobrien	  find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
524350605Sobrien				  type, ind_levels, insn);
524418334Speter
524518334Speter	else if (code0 == REG && code1 == REG)
524618334Speter	  {
524718334Speter	    if (REG_OK_FOR_INDEX_P (op0)
524850605Sobrien		&& REG_MODE_OK_FOR_BASE_P (op1, mode))
524918334Speter	      return 0;
525018334Speter	    else if (REG_OK_FOR_INDEX_P (op1)
525150605Sobrien		     && REG_MODE_OK_FOR_BASE_P (op0, mode))
525218334Speter	      return 0;
525350605Sobrien	    else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
525450605Sobrien	      find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
525550605Sobrien				      type, ind_levels, insn);
525650605Sobrien	    else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
525750605Sobrien	      find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
525850605Sobrien				      type, ind_levels, insn);
525918334Speter	    else if (REG_OK_FOR_INDEX_P (op1))
526050605Sobrien	      find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
526150605Sobrien				      type, ind_levels, insn);
526218334Speter	    else if (REG_OK_FOR_INDEX_P (op0))
526350605Sobrien	      find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
526450605Sobrien				      type, ind_levels, insn);
526518334Speter	    else
526618334Speter	      {
526750605Sobrien		find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
526850605Sobrien					type, ind_levels, insn);
526950605Sobrien		find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
527050605Sobrien					type, ind_levels, insn);
527118334Speter	      }
527218334Speter	  }
527318334Speter
527418334Speter	else if (code0 == REG)
527518334Speter	  {
527650605Sobrien	    find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
527750605Sobrien				    type, ind_levels, insn);
527850605Sobrien	    find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
527950605Sobrien				    type, ind_levels, insn);
528018334Speter	  }
528118334Speter
528218334Speter	else if (code1 == REG)
528318334Speter	  {
528450605Sobrien	    find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
528550605Sobrien				    type, ind_levels, insn);
528650605Sobrien	    find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
528750605Sobrien				    type, ind_levels, insn);
528818334Speter	  }
528918334Speter      }
529018334Speter
529118334Speter      return 0;
529218334Speter
529390285Sobrien    case POST_MODIFY:
529490285Sobrien    case PRE_MODIFY:
529590285Sobrien      {
529690285Sobrien	rtx op0 = XEXP (x, 0);
529790285Sobrien	rtx op1 = XEXP (x, 1);
529890285Sobrien
529990285Sobrien	if (GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)
530090285Sobrien	  return 0;
530190285Sobrien
530290285Sobrien	/* Currently, we only support {PRE,POST}_MODIFY constructs
530390285Sobrien	   where a base register is {inc,dec}remented by the contents
530490285Sobrien	   of another register or by a constant value.  Thus, these
530590285Sobrien	   operands must match.  */
530690285Sobrien	if (op0 != XEXP (op1, 0))
530790285Sobrien	  abort ();
530890285Sobrien
530990285Sobrien	/* Require index register (or constant).  Let's just handle the
531090285Sobrien	   register case in the meantime... If the target allows
531190285Sobrien	   auto-modify by a constant then we could try replacing a pseudo
531290285Sobrien	   register with its equivalent constant where applicable.  */
531390285Sobrien	if (REG_P (XEXP (op1, 1)))
531490285Sobrien	  if (!REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
531590285Sobrien	    find_reloads_address_1 (mode, XEXP (op1, 1), 1, &XEXP (op1, 1),
531690285Sobrien				    opnum, type, ind_levels, insn);
531790285Sobrien
531890285Sobrien	if (REG_P (XEXP (op1, 0)))
531990285Sobrien	  {
532090285Sobrien	    int regno = REGNO (XEXP (op1, 0));
532190285Sobrien	    int reloadnum;
532290285Sobrien
532390285Sobrien	    /* A register that is incremented cannot be constant!  */
532490285Sobrien	    if (regno >= FIRST_PSEUDO_REGISTER
532590285Sobrien		&& reg_equiv_constant[regno] != 0)
532690285Sobrien	      abort ();
532790285Sobrien
532890285Sobrien	    /* Handle a register that is equivalent to a memory location
532990285Sobrien	       which cannot be addressed directly.  */
533090285Sobrien 	    if (reg_equiv_memory_loc[regno] != 0
533190285Sobrien		&& (reg_equiv_address[regno] != 0
533290285Sobrien		    || num_not_at_initial_offset))
533390285Sobrien	      {
533490285Sobrien		rtx tem = make_memloc (XEXP (x, 0), regno);
533590285Sobrien
533690285Sobrien		if (reg_equiv_address[regno]
533790285Sobrien		    || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
533890285Sobrien		  {
533990285Sobrien		    /* First reload the memory location's address.
534090285Sobrien		       We can't use ADDR_TYPE (type) here, because we need to
534190285Sobrien		       write back the value after reading it, hence we actually
534290285Sobrien		       need two registers.  */
534390285Sobrien		    find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
534490285Sobrien					  &XEXP (tem, 0), opnum,
534590285Sobrien					  RELOAD_OTHER,
534690285Sobrien					  ind_levels, insn);
534790285Sobrien
534890285Sobrien		    /* Then reload the memory location into a base
534990285Sobrien		       register.  */
535090285Sobrien		    reloadnum = push_reload (tem, tem, &XEXP (x, 0),
535190285Sobrien					     &XEXP (op1, 0),
535290285Sobrien					     MODE_BASE_REG_CLASS (mode),
535390285Sobrien					     GET_MODE (x), GET_MODE (x), 0,
535490285Sobrien					     0, opnum, RELOAD_OTHER);
535590285Sobrien
535690285Sobrien		    update_auto_inc_notes (this_insn, regno, reloadnum);
535790285Sobrien		    return 0;
535890285Sobrien		  }
535990285Sobrien	      }
536090285Sobrien
536190285Sobrien	    if (reg_renumber[regno] >= 0)
536290285Sobrien	      regno = reg_renumber[regno];
536390285Sobrien
536490285Sobrien	    /* We require a base register here...  */
536590285Sobrien	    if (!REGNO_MODE_OK_FOR_BASE_P (regno, GET_MODE (x)))
536690285Sobrien	      {
536790285Sobrien		reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
536890285Sobrien					 &XEXP (op1, 0), &XEXP (x, 0),
536990285Sobrien					 MODE_BASE_REG_CLASS (mode),
537090285Sobrien					 GET_MODE (x), GET_MODE (x), 0, 0,
537190285Sobrien					 opnum, RELOAD_OTHER);
537290285Sobrien
537390285Sobrien		update_auto_inc_notes (this_insn, regno, reloadnum);
537490285Sobrien		return 0;
537590285Sobrien	      }
537690285Sobrien	  }
537790285Sobrien	else
537890285Sobrien	  abort ();
537990285Sobrien      }
538090285Sobrien      return 0;
538190285Sobrien
538218334Speter    case POST_INC:
538318334Speter    case POST_DEC:
538418334Speter    case PRE_INC:
538518334Speter    case PRE_DEC:
538618334Speter      if (GET_CODE (XEXP (x, 0)) == REG)
538718334Speter	{
538890285Sobrien	  int regno = REGNO (XEXP (x, 0));
538918334Speter	  int value = 0;
539018334Speter	  rtx x_orig = x;
539118334Speter
539218334Speter	  /* A register that is incremented cannot be constant!  */
539318334Speter	  if (regno >= FIRST_PSEUDO_REGISTER
539418334Speter	      && reg_equiv_constant[regno] != 0)
539518334Speter	    abort ();
539618334Speter
539718334Speter	  /* Handle a register that is equivalent to a memory location
539818334Speter	     which cannot be addressed directly.  */
539952557Sobrien	  if (reg_equiv_memory_loc[regno] != 0
540052557Sobrien	      && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
540118334Speter	    {
540218334Speter	      rtx tem = make_memloc (XEXP (x, 0), regno);
540352557Sobrien	      if (reg_equiv_address[regno]
540452557Sobrien		  || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
540552557Sobrien		{
540652557Sobrien		  /* First reload the memory location's address.
540752557Sobrien		     We can't use ADDR_TYPE (type) here, because we need to
540852557Sobrien		     write back the value after reading it, hence we actually
540952557Sobrien		     need two registers.  */
541052557Sobrien		  find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
541152557Sobrien					&XEXP (tem, 0), opnum, type,
541252557Sobrien					ind_levels, insn);
541352557Sobrien		  /* Put this inside a new increment-expression.  */
541452557Sobrien		  x = gen_rtx_fmt_e (GET_CODE (x), GET_MODE (x), tem);
541552557Sobrien		  /* Proceed to reload that, as if it contained a register.  */
541652557Sobrien		}
541718334Speter	    }
541818334Speter
541918334Speter	  /* If we have a hard register that is ok as an index,
542018334Speter	     don't make a reload.  If an autoincrement of a nice register
542118334Speter	     isn't "valid", it must be that no autoincrement is "valid".
542218334Speter	     If that is true and something made an autoincrement anyway,
542318334Speter	     this must be a special context where one is allowed.
542418334Speter	     (For example, a "push" instruction.)
542518334Speter	     We can't improve this address, so leave it alone.  */
542618334Speter
542718334Speter	  /* Otherwise, reload the autoincrement into a suitable hard reg
542818334Speter	     and record how much to increment by.  */
542918334Speter
543018334Speter	  if (reg_renumber[regno] >= 0)
543118334Speter	    regno = reg_renumber[regno];
543218334Speter	  if ((regno >= FIRST_PSEUDO_REGISTER
543318334Speter	       || !(context ? REGNO_OK_FOR_INDEX_P (regno)
543450605Sobrien		    : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
543518334Speter	    {
543650605Sobrien	      int reloadnum;
543718334Speter
543850605Sobrien	      /* If we can output the register afterwards, do so, this
543950605Sobrien		 saves the extra update.
544050605Sobrien		 We can do so if we have an INSN - i.e. no JUMP_INSN nor
544150605Sobrien		 CALL_INSN - and it does not set CC0.
544250605Sobrien		 But don't do this if we cannot directly address the
544350605Sobrien		 memory location, since this will make it harder to
544450605Sobrien		 reuse address reloads, and increases register pressure.
544550605Sobrien		 Also don't do this if we can probably update x directly.  */
544652557Sobrien	      rtx equiv = (GET_CODE (XEXP (x, 0)) == MEM
544752557Sobrien			   ? XEXP (x, 0)
544852557Sobrien			   : reg_equiv_mem[regno]);
544950605Sobrien	      int icode = (int) add_optab->handlers[(int) Pmode].insn_code;
545050605Sobrien	      if (insn && GET_CODE (insn) == INSN && equiv
545152557Sobrien		  && memory_operand (equiv, GET_MODE (equiv))
545250605Sobrien#ifdef HAVE_cc0
545350605Sobrien		  && ! sets_cc0_p (PATTERN (insn))
545450605Sobrien#endif
545550605Sobrien		  && ! (icode != CODE_FOR_nothing
545690285Sobrien			&& ((*insn_data[icode].operand[0].predicate)
545790285Sobrien			    (equiv, Pmode))
545890285Sobrien			&& ((*insn_data[icode].operand[1].predicate)
545990285Sobrien			    (equiv, Pmode))))
546050605Sobrien		{
546170639Sobrien		  /* We use the original pseudo for loc, so that
546270639Sobrien		     emit_reload_insns() knows which pseudo this
546370639Sobrien		     reload refers to and updates the pseudo rtx, not
546470639Sobrien		     its equivalent memory location, as well as the
546570639Sobrien		     corresponding entry in reg_last_reload_reg.  */
546670639Sobrien		  loc = &XEXP (x_orig, 0);
546750605Sobrien		  x = XEXP (x, 0);
546850605Sobrien		  reloadnum
546950605Sobrien		    = push_reload (x, x, loc, loc,
547090285Sobrien				   (context ? INDEX_REG_CLASS :
547190285Sobrien				    MODE_BASE_REG_CLASS (mode)),
547290285Sobrien				   GET_MODE (x), GET_MODE (x), 0, 0,
547390285Sobrien				   opnum, RELOAD_OTHER);
547450605Sobrien		}
547550605Sobrien	      else
547650605Sobrien		{
547750605Sobrien		  reloadnum
547890285Sobrien		    = push_reload (x, NULL_RTX, loc, (rtx*) 0,
547990285Sobrien				   (context ? INDEX_REG_CLASS :
548090285Sobrien				    MODE_BASE_REG_CLASS (mode)),
548150605Sobrien				   GET_MODE (x), GET_MODE (x), 0, 0,
548250605Sobrien				   opnum, type);
548390285Sobrien		  rld[reloadnum].inc
548450605Sobrien		    = find_inc_amount (PATTERN (this_insn), XEXP (x_orig, 0));
548590285Sobrien
548650605Sobrien		  value = 1;
548750605Sobrien		}
548818334Speter
548990285Sobrien	      update_auto_inc_notes (this_insn, REGNO (XEXP (x_orig, 0)),
549090285Sobrien				     reloadnum);
549118334Speter	    }
549218334Speter	  return value;
549318334Speter	}
549418334Speter
549518334Speter      else if (GET_CODE (XEXP (x, 0)) == MEM)
549618334Speter	{
549718334Speter	  /* This is probably the result of a substitution, by eliminate_regs,
549818334Speter	     of an equivalent address for a pseudo that was not allocated to a
549918334Speter	     hard register.  Verify that the specified address is valid and
550018334Speter	     reload it into a register.  */
550190285Sobrien	  /* Variable `tem' might or might not be used in FIND_REG_INC_NOTE.  */
550252557Sobrien	  rtx tem ATTRIBUTE_UNUSED = XEXP (x, 0);
550390285Sobrien	  rtx link;
550418334Speter	  int reloadnum;
550518334Speter
550618334Speter	  /* Since we know we are going to reload this item, don't decrement
550718334Speter	     for the indirection level.
550818334Speter
550918334Speter	     Note that this is actually conservative:  it would be slightly
551018334Speter	     more efficient to use the value of SPILL_INDIRECT_LEVELS from
551118334Speter	     reload1.c here.  */
551250605Sobrien	  /* We can't use ADDR_TYPE (type) here, because we need to
551350605Sobrien	     write back the value after reading it, hence we actually
551450605Sobrien	     need two registers.  */
551518334Speter	  find_reloads_address (GET_MODE (x), &XEXP (x, 0),
551618334Speter				XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 0),
551750605Sobrien				opnum, type, ind_levels, insn);
551818334Speter
551990285Sobrien	  reloadnum = push_reload (x, NULL_RTX, loc, (rtx*) 0,
552090285Sobrien				   (context ? INDEX_REG_CLASS :
552190285Sobrien				    MODE_BASE_REG_CLASS (mode)),
552218334Speter				   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
552390285Sobrien	  rld[reloadnum].inc
552418334Speter	    = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
552518334Speter
552618334Speter	  link = FIND_REG_INC_NOTE (this_insn, tem);
552718334Speter	  if (link != 0)
552818334Speter	    push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
552918334Speter
553018334Speter	  return 1;
553118334Speter	}
553218334Speter      return 0;
553318334Speter
553418334Speter    case MEM:
553518334Speter      /* This is probably the result of a substitution, by eliminate_regs, of
553618334Speter	 an equivalent address for a pseudo that was not allocated to a hard
553718334Speter	 register.  Verify that the specified address is valid and reload it
553818334Speter	 into a register.
553918334Speter
554018334Speter	 Since we know we are going to reload this item, don't decrement for
554118334Speter	 the indirection level.
554218334Speter
554318334Speter	 Note that this is actually conservative:  it would be slightly more
554418334Speter	 efficient to use the value of SPILL_INDIRECT_LEVELS from
554518334Speter	 reload1.c here.  */
554618334Speter
554718334Speter      find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
554850605Sobrien			    opnum, ADDR_TYPE (type), ind_levels, insn);
554990285Sobrien      push_reload (*loc, NULL_RTX, loc, (rtx*) 0,
555090285Sobrien		   (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
555118334Speter		   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
555218334Speter      return 1;
555318334Speter
555418334Speter    case REG:
555518334Speter      {
555690285Sobrien	int regno = REGNO (x);
555718334Speter
555818334Speter	if (reg_equiv_constant[regno] != 0)
555918334Speter	  {
556052557Sobrien	    find_reloads_address_part (reg_equiv_constant[regno], loc,
556190285Sobrien				       (context ? INDEX_REG_CLASS :
556290285Sobrien					MODE_BASE_REG_CLASS (mode)),
556318334Speter				       GET_MODE (x), opnum, type, ind_levels);
556418334Speter	    return 1;
556518334Speter	  }
556618334Speter
556718334Speter#if 0 /* This might screw code in reload1.c to delete prior output-reload
556818334Speter	 that feeds this insn.  */
556918334Speter	if (reg_equiv_mem[regno] != 0)
557018334Speter	  {
557190285Sobrien	    push_reload (reg_equiv_mem[regno], NULL_RTX, loc, (rtx*) 0,
557290285Sobrien			 (context ? INDEX_REG_CLASS :
557390285Sobrien			  MODE_BASE_REG_CLASS (mode)),
557418334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
557518334Speter	    return 1;
557618334Speter	  }
557718334Speter#endif
557818334Speter
557952557Sobrien	if (reg_equiv_memory_loc[regno]
558052557Sobrien	    && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
558118334Speter	  {
558252557Sobrien	    rtx tem = make_memloc (x, regno);
558352557Sobrien	    if (reg_equiv_address[regno] != 0
558452557Sobrien		|| ! rtx_equal_p (tem, reg_equiv_mem[regno]))
558552557Sobrien	      {
558652557Sobrien		x = tem;
558752557Sobrien		find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
558852557Sobrien				      &XEXP (x, 0), opnum, ADDR_TYPE (type),
558952557Sobrien				      ind_levels, insn);
559052557Sobrien	      }
559118334Speter	  }
559218334Speter
559318334Speter	if (reg_renumber[regno] >= 0)
559418334Speter	  regno = reg_renumber[regno];
559518334Speter
559618334Speter	if ((regno >= FIRST_PSEUDO_REGISTER
559718334Speter	     || !(context ? REGNO_OK_FOR_INDEX_P (regno)
559850605Sobrien		  : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
559918334Speter	  {
560090285Sobrien	    push_reload (x, NULL_RTX, loc, (rtx*) 0,
560190285Sobrien			 (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
560218334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
560318334Speter	    return 1;
560418334Speter	  }
560518334Speter
560618334Speter	/* If a register appearing in an address is the subject of a CLOBBER
560718334Speter	   in this insn, reload it into some other register to be safe.
560818334Speter	   The CLOBBER is supposed to make the register unavailable
560918334Speter	   from before this insn to after it.  */
561070639Sobrien	if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
561118334Speter	  {
561290285Sobrien	    push_reload (x, NULL_RTX, loc, (rtx*) 0,
561390285Sobrien			 (context ? INDEX_REG_CLASS : MODE_BASE_REG_CLASS (mode)),
561418334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
561518334Speter	    return 1;
561618334Speter	  }
561718334Speter      }
561818334Speter      return 0;
561918334Speter
562018334Speter    case SUBREG:
562118334Speter      if (GET_CODE (SUBREG_REG (x)) == REG)
562218334Speter	{
562318334Speter	  /* If this is a SUBREG of a hard register and the resulting register
562418334Speter	     is of the wrong class, reload the whole SUBREG.  This avoids
562518334Speter	     needless copies if SUBREG_REG is multi-word.  */
562618334Speter	  if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
562718334Speter	    {
562890285Sobrien	      int regno = subreg_regno (x);
562918334Speter
563018334Speter	      if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
563150605Sobrien		     : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
563218334Speter		{
563390285Sobrien		  push_reload (x, NULL_RTX, loc, (rtx*) 0,
563490285Sobrien			       (context ? INDEX_REG_CLASS :
563590285Sobrien				MODE_BASE_REG_CLASS (mode)),
563618334Speter			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
563718334Speter		  return 1;
563818334Speter		}
563918334Speter	    }
564018334Speter	  /* If this is a SUBREG of a pseudo-register, and the pseudo-register
564118334Speter	     is larger than the class size, then reload the whole SUBREG.  */
564218334Speter	  else
564318334Speter	    {
564452557Sobrien	      enum reg_class class = (context ? INDEX_REG_CLASS
564590285Sobrien				      : MODE_BASE_REG_CLASS (mode));
564618334Speter	      if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
564718334Speter		  > reg_class_size[class])
564818334Speter		{
564952557Sobrien		  x = find_reloads_subreg_address (x, 0, opnum, type,
565052557Sobrien						   ind_levels, insn);
565190285Sobrien		  push_reload (x, NULL_RTX, loc, (rtx*) 0, class,
565218334Speter			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
565318334Speter		  return 1;
565418334Speter		}
565518334Speter	    }
565618334Speter	}
565718334Speter      break;
565890285Sobrien
565950605Sobrien    default:
566050605Sobrien      break;
566118334Speter    }
566218334Speter
566318334Speter  {
566490285Sobrien    const char *fmt = GET_RTX_FORMAT (code);
566590285Sobrien    int i;
566618334Speter
566718334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
566818334Speter      {
566918334Speter	if (fmt[i] == 'e')
567050605Sobrien	  find_reloads_address_1 (mode, XEXP (x, i), context, &XEXP (x, i),
567150605Sobrien				  opnum, type, ind_levels, insn);
567218334Speter      }
567318334Speter  }
567418334Speter
567518334Speter  return 0;
567618334Speter}
567718334Speter
567818334Speter/* X, which is found at *LOC, is a part of an address that needs to be
567918334Speter   reloaded into a register of class CLASS.  If X is a constant, or if
568018334Speter   X is a PLUS that contains a constant, check that the constant is a
568118334Speter   legitimate operand and that we are supposed to be able to load
568218334Speter   it into the register.
568318334Speter
568418334Speter   If not, force the constant into memory and reload the MEM instead.
568518334Speter
568618334Speter   MODE is the mode to use, in case X is an integer constant.
568718334Speter
568818334Speter   OPNUM and TYPE describe the purpose of any reloads made.
568918334Speter
569018334Speter   IND_LEVELS says how many levels of indirect addressing this machine
569118334Speter   supports.  */
569218334Speter
569318334Speterstatic void
569418334Speterfind_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
569518334Speter     rtx x;
569618334Speter     rtx *loc;
569718334Speter     enum reg_class class;
569818334Speter     enum machine_mode mode;
569918334Speter     int opnum;
570018334Speter     enum reload_type type;
570118334Speter     int ind_levels;
570218334Speter{
570318334Speter  if (CONSTANT_P (x)
570418334Speter      && (! LEGITIMATE_CONSTANT_P (x)
570518334Speter	  || PREFERRED_RELOAD_CLASS (x, class) == NO_REGS))
570618334Speter    {
570752557Sobrien      rtx tem;
570852557Sobrien
570990285Sobrien      tem = x = force_const_mem (mode, x);
571018334Speter      find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
571150605Sobrien			    opnum, type, ind_levels, 0);
571218334Speter    }
571318334Speter
571418334Speter  else if (GET_CODE (x) == PLUS
571518334Speter	   && CONSTANT_P (XEXP (x, 1))
571618334Speter	   && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
571718334Speter	       || PREFERRED_RELOAD_CLASS (XEXP (x, 1), class) == NO_REGS))
571818334Speter    {
571952557Sobrien      rtx tem;
572018334Speter
572190285Sobrien      tem = force_const_mem (GET_MODE (x), XEXP (x, 1));
572250605Sobrien      x = gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), tem);
572318334Speter      find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
572450605Sobrien			    opnum, type, ind_levels, 0);
572518334Speter    }
572618334Speter
572790285Sobrien  push_reload (x, NULL_RTX, loc, (rtx*) 0, class,
572818334Speter	       mode, VOIDmode, 0, 0, opnum, type);
572918334Speter}
573018334Speter
573152557Sobrien/* X, a subreg of a pseudo, is a part of an address that needs to be
573252557Sobrien   reloaded.
573352557Sobrien
573452557Sobrien   If the pseudo is equivalent to a memory location that cannot be directly
573552557Sobrien   addressed, make the necessary address reloads.
573652557Sobrien
573752557Sobrien   If address reloads have been necessary, or if the address is changed
573852557Sobrien   by register elimination, return the rtx of the memory location;
573952557Sobrien   otherwise, return X.
574052557Sobrien
574152557Sobrien   If FORCE_REPLACE is nonzero, unconditionally replace the subreg with the
574252557Sobrien   memory location.
574352557Sobrien
574452557Sobrien   OPNUM and TYPE identify the purpose of the reload.
574552557Sobrien
574652557Sobrien   IND_LEVELS says how many levels of indirect addressing are
574752557Sobrien   supported at this point in the address.
574852557Sobrien
574952557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
575052557Sobrien   to determine where to put USEs for pseudos that we have to replace with
575152557Sobrien   stack slots.  */
575252557Sobrien
575352557Sobrienstatic rtx
575452557Sobrienfind_reloads_subreg_address (x, force_replace, opnum, type,
575552557Sobrien			     ind_levels, insn)
575652557Sobrien     rtx x;
575752557Sobrien     int force_replace;
575852557Sobrien     int opnum;
575952557Sobrien     enum reload_type type;
576052557Sobrien     int ind_levels;
576152557Sobrien     rtx insn;
576252557Sobrien{
576352557Sobrien  int regno = REGNO (SUBREG_REG (x));
576452557Sobrien
576552557Sobrien  if (reg_equiv_memory_loc[regno])
576652557Sobrien    {
576752557Sobrien      /* If the address is not directly addressable, or if the address is not
576852557Sobrien	 offsettable, then it must be replaced.  */
576952557Sobrien      if (! force_replace
577052557Sobrien	  && (reg_equiv_address[regno]
577152557Sobrien	      || ! offsettable_memref_p (reg_equiv_mem[regno])))
577252557Sobrien	force_replace = 1;
577352557Sobrien
577452557Sobrien      if (force_replace || num_not_at_initial_offset)
577552557Sobrien	{
577652557Sobrien	  rtx tem = make_memloc (SUBREG_REG (x), regno);
577752557Sobrien
577852557Sobrien	  /* If the address changes because of register elimination, then
577952557Sobrien	     it must be replaced.  */
578052557Sobrien	  if (force_replace
578152557Sobrien	      || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
578252557Sobrien	    {
578390285Sobrien	      int offset = SUBREG_BYTE (x);
578490285Sobrien	      unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
578590285Sobrien	      unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
578652557Sobrien
578790285Sobrien	      XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
578890285Sobrien	      PUT_MODE (tem, GET_MODE (x));
578990285Sobrien
579090285Sobrien	      /* If this was a paradoxical subreg that we replaced, the
579190285Sobrien		 resulting memory must be sufficiently aligned to allow
579290285Sobrien		 us to widen the mode of the memory.  */
579390285Sobrien	      if (outer_size > inner_size && STRICT_ALIGNMENT)
579452557Sobrien		{
579590285Sobrien		  rtx base;
579652557Sobrien
579790285Sobrien		  base = XEXP (tem, 0);
579890285Sobrien		  if (GET_CODE (base) == PLUS)
579990285Sobrien		    {
580090285Sobrien		      if (GET_CODE (XEXP (base, 1)) == CONST_INT
580190285Sobrien			  && INTVAL (XEXP (base, 1)) % outer_size != 0)
580290285Sobrien			return x;
580390285Sobrien		      base = XEXP (base, 0);
580490285Sobrien		    }
580590285Sobrien		  if (GET_CODE (base) != REG
580690285Sobrien		      || (REGNO_POINTER_ALIGN (REGNO (base))
580790285Sobrien			  < outer_size * BITS_PER_UNIT))
580890285Sobrien		    return x;
580952557Sobrien		}
581090285Sobrien
581152557Sobrien	      find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
581252557Sobrien				    &XEXP (tem, 0), opnum, ADDR_TYPE (type),
581352557Sobrien				    ind_levels, insn);
581490285Sobrien
581552557Sobrien	      /* If this is not a toplevel operand, find_reloads doesn't see
581652557Sobrien		 this substitution.  We have to emit a USE of the pseudo so
581752557Sobrien		 that delete_output_reload can see it.  */
581890285Sobrien	      if (replace_reloads && recog_data.operand[opnum] != x)
581990285Sobrien		/* We mark the USE with QImode so that we recognize it
582090285Sobrien		   as one that can be safely deleted at the end of
582190285Sobrien		   reload.  */
582290285Sobrien		PUT_MODE (emit_insn_before (gen_rtx_USE (VOIDmode,
582390285Sobrien							 SUBREG_REG (x)),
582490285Sobrien					    insn), QImode);
582552557Sobrien	      x = tem;
582652557Sobrien	    }
582752557Sobrien	}
582852557Sobrien    }
582952557Sobrien  return x;
583052557Sobrien}
583152557Sobrien
583218334Speter/* Substitute into the current INSN the registers into which we have reloaded
583318334Speter   the things that need reloading.  The array `replacements'
583490285Sobrien   contains the locations of all pointers that must be changed
583518334Speter   and says what to replace them with.
583618334Speter
583718334Speter   Return the rtx that X translates into; usually X, but modified.  */
583818334Speter
583918334Spetervoid
584090285Sobriensubst_reloads (insn)
584190285Sobrien     rtx insn;
584218334Speter{
584390285Sobrien  int i;
584418334Speter
584518334Speter  for (i = 0; i < n_replacements; i++)
584618334Speter    {
584790285Sobrien      struct replacement *r = &replacements[i];
584890285Sobrien      rtx reloadreg = rld[r->what].reg_rtx;
584918334Speter      if (reloadreg)
585018334Speter	{
585190285Sobrien#ifdef ENABLE_CHECKING
585290285Sobrien	  /* Internal consistency test.  Check that we don't modify
585390285Sobrien	     anything in the equivalence arrays.  Whenever something from
585490285Sobrien	     those arrays needs to be reloaded, it must be unshared before
585590285Sobrien	     being substituted into; the equivalence must not be modified.
585690285Sobrien	     Otherwise, if the equivalence is used after that, it will
585790285Sobrien	     have been modified, and the thing substituted (probably a
585890285Sobrien	     register) is likely overwritten and not a usable equivalence.  */
585990285Sobrien	  int check_regno;
586090285Sobrien
586190285Sobrien	  for (check_regno = 0; check_regno < max_regno; check_regno++)
586290285Sobrien	    {
586390285Sobrien#define CHECK_MODF(ARRAY)						\
586490285Sobrien	      if (ARRAY[check_regno]					\
586590285Sobrien		  && loc_mentioned_in_p (r->where,			\
586690285Sobrien					 ARRAY[check_regno]))		\
586790285Sobrien		abort ()
586890285Sobrien
586990285Sobrien	      CHECK_MODF (reg_equiv_constant);
587090285Sobrien	      CHECK_MODF (reg_equiv_memory_loc);
587190285Sobrien	      CHECK_MODF (reg_equiv_address);
587290285Sobrien	      CHECK_MODF (reg_equiv_mem);
587390285Sobrien#undef CHECK_MODF
587490285Sobrien	    }
587590285Sobrien#endif /* ENABLE_CHECKING */
587690285Sobrien
587790285Sobrien	  /* If we're replacing a LABEL_REF with a register, add a
587890285Sobrien	     REG_LABEL note to indicate to flow which label this
587990285Sobrien	     register refers to.  */
588090285Sobrien	  if (GET_CODE (*r->where) == LABEL_REF
588190285Sobrien	      && GET_CODE (insn) == JUMP_INSN)
588290285Sobrien	    REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL,
588390285Sobrien						  XEXP (*r->where, 0),
588490285Sobrien						  REG_NOTES (insn));
588590285Sobrien
588618334Speter	  /* Encapsulate RELOADREG so its machine mode matches what
588718334Speter	     used to be there.  Note that gen_lowpart_common will
588818334Speter	     do the wrong thing if RELOADREG is multi-word.  RELOADREG
588918334Speter	     will always be a REG here.  */
589018334Speter	  if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
589150605Sobrien	    reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
589218334Speter
589318334Speter	  /* If we are putting this into a SUBREG and RELOADREG is a
589418334Speter	     SUBREG, we would be making nested SUBREGs, so we have to fix
589518334Speter	     this up.  Note that r->where == &SUBREG_REG (*r->subreg_loc).  */
589618334Speter
589718334Speter	  if (r->subreg_loc != 0 && GET_CODE (reloadreg) == SUBREG)
589818334Speter	    {
589918334Speter	      if (GET_MODE (*r->subreg_loc)
590018334Speter		  == GET_MODE (SUBREG_REG (reloadreg)))
590118334Speter		*r->subreg_loc = SUBREG_REG (reloadreg);
590218334Speter	      else
590318334Speter		{
590490285Sobrien		  int final_offset =
590590285Sobrien		    SUBREG_BYTE (*r->subreg_loc) + SUBREG_BYTE (reloadreg);
590690285Sobrien
590790285Sobrien		  /* When working with SUBREGs the rule is that the byte
590890285Sobrien		     offset must be a multiple of the SUBREG's mode.  */
590990285Sobrien		  final_offset = (final_offset /
591090285Sobrien				  GET_MODE_SIZE (GET_MODE (*r->subreg_loc)));
591190285Sobrien		  final_offset = (final_offset *
591290285Sobrien				  GET_MODE_SIZE (GET_MODE (*r->subreg_loc)));
591390285Sobrien
591418334Speter		  *r->where = SUBREG_REG (reloadreg);
591590285Sobrien		  SUBREG_BYTE (*r->subreg_loc) = final_offset;
591618334Speter		}
591718334Speter	    }
591818334Speter	  else
591918334Speter	    *r->where = reloadreg;
592018334Speter	}
592118334Speter      /* If reload got no reg and isn't optional, something's wrong.  */
592290285Sobrien      else if (! rld[r->what].optional)
592318334Speter	abort ();
592418334Speter    }
592518334Speter}
592618334Speter
592796288Sobrien/* Make a copy of any replacements being done into X and move those
592896288Sobrien   copies to locations in Y, a copy of X.  */
592918334Speter
593018334Spetervoid
593118334Spetercopy_replacements (x, y)
593296288Sobrien     rtx x, y;
593318334Speter{
593418334Speter  /* We can't support X being a SUBREG because we might then need to know its
593518334Speter     location if something inside it was replaced.  */
593696288Sobrien  if (GET_CODE (x) == SUBREG)
593718334Speter    abort ();
593818334Speter
593996288Sobrien  copy_replacements_1 (&x, &y, n_replacements);
594096288Sobrien}
594196288Sobrien
594296288Sobrienstatic void
594396288Sobriencopy_replacements_1 (px, py, orig_replacements)
594496288Sobrien     rtx *px;
594596288Sobrien     rtx *py;
594696288Sobrien     int orig_replacements;
594796288Sobrien{
594896288Sobrien  int i, j;
594996288Sobrien  rtx x, y;
595096288Sobrien  struct replacement *r;
595196288Sobrien  enum rtx_code code;
595296288Sobrien  const char *fmt;
595396288Sobrien
595496288Sobrien  for (j = 0; j < orig_replacements; j++)
595596288Sobrien    {
595696288Sobrien      if (replacements[j].subreg_loc == px)
595718334Speter	{
595896288Sobrien	  r = &replacements[n_replacements++];
595996288Sobrien	  r->where = replacements[j].where;
596096288Sobrien	  r->subreg_loc = py;
596196288Sobrien	  r->what = replacements[j].what;
596296288Sobrien	  r->mode = replacements[j].mode;
596318334Speter	}
596496288Sobrien      else if (replacements[j].where == px)
596596288Sobrien	{
596696288Sobrien	  r = &replacements[n_replacements++];
596796288Sobrien	  r->where = py;
596896288Sobrien	  r->subreg_loc = 0;
596996288Sobrien	  r->what = replacements[j].what;
597096288Sobrien	  r->mode = replacements[j].mode;
597196288Sobrien	}
597296288Sobrien    }
597396288Sobrien
597496288Sobrien  x = *px;
597596288Sobrien  y = *py;
597696288Sobrien  code = GET_CODE (x);
597796288Sobrien  fmt = GET_RTX_FORMAT (code);
597896288Sobrien
597996288Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
598096288Sobrien    {
598196288Sobrien      if (fmt[i] == 'e')
598296288Sobrien	copy_replacements_1 (&XEXP (x, i), &XEXP (y, i), orig_replacements);
598396288Sobrien      else if (fmt[i] == 'E')
598496288Sobrien	for (j = XVECLEN (x, i); --j >= 0; )
598596288Sobrien	  copy_replacements_1 (&XVECEXP (x, i, j), &XVECEXP (y, i, j),
598696288Sobrien			       orig_replacements);
598796288Sobrien    }
598818334Speter}
598950605Sobrien
599050605Sobrien/* Change any replacements being done to *X to be done to *Y */
599150605Sobrien
599250605Sobrienvoid
599350605Sobrienmove_replacements (x, y)
599450605Sobrien     rtx *x;
599550605Sobrien     rtx *y;
599650605Sobrien{
599750605Sobrien  int i;
599850605Sobrien
599950605Sobrien  for (i = 0; i < n_replacements; i++)
600050605Sobrien    if (replacements[i].subreg_loc == x)
600150605Sobrien      replacements[i].subreg_loc = y;
600250605Sobrien    else if (replacements[i].where == x)
600350605Sobrien      {
600450605Sobrien	replacements[i].where = y;
600550605Sobrien	replacements[i].subreg_loc = 0;
600650605Sobrien      }
600750605Sobrien}
600818334Speter
600918334Speter/* If LOC was scheduled to be replaced by something, return the replacement.
601018334Speter   Otherwise, return *LOC.  */
601118334Speter
601218334Speterrtx
601318334Speterfind_replacement (loc)
601418334Speter     rtx *loc;
601518334Speter{
601618334Speter  struct replacement *r;
601718334Speter
601818334Speter  for (r = &replacements[0]; r < &replacements[n_replacements]; r++)
601918334Speter    {
602090285Sobrien      rtx reloadreg = rld[r->what].reg_rtx;
602118334Speter
602218334Speter      if (reloadreg && r->where == loc)
602318334Speter	{
602418334Speter	  if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
602550605Sobrien	    reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
602618334Speter
602718334Speter	  return reloadreg;
602818334Speter	}
602918334Speter      else if (reloadreg && r->subreg_loc == loc)
603018334Speter	{
603118334Speter	  /* RELOADREG must be either a REG or a SUBREG.
603218334Speter
603318334Speter	     ??? Is it actually still ever a SUBREG?  If so, why?  */
603418334Speter
603518334Speter	  if (GET_CODE (reloadreg) == REG)
603650605Sobrien	    return gen_rtx_REG (GET_MODE (*loc),
603790285Sobrien				(REGNO (reloadreg) +
603890285Sobrien				 subreg_regno_offset (REGNO (SUBREG_REG (*loc)),
603990285Sobrien						      GET_MODE (SUBREG_REG (*loc)),
604090285Sobrien						      SUBREG_BYTE (*loc),
604190285Sobrien						      GET_MODE (*loc))));
604218334Speter	  else if (GET_MODE (reloadreg) == GET_MODE (*loc))
604318334Speter	    return reloadreg;
604418334Speter	  else
604590285Sobrien	    {
604690285Sobrien	      int final_offset = SUBREG_BYTE (reloadreg) + SUBREG_BYTE (*loc);
604790285Sobrien
604890285Sobrien	      /* When working with SUBREGs the rule is that the byte
604990285Sobrien		 offset must be a multiple of the SUBREG's mode.  */
605090285Sobrien	      final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (*loc)));
605190285Sobrien	      final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (*loc)));
605290285Sobrien	      return gen_rtx_SUBREG (GET_MODE (*loc), SUBREG_REG (reloadreg),
605390285Sobrien				     final_offset);
605490285Sobrien	    }
605518334Speter	}
605618334Speter    }
605718334Speter
605850605Sobrien  /* If *LOC is a PLUS, MINUS, or MULT, see if a replacement is scheduled for
605950605Sobrien     what's inside and make a new rtl if so.  */
606050605Sobrien  if (GET_CODE (*loc) == PLUS || GET_CODE (*loc) == MINUS
606150605Sobrien      || GET_CODE (*loc) == MULT)
606250605Sobrien    {
606350605Sobrien      rtx x = find_replacement (&XEXP (*loc, 0));
606450605Sobrien      rtx y = find_replacement (&XEXP (*loc, 1));
606550605Sobrien
606650605Sobrien      if (x != XEXP (*loc, 0) || y != XEXP (*loc, 1))
606750605Sobrien	return gen_rtx_fmt_ee (GET_CODE (*loc), GET_MODE (*loc), x, y);
606850605Sobrien    }
606950605Sobrien
607018334Speter  return *loc;
607118334Speter}
607218334Speter
607318334Speter/* Return nonzero if register in range [REGNO, ENDREGNO)
607418334Speter   appears either explicitly or implicitly in X
607518334Speter   other than being stored into (except for earlyclobber operands).
607618334Speter
607718334Speter   References contained within the substructure at LOC do not count.
607818334Speter   LOC may be zero, meaning don't ignore anything.
607918334Speter
608018334Speter   This is similar to refers_to_regno_p in rtlanal.c except that we
608118334Speter   look at equivalences for pseudos that didn't get hard registers.  */
608218334Speter
608318334Speterint
608418334Speterrefers_to_regno_for_reload_p (regno, endregno, x, loc)
608590285Sobrien     unsigned int regno, endregno;
608618334Speter     rtx x;
608718334Speter     rtx *loc;
608818334Speter{
608990285Sobrien  int i;
609090285Sobrien  unsigned int r;
609190285Sobrien  RTX_CODE code;
609290285Sobrien  const char *fmt;
609318334Speter
609418334Speter  if (x == 0)
609518334Speter    return 0;
609618334Speter
609718334Speter repeat:
609818334Speter  code = GET_CODE (x);
609918334Speter
610018334Speter  switch (code)
610118334Speter    {
610218334Speter    case REG:
610390285Sobrien      r = REGNO (x);
610418334Speter
610518334Speter      /* If this is a pseudo, a hard register must not have been allocated.
610618334Speter	 X must therefore either be a constant or be in memory.  */
610790285Sobrien      if (r >= FIRST_PSEUDO_REGISTER)
610818334Speter	{
610990285Sobrien	  if (reg_equiv_memory_loc[r])
611018334Speter	    return refers_to_regno_for_reload_p (regno, endregno,
611190285Sobrien						 reg_equiv_memory_loc[r],
611290285Sobrien						 (rtx*) 0);
611318334Speter
611490285Sobrien	  if (reg_equiv_constant[r])
611518334Speter	    return 0;
611618334Speter
611718334Speter	  abort ();
611818334Speter	}
611918334Speter
612090285Sobrien      return (endregno > r
612190285Sobrien	      && regno < r + (r < FIRST_PSEUDO_REGISTER
612290285Sobrien			      ? HARD_REGNO_NREGS (r, GET_MODE (x))
612318334Speter			      : 1));
612418334Speter
612518334Speter    case SUBREG:
612618334Speter      /* If this is a SUBREG of a hard reg, we can see exactly which
612718334Speter	 registers are being modified.  Otherwise, handle normally.  */
612818334Speter      if (GET_CODE (SUBREG_REG (x)) == REG
612918334Speter	  && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
613018334Speter	{
613190285Sobrien	  unsigned int inner_regno = subreg_regno (x);
613290285Sobrien	  unsigned int inner_endregno
613318334Speter	    = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
613418334Speter			     ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
613518334Speter
613618334Speter	  return endregno > inner_regno && regno < inner_endregno;
613718334Speter	}
613818334Speter      break;
613918334Speter
614018334Speter    case CLOBBER:
614118334Speter    case SET:
614218334Speter      if (&SET_DEST (x) != loc
614318334Speter	  /* Note setting a SUBREG counts as referring to the REG it is in for
614418334Speter	     a pseudo but not for hard registers since we can
614518334Speter	     treat each word individually.  */
614618334Speter	  && ((GET_CODE (SET_DEST (x)) == SUBREG
614718334Speter	       && loc != &SUBREG_REG (SET_DEST (x))
614818334Speter	       && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
614918334Speter	       && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
615018334Speter	       && refers_to_regno_for_reload_p (regno, endregno,
615118334Speter						SUBREG_REG (SET_DEST (x)),
615218334Speter						loc))
615318334Speter	      /* If the output is an earlyclobber operand, this is
615418334Speter		 a conflict.  */
615518334Speter	      || ((GET_CODE (SET_DEST (x)) != REG
615618334Speter		   || earlyclobber_operand_p (SET_DEST (x)))
615718334Speter		  && refers_to_regno_for_reload_p (regno, endregno,
615818334Speter						   SET_DEST (x), loc))))
615918334Speter	return 1;
616018334Speter
616118334Speter      if (code == CLOBBER || loc == &SET_SRC (x))
616218334Speter	return 0;
616318334Speter      x = SET_SRC (x);
616418334Speter      goto repeat;
616590285Sobrien
616650605Sobrien    default:
616750605Sobrien      break;
616818334Speter    }
616918334Speter
617018334Speter  /* X does not match, so try its subexpressions.  */
617118334Speter
617218334Speter  fmt = GET_RTX_FORMAT (code);
617318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
617418334Speter    {
617518334Speter      if (fmt[i] == 'e' && loc != &XEXP (x, i))
617618334Speter	{
617718334Speter	  if (i == 0)
617818334Speter	    {
617918334Speter	      x = XEXP (x, 0);
618018334Speter	      goto repeat;
618118334Speter	    }
618218334Speter	  else
618318334Speter	    if (refers_to_regno_for_reload_p (regno, endregno,
618418334Speter					      XEXP (x, i), loc))
618518334Speter	      return 1;
618618334Speter	}
618718334Speter      else if (fmt[i] == 'E')
618818334Speter	{
618990285Sobrien	  int j;
619090285Sobrien	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
619118334Speter	    if (loc != &XVECEXP (x, i, j)
619218334Speter		&& refers_to_regno_for_reload_p (regno, endregno,
619318334Speter						 XVECEXP (x, i, j), loc))
619418334Speter	      return 1;
619518334Speter	}
619618334Speter    }
619718334Speter  return 0;
619818334Speter}
619918334Speter
620018334Speter/* Nonzero if modifying X will affect IN.  If X is a register or a SUBREG,
620118334Speter   we check if any register number in X conflicts with the relevant register
620218334Speter   numbers.  If X is a constant, return 0.  If X is a MEM, return 1 iff IN
620318334Speter   contains a MEM (we don't bother checking for memory addresses that can't
620490285Sobrien   conflict because we expect this to be a rare case.
620518334Speter
620690285Sobrien   This function is similar to reg_overlap_mentioned_p in rtlanal.c except
620718334Speter   that we look at equivalences for pseudos that didn't get hard registers.  */
620818334Speter
620918334Speterint
621018334Speterreg_overlap_mentioned_for_reload_p (x, in)
621118334Speter     rtx x, in;
621218334Speter{
621318334Speter  int regno, endregno;
621418334Speter
621550605Sobrien  /* Overly conservative.  */
621690285Sobrien  if (GET_CODE (x) == STRICT_LOW_PART
621790285Sobrien      || GET_RTX_CLASS (GET_CODE (x)) == 'a')
621850605Sobrien    x = XEXP (x, 0);
621950605Sobrien
622050605Sobrien  /* If either argument is a constant, then modifying X can not affect IN.  */
622150605Sobrien  if (CONSTANT_P (x) || CONSTANT_P (in))
622250605Sobrien    return 0;
622350605Sobrien  else if (GET_CODE (x) == SUBREG)
622418334Speter    {
622518334Speter      regno = REGNO (SUBREG_REG (x));
622618334Speter      if (regno < FIRST_PSEUDO_REGISTER)
622790285Sobrien	regno += subreg_regno_offset (REGNO (SUBREG_REG (x)),
622890285Sobrien				      GET_MODE (SUBREG_REG (x)),
622990285Sobrien				      SUBREG_BYTE (x),
623090285Sobrien				      GET_MODE (x));
623118334Speter    }
623218334Speter  else if (GET_CODE (x) == REG)
623318334Speter    {
623418334Speter      regno = REGNO (x);
623518334Speter
623618334Speter      /* If this is a pseudo, it must not have been assigned a hard register.
623718334Speter	 Therefore, it must either be in memory or be a constant.  */
623818334Speter
623918334Speter      if (regno >= FIRST_PSEUDO_REGISTER)
624018334Speter	{
624118334Speter	  if (reg_equiv_memory_loc[regno])
624218334Speter	    return refers_to_mem_for_reload_p (in);
624318334Speter	  else if (reg_equiv_constant[regno])
624418334Speter	    return 0;
624518334Speter	  abort ();
624618334Speter	}
624718334Speter    }
624818334Speter  else if (GET_CODE (x) == MEM)
624918334Speter    return refers_to_mem_for_reload_p (in);
625018334Speter  else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
625118334Speter	   || GET_CODE (x) == CC0)
625218334Speter    return reg_mentioned_p (x, in);
625390285Sobrien  else if (GET_CODE (x) == PLUS)
625490285Sobrien    return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
625590285Sobrien	    || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
625618334Speter  else
625718334Speter    abort ();
625818334Speter
625918334Speter  endregno = regno + (regno < FIRST_PSEUDO_REGISTER
626018334Speter		      ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
626118334Speter
626290285Sobrien  return refers_to_regno_for_reload_p (regno, endregno, in, (rtx*) 0);
626318334Speter}
626418334Speter
626518334Speter/* Return nonzero if anything in X contains a MEM.  Look also for pseudo
626618334Speter   registers.  */
626718334Speter
626818334Speterint
626918334Speterrefers_to_mem_for_reload_p (x)
627018334Speter     rtx x;
627118334Speter{
627290285Sobrien  const char *fmt;
627318334Speter  int i;
627418334Speter
627518334Speter  if (GET_CODE (x) == MEM)
627618334Speter    return 1;
627718334Speter
627818334Speter  if (GET_CODE (x) == REG)
627918334Speter    return (REGNO (x) >= FIRST_PSEUDO_REGISTER
628018334Speter	    && reg_equiv_memory_loc[REGNO (x)]);
628190285Sobrien
628218334Speter  fmt = GET_RTX_FORMAT (GET_CODE (x));
628318334Speter  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
628418334Speter    if (fmt[i] == 'e'
628518334Speter	&& (GET_CODE (XEXP (x, i)) == MEM
628618334Speter	    || refers_to_mem_for_reload_p (XEXP (x, i))))
628718334Speter      return 1;
628890285Sobrien
628918334Speter  return 0;
629018334Speter}
629118334Speter
629218334Speter/* Check the insns before INSN to see if there is a suitable register
629318334Speter   containing the same value as GOAL.
629418334Speter   If OTHER is -1, look for a register in class CLASS.
629518334Speter   Otherwise, just see if register number OTHER shares GOAL's value.
629618334Speter
629718334Speter   Return an rtx for the register found, or zero if none is found.
629818334Speter
629918334Speter   If RELOAD_REG_P is (short *)1,
630018334Speter   we reject any hard reg that appears in reload_reg_rtx
630118334Speter   because such a hard reg is also needed coming into this insn.
630218334Speter
630318334Speter   If RELOAD_REG_P is any other nonzero value,
630418334Speter   it is a vector indexed by hard reg number
630518334Speter   and we reject any hard reg whose element in the vector is nonnegative
630618334Speter   as well as any that appears in reload_reg_rtx.
630718334Speter
630818334Speter   If GOAL is zero, then GOALREG is a register number; we look
630918334Speter   for an equivalent for that register.
631018334Speter
631118334Speter   MODE is the machine mode of the value we want an equivalence for.
631218334Speter   If GOAL is nonzero and not VOIDmode, then it must have mode MODE.
631318334Speter
631418334Speter   This function is used by jump.c as well as in the reload pass.
631518334Speter
631618334Speter   If GOAL is the sum of the stack pointer and a constant, we treat it
631718334Speter   as if it were a constant except that sp is required to be unchanging.  */
631818334Speter
631918334Speterrtx
632018334Speterfind_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
632190285Sobrien     rtx goal;
632218334Speter     rtx insn;
632318334Speter     enum reg_class class;
632490285Sobrien     int other;
632518334Speter     short *reload_reg_p;
632618334Speter     int goalreg;
632718334Speter     enum machine_mode mode;
632818334Speter{
632990285Sobrien  rtx p = insn;
633018334Speter  rtx goaltry, valtry, value, where;
633190285Sobrien  rtx pat;
633290285Sobrien  int regno = -1;
633318334Speter  int valueno;
633418334Speter  int goal_mem = 0;
633518334Speter  int goal_const = 0;
633618334Speter  int goal_mem_addr_varies = 0;
633718334Speter  int need_stable_sp = 0;
633818334Speter  int nregs;
633918334Speter  int valuenregs;
634018334Speter
634118334Speter  if (goal == 0)
634218334Speter    regno = goalreg;
634318334Speter  else if (GET_CODE (goal) == REG)
634418334Speter    regno = REGNO (goal);
634518334Speter  else if (GET_CODE (goal) == MEM)
634618334Speter    {
634718334Speter      enum rtx_code code = GET_CODE (XEXP (goal, 0));
634818334Speter      if (MEM_VOLATILE_P (goal))
634918334Speter	return 0;
635018334Speter      if (flag_float_store && GET_MODE_CLASS (GET_MODE (goal)) == MODE_FLOAT)
635118334Speter	return 0;
635218334Speter      /* An address with side effects must be reexecuted.  */
635318334Speter      switch (code)
635418334Speter	{
635518334Speter	case POST_INC:
635618334Speter	case PRE_INC:
635718334Speter	case POST_DEC:
635818334Speter	case PRE_DEC:
635990285Sobrien	case POST_MODIFY:
636090285Sobrien	case PRE_MODIFY:
636118334Speter	  return 0;
636250605Sobrien	default:
636350605Sobrien	  break;
636418334Speter	}
636518334Speter      goal_mem = 1;
636618334Speter    }
636718334Speter  else if (CONSTANT_P (goal))
636818334Speter    goal_const = 1;
636918334Speter  else if (GET_CODE (goal) == PLUS
637018334Speter	   && XEXP (goal, 0) == stack_pointer_rtx
637118334Speter	   && CONSTANT_P (XEXP (goal, 1)))
637218334Speter    goal_const = need_stable_sp = 1;
637350605Sobrien  else if (GET_CODE (goal) == PLUS
637450605Sobrien	   && XEXP (goal, 0) == frame_pointer_rtx
637550605Sobrien	   && CONSTANT_P (XEXP (goal, 1)))
637650605Sobrien    goal_const = 1;
637718334Speter  else
637818334Speter    return 0;
637918334Speter
638018334Speter  /* Scan insns back from INSN, looking for one that copies
638118334Speter     a value into or out of GOAL.
638218334Speter     Stop and give up if we reach a label.  */
638318334Speter
638418334Speter  while (1)
638518334Speter    {
638618334Speter      p = PREV_INSN (p);
638718334Speter      if (p == 0 || GET_CODE (p) == CODE_LABEL)
638818334Speter	return 0;
638990285Sobrien
639018334Speter      if (GET_CODE (p) == INSN
639150605Sobrien	  /* If we don't want spill regs ...  */
639218334Speter	  && (! (reload_reg_p != 0
639318334Speter		 && reload_reg_p != (short *) (HOST_WIDE_INT) 1)
639490285Sobrien	      /* ... then ignore insns introduced by reload; they aren't
639590285Sobrien		 useful and can cause results in reload_as_needed to be
639690285Sobrien		 different from what they were when calculating the need for
639790285Sobrien		 spills.  If we notice an input-reload insn here, we will
639890285Sobrien		 reject it below, but it might hide a usable equivalent.
639990285Sobrien		 That makes bad code.  It may even abort: perhaps no reg was
640090285Sobrien		 spilled for this insn because it was assumed we would find
640190285Sobrien		 that equivalent.  */
640218334Speter	      || INSN_UID (p) < reload_first_uid))
640318334Speter	{
640418334Speter	  rtx tem;
640518334Speter	  pat = single_set (p);
640690285Sobrien
640718334Speter	  /* First check for something that sets some reg equal to GOAL.  */
640818334Speter	  if (pat != 0
640918334Speter	      && ((regno >= 0
641018334Speter		   && true_regnum (SET_SRC (pat)) == regno
641118334Speter		   && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
641218334Speter		  ||
641318334Speter		  (regno >= 0
641418334Speter		   && true_regnum (SET_DEST (pat)) == regno
641518334Speter		   && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0)
641618334Speter		  ||
641718334Speter		  (goal_const && rtx_equal_p (SET_SRC (pat), goal)
641850605Sobrien		   /* When looking for stack pointer + const,
641950605Sobrien		      make sure we don't use a stack adjust.  */
642050605Sobrien		   && !reg_overlap_mentioned_for_reload_p (SET_DEST (pat), goal)
642118334Speter		   && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
642218334Speter		  || (goal_mem
642318334Speter		      && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0
642418334Speter		      && rtx_renumbered_equal_p (goal, SET_SRC (pat)))
642518334Speter		  || (goal_mem
642618334Speter		      && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0
642718334Speter		      && rtx_renumbered_equal_p (goal, SET_DEST (pat)))
642818334Speter		  /* If we are looking for a constant,
642918334Speter		     and something equivalent to that constant was copied
643018334Speter		     into a reg, we can use that reg.  */
643190285Sobrien		  || (goal_const && REG_NOTES (p) != 0
643290285Sobrien		      && (tem = find_reg_note (p, REG_EQUIV, NULL_RTX))
643390285Sobrien		      && ((rtx_equal_p (XEXP (tem, 0), goal)
643490285Sobrien			   && (valueno
643590285Sobrien			       = true_regnum (valtry = SET_DEST (pat))) >= 0)
643690285Sobrien			  || (GET_CODE (SET_DEST (pat)) == REG
643790285Sobrien			      && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
643890285Sobrien			      && (GET_MODE_CLASS (GET_MODE (XEXP (tem, 0)))
643990285Sobrien				  == MODE_FLOAT)
644090285Sobrien			      && GET_CODE (goal) == CONST_INT
644190285Sobrien			      && 0 != (goaltry
644290285Sobrien				       = operand_subword (XEXP (tem, 0), 0, 0,
644318334Speter							  VOIDmode))
644490285Sobrien			      && rtx_equal_p (goal, goaltry)
644590285Sobrien			      && (valtry
644690285Sobrien				  = operand_subword (SET_DEST (pat), 0, 0,
644790285Sobrien						     VOIDmode))
644890285Sobrien			      && (valueno = true_regnum (valtry)) >= 0)))
644918334Speter		  || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
645018334Speter							  NULL_RTX))
645118334Speter		      && GET_CODE (SET_DEST (pat)) == REG
645218334Speter		      && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
645390285Sobrien		      && (GET_MODE_CLASS (GET_MODE (XEXP (tem, 0)))
645490285Sobrien			  == MODE_FLOAT)
645518334Speter		      && GET_CODE (goal) == CONST_INT
645618334Speter		      && 0 != (goaltry = operand_subword (XEXP (tem, 0), 1, 0,
645718334Speter							  VOIDmode))
645818334Speter		      && rtx_equal_p (goal, goaltry)
645918334Speter		      && (valtry
646018334Speter			  = operand_subword (SET_DEST (pat), 1, 0, VOIDmode))
646118334Speter		      && (valueno = true_regnum (valtry)) >= 0)))
646270639Sobrien	    {
646370639Sobrien	      if (other >= 0)
646470639Sobrien		{
646570639Sobrien		  if (valueno != other)
646670639Sobrien		    continue;
646770639Sobrien		}
646870639Sobrien	      else if ((unsigned) valueno >= FIRST_PSEUDO_REGISTER)
646970639Sobrien		continue;
647070639Sobrien	      else
647170639Sobrien		{
647270639Sobrien		  int i;
647370639Sobrien
647470639Sobrien		  for (i = HARD_REGNO_NREGS (valueno, mode) - 1; i >= 0; i--)
647570639Sobrien		    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
647670639Sobrien					     valueno + i))
647770639Sobrien		      break;
647870639Sobrien		  if (i >= 0)
647970639Sobrien		    continue;
648070639Sobrien		}
648170639Sobrien	      value = valtry;
648270639Sobrien	      where = p;
648370639Sobrien	      break;
648470639Sobrien	    }
648518334Speter	}
648618334Speter    }
648718334Speter
648818334Speter  /* We found a previous insn copying GOAL into a suitable other reg VALUE
648918334Speter     (or copying VALUE into GOAL, if GOAL is also a register).
649018334Speter     Now verify that VALUE is really valid.  */
649118334Speter
649218334Speter  /* VALUENO is the register number of VALUE; a hard register.  */
649318334Speter
649418334Speter  /* Don't try to re-use something that is killed in this insn.  We want
649518334Speter     to be able to trust REG_UNUSED notes.  */
649690285Sobrien  if (REG_NOTES (where) != 0 && find_reg_note (where, REG_UNUSED, value))
649718334Speter    return 0;
649818334Speter
649918334Speter  /* If we propose to get the value from the stack pointer or if GOAL is
650018334Speter     a MEM based on the stack pointer, we need a stable SP.  */
650150605Sobrien  if (valueno == STACK_POINTER_REGNUM || regno == STACK_POINTER_REGNUM
650218334Speter      || (goal_mem && reg_overlap_mentioned_for_reload_p (stack_pointer_rtx,
650318334Speter							  goal)))
650418334Speter    need_stable_sp = 1;
650518334Speter
650618334Speter  /* Reject VALUE if the copy-insn moved the wrong sort of datum.  */
650718334Speter  if (GET_MODE (value) != mode)
650818334Speter    return 0;
650918334Speter
651018334Speter  /* Reject VALUE if it was loaded from GOAL
651118334Speter     and is also a register that appears in the address of GOAL.  */
651218334Speter
651350605Sobrien  if (goal_mem && value == SET_DEST (single_set (where))
651418334Speter      && refers_to_regno_for_reload_p (valueno,
651518334Speter				       (valueno
651618334Speter					+ HARD_REGNO_NREGS (valueno, mode)),
651790285Sobrien				       goal, (rtx*) 0))
651818334Speter    return 0;
651918334Speter
652018334Speter  /* Reject registers that overlap GOAL.  */
652118334Speter
652218334Speter  if (!goal_mem && !goal_const
652390285Sobrien      && regno + (int) HARD_REGNO_NREGS (regno, mode) > valueno
652490285Sobrien      && regno < valueno + (int) HARD_REGNO_NREGS (valueno, mode))
652518334Speter    return 0;
652618334Speter
652770639Sobrien  nregs = HARD_REGNO_NREGS (regno, mode);
652870639Sobrien  valuenregs = HARD_REGNO_NREGS (valueno, mode);
652970639Sobrien
653018334Speter  /* Reject VALUE if it is one of the regs reserved for reloads.
653118334Speter     Reload1 knows how to reuse them anyway, and it would get
653218334Speter     confused if we allocated one without its knowledge.
653318334Speter     (Now that insns introduced by reload are ignored above,
653418334Speter     this case shouldn't happen, but I'm not positive.)  */
653518334Speter
653670639Sobrien  if (reload_reg_p != 0 && reload_reg_p != (short *) (HOST_WIDE_INT) 1)
653770639Sobrien    {
653870639Sobrien      int i;
653970639Sobrien      for (i = 0; i < valuenregs; ++i)
654070639Sobrien	if (reload_reg_p[valueno + i] >= 0)
654170639Sobrien	  return 0;
654270639Sobrien    }
654318334Speter
654418334Speter  /* Reject VALUE if it is a register being used for an input reload
654518334Speter     even if it is not one of those reserved.  */
654618334Speter
654718334Speter  if (reload_reg_p != 0)
654818334Speter    {
654918334Speter      int i;
655018334Speter      for (i = 0; i < n_reloads; i++)
655190285Sobrien	if (rld[i].reg_rtx != 0 && rld[i].in)
655218334Speter	  {
655390285Sobrien	    int regno1 = REGNO (rld[i].reg_rtx);
655418334Speter	    int nregs1 = HARD_REGNO_NREGS (regno1,
655590285Sobrien					   GET_MODE (rld[i].reg_rtx));
655618334Speter	    if (regno1 < valueno + valuenregs
655718334Speter		&& regno1 + nregs1 > valueno)
655818334Speter	      return 0;
655918334Speter	  }
656018334Speter    }
656118334Speter
656218334Speter  if (goal_mem)
656318334Speter    /* We must treat frame pointer as varying here,
656418334Speter       since it can vary--in a nonlocal goto as generated by expand_goto.  */
656518334Speter    goal_mem_addr_varies = !CONSTANT_ADDRESS_P (XEXP (goal, 0));
656618334Speter
656718334Speter  /* Now verify that the values of GOAL and VALUE remain unaltered
656818334Speter     until INSN is reached.  */
656918334Speter
657018334Speter  p = insn;
657118334Speter  while (1)
657218334Speter    {
657318334Speter      p = PREV_INSN (p);
657418334Speter      if (p == where)
657518334Speter	return value;
657618334Speter
657718334Speter      /* Don't trust the conversion past a function call
657818334Speter	 if either of the two is in a call-clobbered register, or memory.  */
657970639Sobrien      if (GET_CODE (p) == CALL_INSN)
658070639Sobrien	{
658170639Sobrien	  int i;
658218334Speter
658370639Sobrien	  if (goal_mem || need_stable_sp)
658470639Sobrien	    return 0;
658570639Sobrien
658670639Sobrien	  if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
658770639Sobrien	    for (i = 0; i < nregs; ++i)
658870639Sobrien	      if (call_used_regs[regno + i])
658970639Sobrien		return 0;
659070639Sobrien
659170639Sobrien	  if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER)
659270639Sobrien	    for (i = 0; i < valuenregs; ++i)
659370639Sobrien	      if (call_used_regs[valueno + i])
659470639Sobrien		return 0;
659590285Sobrien#ifdef NON_SAVING_SETJMP
659690285Sobrien	  if (NON_SAVING_SETJMP && find_reg_note (p, REG_SETJMP, NULL))
659790285Sobrien	    return 0;
659890285Sobrien#endif
659970639Sobrien	}
660070639Sobrien
660190285Sobrien      if (INSN_P (p))
660218334Speter	{
660350605Sobrien	  pat = PATTERN (p);
660450605Sobrien
660590285Sobrien	  /* Watch out for unspec_volatile, and volatile asms.  */
660690285Sobrien	  if (volatile_insn_p (pat))
660750605Sobrien	    return 0;
660850605Sobrien
660918334Speter	  /* If this insn P stores in either GOAL or VALUE, return 0.
661018334Speter	     If GOAL is a memory ref and this insn writes memory, return 0.
661118334Speter	     If GOAL is a memory ref and its address is not constant,
661218334Speter	     and this insn P changes a register used in GOAL, return 0.  */
661318334Speter
661490285Sobrien	  if (GET_CODE (pat) == COND_EXEC)
661590285Sobrien	    pat = COND_EXEC_CODE (pat);
661618334Speter	  if (GET_CODE (pat) == SET || GET_CODE (pat) == CLOBBER)
661718334Speter	    {
661890285Sobrien	      rtx dest = SET_DEST (pat);
661918334Speter	      while (GET_CODE (dest) == SUBREG
662018334Speter		     || GET_CODE (dest) == ZERO_EXTRACT
662118334Speter		     || GET_CODE (dest) == SIGN_EXTRACT
662218334Speter		     || GET_CODE (dest) == STRICT_LOW_PART)
662318334Speter		dest = XEXP (dest, 0);
662418334Speter	      if (GET_CODE (dest) == REG)
662518334Speter		{
662690285Sobrien		  int xregno = REGNO (dest);
662718334Speter		  int xnregs;
662818334Speter		  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
662918334Speter		    xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
663018334Speter		  else
663118334Speter		    xnregs = 1;
663218334Speter		  if (xregno < regno + nregs && xregno + xnregs > regno)
663318334Speter		    return 0;
663418334Speter		  if (xregno < valueno + valuenregs
663518334Speter		      && xregno + xnregs > valueno)
663618334Speter		    return 0;
663718334Speter		  if (goal_mem_addr_varies
663818334Speter		      && reg_overlap_mentioned_for_reload_p (dest, goal))
663918334Speter		    return 0;
664050605Sobrien		  if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
664150605Sobrien		    return 0;
664218334Speter		}
664318334Speter	      else if (goal_mem && GET_CODE (dest) == MEM
664418334Speter		       && ! push_operand (dest, GET_MODE (dest)))
664518334Speter		return 0;
664618334Speter	      else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
664718334Speter		       && reg_equiv_memory_loc[regno] != 0)
664818334Speter		return 0;
664918334Speter	      else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
665018334Speter		return 0;
665118334Speter	    }
665218334Speter	  else if (GET_CODE (pat) == PARALLEL)
665318334Speter	    {
665490285Sobrien	      int i;
665518334Speter	      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
665618334Speter		{
665790285Sobrien		  rtx v1 = XVECEXP (pat, 0, i);
665890285Sobrien		  if (GET_CODE (v1) == COND_EXEC)
665990285Sobrien		    v1 = COND_EXEC_CODE (v1);
666018334Speter		  if (GET_CODE (v1) == SET || GET_CODE (v1) == CLOBBER)
666118334Speter		    {
666290285Sobrien		      rtx dest = SET_DEST (v1);
666318334Speter		      while (GET_CODE (dest) == SUBREG
666418334Speter			     || GET_CODE (dest) == ZERO_EXTRACT
666518334Speter			     || GET_CODE (dest) == SIGN_EXTRACT
666618334Speter			     || GET_CODE (dest) == STRICT_LOW_PART)
666718334Speter			dest = XEXP (dest, 0);
666818334Speter		      if (GET_CODE (dest) == REG)
666918334Speter			{
667090285Sobrien			  int xregno = REGNO (dest);
667118334Speter			  int xnregs;
667218334Speter			  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
667318334Speter			    xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
667418334Speter			  else
667518334Speter			    xnregs = 1;
667618334Speter			  if (xregno < regno + nregs
667718334Speter			      && xregno + xnregs > regno)
667818334Speter			    return 0;
667918334Speter			  if (xregno < valueno + valuenregs
668018334Speter			      && xregno + xnregs > valueno)
668118334Speter			    return 0;
668218334Speter			  if (goal_mem_addr_varies
668318334Speter			      && reg_overlap_mentioned_for_reload_p (dest,
668418334Speter								     goal))
668518334Speter			    return 0;
668650605Sobrien			  if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
668750605Sobrien			    return 0;
668818334Speter			}
668918334Speter		      else if (goal_mem && GET_CODE (dest) == MEM
669018334Speter			       && ! push_operand (dest, GET_MODE (dest)))
669118334Speter			return 0;
669250605Sobrien		      else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
669350605Sobrien			       && reg_equiv_memory_loc[regno] != 0)
669450605Sobrien			return 0;
669518334Speter		      else if (need_stable_sp
669618334Speter			       && push_operand (dest, GET_MODE (dest)))
669718334Speter			return 0;
669818334Speter		    }
669918334Speter		}
670018334Speter	    }
670118334Speter
670218334Speter	  if (GET_CODE (p) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (p))
670318334Speter	    {
670418334Speter	      rtx link;
670518334Speter
670618334Speter	      for (link = CALL_INSN_FUNCTION_USAGE (p); XEXP (link, 1) != 0;
670718334Speter		   link = XEXP (link, 1))
670818334Speter		{
670918334Speter		  pat = XEXP (link, 0);
671018334Speter		  if (GET_CODE (pat) == CLOBBER)
671118334Speter		    {
671290285Sobrien		      rtx dest = SET_DEST (pat);
671390285Sobrien
671418334Speter		      if (GET_CODE (dest) == REG)
671518334Speter			{
671690285Sobrien			  int xregno = REGNO (dest);
671790285Sobrien			  int xnregs
671890285Sobrien			    = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
671990285Sobrien
672018334Speter			  if (xregno < regno + nregs
672118334Speter			      && xregno + xnregs > regno)
672218334Speter			    return 0;
672390285Sobrien			  else if (xregno < valueno + valuenregs
672490285Sobrien				   && xregno + xnregs > valueno)
672518334Speter			    return 0;
672690285Sobrien			  else if (goal_mem_addr_varies
672790285Sobrien				   && reg_overlap_mentioned_for_reload_p (dest,
672818334Speter								     goal))
672918334Speter			    return 0;
673018334Speter			}
673190285Sobrien
673218334Speter		      else if (goal_mem && GET_CODE (dest) == MEM
673318334Speter			       && ! push_operand (dest, GET_MODE (dest)))
673418334Speter			return 0;
673518334Speter		      else if (need_stable_sp
673618334Speter			       && push_operand (dest, GET_MODE (dest)))
673718334Speter			return 0;
673818334Speter		    }
673918334Speter		}
674018334Speter	    }
674118334Speter
674218334Speter#ifdef AUTO_INC_DEC
674318334Speter	  /* If this insn auto-increments or auto-decrements
674418334Speter	     either regno or valueno, return 0 now.
674518334Speter	     If GOAL is a memory ref and its address is not constant,
674618334Speter	     and this insn P increments a register used in GOAL, return 0.  */
674718334Speter	  {
674890285Sobrien	    rtx link;
674918334Speter
675018334Speter	    for (link = REG_NOTES (p); link; link = XEXP (link, 1))
675118334Speter	      if (REG_NOTE_KIND (link) == REG_INC
675218334Speter		  && GET_CODE (XEXP (link, 0)) == REG)
675318334Speter		{
675490285Sobrien		  int incno = REGNO (XEXP (link, 0));
675518334Speter		  if (incno < regno + nregs && incno >= regno)
675618334Speter		    return 0;
675718334Speter		  if (incno < valueno + valuenregs && incno >= valueno)
675818334Speter		    return 0;
675918334Speter		  if (goal_mem_addr_varies
676018334Speter		      && reg_overlap_mentioned_for_reload_p (XEXP (link, 0),
676118334Speter							     goal))
676218334Speter		    return 0;
676318334Speter		}
676418334Speter	  }
676518334Speter#endif
676618334Speter	}
676718334Speter    }
676818334Speter}
676918334Speter
677018334Speter/* Find a place where INCED appears in an increment or decrement operator
677118334Speter   within X, and return the amount INCED is incremented or decremented by.
677218334Speter   The value is always positive.  */
677318334Speter
677418334Speterstatic int
677518334Speterfind_inc_amount (x, inced)
677618334Speter     rtx x, inced;
677718334Speter{
677890285Sobrien  enum rtx_code code = GET_CODE (x);
677990285Sobrien  const char *fmt;
678090285Sobrien  int i;
678118334Speter
678218334Speter  if (code == MEM)
678318334Speter    {
678490285Sobrien      rtx addr = XEXP (x, 0);
678518334Speter      if ((GET_CODE (addr) == PRE_DEC
678618334Speter	   || GET_CODE (addr) == POST_DEC
678718334Speter	   || GET_CODE (addr) == PRE_INC
678818334Speter	   || GET_CODE (addr) == POST_INC)
678918334Speter	  && XEXP (addr, 0) == inced)
679018334Speter	return GET_MODE_SIZE (GET_MODE (x));
679190285Sobrien      else if ((GET_CODE (addr) == PRE_MODIFY
679290285Sobrien		|| GET_CODE (addr) == POST_MODIFY)
679390285Sobrien	       && GET_CODE (XEXP (addr, 1)) == PLUS
679490285Sobrien	       && XEXP (addr, 0) == XEXP (XEXP (addr, 1), 0)
679590285Sobrien	       && XEXP (addr, 0) == inced
679690285Sobrien	       && GET_CODE (XEXP (XEXP (addr, 1), 1)) == CONST_INT)
679790285Sobrien	{
679890285Sobrien	  i = INTVAL (XEXP (XEXP (addr, 1), 1));
679990285Sobrien	  return i < 0 ? -i : i;
680090285Sobrien	}
680118334Speter    }
680218334Speter
680318334Speter  fmt = GET_RTX_FORMAT (code);
680418334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
680518334Speter    {
680618334Speter      if (fmt[i] == 'e')
680718334Speter	{
680890285Sobrien	  int tem = find_inc_amount (XEXP (x, i), inced);
680918334Speter	  if (tem != 0)
681018334Speter	    return tem;
681118334Speter	}
681218334Speter      if (fmt[i] == 'E')
681318334Speter	{
681490285Sobrien	  int j;
681518334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
681618334Speter	    {
681790285Sobrien	      int tem = find_inc_amount (XVECEXP (x, i, j), inced);
681818334Speter	      if (tem != 0)
681918334Speter		return tem;
682018334Speter	    }
682118334Speter	}
682218334Speter    }
682318334Speter
682418334Speter  return 0;
682518334Speter}
682618334Speter
682790285Sobrien/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
682890285Sobrien   If SETS is nonzero, also consider SETs.  */
682918334Speter
683018334Speterint
683170639Sobrienregno_clobbered_p (regno, insn, mode, sets)
683290285Sobrien     unsigned int regno;
683318334Speter     rtx insn;
683470639Sobrien     enum machine_mode mode;
683570639Sobrien     int sets;
683618334Speter{
683790285Sobrien  unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
683890285Sobrien  unsigned int endregno = regno + nregs;
683970639Sobrien
684070639Sobrien  if ((GET_CODE (PATTERN (insn)) == CLOBBER
684170639Sobrien       || (sets && GET_CODE (PATTERN (insn)) == SET))
684218334Speter      && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
684370639Sobrien    {
684490285Sobrien      unsigned int test = REGNO (XEXP (PATTERN (insn), 0));
684518334Speter
684670639Sobrien      return test >= regno && test < endregno;
684770639Sobrien    }
684870639Sobrien
684918334Speter  if (GET_CODE (PATTERN (insn)) == PARALLEL)
685018334Speter    {
685118334Speter      int i = XVECLEN (PATTERN (insn), 0) - 1;
685218334Speter
685318334Speter      for (; i >= 0; i--)
685418334Speter	{
685518334Speter	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
685670639Sobrien	  if ((GET_CODE (elt) == CLOBBER
685770639Sobrien	       || (sets && GET_CODE (PATTERN (insn)) == SET))
685870639Sobrien	      && GET_CODE (XEXP (elt, 0)) == REG)
685970639Sobrien	    {
686090285Sobrien	      unsigned int test = REGNO (XEXP (elt, 0));
686170639Sobrien
686270639Sobrien	      if (test >= regno && test < endregno)
686370639Sobrien		return 1;
686470639Sobrien	    }
686518334Speter	}
686618334Speter    }
686718334Speter
686818334Speter  return 0;
686918334Speter}
687018334Speter
687190285Sobrienstatic const char *const reload_when_needed_name[] =
687218334Speter{
687390285Sobrien  "RELOAD_FOR_INPUT",
687490285Sobrien  "RELOAD_FOR_OUTPUT",
687518334Speter  "RELOAD_FOR_INSN",
687650605Sobrien  "RELOAD_FOR_INPUT_ADDRESS",
687750605Sobrien  "RELOAD_FOR_INPADDR_ADDRESS",
687818334Speter  "RELOAD_FOR_OUTPUT_ADDRESS",
687950605Sobrien  "RELOAD_FOR_OUTADDR_ADDRESS",
688090285Sobrien  "RELOAD_FOR_OPERAND_ADDRESS",
688118334Speter  "RELOAD_FOR_OPADDR_ADDR",
688290285Sobrien  "RELOAD_OTHER",
688318334Speter  "RELOAD_FOR_OTHER_ADDRESS"
688418334Speter};
688518334Speter
688690285Sobrienstatic const char * const reg_class_names[] = REG_CLASS_NAMES;
688718334Speter
688850605Sobrien/* These functions are used to print the variables set by 'find_reloads' */
688918334Speter
689018334Spetervoid
689150605Sobriendebug_reload_to_stream (f)
689250605Sobrien     FILE *f;
689318334Speter{
689418334Speter  int r;
689590285Sobrien  const char *prefix;
689618334Speter
689750605Sobrien  if (! f)
689850605Sobrien    f = stderr;
689918334Speter  for (r = 0; r < n_reloads; r++)
690018334Speter    {
690150605Sobrien      fprintf (f, "Reload %d: ", r);
690218334Speter
690390285Sobrien      if (rld[r].in != 0)
690418334Speter	{
690550605Sobrien	  fprintf (f, "reload_in (%s) = ",
690690285Sobrien		   GET_MODE_NAME (rld[r].inmode));
690790285Sobrien	  print_inline_rtx (f, rld[r].in, 24);
690850605Sobrien	  fprintf (f, "\n\t");
690918334Speter	}
691018334Speter
691190285Sobrien      if (rld[r].out != 0)
691218334Speter	{
691350605Sobrien	  fprintf (f, "reload_out (%s) = ",
691490285Sobrien		   GET_MODE_NAME (rld[r].outmode));
691590285Sobrien	  print_inline_rtx (f, rld[r].out, 24);
691650605Sobrien	  fprintf (f, "\n\t");
691718334Speter	}
691818334Speter
691990285Sobrien      fprintf (f, "%s, ", reg_class_names[(int) rld[r].class]);
692018334Speter
692150605Sobrien      fprintf (f, "%s (opnum = %d)",
692290285Sobrien	       reload_when_needed_name[(int) rld[r].when_needed],
692390285Sobrien	       rld[r].opnum);
692418334Speter
692590285Sobrien      if (rld[r].optional)
692650605Sobrien	fprintf (f, ", optional");
692718334Speter
692890285Sobrien      if (rld[r].nongroup)
692990285Sobrien	fprintf (f, ", nongroup");
693018334Speter
693190285Sobrien      if (rld[r].inc != 0)
693290285Sobrien	fprintf (f, ", inc by %d", rld[r].inc);
693350605Sobrien
693490285Sobrien      if (rld[r].nocombine)
693550605Sobrien	fprintf (f, ", can't combine");
693618334Speter
693790285Sobrien      if (rld[r].secondary_p)
693850605Sobrien	fprintf (f, ", secondary_reload_p");
693918334Speter
694090285Sobrien      if (rld[r].in_reg != 0)
694118334Speter	{
694250605Sobrien	  fprintf (f, "\n\treload_in_reg: ");
694390285Sobrien	  print_inline_rtx (f, rld[r].in_reg, 24);
694418334Speter	}
694518334Speter
694690285Sobrien      if (rld[r].out_reg != 0)
694752557Sobrien	{
694852557Sobrien	  fprintf (f, "\n\treload_out_reg: ");
694990285Sobrien	  print_inline_rtx (f, rld[r].out_reg, 24);
695052557Sobrien	}
695152557Sobrien
695290285Sobrien      if (rld[r].reg_rtx != 0)
695318334Speter	{
695450605Sobrien	  fprintf (f, "\n\treload_reg_rtx: ");
695590285Sobrien	  print_inline_rtx (f, rld[r].reg_rtx, 24);
695618334Speter	}
695718334Speter
695850605Sobrien      prefix = "\n\t";
695990285Sobrien      if (rld[r].secondary_in_reload != -1)
696018334Speter	{
696150605Sobrien	  fprintf (f, "%ssecondary_in_reload = %d",
696290285Sobrien		   prefix, rld[r].secondary_in_reload);
696350605Sobrien	  prefix = ", ";
696418334Speter	}
696518334Speter
696690285Sobrien      if (rld[r].secondary_out_reload != -1)
696750605Sobrien	fprintf (f, "%ssecondary_out_reload = %d\n",
696890285Sobrien		 prefix, rld[r].secondary_out_reload);
696918334Speter
697050605Sobrien      prefix = "\n\t";
697190285Sobrien      if (rld[r].secondary_in_icode != CODE_FOR_nothing)
697218334Speter	{
697390285Sobrien	  fprintf (f, "%ssecondary_in_icode = %s", prefix,
697490285Sobrien		   insn_data[rld[r].secondary_in_icode].name);
697550605Sobrien	  prefix = ", ";
697618334Speter	}
697718334Speter
697890285Sobrien      if (rld[r].secondary_out_icode != CODE_FOR_nothing)
697990285Sobrien	fprintf (f, "%ssecondary_out_icode = %s", prefix,
698090285Sobrien		 insn_data[rld[r].secondary_out_icode].name);
698118334Speter
698250605Sobrien      fprintf (f, "\n");
698318334Speter    }
698450605Sobrien}
698518334Speter
698650605Sobrienvoid
698750605Sobriendebug_reload ()
698850605Sobrien{
698950605Sobrien  debug_reload_to_stream (stderr);
699018334Speter}
6991