reload.c revision 52557
118334Speter/* Search an insn for pseudo regs that must be in hard regs and are not.
252557Sobrien   Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
318334Speter
418334SpeterThis file is part of GNU CC.
518334Speter
618334SpeterGNU CC is free software; you can redistribute it and/or modify
718334Speterit under the terms of the GNU General Public License as published by
818334Speterthe Free Software Foundation; either version 2, or (at your option)
918334Speterany later version.
1018334Speter
1118334SpeterGNU CC is distributed in the hope that it will be useful,
1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1418334SpeterGNU General Public License for more details.
1518334Speter
1618334SpeterYou should have received a copy of the GNU General Public License
1718334Speteralong with GNU CC; see the file COPYING.  If not, write to
1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
1918334SpeterBoston, MA 02111-1307, USA.  */
2018334Speter
2152557Sobrien/* $FreeBSD: head/contrib/gcc/reload.c 52557 1999-10-27 09:23:37Z obrien $ */
2218334Speter
2352557Sobrien
2418334Speter/* This file contains subroutines used only from the file reload1.c.
2518334Speter   It knows how to scan one insn for operands and values
2618334Speter   that need to be copied into registers to make valid code.
2718334Speter   It also finds other operands and values which are valid
2818334Speter   but for which equivalent values in registers exist and
2918334Speter   ought to be used instead.
3018334Speter
3118334Speter   Before processing the first insn of the function, call `init_reload'.
3218334Speter
3318334Speter   To scan an insn, call `find_reloads'.  This does two things:
3418334Speter   1. sets up tables describing which values must be reloaded
3518334Speter   for this insn, and what kind of hard regs they must be reloaded into;
3618334Speter   2. optionally record the locations where those values appear in
3718334Speter   the data, so they can be replaced properly later.
3818334Speter   This is done only if the second arg to `find_reloads' is nonzero.
3918334Speter
4018334Speter   The third arg to `find_reloads' specifies the number of levels
4118334Speter   of indirect addressing supported by the machine.  If it is zero,
4218334Speter   indirect addressing is not valid.  If it is one, (MEM (REG n))
4318334Speter   is valid even if (REG n) did not get a hard register; if it is two,
4418334Speter   (MEM (MEM (REG n))) is also valid even if (REG n) did not get a
4518334Speter   hard register, and similarly for higher values.
4618334Speter
4718334Speter   Then you must choose the hard regs to reload those pseudo regs into,
4818334Speter   and generate appropriate load insns before this insn and perhaps
4918334Speter   also store insns after this insn.  Set up the array `reload_reg_rtx'
5018334Speter   to contain the REG rtx's for the registers you used.  In some
5118334Speter   cases `find_reloads' will return a nonzero value in `reload_reg_rtx'
5218334Speter   for certain reloads.  Then that tells you which register to use,
5318334Speter   so you do not need to allocate one.  But you still do need to add extra
5418334Speter   instructions to copy the value into and out of that register.
5518334Speter
5618334Speter   Finally you must call `subst_reloads' to substitute the reload reg rtx's
5718334Speter   into the locations already recorded.
5818334Speter
5918334SpeterNOTE SIDE EFFECTS:
6018334Speter
6118334Speter   find_reloads can alter the operands of the instruction it is called on.
6218334Speter
6318334Speter   1. Two operands of any sort may be interchanged, if they are in a
6418334Speter   commutative instruction.
6518334Speter   This happens only if find_reloads thinks the instruction will compile
6618334Speter   better that way.
6718334Speter
6818334Speter   2. Pseudo-registers that are equivalent to constants are replaced
6918334Speter   with those constants if they are not in hard registers.
7018334Speter
7118334Speter1 happens every time find_reloads is called.
7218334Speter2 happens only when REPLACE is 1, which is only when
7318334Speteractually doing the reloads, not when just counting them.
7418334Speter
7518334Speter
7618334SpeterUsing a reload register for several reloads in one insn:
7718334Speter
7818334SpeterWhen an insn has reloads, it is considered as having three parts:
7918334Speterthe input reloads, the insn itself after reloading, and the output reloads.
8018334SpeterReloads of values used in memory addresses are often needed for only one part.
8118334Speter
8218334SpeterWhen this is so, reload_when_needed records which part needs the reload.
8318334SpeterTwo reloads for different parts of the insn can share the same reload
8418334Speterregister.
8518334Speter
8618334SpeterWhen a reload is used for addresses in multiple parts, or when it is
8718334Speteran ordinary operand, it is classified as RELOAD_OTHER, and cannot share
8818334Spetera register with any other reload.  */
8918334Speter
9018334Speter#define REG_OK_STRICT
9118334Speter
9218334Speter#include "config.h"
9350605Sobrien#include "system.h"
9418334Speter#include "rtl.h"
9518334Speter#include "insn-config.h"
9618334Speter#include "insn-codes.h"
9718334Speter#include "recog.h"
9818334Speter#include "reload.h"
9918334Speter#include "regs.h"
10018334Speter#include "hard-reg-set.h"
10118334Speter#include "flags.h"
10218334Speter#include "real.h"
10318334Speter#include "output.h"
10450605Sobrien#include "expr.h"
10550605Sobrien#include "toplev.h"
10618334Speter
10718334Speter#ifndef REGISTER_MOVE_COST
10818334Speter#define REGISTER_MOVE_COST(x, y) 2
10918334Speter#endif
11050605Sobrien
11150605Sobrien#ifndef REGNO_MODE_OK_FOR_BASE_P
11250605Sobrien#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
11350605Sobrien#endif
11450605Sobrien
11550605Sobrien#ifndef REG_MODE_OK_FOR_BASE_P
11650605Sobrien#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
11750605Sobrien#endif
11818334Speter
11918334Speter/* The variables set up by `find_reloads' are:
12018334Speter
12118334Speter   n_reloads		  number of distinct reloads needed; max reload # + 1
12218334Speter       tables indexed by reload number
12318334Speter   reload_in		  rtx for value to reload from
12418334Speter   reload_out		  rtx for where to store reload-reg afterward if nec
12518334Speter			   (often the same as reload_in)
12618334Speter   reload_reg_class	  enum reg_class, saying what regs to reload into
12718334Speter   reload_inmode	  enum machine_mode; mode this operand should have
12818334Speter			   when reloaded, on input.
12918334Speter   reload_outmode	  enum machine_mode; mode this operand should have
13018334Speter			   when reloaded, on output.
13118334Speter   reload_optional	  char, nonzero for an optional reload.
13218334Speter			   Optional reloads are ignored unless the
13318334Speter			   value is already sitting in a register.
13450605Sobrien   reload_nongroup	  char, nonzero when a reload must use a register
13550605Sobrien			   not already allocated to a group.
13618334Speter   reload_inc		  int, positive amount to increment or decrement by if
13718334Speter			   reload_in is a PRE_DEC, PRE_INC, POST_DEC, POST_INC.
13818334Speter			   Ignored otherwise (don't assume it is zero).
13918334Speter   reload_in_reg	  rtx.  A reg for which reload_in is the equivalent.
14018334Speter			   If reload_in is a symbol_ref which came from
14118334Speter			   reg_equiv_constant, then this is the pseudo
14218334Speter			   which has that symbol_ref as equivalent.
14318334Speter   reload_reg_rtx	  rtx.  This is the register to reload into.
14418334Speter			   If it is zero when `find_reloads' returns,
14518334Speter			   you must find a suitable register in the class
14618334Speter			   specified by reload_reg_class, and store here
14718334Speter			   an rtx for that register with mode from
14818334Speter			   reload_inmode or reload_outmode.
14918334Speter   reload_nocombine	  char, nonzero if this reload shouldn't be
15018334Speter			   combined with another reload.
15118334Speter   reload_opnum		  int, operand number being reloaded.  This is
15218334Speter			   used to group related reloads and need not always
15318334Speter			   be equal to the actual operand number in the insn,
15418334Speter			   though it current will be; for in-out operands, it
15518334Speter			   is one of the two operand numbers.
15618334Speter   reload_when_needed    enum, classifies reload as needed either for
15718334Speter			   addressing an input reload, addressing an output,
15818334Speter			   for addressing a non-reloaded mem ref,
15918334Speter			   or for unspecified purposes (i.e., more than one
16018334Speter			   of the above).
16118334Speter   reload_secondary_p	  int, 1 if this is a secondary register for one
16218334Speter			   or more reloads.
16318334Speter   reload_secondary_in_reload
16418334Speter   reload_secondary_out_reload
16518334Speter   			  int, gives the reload number of a secondary
16618334Speter			   reload, when needed; otherwise -1
16718334Speter   reload_secondary_in_icode
16818334Speter   reload_secondary_out_icode
16918334Speter			  enum insn_code, if a secondary reload is required,
17018334Speter			   gives the INSN_CODE that uses the secondary
17118334Speter			   reload as a scratch register, or CODE_FOR_nothing
17218334Speter			   if the secondary reload register is to be an
17318334Speter			   intermediate register.  */
17418334Speterint n_reloads;
17518334Speter
17618334Speterrtx reload_in[MAX_RELOADS];
17718334Speterrtx reload_out[MAX_RELOADS];
17818334Speterenum reg_class reload_reg_class[MAX_RELOADS];
17918334Speterenum machine_mode reload_inmode[MAX_RELOADS];
18018334Speterenum machine_mode reload_outmode[MAX_RELOADS];
18118334Speterrtx reload_reg_rtx[MAX_RELOADS];
18218334Speterchar reload_optional[MAX_RELOADS];
18350605Sobrienchar reload_nongroup[MAX_RELOADS];
18418334Speterint reload_inc[MAX_RELOADS];
18518334Speterrtx reload_in_reg[MAX_RELOADS];
18652557Sobrienrtx reload_out_reg[MAX_RELOADS];
18718334Speterchar reload_nocombine[MAX_RELOADS];
18818334Speterint reload_opnum[MAX_RELOADS];
18918334Speterenum reload_type reload_when_needed[MAX_RELOADS];
19018334Speterint reload_secondary_p[MAX_RELOADS];
19118334Speterint reload_secondary_in_reload[MAX_RELOADS];
19218334Speterint reload_secondary_out_reload[MAX_RELOADS];
19318334Speterenum insn_code reload_secondary_in_icode[MAX_RELOADS];
19418334Speterenum insn_code reload_secondary_out_icode[MAX_RELOADS];
19518334Speter
19618334Speter/* All the "earlyclobber" operands of the current insn
19718334Speter   are recorded here.  */
19818334Speterint n_earlyclobbers;
19918334Speterrtx reload_earlyclobbers[MAX_RECOG_OPERANDS];
20018334Speter
20118334Speterint reload_n_operands;
20218334Speter
20318334Speter/* Replacing reloads.
20418334Speter
20518334Speter   If `replace_reloads' is nonzero, then as each reload is recorded
20618334Speter   an entry is made for it in the table `replacements'.
20718334Speter   Then later `subst_reloads' can look through that table and
20818334Speter   perform all the replacements needed.  */
20918334Speter
21018334Speter/* Nonzero means record the places to replace.  */
21118334Speterstatic int replace_reloads;
21218334Speter
21318334Speter/* Each replacement is recorded with a structure like this.  */
21418334Speterstruct replacement
21518334Speter{
21618334Speter  rtx *where;			/* Location to store in */
21718334Speter  rtx *subreg_loc;		/* Location of SUBREG if WHERE is inside
21818334Speter				   a SUBREG; 0 otherwise.  */
21918334Speter  int what;			/* which reload this is for */
22018334Speter  enum machine_mode mode;	/* mode it must have */
22118334Speter};
22218334Speter
22318334Speterstatic struct replacement replacements[MAX_RECOG_OPERANDS * ((MAX_REGS_PER_ADDRESS * 2) + 1)];
22418334Speter
22518334Speter/* Number of replacements currently recorded.  */
22618334Speterstatic int n_replacements;
22718334Speter
22818334Speter/* Used to track what is modified by an operand.  */
22918334Speterstruct decomposition
23018334Speter{
23150605Sobrien  int reg_flag;		/* Nonzero if referencing a register.  */
23250605Sobrien  int safe;		/* Nonzero if this can't conflict with anything.  */
23350605Sobrien  rtx base;		/* Base address for MEM.  */
23450605Sobrien  HOST_WIDE_INT start;	/* Starting offset or register number.  */
23518334Speter  HOST_WIDE_INT end;	/* Ending offset or register number.  */
23618334Speter};
23718334Speter
23818334Speter#ifdef SECONDARY_MEMORY_NEEDED
23918334Speter
24018334Speter/* Save MEMs needed to copy from one class of registers to another.  One MEM
24118334Speter   is used per mode, but normally only one or two modes are ever used.
24218334Speter
24318334Speter   We keep two versions, before and after register elimination.  The one
24418334Speter   after register elimination is record separately for each operand.  This
24518334Speter   is done in case the address is not valid to be sure that we separately
24618334Speter   reload each.  */
24718334Speter
24818334Speterstatic rtx secondary_memlocs[NUM_MACHINE_MODES];
24918334Speterstatic rtx secondary_memlocs_elim[NUM_MACHINE_MODES][MAX_RECOG_OPERANDS];
25018334Speter#endif
25118334Speter
25218334Speter/* The instruction we are doing reloads for;
25318334Speter   so we can test whether a register dies in it.  */
25418334Speterstatic rtx this_insn;
25518334Speter
25618334Speter/* Nonzero if this instruction is a user-specified asm with operands.  */
25718334Speterstatic int this_insn_is_asm;
25818334Speter
25918334Speter/* If hard_regs_live_known is nonzero,
26018334Speter   we can tell which hard regs are currently live,
26118334Speter   at least enough to succeed in choosing dummy reloads.  */
26218334Speterstatic int hard_regs_live_known;
26318334Speter
26418334Speter/* Indexed by hard reg number,
26550605Sobrien   element is nonnegative if hard reg has been spilled.
26618334Speter   This vector is passed to `find_reloads' as an argument
26718334Speter   and is not changed here.  */
26818334Speterstatic short *static_reload_reg_p;
26918334Speter
27018334Speter/* Set to 1 in subst_reg_equivs if it changes anything.  */
27118334Speterstatic int subst_reg_equivs_changed;
27218334Speter
27318334Speter/* On return from push_reload, holds the reload-number for the OUT
27418334Speter   operand, which can be different for that from the input operand.  */
27518334Speterstatic int output_reloadnum;
27618334Speter
27718334Speter  /* Compare two RTX's.  */
27818334Speter#define MATCHES(x, y) \
27918334Speter (x == y || (x != 0 && (GET_CODE (x) == REG				\
28018334Speter			? GET_CODE (y) == REG && REGNO (x) == REGNO (y)	\
28118334Speter			: rtx_equal_p (x, y) && ! side_effects_p (x))))
28218334Speter
28318334Speter  /* Indicates if two reloads purposes are for similar enough things that we
28418334Speter     can merge their reloads.  */
28518334Speter#define MERGABLE_RELOADS(when1, when2, op1, op2) \
28618334Speter  ((when1) == RELOAD_OTHER || (when2) == RELOAD_OTHER	\
28718334Speter   || ((when1) == (when2) && (op1) == (op2))		\
28818334Speter   || ((when1) == RELOAD_FOR_INPUT && (when2) == RELOAD_FOR_INPUT) \
28918334Speter   || ((when1) == RELOAD_FOR_OPERAND_ADDRESS		\
29018334Speter       && (when2) == RELOAD_FOR_OPERAND_ADDRESS)	\
29118334Speter   || ((when1) == RELOAD_FOR_OTHER_ADDRESS		\
29218334Speter       && (when2) == RELOAD_FOR_OTHER_ADDRESS))
29318334Speter
29418334Speter  /* Nonzero if these two reload purposes produce RELOAD_OTHER when merged.  */
29518334Speter#define MERGE_TO_OTHER(when1, when2, op1, op2) \
29618334Speter  ((when1) != (when2)					\
29718334Speter   || ! ((op1) == (op2)					\
29818334Speter	 || (when1) == RELOAD_FOR_INPUT			\
29918334Speter	 || (when1) == RELOAD_FOR_OPERAND_ADDRESS	\
30018334Speter	 || (when1) == RELOAD_FOR_OTHER_ADDRESS))
30118334Speter
30250605Sobrien  /* If we are going to reload an address, compute the reload type to
30350605Sobrien     use.  */
30450605Sobrien#define ADDR_TYPE(type)					\
30550605Sobrien  ((type) == RELOAD_FOR_INPUT_ADDRESS			\
30650605Sobrien   ? RELOAD_FOR_INPADDR_ADDRESS				\
30750605Sobrien   : ((type) == RELOAD_FOR_OUTPUT_ADDRESS		\
30850605Sobrien      ? RELOAD_FOR_OUTADDR_ADDRESS			\
30950605Sobrien      : (type)))
31050605Sobrien
31150605Sobrien#ifdef HAVE_SECONDARY_RELOADS
31218334Speterstatic int push_secondary_reload PROTO((int, rtx, int, int, enum reg_class,
31318334Speter					enum machine_mode, enum reload_type,
31418334Speter					enum insn_code *));
31550605Sobrien#endif
31650605Sobrienstatic enum reg_class find_valid_class PROTO((enum machine_mode, int));
31718334Speterstatic int push_reload		PROTO((rtx, rtx, rtx *, rtx *, enum reg_class,
31818334Speter				       enum machine_mode, enum machine_mode,
31918334Speter				       int, int, int, enum reload_type));
32018334Speterstatic void push_replacement	PROTO((rtx *, int, enum machine_mode));
32118334Speterstatic void combine_reloads	PROTO((void));
32252557Sobrienstatic int find_reusable_reload	PROTO((rtx *, rtx, enum reg_class,
32352557Sobrien				       enum reload_type, int, int));
32418334Speterstatic rtx find_dummy_reload	PROTO((rtx, rtx, rtx *, rtx *,
32518334Speter				       enum machine_mode, enum machine_mode,
32650605Sobrien				       enum reg_class, int, int));
32718334Speterstatic int earlyclobber_operand_p PROTO((rtx));
32818334Speterstatic int hard_reg_set_here_p	PROTO((int, int, rtx));
32918334Speterstatic struct decomposition decompose PROTO((rtx));
33018334Speterstatic int immune_p		PROTO((rtx, rtx, struct decomposition));
33152557Sobrienstatic int alternative_allows_memconst PROTO((const char *, int));
33252557Sobrienstatic rtx find_reloads_toplev	PROTO((rtx, int, enum reload_type, int, int, rtx));
33318334Speterstatic rtx make_memloc		PROTO((rtx, int));
33418334Speterstatic int find_reloads_address	PROTO((enum machine_mode, rtx *, rtx, rtx *,
33550605Sobrien				       int, enum reload_type, int, rtx));
33652557Sobrienstatic rtx subst_reg_equivs	PROTO((rtx, rtx));
33718334Speterstatic rtx subst_indexed_address PROTO((rtx));
33850605Sobrienstatic int find_reloads_address_1 PROTO((enum machine_mode, rtx, int, rtx *,
33950605Sobrien					 int, enum reload_type,int, rtx));
34018334Speterstatic void find_reloads_address_part PROTO((rtx, rtx *, enum reg_class,
34118334Speter					     enum machine_mode, int,
34218334Speter					     enum reload_type, int));
34352557Sobrienstatic rtx find_reloads_subreg_address PROTO((rtx, int, int, enum reload_type,
34452557Sobrien					      int, rtx));
34518334Speterstatic int find_inc_amount	PROTO((rtx, rtx));
34652557Sobrienstatic int loc_mentioned_in_p	PROTO((rtx *, rtx));
34718334Speter
34818334Speter#ifdef HAVE_SECONDARY_RELOADS
34918334Speter
35018334Speter/* Determine if any secondary reloads are needed for loading (if IN_P is
35118334Speter   non-zero) or storing (if IN_P is zero) X to or from a reload register of
35218334Speter   register class RELOAD_CLASS in mode RELOAD_MODE.  If secondary reloads
35318334Speter   are needed, push them.
35418334Speter
35518334Speter   Return the reload number of the secondary reload we made, or -1 if
35618334Speter   we didn't need one.  *PICODE is set to the insn_code to use if we do
35718334Speter   need a secondary reload.  */
35818334Speter
35918334Speterstatic int
36018334Speterpush_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
36118334Speter		       type, picode)
36218334Speter     int in_p;
36318334Speter     rtx x;
36418334Speter     int opnum;
36518334Speter     int optional;
36618334Speter     enum reg_class reload_class;
36718334Speter     enum machine_mode reload_mode;
36818334Speter     enum reload_type type;
36918334Speter     enum insn_code *picode;
37018334Speter{
37118334Speter  enum reg_class class = NO_REGS;
37218334Speter  enum machine_mode mode = reload_mode;
37318334Speter  enum insn_code icode = CODE_FOR_nothing;
37418334Speter  enum reg_class t_class = NO_REGS;
37518334Speter  enum machine_mode t_mode = VOIDmode;
37618334Speter  enum insn_code t_icode = CODE_FOR_nothing;
37718334Speter  enum reload_type secondary_type;
37818334Speter  int s_reload, t_reload = -1;
37918334Speter
38050605Sobrien  if (type == RELOAD_FOR_INPUT_ADDRESS
38150605Sobrien      || type == RELOAD_FOR_OUTPUT_ADDRESS
38250605Sobrien      || type == RELOAD_FOR_INPADDR_ADDRESS
38350605Sobrien      || type == RELOAD_FOR_OUTADDR_ADDRESS)
38418334Speter    secondary_type = type;
38518334Speter  else
38618334Speter    secondary_type = in_p ? RELOAD_FOR_INPUT_ADDRESS : RELOAD_FOR_OUTPUT_ADDRESS;
38718334Speter
38818334Speter  *picode = CODE_FOR_nothing;
38918334Speter
39018334Speter  /* If X is a paradoxical SUBREG, use the inner value to determine both the
39118334Speter     mode and object being reloaded.  */
39218334Speter  if (GET_CODE (x) == SUBREG
39318334Speter      && (GET_MODE_SIZE (GET_MODE (x))
39418334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
39518334Speter    {
39618334Speter      x = SUBREG_REG (x);
39718334Speter      reload_mode = GET_MODE (x);
39818334Speter    }
39918334Speter
40018334Speter  /* If X is a pseudo-register that has an equivalent MEM (actually, if it
40118334Speter     is still a pseudo-register by now, it *must* have an equivalent MEM
40218334Speter     but we don't want to assume that), use that equivalent when seeing if
40318334Speter     a secondary reload is needed since whether or not a reload is needed
40418334Speter     might be sensitive to the form of the MEM.  */
40518334Speter
40618334Speter  if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
40718334Speter      && reg_equiv_mem[REGNO (x)] != 0)
40818334Speter    x = reg_equiv_mem[REGNO (x)];
40918334Speter
41018334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
41118334Speter  if (in_p)
41218334Speter    class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
41318334Speter#endif
41418334Speter
41518334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
41618334Speter  if (! in_p)
41718334Speter    class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
41818334Speter#endif
41918334Speter
42018334Speter  /* If we don't need any secondary registers, done.  */
42118334Speter  if (class == NO_REGS)
42218334Speter    return -1;
42318334Speter
42418334Speter  /* Get a possible insn to use.  If the predicate doesn't accept X, don't
42518334Speter     use the insn.  */
42618334Speter
42718334Speter  icode = (in_p ? reload_in_optab[(int) reload_mode]
42818334Speter	   : reload_out_optab[(int) reload_mode]);
42918334Speter
43018334Speter  if (icode != CODE_FOR_nothing
43118334Speter      && insn_operand_predicate[(int) icode][in_p]
43218334Speter      && (! (insn_operand_predicate[(int) icode][in_p]) (x, reload_mode)))
43318334Speter    icode = CODE_FOR_nothing;
43418334Speter
43518334Speter  /* If we will be using an insn, see if it can directly handle the reload
43618334Speter     register we will be using.  If it can, the secondary reload is for a
43718334Speter     scratch register.  If it can't, we will use the secondary reload for
43818334Speter     an intermediate register and require a tertiary reload for the scratch
43918334Speter     register.  */
44018334Speter
44118334Speter  if (icode != CODE_FOR_nothing)
44218334Speter    {
44318334Speter      /* If IN_P is non-zero, the reload register will be the output in
44418334Speter	 operand 0.  If IN_P is zero, the reload register will be the input
44518334Speter	 in operand 1.  Outputs should have an initial "=", which we must
44618334Speter	 skip.  */
44718334Speter
44818334Speter      char insn_letter = insn_operand_constraint[(int) icode][!in_p][in_p];
44918334Speter      enum reg_class insn_class
45018334Speter	= (insn_letter == 'r' ? GENERAL_REGS
45152557Sobrien	   : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
45218334Speter
45318334Speter      if (insn_class == NO_REGS
45418334Speter	  || (in_p && insn_operand_constraint[(int) icode][!in_p][0] != '=')
45518334Speter	  /* The scratch register's constraint must start with "=&".  */
45618334Speter	  || insn_operand_constraint[(int) icode][2][0] != '='
45718334Speter	  || insn_operand_constraint[(int) icode][2][1] != '&')
45818334Speter	abort ();
45918334Speter
46018334Speter      if (reg_class_subset_p (reload_class, insn_class))
46118334Speter	mode = insn_operand_mode[(int) icode][2];
46218334Speter      else
46318334Speter	{
46418334Speter	  char t_letter = insn_operand_constraint[(int) icode][2][2];
46518334Speter	  class = insn_class;
46618334Speter	  t_mode = insn_operand_mode[(int) icode][2];
46718334Speter	  t_class = (t_letter == 'r' ? GENERAL_REGS
46852557Sobrien		     : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
46918334Speter	  t_icode = icode;
47018334Speter	  icode = CODE_FOR_nothing;
47118334Speter	}
47218334Speter    }
47318334Speter
47418334Speter  /* This case isn't valid, so fail.  Reload is allowed to use the same
47518334Speter     register for RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_INPUT reloads, but
47618334Speter     in the case of a secondary register, we actually need two different
47718334Speter     registers for correct code.  We fail here to prevent the possibility of
47818334Speter     silently generating incorrect code later.
47918334Speter
48018334Speter     The convention is that secondary input reloads are valid only if the
48118334Speter     secondary_class is different from class.  If you have such a case, you
48218334Speter     can not use secondary reloads, you must work around the problem some
48318334Speter     other way.
48418334Speter
48518334Speter     Allow this when MODE is not reload_mode and assume that the generated
48618334Speter     code handles this case (it does on the Alpha, which is the only place
48718334Speter     this currently happens).  */
48818334Speter
48918334Speter  if (in_p && class == reload_class && mode == reload_mode)
49018334Speter    abort ();
49118334Speter
49218334Speter  /* If we need a tertiary reload, see if we have one we can reuse or else
49318334Speter     make a new one.  */
49418334Speter
49518334Speter  if (t_class != NO_REGS)
49618334Speter    {
49718334Speter      for (t_reload = 0; t_reload < n_reloads; t_reload++)
49818334Speter	if (reload_secondary_p[t_reload]
49918334Speter	    && (reg_class_subset_p (t_class, reload_reg_class[t_reload])
50018334Speter		|| reg_class_subset_p (reload_reg_class[t_reload], t_class))
50118334Speter	    && ((in_p && reload_inmode[t_reload] == t_mode)
50218334Speter		|| (! in_p && reload_outmode[t_reload] == t_mode))
50318334Speter	    && ((in_p && (reload_secondary_in_icode[t_reload]
50418334Speter			  == CODE_FOR_nothing))
50518334Speter		|| (! in_p &&(reload_secondary_out_icode[t_reload]
50618334Speter			      == CODE_FOR_nothing)))
50750605Sobrien	    && (reg_class_size[(int) t_class] == 1 || SMALL_REGISTER_CLASSES)
50818334Speter	    && MERGABLE_RELOADS (secondary_type,
50918334Speter				 reload_when_needed[t_reload],
51018334Speter				 opnum, reload_opnum[t_reload]))
51118334Speter	  {
51218334Speter	    if (in_p)
51318334Speter	      reload_inmode[t_reload] = t_mode;
51418334Speter	    if (! in_p)
51518334Speter	      reload_outmode[t_reload] = t_mode;
51618334Speter
51718334Speter	    if (reg_class_subset_p (t_class, reload_reg_class[t_reload]))
51818334Speter	      reload_reg_class[t_reload] = t_class;
51918334Speter
52018334Speter	    reload_opnum[t_reload] = MIN (reload_opnum[t_reload], opnum);
52118334Speter	    reload_optional[t_reload] &= optional;
52218334Speter	    reload_secondary_p[t_reload] = 1;
52318334Speter	    if (MERGE_TO_OTHER (secondary_type, reload_when_needed[t_reload],
52418334Speter				opnum, reload_opnum[t_reload]))
52518334Speter	      reload_when_needed[t_reload] = RELOAD_OTHER;
52618334Speter	  }
52718334Speter
52818334Speter      if (t_reload == n_reloads)
52918334Speter	{
53018334Speter	  /* We need to make a new tertiary reload for this register class.  */
53118334Speter	  reload_in[t_reload] = reload_out[t_reload] = 0;
53218334Speter	  reload_reg_class[t_reload] = t_class;
53318334Speter	  reload_inmode[t_reload] = in_p ? t_mode : VOIDmode;
53418334Speter	  reload_outmode[t_reload] = ! in_p ? t_mode : VOIDmode;
53518334Speter	  reload_reg_rtx[t_reload] = 0;
53618334Speter	  reload_optional[t_reload] = optional;
53750605Sobrien	  reload_nongroup[t_reload] = 0;
53818334Speter	  reload_inc[t_reload] = 0;
53918334Speter	  /* Maybe we could combine these, but it seems too tricky.  */
54018334Speter	  reload_nocombine[t_reload] = 1;
54118334Speter	  reload_in_reg[t_reload] = 0;
54252557Sobrien	  reload_out_reg[t_reload] = 0;
54318334Speter	  reload_opnum[t_reload] = opnum;
54418334Speter	  reload_when_needed[t_reload] = secondary_type;
54518334Speter	  reload_secondary_in_reload[t_reload] = -1;
54618334Speter	  reload_secondary_out_reload[t_reload] = -1;
54718334Speter	  reload_secondary_in_icode[t_reload] = CODE_FOR_nothing;
54818334Speter	  reload_secondary_out_icode[t_reload] = CODE_FOR_nothing;
54918334Speter	  reload_secondary_p[t_reload] = 1;
55018334Speter
55118334Speter	  n_reloads++;
55218334Speter	}
55318334Speter    }
55418334Speter
55518334Speter  /* See if we can reuse an existing secondary reload.  */
55618334Speter  for (s_reload = 0; s_reload < n_reloads; s_reload++)
55718334Speter    if (reload_secondary_p[s_reload]
55818334Speter	&& (reg_class_subset_p (class, reload_reg_class[s_reload])
55918334Speter	    || reg_class_subset_p (reload_reg_class[s_reload], class))
56018334Speter	&& ((in_p && reload_inmode[s_reload] == mode)
56118334Speter	    || (! in_p && reload_outmode[s_reload] == mode))
56218334Speter	&& ((in_p && reload_secondary_in_reload[s_reload] == t_reload)
56318334Speter	    || (! in_p && reload_secondary_out_reload[s_reload] == t_reload))
56418334Speter	&& ((in_p && reload_secondary_in_icode[s_reload] == t_icode)
56518334Speter	    || (! in_p && reload_secondary_out_icode[s_reload] == t_icode))
56650605Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
56718334Speter	&& MERGABLE_RELOADS (secondary_type, reload_when_needed[s_reload],
56818334Speter			     opnum, reload_opnum[s_reload]))
56918334Speter      {
57018334Speter	if (in_p)
57118334Speter	  reload_inmode[s_reload] = mode;
57218334Speter	if (! in_p)
57318334Speter	  reload_outmode[s_reload] = mode;
57418334Speter
57518334Speter	if (reg_class_subset_p (class, reload_reg_class[s_reload]))
57618334Speter	  reload_reg_class[s_reload] = class;
57718334Speter
57818334Speter	reload_opnum[s_reload] = MIN (reload_opnum[s_reload], opnum);
57918334Speter	reload_optional[s_reload] &= optional;
58018334Speter	reload_secondary_p[s_reload] = 1;
58118334Speter	if (MERGE_TO_OTHER (secondary_type, reload_when_needed[s_reload],
58218334Speter			    opnum, reload_opnum[s_reload]))
58318334Speter	  reload_when_needed[s_reload] = RELOAD_OTHER;
58418334Speter      }
58518334Speter
58618334Speter  if (s_reload == n_reloads)
58718334Speter    {
58850605Sobrien#ifdef SECONDARY_MEMORY_NEEDED
58950605Sobrien      /* If we need a memory location to copy between the two reload regs,
59050605Sobrien	 set it up now.  Note that we do the input case before making
59150605Sobrien	 the reload and the output case after.  This is due to the
59250605Sobrien	 way reloads are output.  */
59350605Sobrien
59450605Sobrien      if (in_p && icode == CODE_FOR_nothing
59550605Sobrien	  && SECONDARY_MEMORY_NEEDED (class, reload_class, mode))
59650605Sobrien	get_secondary_mem (x, reload_mode, opnum, type);
59750605Sobrien#endif
59850605Sobrien
59918334Speter      /* We need to make a new secondary reload for this register class.  */
60018334Speter      reload_in[s_reload] = reload_out[s_reload] = 0;
60118334Speter      reload_reg_class[s_reload] = class;
60218334Speter
60318334Speter      reload_inmode[s_reload] = in_p ? mode : VOIDmode;
60418334Speter      reload_outmode[s_reload] = ! in_p ? mode : VOIDmode;
60518334Speter      reload_reg_rtx[s_reload] = 0;
60618334Speter      reload_optional[s_reload] = optional;
60750605Sobrien      reload_nongroup[s_reload] = 0;
60818334Speter      reload_inc[s_reload] = 0;
60918334Speter      /* Maybe we could combine these, but it seems too tricky.  */
61018334Speter      reload_nocombine[s_reload] = 1;
61118334Speter      reload_in_reg[s_reload] = 0;
61252557Sobrien      reload_out_reg[s_reload] = 0;
61318334Speter      reload_opnum[s_reload] = opnum;
61418334Speter      reload_when_needed[s_reload] = secondary_type;
61518334Speter      reload_secondary_in_reload[s_reload] = in_p ? t_reload : -1;
61618334Speter      reload_secondary_out_reload[s_reload] = ! in_p ? t_reload : -1;
61718334Speter      reload_secondary_in_icode[s_reload] = in_p ? t_icode : CODE_FOR_nothing;
61818334Speter      reload_secondary_out_icode[s_reload]
61918334Speter	= ! in_p ? t_icode : CODE_FOR_nothing;
62018334Speter      reload_secondary_p[s_reload] = 1;
62118334Speter
62218334Speter      n_reloads++;
62318334Speter
62418334Speter#ifdef SECONDARY_MEMORY_NEEDED
62518334Speter      if (! in_p && icode == CODE_FOR_nothing
62650605Sobrien	  && SECONDARY_MEMORY_NEEDED (reload_class, class, mode))
62750605Sobrien	get_secondary_mem (x, mode, opnum, type);
62818334Speter#endif
62918334Speter    }
63018334Speter
63118334Speter  *picode = icode;
63218334Speter  return s_reload;
63318334Speter}
63418334Speter#endif /* HAVE_SECONDARY_RELOADS */
63518334Speter
63618334Speter#ifdef SECONDARY_MEMORY_NEEDED
63718334Speter
63818334Speter/* Return a memory location that will be used to copy X in mode MODE.
63918334Speter   If we haven't already made a location for this mode in this insn,
64018334Speter   call find_reloads_address on the location being returned.  */
64118334Speter
64218334Speterrtx
64318334Speterget_secondary_mem (x, mode, opnum, type)
64418334Speter     rtx x;
64518334Speter     enum machine_mode mode;
64618334Speter     int opnum;
64718334Speter     enum reload_type type;
64818334Speter{
64918334Speter  rtx loc;
65018334Speter  int mem_valid;
65118334Speter
65218334Speter  /* By default, if MODE is narrower than a word, widen it to a word.
65318334Speter     This is required because most machines that require these memory
65418334Speter     locations do not support short load and stores from all registers
65518334Speter     (e.g., FP registers).  */
65618334Speter
65718334Speter#ifdef SECONDARY_MEMORY_NEEDED_MODE
65818334Speter  mode = SECONDARY_MEMORY_NEEDED_MODE (mode);
65918334Speter#else
66018334Speter  if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
66118334Speter    mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0);
66218334Speter#endif
66318334Speter
66418334Speter  /* If we already have made a MEM for this operand in MODE, return it.  */
66518334Speter  if (secondary_memlocs_elim[(int) mode][opnum] != 0)
66618334Speter    return secondary_memlocs_elim[(int) mode][opnum];
66718334Speter
66818334Speter  /* If this is the first time we've tried to get a MEM for this mode,
66918334Speter     allocate a new one.  `something_changed' in reload will get set
67018334Speter     by noticing that the frame size has changed.  */
67118334Speter
67218334Speter  if (secondary_memlocs[(int) mode] == 0)
67318334Speter    {
67418334Speter#ifdef SECONDARY_MEMORY_NEEDED_RTX
67518334Speter      secondary_memlocs[(int) mode] = SECONDARY_MEMORY_NEEDED_RTX (mode);
67618334Speter#else
67718334Speter      secondary_memlocs[(int) mode]
67818334Speter	= assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
67918334Speter#endif
68018334Speter    }
68118334Speter
68218334Speter  /* Get a version of the address doing any eliminations needed.  If that
68318334Speter     didn't give us a new MEM, make a new one if it isn't valid.  */
68418334Speter
68518334Speter  loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX);
68618334Speter  mem_valid = strict_memory_address_p (mode, XEXP (loc, 0));
68718334Speter
68818334Speter  if (! mem_valid && loc == secondary_memlocs[(int) mode])
68918334Speter    loc = copy_rtx (loc);
69018334Speter
69118334Speter  /* The only time the call below will do anything is if the stack
69218334Speter     offset is too large.  In that case IND_LEVELS doesn't matter, so we
69318334Speter     can just pass a zero.  Adjust the type to be the address of the
69418334Speter     corresponding object.  If the address was valid, save the eliminated
69518334Speter     address.  If it wasn't valid, we need to make a reload each time, so
69618334Speter     don't save it.  */
69718334Speter
69818334Speter  if (! mem_valid)
69918334Speter    {
70018334Speter      type =  (type == RELOAD_FOR_INPUT ? RELOAD_FOR_INPUT_ADDRESS
70118334Speter	       : type == RELOAD_FOR_OUTPUT ? RELOAD_FOR_OUTPUT_ADDRESS
70218334Speter	       : RELOAD_OTHER);
70318334Speter
70418334Speter      find_reloads_address (mode, NULL_PTR, XEXP (loc, 0), &XEXP (loc, 0),
70550605Sobrien			    opnum, type, 0, 0);
70618334Speter    }
70718334Speter
70818334Speter  secondary_memlocs_elim[(int) mode][opnum] = loc;
70918334Speter  return loc;
71018334Speter}
71118334Speter
71218334Speter/* Clear any secondary memory locations we've made.  */
71318334Speter
71418334Spetervoid
71518334Speterclear_secondary_mem ()
71618334Speter{
71718334Speter  bzero ((char *) secondary_memlocs, sizeof secondary_memlocs);
71818334Speter}
71918334Speter#endif /* SECONDARY_MEMORY_NEEDED */
72018334Speter
72150605Sobrien/* Find the largest class for which every register number plus N is valid in
72250605Sobrien   M1 (if in range).  Abort if no such class exists.  */
72350605Sobrien
72450605Sobrienstatic enum reg_class
72550605Sobrienfind_valid_class (m1, n)
72650605Sobrien     enum machine_mode  m1;
72750605Sobrien     int n;
72850605Sobrien{
72950605Sobrien  int class;
73050605Sobrien  int regno;
73150605Sobrien  enum reg_class best_class;
73250605Sobrien  int best_size = 0;
73350605Sobrien
73450605Sobrien  for (class = 1; class < N_REG_CLASSES; class++)
73550605Sobrien    {
73650605Sobrien      int bad = 0;
73750605Sobrien      for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++)
73850605Sobrien	if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
73950605Sobrien	    && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
74050605Sobrien	    && ! HARD_REGNO_MODE_OK (regno + n, m1))
74150605Sobrien	  bad = 1;
74250605Sobrien
74350605Sobrien      if (! bad && reg_class_size[class] > best_size)
74450605Sobrien	best_class = class, best_size = reg_class_size[class];
74550605Sobrien    }
74650605Sobrien
74750605Sobrien  if (best_size == 0)
74850605Sobrien    abort ();
74950605Sobrien
75050605Sobrien  return best_class;
75150605Sobrien}
75250605Sobrien
75352557Sobrien/* Return the number of a previously made reload that can be combined with
75452557Sobrien   a new one, or n_reloads if none of the existing reloads can be used.
75552557Sobrien   OUT, CLASS, TYPE and OPNUM are the same arguments as passed to
75652557Sobrien   push_reload, they determine the kind of the new reload that we try to
75752557Sobrien   combine.  P_IN points to the corresponding value of IN, which can be
75852557Sobrien   modified by this function.
75952557Sobrien   DONT_SHARE is nonzero if we can't share any input-only reload for IN.  */
76052557Sobrienstatic int
76152557Sobrienfind_reusable_reload (p_in, out, class, type, opnum, dont_share)
76252557Sobrien     rtx *p_in, out;
76352557Sobrien     enum reg_class class;
76452557Sobrien     enum reload_type type;
76552557Sobrien     int opnum, dont_share;
76652557Sobrien{
76752557Sobrien  rtx in = *p_in;
76852557Sobrien  int i;
76952557Sobrien  /* We can't merge two reloads if the output of either one is
77052557Sobrien     earlyclobbered.  */
77152557Sobrien
77252557Sobrien  if (earlyclobber_operand_p (out))
77352557Sobrien    return n_reloads;
77452557Sobrien
77552557Sobrien  /* We can use an existing reload if the class is right
77652557Sobrien     and at least one of IN and OUT is a match
77752557Sobrien     and the other is at worst neutral.
77852557Sobrien     (A zero compared against anything is neutral.)
77952557Sobrien
78052557Sobrien     If SMALL_REGISTER_CLASSES, don't use existing reloads unless they are
78152557Sobrien     for the same thing since that can cause us to need more reload registers
78252557Sobrien     than we otherwise would.  */
78352557Sobrien
78452557Sobrien  for (i = 0; i < n_reloads; i++)
78552557Sobrien    if ((reg_class_subset_p (class, reload_reg_class[i])
78652557Sobrien	 || reg_class_subset_p (reload_reg_class[i], class))
78752557Sobrien	/* If the existing reload has a register, it must fit our class.  */
78852557Sobrien	&& (reload_reg_rtx[i] == 0
78952557Sobrien	    || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
79052557Sobrien				  true_regnum (reload_reg_rtx[i])))
79152557Sobrien	&& ((in != 0 && MATCHES (reload_in[i], in) && ! dont_share
79252557Sobrien	     && (out == 0 || reload_out[i] == 0 || MATCHES (reload_out[i], out)))
79352557Sobrien	    ||
79452557Sobrien	    (out != 0 && MATCHES (reload_out[i], out)
79552557Sobrien	     && (in == 0 || reload_in[i] == 0 || MATCHES (reload_in[i], in))))
79652557Sobrien	&& (reload_out[i] == 0 || ! earlyclobber_operand_p (reload_out[i]))
79752557Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
79852557Sobrien	    && MERGABLE_RELOADS (type, reload_when_needed[i],
79952557Sobrien				 opnum, reload_opnum[i]))
80052557Sobrien      return i;
80152557Sobrien
80252557Sobrien  /* Reloading a plain reg for input can match a reload to postincrement
80352557Sobrien     that reg, since the postincrement's value is the right value.
80452557Sobrien     Likewise, it can match a preincrement reload, since we regard
80552557Sobrien     the preincrementation as happening before any ref in this insn
80652557Sobrien     to that register.  */
80752557Sobrien  for (i = 0; i < n_reloads; i++)
80852557Sobrien    if ((reg_class_subset_p (class, reload_reg_class[i])
80952557Sobrien	 || reg_class_subset_p (reload_reg_class[i], class))
81052557Sobrien	/* If the existing reload has a register, it must fit our
81152557Sobrien	   class.  */
81252557Sobrien	&& (reload_reg_rtx[i] == 0
81352557Sobrien	    || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
81452557Sobrien				  true_regnum (reload_reg_rtx[i])))
81552557Sobrien	&& out == 0 && reload_out[i] == 0 && reload_in[i] != 0
81652557Sobrien	&& ((GET_CODE (in) == REG
81752557Sobrien	     && (GET_CODE (reload_in[i]) == POST_INC
81852557Sobrien		 || GET_CODE (reload_in[i]) == POST_DEC
81952557Sobrien		 || GET_CODE (reload_in[i]) == PRE_INC
82052557Sobrien		 || GET_CODE (reload_in[i]) == PRE_DEC)
82152557Sobrien	     && MATCHES (XEXP (reload_in[i], 0), in))
82252557Sobrien	    ||
82352557Sobrien	    (GET_CODE (reload_in[i]) == REG
82452557Sobrien	     && (GET_CODE (in) == POST_INC
82552557Sobrien		 || GET_CODE (in) == POST_DEC
82652557Sobrien		 || GET_CODE (in) == PRE_INC
82752557Sobrien		 || GET_CODE (in) == PRE_DEC)
82852557Sobrien	     && MATCHES (XEXP (in, 0), reload_in[i])))
82952557Sobrien	&& (reload_out[i] == 0 || ! earlyclobber_operand_p (reload_out[i]))
83052557Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
83152557Sobrien	&& MERGABLE_RELOADS (type, reload_when_needed[i],
83252557Sobrien			     opnum, reload_opnum[i]))
83352557Sobrien      {
83452557Sobrien	/* Make sure reload_in ultimately has the increment,
83552557Sobrien	   not the plain register.  */
83652557Sobrien	if (GET_CODE (in) == REG)
83752557Sobrien	  *p_in = reload_in[i];
83852557Sobrien	return i;
83952557Sobrien      }
84052557Sobrien  return n_reloads;
84152557Sobrien}
84252557Sobrien
84318334Speter/* Record one reload that needs to be performed.
84418334Speter   IN is an rtx saying where the data are to be found before this instruction.
84518334Speter   OUT says where they must be stored after the instruction.
84618334Speter   (IN is zero for data not read, and OUT is zero for data not written.)
84718334Speter   INLOC and OUTLOC point to the places in the instructions where
84818334Speter   IN and OUT were found.
84918334Speter   If IN and OUT are both non-zero, it means the same register must be used
85018334Speter   to reload both IN and OUT.
85118334Speter
85218334Speter   CLASS is a register class required for the reloaded data.
85318334Speter   INMODE is the machine mode that the instruction requires
85418334Speter   for the reg that replaces IN and OUTMODE is likewise for OUT.
85518334Speter
85618334Speter   If IN is zero, then OUT's location and mode should be passed as
85718334Speter   INLOC and INMODE.
85818334Speter
85918334Speter   STRICT_LOW is the 1 if there is a containing STRICT_LOW_PART rtx.
86018334Speter
86118334Speter   OPTIONAL nonzero means this reload does not need to be performed:
86218334Speter   it can be discarded if that is more convenient.
86318334Speter
86418334Speter   OPNUM and TYPE say what the purpose of this reload is.
86518334Speter
86618334Speter   The return value is the reload-number for this reload.
86718334Speter
86818334Speter   If both IN and OUT are nonzero, in some rare cases we might
86918334Speter   want to make two separate reloads.  (Actually we never do this now.)
87018334Speter   Therefore, the reload-number for OUT is stored in
87118334Speter   output_reloadnum when we return; the return value applies to IN.
87218334Speter   Usually (presently always), when IN and OUT are nonzero,
87318334Speter   the two reload-numbers are equal, but the caller should be careful to
87418334Speter   distinguish them.  */
87518334Speter
87618334Speterstatic int
87718334Speterpush_reload (in, out, inloc, outloc, class,
87818334Speter	     inmode, outmode, strict_low, optional, opnum, type)
87952557Sobrien     rtx in, out;
88018334Speter     rtx *inloc, *outloc;
88118334Speter     enum reg_class class;
88218334Speter     enum machine_mode inmode, outmode;
88318334Speter     int strict_low;
88418334Speter     int optional;
88518334Speter     int opnum;
88618334Speter     enum reload_type type;
88718334Speter{
88818334Speter  register int i;
88918334Speter  int dont_share = 0;
89018334Speter  int dont_remove_subreg = 0;
89118334Speter  rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
89218334Speter  int secondary_in_reload = -1, secondary_out_reload = -1;
89318334Speter  enum insn_code secondary_in_icode = CODE_FOR_nothing;
89418334Speter  enum insn_code secondary_out_icode = CODE_FOR_nothing;
89518334Speter
89618334Speter  /* INMODE and/or OUTMODE could be VOIDmode if no mode
89718334Speter     has been specified for the operand.  In that case,
89818334Speter     use the operand's mode as the mode to reload.  */
89918334Speter  if (inmode == VOIDmode && in != 0)
90018334Speter    inmode = GET_MODE (in);
90118334Speter  if (outmode == VOIDmode && out != 0)
90218334Speter    outmode = GET_MODE (out);
90318334Speter
90418334Speter  /* If IN is a pseudo register everywhere-equivalent to a constant, and
90518334Speter     it is not in a hard register, reload straight from the constant,
90618334Speter     since we want to get rid of such pseudo registers.
90718334Speter     Often this is done earlier, but not always in find_reloads_address.  */
90818334Speter  if (in != 0 && GET_CODE (in) == REG)
90918334Speter    {
91018334Speter      register int regno = REGNO (in);
91118334Speter
91218334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
91318334Speter	  && reg_equiv_constant[regno] != 0)
91418334Speter	in = reg_equiv_constant[regno];
91518334Speter    }
91618334Speter
91718334Speter  /* Likewise for OUT.  Of course, OUT will never be equivalent to
91818334Speter     an actual constant, but it might be equivalent to a memory location
91918334Speter     (in the case of a parameter).  */
92018334Speter  if (out != 0 && GET_CODE (out) == REG)
92118334Speter    {
92218334Speter      register int regno = REGNO (out);
92318334Speter
92418334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
92518334Speter	  && reg_equiv_constant[regno] != 0)
92618334Speter	out = reg_equiv_constant[regno];
92718334Speter    }
92818334Speter
92918334Speter  /* If we have a read-write operand with an address side-effect,
93018334Speter     change either IN or OUT so the side-effect happens only once.  */
93118334Speter  if (in != 0 && out != 0 && GET_CODE (in) == MEM && rtx_equal_p (in, out))
93218334Speter    {
93318334Speter      if (GET_CODE (XEXP (in, 0)) == POST_INC
93418334Speter	  || GET_CODE (XEXP (in, 0)) == POST_DEC)
93550605Sobrien	in = gen_rtx_MEM (GET_MODE (in), XEXP (XEXP (in, 0), 0));
93618334Speter      if (GET_CODE (XEXP (in, 0)) == PRE_INC
93718334Speter	  || GET_CODE (XEXP (in, 0)) == PRE_DEC)
93850605Sobrien	out = gen_rtx_MEM (GET_MODE (out), XEXP (XEXP (out, 0), 0));
93918334Speter    }
94018334Speter
94118334Speter  /* If we are reloading a (SUBREG constant ...), really reload just the
94218334Speter     inside expression in its own mode.  Similarly for (SUBREG (PLUS ...)).
94318334Speter     If we have (SUBREG:M1 (MEM:M2 ...) ...) (or an inner REG that is still
94418334Speter     a pseudo and hence will become a MEM) with M1 wider than M2 and the
94518334Speter     register is a pseudo, also reload the inside expression.
94618334Speter     For machines that extend byte loads, do this for any SUBREG of a pseudo
94718334Speter     where both M1 and M2 are a word or smaller, M1 is wider than M2, and
94818334Speter     M2 is an integral mode that gets extended when loaded.
94918334Speter     Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
95018334Speter     either M1 is not valid for R or M2 is wider than a word but we only
95118334Speter     need one word to store an M2-sized quantity in R.
95218334Speter     (However, if OUT is nonzero, we need to reload the reg *and*
95318334Speter     the subreg, so do nothing here, and let following statement handle it.)
95418334Speter
95518334Speter     Note that the case of (SUBREG (CONST_INT...)...) is handled elsewhere;
95618334Speter     we can't handle it here because CONST_INT does not indicate a mode.
95718334Speter
95818334Speter     Similarly, we must reload the inside expression if we have a
95918334Speter     STRICT_LOW_PART (presumably, in == out in the cas).
96018334Speter
96118334Speter     Also reload the inner expression if it does not require a secondary
96218334Speter     reload but the SUBREG does.
96318334Speter
96418334Speter     Finally, reload the inner expression if it is a register that is in
96518334Speter     the class whose registers cannot be referenced in a different size
96618334Speter     and M1 is not the same size as M2.  If SUBREG_WORD is nonzero, we
96718334Speter     cannot reload just the inside since we might end up with the wrong
96852557Sobrien     register class.  But if it is inside a STRICT_LOW_PART, we have
96952557Sobrien     no choice, so we hope we do get the right register class there.  */
97018334Speter
97152557Sobrien  if (in != 0 && GET_CODE (in) == SUBREG
97252557Sobrien      && (SUBREG_WORD (in) == 0 || strict_low)
97318334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
97418334Speter      && class != CLASS_CANNOT_CHANGE_SIZE
97518334Speter#endif
97618334Speter      && (CONSTANT_P (SUBREG_REG (in))
97718334Speter	  || GET_CODE (SUBREG_REG (in)) == PLUS
97818334Speter	  || strict_low
97918334Speter	  || (((GET_CODE (SUBREG_REG (in)) == REG
98018334Speter		&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
98118334Speter	       || GET_CODE (SUBREG_REG (in)) == MEM)
98218334Speter	      && ((GET_MODE_SIZE (inmode)
98318334Speter		   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
98418334Speter#ifdef LOAD_EXTEND_OP
98518334Speter		  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
98618334Speter		      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
98718334Speter			  <= UNITS_PER_WORD)
98818334Speter		      && (GET_MODE_SIZE (inmode)
98918334Speter			  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
99018334Speter		      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
99118334Speter		      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != NIL)
99218334Speter#endif
99350605Sobrien#ifdef WORD_REGISTER_OPERATIONS
99450605Sobrien		  || ((GET_MODE_SIZE (inmode)
99550605Sobrien		       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
99650605Sobrien		      && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
99750605Sobrien			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
99850605Sobrien			   / UNITS_PER_WORD)))
99950605Sobrien#endif
100018334Speter		  ))
100118334Speter	  || (GET_CODE (SUBREG_REG (in)) == REG
100218334Speter	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
100318334Speter	      /* The case where out is nonzero
100418334Speter		 is handled differently in the following statement.  */
100518334Speter	      && (out == 0 || SUBREG_WORD (in) == 0)
100618334Speter	      && ((GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
100718334Speter		   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
100818334Speter		       > UNITS_PER_WORD)
100918334Speter		   && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
101018334Speter			/ UNITS_PER_WORD)
101118334Speter		       != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
101218334Speter					    GET_MODE (SUBREG_REG (in)))))
101318334Speter		  || ! HARD_REGNO_MODE_OK ((REGNO (SUBREG_REG (in))
101418334Speter					    + SUBREG_WORD (in)),
101518334Speter					   inmode)))
101618334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
101718334Speter	  || (SECONDARY_INPUT_RELOAD_CLASS (class, inmode, in) != NO_REGS
101818334Speter	      && (SECONDARY_INPUT_RELOAD_CLASS (class,
101918334Speter						GET_MODE (SUBREG_REG (in)),
102018334Speter						SUBREG_REG (in))
102118334Speter		  == NO_REGS))
102218334Speter#endif
102318334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
102418334Speter	  || (GET_CODE (SUBREG_REG (in)) == REG
102518334Speter	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
102618334Speter	      && (TEST_HARD_REG_BIT
102718334Speter		  (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
102818334Speter		   REGNO (SUBREG_REG (in))))
102918334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
103018334Speter		  != GET_MODE_SIZE (inmode)))
103118334Speter#endif
103218334Speter	  ))
103318334Speter    {
103418334Speter      in_subreg_loc = inloc;
103518334Speter      inloc = &SUBREG_REG (in);
103618334Speter      in = *inloc;
103750605Sobrien#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
103818334Speter      if (GET_CODE (in) == MEM)
103918334Speter	/* This is supposed to happen only for paradoxical subregs made by
104018334Speter	   combine.c.  (SUBREG (MEM)) isn't supposed to occur other ways.  */
104118334Speter	if (GET_MODE_SIZE (GET_MODE (in)) > GET_MODE_SIZE (inmode))
104218334Speter	  abort ();
104318334Speter#endif
104418334Speter      inmode = GET_MODE (in);
104518334Speter    }
104618334Speter
104718334Speter  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
104818334Speter     either M1 is not valid for R or M2 is wider than a word but we only
104918334Speter     need one word to store an M2-sized quantity in R.
105018334Speter
105118334Speter     However, we must reload the inner reg *as well as* the subreg in
105218334Speter     that case.  */
105318334Speter
105450605Sobrien  /* Similar issue for (SUBREG constant ...) if it was not handled by the
105550605Sobrien     code above.  This can happen if SUBREG_WORD != 0.  */
105650605Sobrien
105718334Speter  if (in != 0 && GET_CODE (in) == SUBREG
105850605Sobrien      && (CONSTANT_P (SUBREG_REG (in))
105950605Sobrien	  || (GET_CODE (SUBREG_REG (in)) == REG
106050605Sobrien	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
106150605Sobrien	      && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in))
106250605Sobrien					+ SUBREG_WORD (in),
106350605Sobrien					inmode)
106450605Sobrien		  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
106550605Sobrien		      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
106650605Sobrien			  > UNITS_PER_WORD)
106750605Sobrien		      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
106850605Sobrien			   / UNITS_PER_WORD)
106950605Sobrien			  != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
107050605Sobrien					       GET_MODE (SUBREG_REG (in)))))))))
107118334Speter    {
107218334Speter      /* This relies on the fact that emit_reload_insns outputs the
107318334Speter	 instructions for input reloads of type RELOAD_OTHER in the same
107418334Speter	 order as the reloads.  Thus if the outer reload is also of type
107518334Speter	 RELOAD_OTHER, we are guaranteed that this inner reload will be
107618334Speter	 output before the outer reload.  */
107718334Speter      push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR,
107850605Sobrien		   find_valid_class (inmode, SUBREG_WORD (in)),
107950605Sobrien		   VOIDmode, VOIDmode, 0, 0, opnum, type);
108018334Speter      dont_remove_subreg = 1;
108118334Speter    }
108218334Speter
108318334Speter  /* Similarly for paradoxical and problematical SUBREGs on the output.
108418334Speter     Note that there is no reason we need worry about the previous value
108518334Speter     of SUBREG_REG (out); even if wider than out,
108618334Speter     storing in a subreg is entitled to clobber it all
108718334Speter     (except in the case of STRICT_LOW_PART,
108818334Speter     and in that case the constraint should label it input-output.)  */
108952557Sobrien  if (out != 0 && GET_CODE (out) == SUBREG
109052557Sobrien      && (SUBREG_WORD (out) == 0 || strict_low)
109118334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
109218334Speter      && class != CLASS_CANNOT_CHANGE_SIZE
109318334Speter#endif
109418334Speter      && (CONSTANT_P (SUBREG_REG (out))
109518334Speter	  || strict_low
109618334Speter	  || (((GET_CODE (SUBREG_REG (out)) == REG
109718334Speter		&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
109818334Speter	       || GET_CODE (SUBREG_REG (out)) == MEM)
109918334Speter	      && ((GET_MODE_SIZE (outmode)
110050605Sobrien		   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
110150605Sobrien#ifdef WORD_REGISTER_OPERATIONS
110250605Sobrien		  || ((GET_MODE_SIZE (outmode)
110350605Sobrien		       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
110450605Sobrien		      && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
110550605Sobrien			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
110650605Sobrien			   / UNITS_PER_WORD)))
110750605Sobrien#endif
110850605Sobrien	          ))
110918334Speter	  || (GET_CODE (SUBREG_REG (out)) == REG
111018334Speter	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
111118334Speter	      && ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
111218334Speter		   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
111318334Speter		       > UNITS_PER_WORD)
111418334Speter		   && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
111518334Speter			/ UNITS_PER_WORD)
111618334Speter		       != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
111718334Speter					    GET_MODE (SUBREG_REG (out)))))
111818334Speter		  || ! HARD_REGNO_MODE_OK ((REGNO (SUBREG_REG (out))
111918334Speter					    + SUBREG_WORD (out)),
112018334Speter					   outmode)))
112118334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
112218334Speter	  || (SECONDARY_OUTPUT_RELOAD_CLASS (class, outmode, out) != NO_REGS
112318334Speter	      && (SECONDARY_OUTPUT_RELOAD_CLASS (class,
112418334Speter						 GET_MODE (SUBREG_REG (out)),
112518334Speter						 SUBREG_REG (out))
112618334Speter		  == NO_REGS))
112718334Speter#endif
112818334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
112918334Speter	  || (GET_CODE (SUBREG_REG (out)) == REG
113018334Speter	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
113118334Speter	      && (TEST_HARD_REG_BIT
113218334Speter		  (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
113318334Speter		   REGNO (SUBREG_REG (out))))
113418334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
113518334Speter		  != GET_MODE_SIZE (outmode)))
113618334Speter#endif
113718334Speter	  ))
113818334Speter    {
113918334Speter      out_subreg_loc = outloc;
114018334Speter      outloc = &SUBREG_REG (out);
114118334Speter      out = *outloc;
114250605Sobrien#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
114318334Speter     if (GET_CODE (out) == MEM
114418334Speter	  && GET_MODE_SIZE (GET_MODE (out)) > GET_MODE_SIZE (outmode))
114518334Speter	abort ();
114618334Speter#endif
114718334Speter      outmode = GET_MODE (out);
114818334Speter    }
114918334Speter
115018334Speter  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
115118334Speter     either M1 is not valid for R or M2 is wider than a word but we only
115218334Speter     need one word to store an M2-sized quantity in R.
115318334Speter
115418334Speter     However, we must reload the inner reg *as well as* the subreg in
115518334Speter     that case.  In this case, the inner reg is an in-out reload.  */
115618334Speter
115718334Speter  if (out != 0 && GET_CODE (out) == SUBREG
115818334Speter      && GET_CODE (SUBREG_REG (out)) == REG
115918334Speter      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
116050605Sobrien      && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)) + SUBREG_WORD (out),
116150605Sobrien				outmode)
116218334Speter	  || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
116318334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
116418334Speter		  > UNITS_PER_WORD)
116518334Speter	      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
116618334Speter		   / UNITS_PER_WORD)
116718334Speter		  != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
116818334Speter				       GET_MODE (SUBREG_REG (out)))))))
116918334Speter    {
117018334Speter      /* This relies on the fact that emit_reload_insns outputs the
117118334Speter	 instructions for output reloads of type RELOAD_OTHER in reverse
117218334Speter	 order of the reloads.  Thus if the outer reload is also of type
117318334Speter	 RELOAD_OTHER, we are guaranteed that this inner reload will be
117418334Speter	 output after the outer reload.  */
117518334Speter      dont_remove_subreg = 1;
117618334Speter      push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
117750605Sobrien		   &SUBREG_REG (out),
117850605Sobrien		   find_valid_class (outmode, SUBREG_WORD (out)),
117950605Sobrien		   VOIDmode, VOIDmode, 0, 0,
118018334Speter		   opnum, RELOAD_OTHER);
118118334Speter    }
118218334Speter
118318334Speter  /* If IN appears in OUT, we can't share any input-only reload for IN.  */
118418334Speter  if (in != 0 && out != 0 && GET_CODE (out) == MEM
118518334Speter      && (GET_CODE (in) == REG || GET_CODE (in) == MEM)
118618334Speter      && reg_overlap_mentioned_for_reload_p (in, XEXP (out, 0)))
118718334Speter    dont_share = 1;
118818334Speter
118918334Speter  /* If IN is a SUBREG of a hard register, make a new REG.  This
119018334Speter     simplifies some of the cases below.  */
119118334Speter
119218334Speter  if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
119318334Speter      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
119418334Speter      && ! dont_remove_subreg)
119550605Sobrien    in = gen_rtx_REG (GET_MODE (in),
119650605Sobrien		      REGNO (SUBREG_REG (in)) + SUBREG_WORD (in));
119718334Speter
119818334Speter  /* Similarly for OUT.  */
119918334Speter  if (out != 0 && GET_CODE (out) == SUBREG
120018334Speter      && GET_CODE (SUBREG_REG (out)) == REG
120118334Speter      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
120218334Speter      && ! dont_remove_subreg)
120350605Sobrien    out = gen_rtx_REG (GET_MODE (out),
120450605Sobrien		       REGNO (SUBREG_REG (out)) + SUBREG_WORD (out));
120518334Speter
120618334Speter  /* Narrow down the class of register wanted if that is
120718334Speter     desirable on this machine for efficiency.  */
120818334Speter  if (in != 0)
120918334Speter    class = PREFERRED_RELOAD_CLASS (in, class);
121018334Speter
121118334Speter  /* Output reloads may need analogous treatment, different in detail.  */
121218334Speter#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
121318334Speter  if (out != 0)
121418334Speter    class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class);
121518334Speter#endif
121618334Speter
121718334Speter  /* Make sure we use a class that can handle the actual pseudo
121818334Speter     inside any subreg.  For example, on the 386, QImode regs
121918334Speter     can appear within SImode subregs.  Although GENERAL_REGS
122018334Speter     can handle SImode, QImode needs a smaller class.  */
122118334Speter#ifdef LIMIT_RELOAD_CLASS
122218334Speter  if (in_subreg_loc)
122318334Speter    class = LIMIT_RELOAD_CLASS (inmode, class);
122418334Speter  else if (in != 0 && GET_CODE (in) == SUBREG)
122518334Speter    class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), class);
122618334Speter
122718334Speter  if (out_subreg_loc)
122818334Speter    class = LIMIT_RELOAD_CLASS (outmode, class);
122918334Speter  if (out != 0 && GET_CODE (out) == SUBREG)
123018334Speter    class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), class);
123118334Speter#endif
123218334Speter
123318334Speter  /* Verify that this class is at least possible for the mode that
123418334Speter     is specified.  */
123518334Speter  if (this_insn_is_asm)
123618334Speter    {
123718334Speter      enum machine_mode mode;
123818334Speter      if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
123918334Speter	mode = inmode;
124018334Speter      else
124118334Speter	mode = outmode;
124218334Speter      if (mode == VOIDmode)
124318334Speter	{
124418334Speter	  error_for_asm (this_insn, "cannot reload integer constant operand in `asm'");
124518334Speter	  mode = word_mode;
124618334Speter	  if (in != 0)
124718334Speter	    inmode = word_mode;
124818334Speter	  if (out != 0)
124918334Speter	    outmode = word_mode;
125018334Speter	}
125118334Speter      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
125218334Speter	if (HARD_REGNO_MODE_OK (i, mode)
125318334Speter	    && TEST_HARD_REG_BIT (reg_class_contents[(int) class], i))
125418334Speter	  {
125518334Speter	    int nregs = HARD_REGNO_NREGS (i, mode);
125618334Speter
125718334Speter	    int j;
125818334Speter	    for (j = 1; j < nregs; j++)
125918334Speter	      if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class], i + j))
126018334Speter		break;
126118334Speter	    if (j == nregs)
126218334Speter	      break;
126318334Speter	  }
126418334Speter      if (i == FIRST_PSEUDO_REGISTER)
126518334Speter	{
126618334Speter	  error_for_asm (this_insn, "impossible register constraint in `asm'");
126718334Speter	  class = ALL_REGS;
126818334Speter	}
126918334Speter    }
127018334Speter
127152557Sobrien  /* Optional output reloads are always OK even if we have no register class,
127252557Sobrien     since the function of these reloads is only to have spill_reg_store etc.
127352557Sobrien     set, so that the storing insn can be deleted later.  */
127452557Sobrien  if (class == NO_REGS
127552557Sobrien      && (optional == 0 || type != RELOAD_FOR_OUTPUT))
127618334Speter    abort ();
127718334Speter
127852557Sobrien  i = find_reusable_reload (&in, out, class, type, opnum, dont_share);
127918334Speter
128018334Speter  if (i == n_reloads)
128118334Speter    {
128218334Speter      /* See if we need a secondary reload register to move between CLASS
128318334Speter	 and IN or CLASS and OUT.  Get the icode and push any required reloads
128418334Speter	 needed for each of them if so.  */
128518334Speter
128618334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
128718334Speter      if (in != 0)
128818334Speter	secondary_in_reload
128918334Speter	  = push_secondary_reload (1, in, opnum, optional, class, inmode, type,
129018334Speter				   &secondary_in_icode);
129118334Speter#endif
129218334Speter
129318334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
129418334Speter      if (out != 0 && GET_CODE (out) != SCRATCH)
129518334Speter	secondary_out_reload
129618334Speter	  = push_secondary_reload (0, out, opnum, optional, class, outmode,
129718334Speter				   type, &secondary_out_icode);
129818334Speter#endif
129918334Speter
130018334Speter      /* We found no existing reload suitable for re-use.
130118334Speter	 So add an additional reload.  */
130218334Speter
130350605Sobrien#ifdef SECONDARY_MEMORY_NEEDED
130450605Sobrien      /* If a memory location is needed for the copy, make one.  */
130550605Sobrien      if (in != 0 && GET_CODE (in) == REG
130650605Sobrien	  && REGNO (in) < FIRST_PSEUDO_REGISTER
130750605Sobrien	  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
130850605Sobrien				     class, inmode))
130950605Sobrien	get_secondary_mem (in, inmode, opnum, type);
131050605Sobrien#endif
131150605Sobrien
131218334Speter      i = n_reloads;
131318334Speter      reload_in[i] = in;
131418334Speter      reload_out[i] = out;
131518334Speter      reload_reg_class[i] = class;
131618334Speter      reload_inmode[i] = inmode;
131718334Speter      reload_outmode[i] = outmode;
131818334Speter      reload_reg_rtx[i] = 0;
131918334Speter      reload_optional[i] = optional;
132050605Sobrien      reload_nongroup[i] = 0;
132118334Speter      reload_inc[i] = 0;
132218334Speter      reload_nocombine[i] = 0;
132318334Speter      reload_in_reg[i] = inloc ? *inloc : 0;
132452557Sobrien      reload_out_reg[i] = outloc ? *outloc : 0;
132518334Speter      reload_opnum[i] = opnum;
132618334Speter      reload_when_needed[i] = type;
132718334Speter      reload_secondary_in_reload[i] = secondary_in_reload;
132818334Speter      reload_secondary_out_reload[i] = secondary_out_reload;
132918334Speter      reload_secondary_in_icode[i] = secondary_in_icode;
133018334Speter      reload_secondary_out_icode[i] = secondary_out_icode;
133118334Speter      reload_secondary_p[i] = 0;
133218334Speter
133318334Speter      n_reloads++;
133418334Speter
133518334Speter#ifdef SECONDARY_MEMORY_NEEDED
133618334Speter      if (out != 0 && GET_CODE (out) == REG
133718334Speter	  && REGNO (out) < FIRST_PSEUDO_REGISTER
133818334Speter	  && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (REGNO (out)),
133918334Speter				      outmode))
134018334Speter	get_secondary_mem (out, outmode, opnum, type);
134118334Speter#endif
134218334Speter    }
134318334Speter  else
134418334Speter    {
134518334Speter      /* We are reusing an existing reload,
134618334Speter	 but we may have additional information for it.
134718334Speter	 For example, we may now have both IN and OUT
134818334Speter	 while the old one may have just one of them.  */
134918334Speter
135050605Sobrien      /* The modes can be different.  If they are, we want to reload in
135150605Sobrien	 the larger mode, so that the value is valid for both modes.  */
135250605Sobrien      if (inmode != VOIDmode
135350605Sobrien	  && GET_MODE_SIZE (inmode) > GET_MODE_SIZE (reload_inmode[i]))
135418334Speter	reload_inmode[i] = inmode;
135550605Sobrien      if (outmode != VOIDmode
135650605Sobrien	  && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (reload_outmode[i]))
135718334Speter	reload_outmode[i] = outmode;
135818334Speter      if (in != 0)
135952557Sobrien	{
136052557Sobrien	  rtx in_reg = inloc ? *inloc : 0;
136152557Sobrien	  /* If we merge reloads for two distinct rtl expressions that
136252557Sobrien	     are identical in content, there might be duplicate address
136352557Sobrien	     reloads.  Remove the extra set now, so that if we later find
136452557Sobrien	     that we can inherit this reload, we can get rid of the
136552557Sobrien	     address reloads altogether.
136652557Sobrien
136752557Sobrien	     Do not do this if both reloads are optional since the result
136852557Sobrien	     would be an optional reload which could potentially leave
136952557Sobrien	     unresolved address replacements.
137052557Sobrien
137152557Sobrien	     It is not sufficient to call transfer_replacements since
137252557Sobrien	     choose_reload_regs will remove the replacements for address
137352557Sobrien	     reloads of inherited reloads which results in the same
137452557Sobrien	     problem.  */
137552557Sobrien	  if (reload_in[i] != in && rtx_equal_p (in, reload_in[i])
137652557Sobrien	      && ! (reload_optional[i] && optional))
137752557Sobrien	    {
137852557Sobrien	      /* We must keep the address reload with the lower operand
137952557Sobrien		 number alive.  */
138052557Sobrien	      if (opnum > reload_opnum[i])
138152557Sobrien		{
138252557Sobrien		  remove_address_replacements (in);
138352557Sobrien		  in = reload_in[i];
138452557Sobrien		  in_reg = reload_in_reg[i];
138552557Sobrien		}
138652557Sobrien	      else
138752557Sobrien		remove_address_replacements (reload_in[i]);
138852557Sobrien	    }
138952557Sobrien	  reload_in[i] = in;
139052557Sobrien	  reload_in_reg[i] = in_reg;
139152557Sobrien	}
139218334Speter      if (out != 0)
139352557Sobrien	{
139452557Sobrien	  reload_out[i] = out;
139552557Sobrien	  reload_out_reg[i] = outloc ? *outloc : 0;
139652557Sobrien	}
139718334Speter      if (reg_class_subset_p (class, reload_reg_class[i]))
139818334Speter	reload_reg_class[i] = class;
139918334Speter      reload_optional[i] &= optional;
140018334Speter      if (MERGE_TO_OTHER (type, reload_when_needed[i],
140118334Speter			  opnum, reload_opnum[i]))
140218334Speter	reload_when_needed[i] = RELOAD_OTHER;
140318334Speter      reload_opnum[i] = MIN (reload_opnum[i], opnum);
140418334Speter    }
140518334Speter
140618334Speter  /* If the ostensible rtx being reload differs from the rtx found
140718334Speter     in the location to substitute, this reload is not safe to combine
140818334Speter     because we cannot reliably tell whether it appears in the insn.  */
140918334Speter
141018334Speter  if (in != 0 && in != *inloc)
141118334Speter    reload_nocombine[i] = 1;
141218334Speter
141318334Speter#if 0
141418334Speter  /* This was replaced by changes in find_reloads_address_1 and the new
141518334Speter     function inc_for_reload, which go with a new meaning of reload_inc.  */
141618334Speter
141718334Speter  /* If this is an IN/OUT reload in an insn that sets the CC,
141818334Speter     it must be for an autoincrement.  It doesn't work to store
141918334Speter     the incremented value after the insn because that would clobber the CC.
142018334Speter     So we must do the increment of the value reloaded from,
142118334Speter     increment it, store it back, then decrement again.  */
142218334Speter  if (out != 0 && sets_cc0_p (PATTERN (this_insn)))
142318334Speter    {
142418334Speter      out = 0;
142518334Speter      reload_out[i] = 0;
142618334Speter      reload_inc[i] = find_inc_amount (PATTERN (this_insn), in);
142718334Speter      /* If we did not find a nonzero amount-to-increment-by,
142818334Speter	 that contradicts the belief that IN is being incremented
142918334Speter	 in an address in this insn.  */
143018334Speter      if (reload_inc[i] == 0)
143118334Speter	abort ();
143218334Speter    }
143318334Speter#endif
143418334Speter
143518334Speter  /* If we will replace IN and OUT with the reload-reg,
143618334Speter     record where they are located so that substitution need
143718334Speter     not do a tree walk.  */
143818334Speter
143918334Speter  if (replace_reloads)
144018334Speter    {
144118334Speter      if (inloc != 0)
144218334Speter	{
144318334Speter	  register struct replacement *r = &replacements[n_replacements++];
144418334Speter	  r->what = i;
144518334Speter	  r->subreg_loc = in_subreg_loc;
144618334Speter	  r->where = inloc;
144718334Speter	  r->mode = inmode;
144818334Speter	}
144918334Speter      if (outloc != 0 && outloc != inloc)
145018334Speter	{
145118334Speter	  register struct replacement *r = &replacements[n_replacements++];
145218334Speter	  r->what = i;
145318334Speter	  r->where = outloc;
145418334Speter	  r->subreg_loc = out_subreg_loc;
145518334Speter	  r->mode = outmode;
145618334Speter	}
145718334Speter    }
145818334Speter
145918334Speter  /* If this reload is just being introduced and it has both
146018334Speter     an incoming quantity and an outgoing quantity that are
146118334Speter     supposed to be made to match, see if either one of the two
146218334Speter     can serve as the place to reload into.
146318334Speter
146418334Speter     If one of them is acceptable, set reload_reg_rtx[i]
146518334Speter     to that one.  */
146618334Speter
146718334Speter  if (in != 0 && out != 0 && in != out && reload_reg_rtx[i] == 0)
146818334Speter    {
146918334Speter      reload_reg_rtx[i] = find_dummy_reload (in, out, inloc, outloc,
147018334Speter					     inmode, outmode,
147150605Sobrien					     reload_reg_class[i], i,
147250605Sobrien					     earlyclobber_operand_p (out));
147318334Speter
147418334Speter      /* If the outgoing register already contains the same value
147518334Speter	 as the incoming one, we can dispense with loading it.
147618334Speter	 The easiest way to tell the caller that is to give a phony
147718334Speter	 value for the incoming operand (same as outgoing one).  */
147818334Speter      if (reload_reg_rtx[i] == out
147918334Speter	  && (GET_CODE (in) == REG || CONSTANT_P (in))
148018334Speter	  && 0 != find_equiv_reg (in, this_insn, 0, REGNO (out),
148118334Speter				  static_reload_reg_p, i, inmode))
148218334Speter	reload_in[i] = out;
148318334Speter    }
148418334Speter
148518334Speter  /* If this is an input reload and the operand contains a register that
148618334Speter     dies in this insn and is used nowhere else, see if it is the right class
148718334Speter     to be used for this reload.  Use it if so.  (This occurs most commonly
148818334Speter     in the case of paradoxical SUBREGs and in-out reloads).  We cannot do
148918334Speter     this if it is also an output reload that mentions the register unless
149018334Speter     the output is a SUBREG that clobbers an entire register.
149118334Speter
149218334Speter     Note that the operand might be one of the spill regs, if it is a
149318334Speter     pseudo reg and we are in a block where spilling has not taken place.
149418334Speter     But if there is no spilling in this block, that is OK.
149518334Speter     An explicitly used hard reg cannot be a spill reg.  */
149618334Speter
149718334Speter  if (reload_reg_rtx[i] == 0 && in != 0)
149818334Speter    {
149918334Speter      rtx note;
150018334Speter      int regno;
150118334Speter
150218334Speter      for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
150318334Speter	if (REG_NOTE_KIND (note) == REG_DEAD
150418334Speter	    && GET_CODE (XEXP (note, 0)) == REG
150518334Speter	    && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
150618334Speter	    && reg_mentioned_p (XEXP (note, 0), in)
150718334Speter	    && ! refers_to_regno_for_reload_p (regno,
150818334Speter					       (regno
150918334Speter						+ HARD_REGNO_NREGS (regno,
151018334Speter								    inmode)),
151118334Speter					       PATTERN (this_insn), inloc)
151218334Speter	    /* If this is also an output reload, IN cannot be used as
151318334Speter	       the reload register if it is set in this insn unless IN
151418334Speter	       is also OUT.  */
151518334Speter	    && (out == 0 || in == out
151618334Speter		|| ! hard_reg_set_here_p (regno,
151718334Speter					  (regno
151818334Speter					   + HARD_REGNO_NREGS (regno,
151918334Speter							       inmode)),
152018334Speter					  PATTERN (this_insn)))
152118334Speter	    /* ??? Why is this code so different from the previous?
152218334Speter	       Is there any simple coherent way to describe the two together?
152318334Speter	       What's going on here.  */
152418334Speter	    && (in != out
152518334Speter		|| (GET_CODE (in) == SUBREG
152618334Speter		    && (((GET_MODE_SIZE (GET_MODE (in)) + (UNITS_PER_WORD - 1))
152718334Speter			 / UNITS_PER_WORD)
152818334Speter			== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
152918334Speter			     + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
153018334Speter	    /* Make sure the operand fits in the reg that dies.  */
153118334Speter	    && GET_MODE_SIZE (inmode) <= GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
153218334Speter	    && HARD_REGNO_MODE_OK (regno, inmode)
153318334Speter	    && GET_MODE_SIZE (outmode) <= GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
153418334Speter	    && HARD_REGNO_MODE_OK (regno, outmode)
153518334Speter	    && TEST_HARD_REG_BIT (reg_class_contents[(int) class], regno)
153618334Speter	    && !fixed_regs[regno])
153718334Speter	  {
153850605Sobrien	    reload_reg_rtx[i] = gen_rtx_REG (inmode, regno);
153918334Speter	    break;
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    {
156318334Speter      register 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
159752557Sobrien  bzero (reload_flags, 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);
161652557Sobrien	  remove_address_replacements (reload_in[i]);
161752557Sobrien	  reload_in[i] = 0;
161852557Sobrien	  something_changed = 1;
161952557Sobrien	}
162052557Sobrien    }
162152557Sobrien  return something_changed;
162250605Sobrien}
162352557Sobrien
162452557Sobrien/* Return non-zero if IN contains a piece of rtl that has the address LOC */
162552557Sobrienstatic int
162652557Sobrienloc_mentioned_in_p (loc, in)
162752557Sobrien     rtx *loc, in;
162852557Sobrien{
162952557Sobrien  enum rtx_code code = GET_CODE (in);
163052557Sobrien  char *fmt = GET_RTX_FORMAT (code);
163152557Sobrien  int i, j;
163252557Sobrien
163352557Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
163452557Sobrien    {
163552557Sobrien      if (loc == &XEXP (in, i))
163652557Sobrien	return 1;
163752557Sobrien      if (fmt[i] == 'e')
163852557Sobrien        {
163952557Sobrien	  if (loc_mentioned_in_p (loc, XEXP (in, i)))
164052557Sobrien	    return 1;
164152557Sobrien        }
164252557Sobrien      else if (fmt[i] == 'E')
164352557Sobrien	for (j = XVECLEN (in, i) - 1; i >= 0; i--)
164452557Sobrien	  if (loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
164552557Sobrien	    return 1;
164652557Sobrien    }
164752557Sobrien  return 0;
164852557Sobrien}
164950605Sobrien
165018334Speter/* If there is only one output reload, and it is not for an earlyclobber
165118334Speter   operand, try to combine it with a (logically unrelated) input reload
165218334Speter   to reduce the number of reload registers needed.
165318334Speter
165418334Speter   This is safe if the input reload does not appear in
165518334Speter   the value being output-reloaded, because this implies
165618334Speter   it is not needed any more once the original insn completes.
165718334Speter
165818334Speter   If that doesn't work, see we can use any of the registers that
165918334Speter   die in this insn as a reload register.  We can if it is of the right
166018334Speter   class and does not appear in the value being output-reloaded.  */
166118334Speter
166218334Speterstatic void
166318334Spetercombine_reloads ()
166418334Speter{
166518334Speter  int i;
166618334Speter  int output_reload = -1;
166718334Speter  int secondary_out = -1;
166818334Speter  rtx note;
166918334Speter
167018334Speter  /* Find the output reload; return unless there is exactly one
167118334Speter     and that one is mandatory.  */
167218334Speter
167318334Speter  for (i = 0; i < n_reloads; i++)
167418334Speter    if (reload_out[i] != 0)
167518334Speter      {
167618334Speter	if (output_reload >= 0)
167718334Speter	  return;
167818334Speter	output_reload = i;
167918334Speter      }
168018334Speter
168118334Speter  if (output_reload < 0 || reload_optional[output_reload])
168218334Speter    return;
168318334Speter
168418334Speter  /* An input-output reload isn't combinable.  */
168518334Speter
168618334Speter  if (reload_in[output_reload] != 0)
168718334Speter    return;
168818334Speter
168918334Speter  /* If this reload is for an earlyclobber operand, we can't do anything.  */
169018334Speter  if (earlyclobber_operand_p (reload_out[output_reload]))
169118334Speter    return;
169218334Speter
169318334Speter  /* Check each input reload; can we combine it?  */
169418334Speter
169518334Speter  for (i = 0; i < n_reloads; i++)
169618334Speter    if (reload_in[i] && ! reload_optional[i] && ! reload_nocombine[i]
169718334Speter	/* Life span of this reload must not extend past main insn.  */
169818334Speter	&& reload_when_needed[i] != RELOAD_FOR_OUTPUT_ADDRESS
169950605Sobrien	&& reload_when_needed[i] != RELOAD_FOR_OUTADDR_ADDRESS
170018334Speter	&& reload_when_needed[i] != RELOAD_OTHER
170118334Speter	&& (CLASS_MAX_NREGS (reload_reg_class[i], reload_inmode[i])
170218334Speter	    == CLASS_MAX_NREGS (reload_reg_class[output_reload],
170318334Speter				reload_outmode[output_reload]))
170418334Speter	&& reload_inc[i] == 0
170518334Speter	&& reload_reg_rtx[i] == 0
170618334Speter#ifdef SECONDARY_MEMORY_NEEDED
170718334Speter	/* Don't combine two reloads with different secondary
170818334Speter	   memory locations.  */
170918334Speter	&& (secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[i]] == 0
171018334Speter	    || secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[output_reload]] == 0
171118334Speter	    || rtx_equal_p (secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[i]],
171218334Speter			    secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[output_reload]]))
171318334Speter#endif
171450605Sobrien	&& (SMALL_REGISTER_CLASSES
171550605Sobrien	    ? (reload_reg_class[i] == reload_reg_class[output_reload])
171650605Sobrien	    : (reg_class_subset_p (reload_reg_class[i],
171750605Sobrien				   reload_reg_class[output_reload])
171850605Sobrien	       || reg_class_subset_p (reload_reg_class[output_reload],
171950605Sobrien				      reload_reg_class[i])))
172018334Speter	&& (MATCHES (reload_in[i], reload_out[output_reload])
172118334Speter	    /* Args reversed because the first arg seems to be
172218334Speter	       the one that we imagine being modified
172318334Speter	       while the second is the one that might be affected.  */
172418334Speter	    || (! reg_overlap_mentioned_for_reload_p (reload_out[output_reload],
172518334Speter						      reload_in[i])
172618334Speter		/* However, if the input is a register that appears inside
172718334Speter		   the output, then we also can't share.
172818334Speter		   Imagine (set (mem (reg 69)) (plus (reg 69) ...)).
172918334Speter		   If the same reload reg is used for both reg 69 and the
173018334Speter		   result to be stored in memory, then that result
173118334Speter		   will clobber the address of the memory ref.  */
173218334Speter		&& ! (GET_CODE (reload_in[i]) == REG
173318334Speter		      && reg_overlap_mentioned_for_reload_p (reload_in[i],
173418334Speter							     reload_out[output_reload]))))
173518334Speter	&& (reg_class_size[(int) reload_reg_class[i]]
173650605Sobrien	    || SMALL_REGISTER_CLASSES)
173718334Speter	/* We will allow making things slightly worse by combining an
173818334Speter	   input and an output, but no worse than that.  */
173918334Speter	&& (reload_when_needed[i] == RELOAD_FOR_INPUT
174018334Speter	    || reload_when_needed[i] == RELOAD_FOR_OUTPUT))
174118334Speter      {
174218334Speter	int j;
174318334Speter
174418334Speter	/* We have found a reload to combine with!  */
174518334Speter	reload_out[i] = reload_out[output_reload];
174652557Sobrien	reload_out_reg[i] = reload_out_reg[output_reload];
174718334Speter	reload_outmode[i] = reload_outmode[output_reload];
174818334Speter	/* Mark the old output reload as inoperative.  */
174918334Speter	reload_out[output_reload] = 0;
175018334Speter	/* The combined reload is needed for the entire insn.  */
175118334Speter	reload_when_needed[i] = RELOAD_OTHER;
175250605Sobrien	/* If the output reload had a secondary reload, copy it.  */
175318334Speter	if (reload_secondary_out_reload[output_reload] != -1)
175418334Speter	  {
175518334Speter	    reload_secondary_out_reload[i]
175618334Speter	      = reload_secondary_out_reload[output_reload];
175718334Speter	    reload_secondary_out_icode[i]
175818334Speter	      = reload_secondary_out_icode[output_reload];
175918334Speter	  }
176018334Speter
176118334Speter#ifdef SECONDARY_MEMORY_NEEDED
176218334Speter	/* Copy any secondary MEM.  */
176318334Speter	if (secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[output_reload]] != 0)
176418334Speter	  secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[i]]
176518334Speter	    = secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[output_reload]];
176618334Speter#endif
176750605Sobrien	/* If required, minimize the register class.  */
176818334Speter	if (reg_class_subset_p (reload_reg_class[output_reload],
176918334Speter				reload_reg_class[i]))
177018334Speter	  reload_reg_class[i] = reload_reg_class[output_reload];
177118334Speter
177218334Speter	/* Transfer all replacements from the old reload to the combined.  */
177318334Speter	for (j = 0; j < n_replacements; j++)
177418334Speter	  if (replacements[j].what == output_reload)
177518334Speter	    replacements[j].what = i;
177618334Speter
177718334Speter	return;
177818334Speter      }
177918334Speter
178018334Speter  /* If this insn has only one operand that is modified or written (assumed
178118334Speter     to be the first),  it must be the one corresponding to this reload.  It
178218334Speter     is safe to use anything that dies in this insn for that output provided
178318334Speter     that it does not occur in the output (we already know it isn't an
178418334Speter     earlyclobber.  If this is an asm insn, give up.  */
178518334Speter
178618334Speter  if (INSN_CODE (this_insn) == -1)
178718334Speter    return;
178818334Speter
178918334Speter  for (i = 1; i < insn_n_operands[INSN_CODE (this_insn)]; i++)
179018334Speter    if (insn_operand_constraint[INSN_CODE (this_insn)][i][0] == '='
179118334Speter	|| insn_operand_constraint[INSN_CODE (this_insn)][i][0] == '+')
179218334Speter      return;
179318334Speter
179418334Speter  /* See if some hard register that dies in this insn and is not used in
179518334Speter     the output is the right class.  Only works if the register we pick
179618334Speter     up can fully hold our output reload.  */
179718334Speter  for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
179818334Speter    if (REG_NOTE_KIND (note) == REG_DEAD
179918334Speter	&& GET_CODE (XEXP (note, 0)) == REG
180018334Speter	&& ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
180118334Speter						 reload_out[output_reload])
180218334Speter	&& REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
180318334Speter	&& HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), reload_outmode[output_reload])
180418334Speter	&& TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[output_reload]],
180518334Speter			      REGNO (XEXP (note, 0)))
180618334Speter	&& (HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), reload_outmode[output_reload])
180718334Speter	    <= HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), GET_MODE (XEXP (note, 0))))
180818334Speter	/* Ensure that a secondary or tertiary reload for this output
180918334Speter	   won't want this register.  */
181018334Speter        && ((secondary_out = reload_secondary_out_reload[output_reload]) == -1
181118334Speter            || (! (TEST_HARD_REG_BIT
181218334Speter		    (reg_class_contents[(int) reload_reg_class[secondary_out]],
181318334Speter		     REGNO (XEXP (note, 0))))
181418334Speter		&& ((secondary_out = reload_secondary_out_reload[secondary_out]) == -1
181518334Speter		    ||  ! (TEST_HARD_REG_BIT
181618334Speter			   (reg_class_contents[(int) reload_reg_class[secondary_out]],
181718334Speter			    REGNO (XEXP (note, 0)))))))
181818334Speter	&& ! fixed_regs[REGNO (XEXP (note, 0))])
181918334Speter      {
182050605Sobrien	reload_reg_rtx[output_reload]
182150605Sobrien	  = gen_rtx_REG (reload_outmode[output_reload],
182250605Sobrien			 REGNO (XEXP (note, 0)));
182318334Speter	return;
182418334Speter      }
182518334Speter}
182618334Speter
182718334Speter/* Try to find a reload register for an in-out reload (expressions IN and OUT).
182818334Speter   See if one of IN and OUT is a register that may be used;
182918334Speter   this is desirable since a spill-register won't be needed.
183018334Speter   If so, return the register rtx that proves acceptable.
183118334Speter
183218334Speter   INLOC and OUTLOC are locations where IN and OUT appear in the insn.
183318334Speter   CLASS is the register class required for the reload.
183418334Speter
183518334Speter   If FOR_REAL is >= 0, it is the number of the reload,
183618334Speter   and in some cases when it can be discovered that OUT doesn't need
183718334Speter   to be computed, clear out reload_out[FOR_REAL].
183818334Speter
183918334Speter   If FOR_REAL is -1, this should not be done, because this call
184050605Sobrien   is just to see if a register can be found, not to find and install it.
184118334Speter
184250605Sobrien   EARLYCLOBBER is non-zero if OUT is an earlyclobber operand.  This
184350605Sobrien   puts an additional constraint on being able to use IN for OUT since
184450605Sobrien   IN must not appear elsewhere in the insn (it is assumed that IN itself
184550605Sobrien   is safe from the earlyclobber).  */
184650605Sobrien
184718334Speterstatic rtx
184818334Speterfind_dummy_reload (real_in, real_out, inloc, outloc,
184950605Sobrien		   inmode, outmode, class, for_real, earlyclobber)
185018334Speter     rtx real_in, real_out;
185118334Speter     rtx *inloc, *outloc;
185218334Speter     enum machine_mode inmode, outmode;
185318334Speter     enum reg_class class;
185418334Speter     int for_real;
185550605Sobrien     int earlyclobber;
185618334Speter{
185718334Speter  rtx in = real_in;
185818334Speter  rtx out = real_out;
185918334Speter  int in_offset = 0;
186018334Speter  int out_offset = 0;
186118334Speter  rtx value = 0;
186218334Speter
186318334Speter  /* If operands exceed a word, we can't use either of them
186418334Speter     unless they have the same size.  */
186518334Speter  if (GET_MODE_SIZE (outmode) != GET_MODE_SIZE (inmode)
186618334Speter      && (GET_MODE_SIZE (outmode) > UNITS_PER_WORD
186718334Speter	  || GET_MODE_SIZE (inmode) > UNITS_PER_WORD))
186818334Speter    return 0;
186918334Speter
187018334Speter  /* Find the inside of any subregs.  */
187118334Speter  while (GET_CODE (out) == SUBREG)
187218334Speter    {
187318334Speter      out_offset = SUBREG_WORD (out);
187418334Speter      out = SUBREG_REG (out);
187518334Speter    }
187618334Speter  while (GET_CODE (in) == SUBREG)
187718334Speter    {
187818334Speter      in_offset = SUBREG_WORD (in);
187918334Speter      in = SUBREG_REG (in);
188018334Speter    }
188118334Speter
188218334Speter  /* Narrow down the reg class, the same way push_reload will;
188318334Speter     otherwise we might find a dummy now, but push_reload won't.  */
188418334Speter  class = PREFERRED_RELOAD_CLASS (in, class);
188518334Speter
188618334Speter  /* See if OUT will do.  */
188718334Speter  if (GET_CODE (out) == REG
188818334Speter      && REGNO (out) < FIRST_PSEUDO_REGISTER)
188918334Speter    {
189018334Speter      register int regno = REGNO (out) + out_offset;
189118334Speter      int nwords = HARD_REGNO_NREGS (regno, outmode);
189218334Speter      rtx saved_rtx;
189318334Speter
189418334Speter      /* When we consider whether the insn uses OUT,
189518334Speter	 ignore references within IN.  They don't prevent us
189618334Speter	 from copying IN into OUT, because those refs would
189718334Speter	 move into the insn that reloads IN.
189818334Speter
189918334Speter	 However, we only ignore IN in its role as this reload.
190018334Speter	 If the insn uses IN elsewhere and it contains OUT,
190118334Speter	 that counts.  We can't be sure it's the "same" operand
190218334Speter	 so it might not go through this reload.  */
190318334Speter      saved_rtx = *inloc;
190418334Speter      *inloc = const0_rtx;
190518334Speter
190618334Speter      if (regno < FIRST_PSEUDO_REGISTER
190718334Speter	  /* A fixed reg that can overlap other regs better not be used
190818334Speter	     for reloading in any way.  */
190918334Speter#ifdef OVERLAPPING_REGNO_P
191018334Speter	  && ! (fixed_regs[regno] && OVERLAPPING_REGNO_P (regno))
191118334Speter#endif
191218334Speter	  && ! refers_to_regno_for_reload_p (regno, regno + nwords,
191318334Speter					     PATTERN (this_insn), outloc))
191418334Speter	{
191518334Speter	  int i;
191618334Speter	  for (i = 0; i < nwords; i++)
191718334Speter	    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
191818334Speter				     regno + i))
191918334Speter	      break;
192018334Speter
192118334Speter	  if (i == nwords)
192218334Speter	    {
192318334Speter	      if (GET_CODE (real_out) == REG)
192418334Speter		value = real_out;
192518334Speter	      else
192650605Sobrien		value = gen_rtx_REG (outmode, regno);
192718334Speter	    }
192818334Speter	}
192918334Speter
193018334Speter      *inloc = saved_rtx;
193118334Speter    }
193218334Speter
193318334Speter  /* Consider using IN if OUT was not acceptable
193418334Speter     or if OUT dies in this insn (like the quotient in a divmod insn).
193518334Speter     We can't use IN unless it is dies in this insn,
193618334Speter     which means we must know accurately which hard regs are live.
193750605Sobrien     Also, the result can't go in IN if IN is used within OUT,
193850605Sobrien     or if OUT is an earlyclobber and IN appears elsewhere in the insn.  */
193918334Speter  if (hard_regs_live_known
194018334Speter      && GET_CODE (in) == REG
194118334Speter      && REGNO (in) < FIRST_PSEUDO_REGISTER
194218334Speter      && (value == 0
194318334Speter	  || find_reg_note (this_insn, REG_UNUSED, real_out))
194418334Speter      && find_reg_note (this_insn, REG_DEAD, real_in)
194518334Speter      && !fixed_regs[REGNO (in)]
194618334Speter      && HARD_REGNO_MODE_OK (REGNO (in),
194718334Speter			     /* The only case where out and real_out might
194818334Speter				have different modes is where real_out
194918334Speter				is a subreg, and in that case, out
195018334Speter				has a real mode.  */
195118334Speter			     (GET_MODE (out) != VOIDmode
195218334Speter			      ? GET_MODE (out) : outmode)))
195318334Speter    {
195418334Speter      register int regno = REGNO (in) + in_offset;
195518334Speter      int nwords = HARD_REGNO_NREGS (regno, inmode);
195618334Speter
195718334Speter      if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, NULL_PTR)
195818334Speter	  && ! hard_reg_set_here_p (regno, regno + nwords,
195950605Sobrien				    PATTERN (this_insn))
196050605Sobrien	  && (! earlyclobber
196150605Sobrien	      || ! refers_to_regno_for_reload_p (regno, regno + nwords,
196250605Sobrien						 PATTERN (this_insn), inloc)))
196318334Speter	{
196418334Speter	  int i;
196518334Speter	  for (i = 0; i < nwords; i++)
196618334Speter	    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
196718334Speter				     regno + i))
196818334Speter	      break;
196918334Speter
197018334Speter	  if (i == nwords)
197118334Speter	    {
197218334Speter	      /* If we were going to use OUT as the reload reg
197318334Speter		 and changed our mind, it means OUT is a dummy that
197418334Speter		 dies here.  So don't bother copying value to it.  */
197518334Speter	      if (for_real >= 0 && value == real_out)
197618334Speter		reload_out[for_real] = 0;
197718334Speter	      if (GET_CODE (real_in) == REG)
197818334Speter		value = real_in;
197918334Speter	      else
198050605Sobrien		value = gen_rtx_REG (inmode, regno);
198118334Speter	    }
198218334Speter	}
198318334Speter    }
198418334Speter
198518334Speter  return value;
198618334Speter}
198718334Speter
198818334Speter/* This page contains subroutines used mainly for determining
198918334Speter   whether the IN or an OUT of a reload can serve as the
199018334Speter   reload register.  */
199118334Speter
199218334Speter/* Return 1 if X is an operand of an insn that is being earlyclobbered.  */
199318334Speter
199418334Speterstatic int
199518334Speterearlyclobber_operand_p (x)
199618334Speter     rtx x;
199718334Speter{
199818334Speter  int i;
199918334Speter
200018334Speter  for (i = 0; i < n_earlyclobbers; i++)
200118334Speter    if (reload_earlyclobbers[i] == x)
200218334Speter      return 1;
200318334Speter
200418334Speter  return 0;
200518334Speter}
200618334Speter
200718334Speter/* Return 1 if expression X alters a hard reg in the range
200818334Speter   from BEG_REGNO (inclusive) to END_REGNO (exclusive),
200918334Speter   either explicitly or in the guise of a pseudo-reg allocated to REGNO.
201018334Speter   X should be the body of an instruction.  */
201118334Speter
201218334Speterstatic int
201318334Speterhard_reg_set_here_p (beg_regno, end_regno, x)
201418334Speter     register int beg_regno, end_regno;
201518334Speter     rtx x;
201618334Speter{
201718334Speter  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
201818334Speter    {
201918334Speter      register rtx op0 = SET_DEST (x);
202018334Speter      while (GET_CODE (op0) == SUBREG)
202118334Speter	op0 = SUBREG_REG (op0);
202218334Speter      if (GET_CODE (op0) == REG)
202318334Speter	{
202418334Speter	  register int r = REGNO (op0);
202518334Speter	  /* See if this reg overlaps range under consideration.  */
202618334Speter	  if (r < end_regno
202718334Speter	      && r + HARD_REGNO_NREGS (r, GET_MODE (op0)) > beg_regno)
202818334Speter	    return 1;
202918334Speter	}
203018334Speter    }
203118334Speter  else if (GET_CODE (x) == PARALLEL)
203218334Speter    {
203318334Speter      register int i = XVECLEN (x, 0) - 1;
203418334Speter      for (; i >= 0; i--)
203518334Speter	if (hard_reg_set_here_p (beg_regno, end_regno, XVECEXP (x, 0, i)))
203618334Speter	  return 1;
203718334Speter    }
203818334Speter
203918334Speter  return 0;
204018334Speter}
204118334Speter
204218334Speter/* Return 1 if ADDR is a valid memory address for mode MODE,
204318334Speter   and check that each pseudo reg has the proper kind of
204418334Speter   hard reg.  */
204518334Speter
204618334Speterint
204718334Speterstrict_memory_address_p (mode, addr)
204818334Speter     enum machine_mode mode;
204918334Speter     register rtx addr;
205018334Speter{
205118334Speter  GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
205218334Speter  return 0;
205318334Speter
205418334Speter win:
205518334Speter  return 1;
205618334Speter}
205718334Speter
205818334Speter/* Like rtx_equal_p except that it allows a REG and a SUBREG to match
205918334Speter   if they are the same hard reg, and has special hacks for
206018334Speter   autoincrement and autodecrement.
206118334Speter   This is specifically intended for find_reloads to use
206218334Speter   in determining whether two operands match.
206318334Speter   X is the operand whose number is the lower of the two.
206418334Speter
206518334Speter   The value is 2 if Y contains a pre-increment that matches
206618334Speter   a non-incrementing address in X.  */
206718334Speter
206818334Speter/* ??? To be completely correct, we should arrange to pass
206918334Speter   for X the output operand and for Y the input operand.
207018334Speter   For now, we assume that the output operand has the lower number
207118334Speter   because that is natural in (SET output (... input ...)).  */
207218334Speter
207318334Speterint
207418334Speteroperands_match_p (x, y)
207518334Speter     register rtx x, y;
207618334Speter{
207718334Speter  register int i;
207818334Speter  register RTX_CODE code = GET_CODE (x);
207918334Speter  register char *fmt;
208018334Speter  int success_2;
208118334Speter
208218334Speter  if (x == y)
208318334Speter    return 1;
208418334Speter  if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
208518334Speter      && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
208618334Speter				  && GET_CODE (SUBREG_REG (y)) == REG)))
208718334Speter    {
208818334Speter      register int j;
208918334Speter
209018334Speter      if (code == SUBREG)
209118334Speter	{
209218334Speter	  i = REGNO (SUBREG_REG (x));
209318334Speter	  if (i >= FIRST_PSEUDO_REGISTER)
209418334Speter	    goto slow;
209518334Speter	  i += SUBREG_WORD (x);
209618334Speter	}
209718334Speter      else
209818334Speter	i = REGNO (x);
209918334Speter
210018334Speter      if (GET_CODE (y) == SUBREG)
210118334Speter	{
210218334Speter	  j = REGNO (SUBREG_REG (y));
210318334Speter	  if (j >= FIRST_PSEUDO_REGISTER)
210418334Speter	    goto slow;
210518334Speter	  j += SUBREG_WORD (y);
210618334Speter	}
210718334Speter      else
210818334Speter	j = REGNO (y);
210918334Speter
211018334Speter      /* On a WORDS_BIG_ENDIAN machine, point to the last register of a
211118334Speter	 multiple hard register group, so that for example (reg:DI 0) and
211218334Speter	 (reg:SI 1) will be considered the same register.  */
211318334Speter      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
211418334Speter	  && i < FIRST_PSEUDO_REGISTER)
211518334Speter	i += (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD) - 1;
211618334Speter      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
211718334Speter	  && j < FIRST_PSEUDO_REGISTER)
211818334Speter	j += (GET_MODE_SIZE (GET_MODE (y)) / UNITS_PER_WORD) - 1;
211918334Speter
212018334Speter      return i == j;
212118334Speter    }
212218334Speter  /* If two operands must match, because they are really a single
212318334Speter     operand of an assembler insn, then two postincrements are invalid
212418334Speter     because the assembler insn would increment only once.
212518334Speter     On the other hand, an postincrement matches ordinary indexing
212618334Speter     if the postincrement is the output operand.  */
212718334Speter  if (code == POST_DEC || code == POST_INC)
212818334Speter    return operands_match_p (XEXP (x, 0), y);
212918334Speter  /* Two preincrements are invalid
213018334Speter     because the assembler insn would increment only once.
213118334Speter     On the other hand, an preincrement matches ordinary indexing
213218334Speter     if the preincrement is the input operand.
213318334Speter     In this case, return 2, since some callers need to do special
213418334Speter     things when this happens.  */
213518334Speter  if (GET_CODE (y) == PRE_DEC || GET_CODE (y) == PRE_INC)
213618334Speter    return operands_match_p (x, XEXP (y, 0)) ? 2 : 0;
213718334Speter
213818334Speter slow:
213918334Speter
214018334Speter  /* Now we have disposed of all the cases
214118334Speter     in which different rtx codes can match.  */
214218334Speter  if (code != GET_CODE (y))
214318334Speter    return 0;
214418334Speter  if (code == LABEL_REF)
214518334Speter    return XEXP (x, 0) == XEXP (y, 0);
214618334Speter  if (code == SYMBOL_REF)
214718334Speter    return XSTR (x, 0) == XSTR (y, 0);
214818334Speter
214918334Speter  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
215018334Speter
215118334Speter  if (GET_MODE (x) != GET_MODE (y))
215218334Speter    return 0;
215318334Speter
215418334Speter  /* Compare the elements.  If any pair of corresponding elements
215518334Speter     fail to match, return 0 for the whole things.  */
215618334Speter
215718334Speter  success_2 = 0;
215818334Speter  fmt = GET_RTX_FORMAT (code);
215918334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
216018334Speter    {
216152557Sobrien      int val, j;
216218334Speter      switch (fmt[i])
216318334Speter	{
216418334Speter	case 'w':
216518334Speter	  if (XWINT (x, i) != XWINT (y, i))
216618334Speter	    return 0;
216718334Speter	  break;
216818334Speter
216918334Speter	case 'i':
217018334Speter	  if (XINT (x, i) != XINT (y, i))
217118334Speter	    return 0;
217218334Speter	  break;
217318334Speter
217418334Speter	case 'e':
217518334Speter	  val = operands_match_p (XEXP (x, i), XEXP (y, i));
217618334Speter	  if (val == 0)
217718334Speter	    return 0;
217818334Speter	  /* If any subexpression returns 2,
217918334Speter	     we should return 2 if we are successful.  */
218018334Speter	  if (val == 2)
218118334Speter	    success_2 = 1;
218218334Speter	  break;
218318334Speter
218418334Speter	case '0':
218518334Speter	  break;
218618334Speter
218752557Sobrien	case 'E':
218852557Sobrien	  if (XVECLEN (x, i) != XVECLEN (y, i))
218952557Sobrien	    return 0;
219052557Sobrien	  for (j = XVECLEN (x, i) - 1; j >= 0; --j)
219152557Sobrien	    {
219252557Sobrien	      val = operands_match_p (XVECEXP (x, i, j), XVECEXP (y, i, j));
219352557Sobrien	      if (val == 0)
219452557Sobrien		return 0;
219552557Sobrien	      if (val == 2)
219652557Sobrien		success_2 = 1;
219752557Sobrien	    }
219852557Sobrien	  break;
219952557Sobrien
220018334Speter	  /* It is believed that rtx's at this level will never
220118334Speter	     contain anything but integers and other rtx's,
220218334Speter	     except for within LABEL_REFs and SYMBOL_REFs.  */
220318334Speter	default:
220418334Speter	  abort ();
220518334Speter	}
220618334Speter    }
220718334Speter  return 1 + success_2;
220818334Speter}
220918334Speter
221018334Speter/* Describe the range of registers or memory referenced by X.
221118334Speter   If X is a register, set REG_FLAG and put the first register
221218334Speter   number into START and the last plus one into END.
221318334Speter   If X is a memory reference, put a base address into BASE
221418334Speter   and a range of integer offsets into START and END.
221518334Speter   If X is pushing on the stack, we can assume it causes no trouble,
221618334Speter   so we set the SAFE field.  */
221718334Speter
221818334Speterstatic struct decomposition
221918334Speterdecompose (x)
222018334Speter     rtx x;
222118334Speter{
222218334Speter  struct decomposition val;
222318334Speter  int all_const = 0;
222418334Speter
222518334Speter  val.reg_flag = 0;
222618334Speter  val.safe = 0;
222750605Sobrien  val.base = 0;
222818334Speter  if (GET_CODE (x) == MEM)
222918334Speter    {
223018334Speter      rtx base, offset = 0;
223118334Speter      rtx addr = XEXP (x, 0);
223218334Speter
223318334Speter      if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
223418334Speter	  || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
223518334Speter	{
223618334Speter	  val.base = XEXP (addr, 0);
223718334Speter	  val.start = - GET_MODE_SIZE (GET_MODE (x));
223818334Speter	  val.end = GET_MODE_SIZE (GET_MODE (x));
223918334Speter	  val.safe = REGNO (val.base) == STACK_POINTER_REGNUM;
224018334Speter	  return val;
224118334Speter	}
224218334Speter
224318334Speter      if (GET_CODE (addr) == CONST)
224418334Speter	{
224518334Speter	  addr = XEXP (addr, 0);
224618334Speter	  all_const = 1;
224718334Speter	}
224818334Speter      if (GET_CODE (addr) == PLUS)
224918334Speter	{
225018334Speter	  if (CONSTANT_P (XEXP (addr, 0)))
225118334Speter	    {
225218334Speter	      base = XEXP (addr, 1);
225318334Speter	      offset = XEXP (addr, 0);
225418334Speter	    }
225518334Speter	  else if (CONSTANT_P (XEXP (addr, 1)))
225618334Speter	    {
225718334Speter	      base = XEXP (addr, 0);
225818334Speter	      offset = XEXP (addr, 1);
225918334Speter	    }
226018334Speter	}
226118334Speter
226218334Speter      if (offset == 0)
226318334Speter	{
226418334Speter	  base = addr;
226518334Speter	  offset = const0_rtx;
226618334Speter	}
226718334Speter      if (GET_CODE (offset) == CONST)
226818334Speter	offset = XEXP (offset, 0);
226918334Speter      if (GET_CODE (offset) == PLUS)
227018334Speter	{
227118334Speter	  if (GET_CODE (XEXP (offset, 0)) == CONST_INT)
227218334Speter	    {
227350605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 1));
227418334Speter	      offset = XEXP (offset, 0);
227518334Speter	    }
227618334Speter	  else if (GET_CODE (XEXP (offset, 1)) == CONST_INT)
227718334Speter	    {
227850605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 0));
227918334Speter	      offset = XEXP (offset, 1);
228018334Speter	    }
228118334Speter	  else
228218334Speter	    {
228350605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, offset);
228418334Speter	      offset = const0_rtx;
228518334Speter	    }
228618334Speter	}
228718334Speter      else if (GET_CODE (offset) != CONST_INT)
228818334Speter	{
228950605Sobrien	  base = gen_rtx_PLUS (GET_MODE (base), base, offset);
229018334Speter	  offset = const0_rtx;
229118334Speter	}
229218334Speter
229318334Speter      if (all_const && GET_CODE (base) == PLUS)
229450605Sobrien	base = gen_rtx_CONST (GET_MODE (base), base);
229518334Speter
229618334Speter      if (GET_CODE (offset) != CONST_INT)
229718334Speter	abort ();
229818334Speter
229918334Speter      val.start = INTVAL (offset);
230018334Speter      val.end = val.start + GET_MODE_SIZE (GET_MODE (x));
230118334Speter      val.base = base;
230218334Speter      return val;
230318334Speter    }
230418334Speter  else if (GET_CODE (x) == REG)
230518334Speter    {
230618334Speter      val.reg_flag = 1;
230718334Speter      val.start = true_regnum (x);
230818334Speter      if (val.start < 0)
230918334Speter	{
231018334Speter	  /* A pseudo with no hard reg.  */
231118334Speter	  val.start = REGNO (x);
231218334Speter	  val.end = val.start + 1;
231318334Speter	}
231418334Speter      else
231518334Speter	/* A hard reg.  */
231618334Speter	val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
231718334Speter    }
231818334Speter  else if (GET_CODE (x) == SUBREG)
231918334Speter    {
232018334Speter      if (GET_CODE (SUBREG_REG (x)) != REG)
232118334Speter	/* This could be more precise, but it's good enough.  */
232218334Speter	return decompose (SUBREG_REG (x));
232318334Speter      val.reg_flag = 1;
232418334Speter      val.start = true_regnum (x);
232518334Speter      if (val.start < 0)
232618334Speter	return decompose (SUBREG_REG (x));
232718334Speter      else
232818334Speter	/* A hard reg.  */
232918334Speter	val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
233018334Speter    }
233118334Speter  else if (CONSTANT_P (x)
233218334Speter	   /* This hasn't been assigned yet, so it can't conflict yet.  */
233318334Speter	   || GET_CODE (x) == SCRATCH)
233418334Speter    val.safe = 1;
233518334Speter  else
233618334Speter    abort ();
233718334Speter  return val;
233818334Speter}
233918334Speter
234018334Speter/* Return 1 if altering Y will not modify the value of X.
234118334Speter   Y is also described by YDATA, which should be decompose (Y).  */
234218334Speter
234318334Speterstatic int
234418334Speterimmune_p (x, y, ydata)
234518334Speter     rtx x, y;
234618334Speter     struct decomposition ydata;
234718334Speter{
234818334Speter  struct decomposition xdata;
234918334Speter
235018334Speter  if (ydata.reg_flag)
235118334Speter    return !refers_to_regno_for_reload_p (ydata.start, ydata.end, x, NULL_PTR);
235218334Speter  if (ydata.safe)
235318334Speter    return 1;
235418334Speter
235518334Speter  if (GET_CODE (y) != MEM)
235618334Speter    abort ();
235718334Speter  /* If Y is memory and X is not, Y can't affect X.  */
235818334Speter  if (GET_CODE (x) != MEM)
235918334Speter    return 1;
236018334Speter
236118334Speter  xdata =  decompose (x);
236218334Speter
236318334Speter  if (! rtx_equal_p (xdata.base, ydata.base))
236418334Speter    {
236518334Speter      /* If bases are distinct symbolic constants, there is no overlap.  */
236618334Speter      if (CONSTANT_P (xdata.base) && CONSTANT_P (ydata.base))
236718334Speter	return 1;
236818334Speter      /* Constants and stack slots never overlap.  */
236918334Speter      if (CONSTANT_P (xdata.base)
237018334Speter	  && (ydata.base == frame_pointer_rtx
237118334Speter	      || ydata.base == hard_frame_pointer_rtx
237218334Speter	      || ydata.base == stack_pointer_rtx))
237318334Speter	return 1;
237418334Speter      if (CONSTANT_P (ydata.base)
237518334Speter	  && (xdata.base == frame_pointer_rtx
237618334Speter	      || xdata.base == hard_frame_pointer_rtx
237718334Speter	      || xdata.base == stack_pointer_rtx))
237818334Speter	return 1;
237918334Speter      /* If either base is variable, we don't know anything.  */
238018334Speter      return 0;
238118334Speter    }
238218334Speter
238318334Speter
238418334Speter  return (xdata.start >= ydata.end || ydata.start >= xdata.end);
238518334Speter}
238618334Speter
238718334Speter/* Similar, but calls decompose.  */
238818334Speter
238918334Speterint
239018334Spetersafe_from_earlyclobber (op, clobber)
239118334Speter     rtx op, clobber;
239218334Speter{
239318334Speter  struct decomposition early_data;
239418334Speter
239518334Speter  early_data = decompose (clobber);
239618334Speter  return immune_p (op, clobber, early_data);
239718334Speter}
239818334Speter
239918334Speter/* Main entry point of this file: search the body of INSN
240018334Speter   for values that need reloading and record them with push_reload.
240118334Speter   REPLACE nonzero means record also where the values occur
240218334Speter   so that subst_reloads can be used.
240318334Speter
240418334Speter   IND_LEVELS says how many levels of indirection are supported by this
240518334Speter   machine; a value of zero means that a memory reference is not a valid
240618334Speter   memory address.
240718334Speter
240818334Speter   LIVE_KNOWN says we have valid information about which hard
240918334Speter   regs are live at each point in the program; this is true when
241018334Speter   we are called from global_alloc but false when stupid register
241118334Speter   allocation has been done.
241218334Speter
241318334Speter   RELOAD_REG_P if nonzero is a vector indexed by hard reg number
241418334Speter   which is nonnegative if the reg has been commandeered for reloading into.
241518334Speter   It is copied into STATIC_RELOAD_REG_P and referenced from there
241652557Sobrien   by various subroutines.
241718334Speter
241852557Sobrien   Return TRUE if some operands need to be changed, because of swapping
241952557Sobrien   commutative operands, reg_equiv_address substitution, or whatever.  */
242052557Sobrien
242152557Sobrienint
242218334Speterfind_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
242318334Speter     rtx insn;
242418334Speter     int replace, ind_levels;
242518334Speter     int live_known;
242618334Speter     short *reload_reg_p;
242718334Speter{
242818334Speter#ifdef REGISTER_CONSTRAINTS
242918334Speter
243018334Speter  register int insn_code_number;
243118334Speter  register int i, j;
243218334Speter  int noperands;
243318334Speter  /* These start out as the constraints for the insn
243418334Speter     and they are chewed up as we consider alternatives.  */
243518334Speter  char *constraints[MAX_RECOG_OPERANDS];
243618334Speter  /* These are the preferred classes for an operand, or NO_REGS if it isn't
243718334Speter     a register.  */
243818334Speter  enum reg_class preferred_class[MAX_RECOG_OPERANDS];
243918334Speter  char pref_or_nothing[MAX_RECOG_OPERANDS];
244018334Speter  /* Nonzero for a MEM operand whose entire address needs a reload.  */
244118334Speter  int address_reloaded[MAX_RECOG_OPERANDS];
244218334Speter  /* Value of enum reload_type to use for operand.  */
244318334Speter  enum reload_type operand_type[MAX_RECOG_OPERANDS];
244418334Speter  /* Value of enum reload_type to use within address of operand.  */
244518334Speter  enum reload_type address_type[MAX_RECOG_OPERANDS];
244618334Speter  /* Save the usage of each operand.  */
244718334Speter  enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS];
244818334Speter  int no_input_reloads = 0, no_output_reloads = 0;
244918334Speter  int n_alternatives;
245018334Speter  int this_alternative[MAX_RECOG_OPERANDS];
245118334Speter  char this_alternative_win[MAX_RECOG_OPERANDS];
245218334Speter  char this_alternative_offmemok[MAX_RECOG_OPERANDS];
245318334Speter  char this_alternative_earlyclobber[MAX_RECOG_OPERANDS];
245418334Speter  int this_alternative_matches[MAX_RECOG_OPERANDS];
245518334Speter  int swapped;
245618334Speter  int goal_alternative[MAX_RECOG_OPERANDS];
245718334Speter  int this_alternative_number;
245818334Speter  int goal_alternative_number;
245918334Speter  int operand_reloadnum[MAX_RECOG_OPERANDS];
246018334Speter  int goal_alternative_matches[MAX_RECOG_OPERANDS];
246118334Speter  int goal_alternative_matched[MAX_RECOG_OPERANDS];
246218334Speter  char goal_alternative_win[MAX_RECOG_OPERANDS];
246318334Speter  char goal_alternative_offmemok[MAX_RECOG_OPERANDS];
246418334Speter  char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
246518334Speter  int goal_alternative_swapped;
246618334Speter  int best;
246718334Speter  int commutative;
246850605Sobrien  int changed;
246918334Speter  char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
247018334Speter  rtx substed_operand[MAX_RECOG_OPERANDS];
247118334Speter  rtx body = PATTERN (insn);
247218334Speter  rtx set = single_set (insn);
247318334Speter  int goal_earlyclobber, this_earlyclobber;
247418334Speter  enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
247552557Sobrien  int retval = 0;
247650605Sobrien  /* Cache the last regno for the last pseudo we did an output reload
247750605Sobrien     for in case the next insn uses it.  */
247850605Sobrien  static int last_output_reload_regno = -1;
247918334Speter
248018334Speter  this_insn = insn;
248118334Speter  n_reloads = 0;
248218334Speter  n_replacements = 0;
248318334Speter  n_earlyclobbers = 0;
248418334Speter  replace_reloads = replace;
248518334Speter  hard_regs_live_known = live_known;
248618334Speter  static_reload_reg_p = reload_reg_p;
248718334Speter
248818334Speter  /* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
248918334Speter     neither are insns that SET cc0.  Insns that use CC0 are not allowed
249018334Speter     to have any input reloads.  */
249118334Speter  if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)
249218334Speter    no_output_reloads = 1;
249318334Speter
249418334Speter#ifdef HAVE_cc0
249518334Speter  if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
249618334Speter    no_input_reloads = 1;
249718334Speter  if (reg_set_p (cc0_rtx, PATTERN (insn)))
249818334Speter    no_output_reloads = 1;
249918334Speter#endif
250018334Speter
250118334Speter#ifdef SECONDARY_MEMORY_NEEDED
250218334Speter  /* The eliminated forms of any secondary memory locations are per-insn, so
250318334Speter     clear them out here.  */
250418334Speter
250518334Speter  bzero ((char *) secondary_memlocs_elim, sizeof secondary_memlocs_elim);
250618334Speter#endif
250718334Speter
250852557Sobrien  /* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
250952557Sobrien     is cheap to move between them.  If it is not, there may not be an insn
251052557Sobrien     to do the copy, so we may need a reload.  */
251152557Sobrien  if (GET_CODE (body) == SET
251252557Sobrien      && GET_CODE (SET_DEST (body)) == REG
251352557Sobrien      && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
251452557Sobrien      && GET_CODE (SET_SRC (body)) == REG
251552557Sobrien      && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
251652557Sobrien      && REGISTER_MOVE_COST (REGNO_REG_CLASS (REGNO (SET_SRC (body))),
251752557Sobrien			     REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
251852557Sobrien    return 0;
251918334Speter
252052557Sobrien  extract_insn (insn);
252118334Speter
252252557Sobrien  noperands = reload_n_operands = recog_n_operands;
252352557Sobrien  n_alternatives = recog_n_alternatives;
252418334Speter
252552557Sobrien  /* Just return "no reloads" if insn has no operands with constraints.  */
252652557Sobrien  if (noperands == 0 || n_alternatives == 0)
252752557Sobrien    return 0;
252818334Speter
252952557Sobrien  insn_code_number = INSN_CODE (insn);
253052557Sobrien  this_insn_is_asm = insn_code_number < 0;
253118334Speter
253252557Sobrien  bcopy ((char *) recog_operand_mode, (char *) operand_mode,
253352557Sobrien	 noperands * sizeof (enum machine_mode));
253452557Sobrien  bcopy ((char *) recog_constraints, (char *) constraints,
253552557Sobrien	 noperands * sizeof (char *));
253618334Speter
253718334Speter  commutative = -1;
253818334Speter
253918334Speter  /* If we will need to know, later, whether some pair of operands
254018334Speter     are the same, we must compare them now and save the result.
254118334Speter     Reloading the base and index registers will clobber them
254218334Speter     and afterward they will fail to match.  */
254318334Speter
254418334Speter  for (i = 0; i < noperands; i++)
254518334Speter    {
254618334Speter      register char *p;
254718334Speter      register int c;
254818334Speter
254918334Speter      substed_operand[i] = recog_operand[i];
255018334Speter      p = constraints[i];
255118334Speter
255218334Speter      modified[i] = RELOAD_READ;
255318334Speter
255418334Speter      /* Scan this operand's constraint to see if it is an output operand,
255518334Speter	 an in-out operand, is commutative, or should match another.  */
255618334Speter
255750605Sobrien      while ((c = *p++))
255818334Speter	{
255918334Speter	  if (c == '=')
256018334Speter	    modified[i] = RELOAD_WRITE;
256118334Speter	  else if (c == '+')
256218334Speter	    modified[i] = RELOAD_READ_WRITE;
256318334Speter	  else if (c == '%')
256418334Speter	    {
256518334Speter	      /* The last operand should not be marked commutative.  */
256618334Speter	      if (i == noperands - 1)
256752557Sobrien		abort ();
256852557Sobrien
256952557Sobrien	      commutative = i;
257018334Speter	    }
257118334Speter	  else if (c >= '0' && c <= '9')
257218334Speter	    {
257318334Speter	      c -= '0';
257418334Speter	      operands_match[c][i]
257518334Speter		= operands_match_p (recog_operand[c], recog_operand[i]);
257618334Speter
257718334Speter	      /* An operand may not match itself.  */
257818334Speter	      if (c == i)
257952557Sobrien		abort ();
258018334Speter
258118334Speter	      /* If C can be commuted with C+1, and C might need to match I,
258218334Speter		 then C+1 might also need to match I.  */
258318334Speter	      if (commutative >= 0)
258418334Speter		{
258518334Speter		  if (c == commutative || c == commutative + 1)
258618334Speter		    {
258718334Speter		      int other = c + (c == commutative ? 1 : -1);
258818334Speter		      operands_match[other][i]
258918334Speter			= operands_match_p (recog_operand[other], recog_operand[i]);
259018334Speter		    }
259118334Speter		  if (i == commutative || i == commutative + 1)
259218334Speter		    {
259318334Speter		      int other = i + (i == commutative ? 1 : -1);
259418334Speter		      operands_match[c][other]
259518334Speter			= operands_match_p (recog_operand[c], recog_operand[other]);
259618334Speter		    }
259718334Speter		  /* Note that C is supposed to be less than I.
259818334Speter		     No need to consider altering both C and I because in
259918334Speter		     that case we would alter one into the other.  */
260018334Speter		}
260118334Speter	    }
260218334Speter	}
260318334Speter    }
260418334Speter
260518334Speter  /* Examine each operand that is a memory reference or memory address
260618334Speter     and reload parts of the addresses into index registers.
260718334Speter     Also here any references to pseudo regs that didn't get hard regs
260818334Speter     but are equivalent to constants get replaced in the insn itself
260918334Speter     with those constants.  Nobody will ever see them again.
261018334Speter
261118334Speter     Finally, set up the preferred classes of each operand.  */
261218334Speter
261318334Speter  for (i = 0; i < noperands; i++)
261418334Speter    {
261518334Speter      register RTX_CODE code = GET_CODE (recog_operand[i]);
261618334Speter
261718334Speter      address_reloaded[i] = 0;
261818334Speter      operand_type[i] = (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT
261918334Speter			 : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT
262018334Speter			 : RELOAD_OTHER);
262118334Speter      address_type[i]
262218334Speter	= (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT_ADDRESS
262318334Speter	   : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT_ADDRESS
262418334Speter	   : RELOAD_OTHER);
262518334Speter
262618334Speter      if (*constraints[i] == 0)
262718334Speter	/* Ignore things like match_operator operands.  */
262818334Speter	;
262918334Speter      else if (constraints[i][0] == 'p')
263018334Speter	{
263118334Speter	  find_reloads_address (VOIDmode, NULL_PTR,
263218334Speter				recog_operand[i], recog_operand_loc[i],
263350605Sobrien				i, operand_type[i], ind_levels, insn);
263450605Sobrien
263550605Sobrien	  /* If we now have a simple operand where we used to have a
263650605Sobrien	     PLUS or MULT, re-recognize and try again.  */
263750605Sobrien	  if ((GET_RTX_CLASS (GET_CODE (*recog_operand_loc[i])) == 'o'
263850605Sobrien	       || GET_CODE (*recog_operand_loc[i]) == SUBREG)
263950605Sobrien	      && (GET_CODE (recog_operand[i]) == MULT
264050605Sobrien		  || GET_CODE (recog_operand[i]) == PLUS))
264150605Sobrien	    {
264250605Sobrien	      INSN_CODE (insn) = -1;
264352557Sobrien	      retval = find_reloads (insn, replace, ind_levels, live_known,
264452557Sobrien				     reload_reg_p);
264552557Sobrien	      return retval;
264650605Sobrien	    }
264750605Sobrien
264818334Speter	  substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
264918334Speter	}
265018334Speter      else if (code == MEM)
265118334Speter	{
265252557Sobrien	  address_reloaded[i]
265352557Sobrien	    = find_reloads_address (GET_MODE (recog_operand[i]),
265418334Speter				    recog_operand_loc[i],
265518334Speter				    XEXP (recog_operand[i], 0),
265618334Speter				    &XEXP (recog_operand[i], 0),
265752557Sobrien				    i, address_type[i], ind_levels, insn);
265818334Speter	  substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
265918334Speter	}
266018334Speter      else if (code == SUBREG)
266150605Sobrien	{
266250605Sobrien	  rtx reg = SUBREG_REG (recog_operand[i]);
266350605Sobrien	  rtx op
266450605Sobrien	    = find_reloads_toplev (recog_operand[i], i, address_type[i],
266550605Sobrien				   ind_levels,
266650605Sobrien				   set != 0
266752557Sobrien				   && &SET_DEST (set) == recog_operand_loc[i],
266852557Sobrien				   insn);
266950605Sobrien
267050605Sobrien	  /* If we made a MEM to load (a part of) the stackslot of a pseudo
267150605Sobrien	     that didn't get a hard register, emit a USE with a REG_EQUAL
267250605Sobrien	     note in front so that we might inherit a previous, possibly
267350605Sobrien	     wider reload.  */
267450605Sobrien
267552557Sobrien	  if (replace
267652557Sobrien	      && GET_CODE (op) == MEM
267750605Sobrien	      && GET_CODE (reg) == REG
267850605Sobrien	      && (GET_MODE_SIZE (GET_MODE (reg))
267950605Sobrien		  >= GET_MODE_SIZE (GET_MODE (op))))
268050605Sobrien            REG_NOTES (emit_insn_before (gen_rtx_USE (VOIDmode, reg), insn))
268150605Sobrien              = gen_rtx_EXPR_LIST (REG_EQUAL,
268250605Sobrien				   reg_equiv_memory_loc[REGNO (reg)], NULL_RTX);
268350605Sobrien
268452557Sobrien	  substed_operand[i] = recog_operand[i] = op;
268550605Sobrien	}
268650605Sobrien      else if (code == PLUS || GET_RTX_CLASS (code) == '1')
268750605Sobrien	/* We can get a PLUS as an "operand" as a result of register
268850605Sobrien	   elimination.  See eliminate_regs and gen_reload.  We handle
268950605Sobrien	   a unary operator by reloading the operand.  */
269052557Sobrien	substed_operand[i] = recog_operand[i]
269118334Speter	  = find_reloads_toplev (recog_operand[i], i, address_type[i],
269252557Sobrien				 ind_levels, 0, insn);
269318334Speter      else if (code == REG)
269418334Speter	{
269518334Speter	  /* This is equivalent to calling find_reloads_toplev.
269618334Speter	     The code is duplicated for speed.
269718334Speter	     When we find a pseudo always equivalent to a constant,
269818334Speter	     we replace it by the constant.  We must be sure, however,
269918334Speter	     that we don't try to replace it in the insn in which it
270018334Speter	     is being set.   */
270118334Speter	  register int regno = REGNO (recog_operand[i]);
270218334Speter	  if (reg_equiv_constant[regno] != 0
270318334Speter	      && (set == 0 || &SET_DEST (set) != recog_operand_loc[i]))
270450605Sobrien	    {
270550605Sobrien	      /* Record the existing mode so that the check if constants are
270650605Sobrien	         allowed will work when operand_mode isn't specified. */
270750605Sobrien
270850605Sobrien	      if (operand_mode[i] == VOIDmode)
270950605Sobrien		operand_mode[i] = GET_MODE (recog_operand[i]);
271050605Sobrien
271150605Sobrien	      substed_operand[i] = recog_operand[i]
271250605Sobrien	        = reg_equiv_constant[regno];
271350605Sobrien	    }
271452557Sobrien	  if (reg_equiv_memory_loc[regno] != 0
271552557Sobrien	      && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
271652557Sobrien	    /* We need not give a valid is_set_dest argument since the case
271752557Sobrien	       of a constant equivalence was checked above.  */
271818334Speter	    substed_operand[i] = recog_operand[i]
271952557Sobrien	      = find_reloads_toplev (recog_operand[i], i, address_type[i],
272052557Sobrien				     ind_levels, 0, insn);
272118334Speter	}
272218334Speter      /* If the operand is still a register (we didn't replace it with an
272318334Speter	 equivalent), get the preferred class to reload it into.  */
272418334Speter      code = GET_CODE (recog_operand[i]);
272518334Speter      preferred_class[i]
272618334Speter	= ((code == REG && REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER)
272718334Speter	   ? reg_preferred_class (REGNO (recog_operand[i])) : NO_REGS);
272818334Speter      pref_or_nothing[i]
272918334Speter	= (code == REG && REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER
273018334Speter	   && reg_alternate_class (REGNO (recog_operand[i])) == NO_REGS);
273118334Speter    }
273218334Speter
273352557Sobrien#ifdef HAVE_cc0
273452557Sobrien  /* If we made any reloads for addresses, see if they violate a
273552557Sobrien     "no input reloads" requirement for this insn.  */
273652557Sobrien  if (no_input_reloads)
273752557Sobrien    for (i = 0; i < n_reloads; i++)
273852557Sobrien      if (reload_in[i] != 0)
273952557Sobrien	abort ();
274052557Sobrien#endif
274152557Sobrien
274218334Speter  /* If this is simply a copy from operand 1 to operand 0, merge the
274318334Speter     preferred classes for the operands.  */
274418334Speter  if (set != 0 && noperands >= 2 && recog_operand[0] == SET_DEST (set)
274518334Speter      && recog_operand[1] == SET_SRC (set))
274618334Speter    {
274718334Speter      preferred_class[0] = preferred_class[1]
274818334Speter	= reg_class_subunion[(int) preferred_class[0]][(int) preferred_class[1]];
274918334Speter      pref_or_nothing[0] |= pref_or_nothing[1];
275018334Speter      pref_or_nothing[1] |= pref_or_nothing[0];
275118334Speter    }
275218334Speter
275318334Speter  /* Now see what we need for pseudo-regs that didn't get hard regs
275418334Speter     or got the wrong kind of hard reg.  For this, we must consider
275518334Speter     all the operands together against the register constraints.  */
275618334Speter
275750605Sobrien  best = MAX_RECOG_OPERANDS * 2 + 600;
275818334Speter
275918334Speter  swapped = 0;
276018334Speter  goal_alternative_swapped = 0;
276118334Speter try_swapped:
276218334Speter
276318334Speter  /* The constraints are made of several alternatives.
276418334Speter     Each operand's constraint looks like foo,bar,... with commas
276518334Speter     separating the alternatives.  The first alternatives for all
276618334Speter     operands go together, the second alternatives go together, etc.
276718334Speter
276818334Speter     First loop over alternatives.  */
276918334Speter
277018334Speter  for (this_alternative_number = 0;
277118334Speter       this_alternative_number < n_alternatives;
277218334Speter       this_alternative_number++)
277318334Speter    {
277418334Speter      /* Loop over operands for one constraint alternative.  */
277518334Speter      /* LOSERS counts those that don't fit this alternative
277618334Speter	 and would require loading.  */
277718334Speter      int losers = 0;
277818334Speter      /* BAD is set to 1 if it some operand can't fit this alternative
277918334Speter	 even after reloading.  */
278018334Speter      int bad = 0;
278118334Speter      /* REJECT is a count of how undesirable this alternative says it is
278218334Speter	 if any reloading is required.  If the alternative matches exactly
278318334Speter	 then REJECT is ignored, but otherwise it gets this much
278418334Speter	 counted against it in addition to the reloading needed.  Each
278518334Speter	 ? counts three times here since we want the disparaging caused by
278618334Speter	 a bad register class to only count 1/3 as much.  */
278718334Speter      int reject = 0;
278818334Speter
278918334Speter      this_earlyclobber = 0;
279018334Speter
279118334Speter      for (i = 0; i < noperands; i++)
279218334Speter	{
279318334Speter	  register char *p = constraints[i];
279418334Speter	  register int win = 0;
279518334Speter	  /* 0 => this operand can be reloaded somehow for this alternative */
279618334Speter	  int badop = 1;
279718334Speter	  /* 0 => this operand can be reloaded if the alternative allows regs.  */
279818334Speter	  int winreg = 0;
279918334Speter	  int c;
280018334Speter	  register rtx operand = recog_operand[i];
280118334Speter	  int offset = 0;
280218334Speter	  /* Nonzero means this is a MEM that must be reloaded into a reg
280318334Speter	     regardless of what the constraint says.  */
280418334Speter	  int force_reload = 0;
280518334Speter	  int offmemok = 0;
280618334Speter	  /* Nonzero if a constant forced into memory would be OK for this
280718334Speter	     operand.  */
280818334Speter	  int constmemok = 0;
280918334Speter	  int earlyclobber = 0;
281018334Speter
281150605Sobrien	  /* If the predicate accepts a unary operator, it means that
281250605Sobrien             we need to reload the operand, but do not do this for
281350605Sobrien	     match_operator and friends.  */
281450605Sobrien	  if (GET_RTX_CLASS (GET_CODE (operand)) == '1' && *p != 0)
281550605Sobrien	    operand = XEXP (operand, 0);
281650605Sobrien
281718334Speter	  /* If the operand is a SUBREG, extract
281818334Speter	     the REG or MEM (or maybe even a constant) within.
281918334Speter	     (Constants can occur as a result of reg_equiv_constant.)  */
282018334Speter
282118334Speter	  while (GET_CODE (operand) == SUBREG)
282218334Speter	    {
282318334Speter	      offset += SUBREG_WORD (operand);
282418334Speter	      operand = SUBREG_REG (operand);
282550605Sobrien	      /* Force reload if this is a constant or PLUS or if there may
282618334Speter		 be a problem accessing OPERAND in the outer mode.  */
282718334Speter	      if (CONSTANT_P (operand)
282818334Speter		  || GET_CODE (operand) == PLUS
282918334Speter		  /* We must force a reload of paradoxical SUBREGs
283018334Speter		     of a MEM because the alignment of the inner value
283118334Speter		     may not be enough to do the outer reference.  On
283218334Speter		     big-endian machines, it may also reference outside
283318334Speter		     the object.
283418334Speter
283518334Speter		     On machines that extend byte operations and we have a
283618334Speter		     SUBREG where both the inner and outer modes are no wider
283718334Speter		     than a word and the inner mode is narrower, is integral,
283818334Speter		     and gets extended when loaded from memory, combine.c has
283918334Speter		     made assumptions about the behavior of the machine in such
284018334Speter		     register access.  If the data is, in fact, in memory we
284118334Speter		     must always load using the size assumed to be in the
284218334Speter		     register and let the insn do the different-sized
284350605Sobrien		     accesses.
284450605Sobrien
284550605Sobrien		     This is doubly true if WORD_REGISTER_OPERATIONS.  In
284650605Sobrien		     this case eliminate_regs has left non-paradoxical
284750605Sobrien		     subregs for push_reloads to see.  Make sure it does
284850605Sobrien		     by forcing the reload.
284950605Sobrien
285050605Sobrien		     ??? When is it right at this stage to have a subreg
285150605Sobrien		     of a mem that is _not_ to be handled specialy?  IMO
285250605Sobrien		     those should have been reduced to just a mem.  */
285318334Speter		  || ((GET_CODE (operand) == MEM
285418334Speter		       || (GET_CODE (operand)== REG
285518334Speter			   && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
285650605Sobrien#ifndef WORD_REGISTER_OPERATIONS
285718334Speter		      && (((GET_MODE_BITSIZE (GET_MODE (operand))
285818334Speter			    < BIGGEST_ALIGNMENT)
285918334Speter			   && (GET_MODE_SIZE (operand_mode[i])
286018334Speter			       > GET_MODE_SIZE (GET_MODE (operand))))
286118334Speter			  || (GET_CODE (operand) == MEM && BYTES_BIG_ENDIAN)
286218334Speter#ifdef LOAD_EXTEND_OP
286318334Speter			  || (GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
286418334Speter			      && (GET_MODE_SIZE (GET_MODE (operand))
286518334Speter				  <= UNITS_PER_WORD)
286618334Speter			      && (GET_MODE_SIZE (operand_mode[i])
286718334Speter				  > GET_MODE_SIZE (GET_MODE (operand)))
286818334Speter			      && INTEGRAL_MODE_P (GET_MODE (operand))
286918334Speter			      && LOAD_EXTEND_OP (GET_MODE (operand)) != NIL)
287018334Speter#endif
287150605Sobrien			  )
287250605Sobrien#endif
287350605Sobrien		      )
287418334Speter		  /* Subreg of a hard reg which can't handle the subreg's mode
287518334Speter		     or which would handle that mode in the wrong number of
287618334Speter		     registers for subregging to work.  */
287718334Speter		  || (GET_CODE (operand) == REG
287818334Speter		      && REGNO (operand) < FIRST_PSEUDO_REGISTER
287918334Speter		      && ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
288018334Speter			   && (GET_MODE_SIZE (GET_MODE (operand))
288118334Speter			       > UNITS_PER_WORD)
288218334Speter			   && ((GET_MODE_SIZE (GET_MODE (operand))
288318334Speter				/ UNITS_PER_WORD)
288418334Speter			       != HARD_REGNO_NREGS (REGNO (operand),
288518334Speter						    GET_MODE (operand))))
288618334Speter			  || ! HARD_REGNO_MODE_OK (REGNO (operand) + offset,
288718334Speter						   operand_mode[i]))))
288818334Speter		force_reload = 1;
288918334Speter	    }
289018334Speter
289118334Speter	  this_alternative[i] = (int) NO_REGS;
289218334Speter	  this_alternative_win[i] = 0;
289318334Speter	  this_alternative_offmemok[i] = 0;
289418334Speter	  this_alternative_earlyclobber[i] = 0;
289518334Speter	  this_alternative_matches[i] = -1;
289618334Speter
289718334Speter	  /* An empty constraint or empty alternative
289818334Speter	     allows anything which matched the pattern.  */
289918334Speter	  if (*p == 0 || *p == ',')
290018334Speter	    win = 1, badop = 0;
290118334Speter
290218334Speter	  /* Scan this alternative's specs for this operand;
290318334Speter	     set WIN if the operand fits any letter in this alternative.
290418334Speter	     Otherwise, clear BADOP if this operand could
290518334Speter	     fit some letter after reloads,
290618334Speter	     or set WINREG if this operand could fit after reloads
290718334Speter	     provided the constraint allows some registers.  */
290818334Speter
290918334Speter	  while (*p && (c = *p++) != ',')
291018334Speter	    switch (c)
291118334Speter	      {
291218334Speter	      case '=':
291318334Speter	      case '+':
291418334Speter	      case '*':
291518334Speter		break;
291618334Speter
291718334Speter	      case '%':
291818334Speter		/* The last operand should not be marked commutative.  */
291918334Speter		if (i != noperands - 1)
292018334Speter		  commutative = i;
292118334Speter		break;
292218334Speter
292318334Speter	      case '?':
292450605Sobrien		reject += 6;
292518334Speter		break;
292618334Speter
292718334Speter	      case '!':
292850605Sobrien		reject = 600;
292918334Speter		break;
293018334Speter
293118334Speter	      case '#':
293218334Speter		/* Ignore rest of this alternative as far as
293318334Speter		   reloading is concerned.  */
293418334Speter		while (*p && *p != ',') p++;
293518334Speter		break;
293618334Speter
293718334Speter	      case '0':
293818334Speter	      case '1':
293918334Speter	      case '2':
294018334Speter	      case '3':
294118334Speter	      case '4':
294218334Speter		c -= '0';
294318334Speter		this_alternative_matches[i] = c;
294418334Speter		/* We are supposed to match a previous operand.
294518334Speter		   If we do, we win if that one did.
294618334Speter		   If we do not, count both of the operands as losers.
294718334Speter		   (This is too conservative, since most of the time
294818334Speter		   only a single reload insn will be needed to make
294918334Speter		   the two operands win.  As a result, this alternative
295018334Speter		   may be rejected when it is actually desirable.)  */
295118334Speter		if ((swapped && (c != commutative || i != commutative + 1))
295218334Speter		    /* If we are matching as if two operands were swapped,
295318334Speter		       also pretend that operands_match had been computed
295418334Speter		       with swapped.
295518334Speter		       But if I is the second of those and C is the first,
295618334Speter		       don't exchange them, because operands_match is valid
295718334Speter		       only on one side of its diagonal.  */
295818334Speter		    ? (operands_match
295918334Speter		        [(c == commutative || c == commutative + 1)
296018334Speter			 ? 2*commutative + 1 - c : c]
296118334Speter		        [(i == commutative || i == commutative + 1)
296218334Speter			 ? 2*commutative + 1 - i : i])
296318334Speter		    : operands_match[c][i])
296450605Sobrien		  {
296550605Sobrien		    /* If we are matching a non-offsettable address where an
296650605Sobrien		       offsettable address was expected, then we must reject
296750605Sobrien		       this combination, because we can't reload it.  */
296850605Sobrien		    if (this_alternative_offmemok[c]
296950605Sobrien			&& GET_CODE (recog_operand[c]) == MEM
297050605Sobrien			&& this_alternative[c] == (int) NO_REGS
297150605Sobrien			&& ! this_alternative_win[c])
297250605Sobrien		      bad = 1;
297350605Sobrien
297450605Sobrien		    win = this_alternative_win[c];
297550605Sobrien		  }
297618334Speter		else
297718334Speter		  {
297818334Speter		    /* Operands don't match.  */
297918334Speter		    rtx value;
298018334Speter		    /* Retroactively mark the operand we had to match
298118334Speter		       as a loser, if it wasn't already.  */
298218334Speter		    if (this_alternative_win[c])
298318334Speter		      losers++;
298418334Speter		    this_alternative_win[c] = 0;
298518334Speter		    if (this_alternative[c] == (int) NO_REGS)
298618334Speter		      bad = 1;
298718334Speter		    /* But count the pair only once in the total badness of
298818334Speter		       this alternative, if the pair can be a dummy reload.  */
298918334Speter		    value
299018334Speter		      = find_dummy_reload (recog_operand[i], recog_operand[c],
299118334Speter					   recog_operand_loc[i], recog_operand_loc[c],
299218334Speter					   operand_mode[i], operand_mode[c],
299350605Sobrien					   this_alternative[c], -1,
299450605Sobrien					   this_alternative_earlyclobber[c]);
299518334Speter
299618334Speter		    if (value != 0)
299718334Speter		      losers--;
299818334Speter		  }
299918334Speter		/* This can be fixed with reloads if the operand
300018334Speter		   we are supposed to match can be fixed with reloads.  */
300118334Speter		badop = 0;
300218334Speter		this_alternative[i] = this_alternative[c];
300318334Speter
300418334Speter		/* If we have to reload this operand and some previous
300518334Speter		   operand also had to match the same thing as this
300618334Speter		   operand, we don't know how to do that.  So reject this
300718334Speter		   alternative.  */
300818334Speter		if (! win || force_reload)
300918334Speter		  for (j = 0; j < i; j++)
301018334Speter		    if (this_alternative_matches[j]
301118334Speter			== this_alternative_matches[i])
301218334Speter		      badop = 1;
301318334Speter
301418334Speter		break;
301518334Speter
301618334Speter	      case 'p':
301718334Speter		/* All necessary reloads for an address_operand
301818334Speter		   were handled in find_reloads_address.  */
301918334Speter		this_alternative[i] = (int) BASE_REG_CLASS;
302018334Speter		win = 1;
302118334Speter		break;
302218334Speter
302318334Speter	      case 'm':
302418334Speter		if (force_reload)
302518334Speter		  break;
302618334Speter		if (GET_CODE (operand) == MEM
302718334Speter		    || (GET_CODE (operand) == REG
302818334Speter			&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
302918334Speter			&& reg_renumber[REGNO (operand)] < 0))
303018334Speter		  win = 1;
303150605Sobrien		if (CONSTANT_P (operand)
303250605Sobrien		    /* force_const_mem does not accept HIGH.  */
303350605Sobrien		    && GET_CODE (operand) != HIGH)
303418334Speter		  badop = 0;
303518334Speter		constmemok = 1;
303618334Speter		break;
303718334Speter
303818334Speter	      case '<':
303918334Speter		if (GET_CODE (operand) == MEM
304018334Speter		    && ! address_reloaded[i]
304118334Speter		    && (GET_CODE (XEXP (operand, 0)) == PRE_DEC
304218334Speter			|| GET_CODE (XEXP (operand, 0)) == POST_DEC))
304318334Speter		  win = 1;
304418334Speter		break;
304518334Speter
304618334Speter	      case '>':
304718334Speter		if (GET_CODE (operand) == MEM
304818334Speter		    && ! address_reloaded[i]
304918334Speter		    && (GET_CODE (XEXP (operand, 0)) == PRE_INC
305018334Speter			|| GET_CODE (XEXP (operand, 0)) == POST_INC))
305118334Speter		  win = 1;
305218334Speter		break;
305318334Speter
305418334Speter		/* Memory operand whose address is not offsettable.  */
305518334Speter	      case 'V':
305618334Speter		if (force_reload)
305718334Speter		  break;
305818334Speter		if (GET_CODE (operand) == MEM
305918334Speter		    && ! (ind_levels ? offsettable_memref_p (operand)
306018334Speter			  : offsettable_nonstrict_memref_p (operand))
306118334Speter		    /* Certain mem addresses will become offsettable
306218334Speter		       after they themselves are reloaded.  This is important;
306318334Speter		       we don't want our own handling of unoffsettables
306418334Speter		       to override the handling of reg_equiv_address.  */
306518334Speter		    && !(GET_CODE (XEXP (operand, 0)) == REG
306618334Speter			 && (ind_levels == 0
306718334Speter			     || reg_equiv_address[REGNO (XEXP (operand, 0))] != 0)))
306818334Speter		  win = 1;
306918334Speter		break;
307018334Speter
307118334Speter		/* Memory operand whose address is offsettable.  */
307218334Speter	      case 'o':
307318334Speter		if (force_reload)
307418334Speter		  break;
307518334Speter		if ((GET_CODE (operand) == MEM
307618334Speter		     /* If IND_LEVELS, find_reloads_address won't reload a
307718334Speter			pseudo that didn't get a hard reg, so we have to
307818334Speter			reject that case.  */
307952557Sobrien		     && ((ind_levels ? offsettable_memref_p (operand)
308052557Sobrien			  : offsettable_nonstrict_memref_p (operand))
308152557Sobrien			 /* A reloaded address is offsettable because it is now
308252557Sobrien			    just a simple register indirect.  */
308352557Sobrien			 || address_reloaded[i]))
308418334Speter		    || (GET_CODE (operand) == REG
308518334Speter			&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
308618334Speter			&& reg_renumber[REGNO (operand)] < 0
308718334Speter			/* If reg_equiv_address is nonzero, we will be
308818334Speter			   loading it into a register; hence it will be
308918334Speter			   offsettable, but we cannot say that reg_equiv_mem
309018334Speter			   is offsettable without checking.  */
309118334Speter			&& ((reg_equiv_mem[REGNO (operand)] != 0
309218334Speter			     && offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
309318334Speter			    || (reg_equiv_address[REGNO (operand)] != 0))))
309418334Speter		  win = 1;
309550605Sobrien		/* force_const_mem does not accept HIGH.  */
309650605Sobrien		if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
309750605Sobrien		    || GET_CODE (operand) == MEM)
309818334Speter		  badop = 0;
309918334Speter		constmemok = 1;
310018334Speter		offmemok = 1;
310118334Speter		break;
310218334Speter
310318334Speter	      case '&':
310418334Speter		/* Output operand that is stored before the need for the
310518334Speter		   input operands (and their index registers) is over.  */
310618334Speter		earlyclobber = 1, this_earlyclobber = 1;
310718334Speter		break;
310818334Speter
310918334Speter	      case 'E':
311018334Speter#ifndef REAL_ARITHMETIC
311118334Speter		/* Match any floating double constant, but only if
311218334Speter		   we can examine the bits of it reliably.  */
311318334Speter		if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
311418334Speter		     || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
311518334Speter		    && GET_MODE (operand) != VOIDmode && ! flag_pretend_float)
311618334Speter		  break;
311718334Speter#endif
311818334Speter		if (GET_CODE (operand) == CONST_DOUBLE)
311918334Speter		  win = 1;
312018334Speter		break;
312118334Speter
312218334Speter	      case 'F':
312318334Speter		if (GET_CODE (operand) == CONST_DOUBLE)
312418334Speter		  win = 1;
312518334Speter		break;
312618334Speter
312718334Speter	      case 'G':
312818334Speter	      case 'H':
312918334Speter		if (GET_CODE (operand) == CONST_DOUBLE
313018334Speter		    && CONST_DOUBLE_OK_FOR_LETTER_P (operand, c))
313118334Speter		  win = 1;
313218334Speter		break;
313318334Speter
313418334Speter	      case 's':
313518334Speter		if (GET_CODE (operand) == CONST_INT
313618334Speter		    || (GET_CODE (operand) == CONST_DOUBLE
313718334Speter			&& GET_MODE (operand) == VOIDmode))
313818334Speter		  break;
313918334Speter	      case 'i':
314018334Speter		if (CONSTANT_P (operand)
314118334Speter#ifdef LEGITIMATE_PIC_OPERAND_P
314218334Speter		    && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand))
314318334Speter#endif
314418334Speter		    )
314518334Speter		  win = 1;
314618334Speter		break;
314718334Speter
314818334Speter	      case 'n':
314918334Speter		if (GET_CODE (operand) == CONST_INT
315018334Speter		    || (GET_CODE (operand) == CONST_DOUBLE
315118334Speter			&& GET_MODE (operand) == VOIDmode))
315218334Speter		  win = 1;
315318334Speter		break;
315418334Speter
315518334Speter	      case 'I':
315618334Speter	      case 'J':
315718334Speter	      case 'K':
315818334Speter	      case 'L':
315918334Speter	      case 'M':
316018334Speter	      case 'N':
316118334Speter	      case 'O':
316218334Speter	      case 'P':
316318334Speter		if (GET_CODE (operand) == CONST_INT
316418334Speter		    && CONST_OK_FOR_LETTER_P (INTVAL (operand), c))
316518334Speter		  win = 1;
316618334Speter		break;
316718334Speter
316818334Speter	      case 'X':
316918334Speter		win = 1;
317018334Speter		break;
317118334Speter
317218334Speter	      case 'g':
317318334Speter		if (! force_reload
317418334Speter		    /* A PLUS is never a valid operand, but reload can make
317518334Speter		       it from a register when eliminating registers.  */
317618334Speter		    && GET_CODE (operand) != PLUS
317718334Speter		    /* A SCRATCH is not a valid operand.  */
317818334Speter		    && GET_CODE (operand) != SCRATCH
317918334Speter#ifdef LEGITIMATE_PIC_OPERAND_P
318018334Speter		    && (! CONSTANT_P (operand)
318118334Speter			|| ! flag_pic
318218334Speter			|| LEGITIMATE_PIC_OPERAND_P (operand))
318318334Speter#endif
318418334Speter		    && (GENERAL_REGS == ALL_REGS
318518334Speter			|| GET_CODE (operand) != REG
318618334Speter			|| (REGNO (operand) >= FIRST_PSEUDO_REGISTER
318718334Speter			    && reg_renumber[REGNO (operand)] < 0)))
318818334Speter		  win = 1;
318918334Speter		/* Drop through into 'r' case */
319018334Speter
319118334Speter	      case 'r':
319218334Speter		this_alternative[i]
319318334Speter		  = (int) reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS];
319418334Speter		goto reg;
319518334Speter
319618334Speter#ifdef EXTRA_CONSTRAINT
319718334Speter              case 'Q':
319818334Speter              case 'R':
319918334Speter              case 'S':
320018334Speter              case 'T':
320118334Speter              case 'U':
320218334Speter		if (EXTRA_CONSTRAINT (operand, c))
320318334Speter		  win = 1;
320418334Speter		break;
320518334Speter#endif
320618334Speter
320718334Speter	      default:
320818334Speter		this_alternative[i]
320918334Speter		  = (int) reg_class_subunion[this_alternative[i]][(int) REG_CLASS_FROM_LETTER (c)];
321018334Speter
321118334Speter	      reg:
321218334Speter		if (GET_MODE (operand) == BLKmode)
321318334Speter		  break;
321418334Speter		winreg = 1;
321518334Speter		if (GET_CODE (operand) == REG
321618334Speter		    && reg_fits_class_p (operand, this_alternative[i],
321718334Speter					 offset, GET_MODE (recog_operand[i])))
321818334Speter		  win = 1;
321918334Speter		break;
322018334Speter	      }
322118334Speter
322218334Speter	  constraints[i] = p;
322318334Speter
322418334Speter	  /* If this operand could be handled with a reg,
322518334Speter	     and some reg is allowed, then this operand can be handled.  */
322618334Speter	  if (winreg && this_alternative[i] != (int) NO_REGS)
322718334Speter	    badop = 0;
322818334Speter
322918334Speter	  /* Record which operands fit this alternative.  */
323018334Speter	  this_alternative_earlyclobber[i] = earlyclobber;
323118334Speter	  if (win && ! force_reload)
323218334Speter	    this_alternative_win[i] = 1;
323318334Speter	  else
323418334Speter	    {
323518334Speter	      int const_to_mem = 0;
323618334Speter
323718334Speter	      this_alternative_offmemok[i] = offmemok;
323818334Speter	      losers++;
323918334Speter	      if (badop)
324018334Speter		bad = 1;
324118334Speter	      /* Alternative loses if it has no regs for a reg operand.  */
324218334Speter	      if (GET_CODE (operand) == REG
324318334Speter		  && this_alternative[i] == (int) NO_REGS
324418334Speter		  && this_alternative_matches[i] < 0)
324518334Speter		bad = 1;
324618334Speter
324750605Sobrien#if 0
324850605Sobrien	      /* If this is a pseudo-register that is set in the previous
324950605Sobrien		 insns, there's a good chance that it will already be in a
325050605Sobrien		 spill register and we can use that spill register.  So
325150605Sobrien		 make this case cheaper.
325218334Speter
325350605Sobrien		 Disabled for egcs.  egcs has better inheritance code and
325450605Sobrien		 this change causes problems with the improved reload
325550605Sobrien		 inheritance code.  */
325650605Sobrien	      if (GET_CODE (operand) == REG
325750605Sobrien		  && REGNO (operand) >= FIRST_PSEUDO_REGISTER
325850605Sobrien		  && REGNO (operand) == last_output_reload_regno)
325950605Sobrien		reject--;
326050605Sobrien#endif
326150605Sobrien
326218334Speter	      /* If this is a constant that is reloaded into the desired
326318334Speter		 class by copying it to memory first, count that as another
326418334Speter		 reload.  This is consistent with other code and is
326518334Speter		 required to avoid choosing another alternative when
326618334Speter		 the constant is moved into memory by this function on
326718334Speter		 an early reload pass.  Note that the test here is
326818334Speter		 precisely the same as in the code below that calls
326918334Speter		 force_const_mem.  */
327018334Speter	      if (CONSTANT_P (operand)
327118334Speter		  /* force_const_mem does not accept HIGH.  */
327218334Speter		  && GET_CODE (operand) != HIGH
327350605Sobrien		  && ((PREFERRED_RELOAD_CLASS (operand,
327418334Speter					      (enum reg_class) this_alternative[i])
327550605Sobrien		       == NO_REGS)
327650605Sobrien		      || no_input_reloads)
327718334Speter		  && operand_mode[i] != VOIDmode)
327818334Speter		{
327918334Speter		  const_to_mem = 1;
328018334Speter		  if (this_alternative[i] != (int) NO_REGS)
328118334Speter		    losers++;
328218334Speter		}
328318334Speter
328418334Speter	      /* If we can't reload this value at all, reject this
328518334Speter		 alternative.  Note that we could also lose due to
328618334Speter		 LIMIT_RELOAD_RELOAD_CLASS, but we don't check that
328718334Speter		 here.  */
328818334Speter
328918334Speter	      if (! CONSTANT_P (operand)
329018334Speter		  && (enum reg_class) this_alternative[i] != NO_REGS
329118334Speter		  && (PREFERRED_RELOAD_CLASS (operand,
329218334Speter					      (enum reg_class) this_alternative[i])
329318334Speter		      == NO_REGS))
329418334Speter		bad = 1;
329518334Speter
329650605Sobrien	      /* Alternative loses if it requires a type of reload not
329750605Sobrien		 permitted for this insn.  We can always reload SCRATCH
329850605Sobrien		 and objects with a REG_UNUSED note.  */
329950605Sobrien	      else if (GET_CODE (operand) != SCRATCH
330050605Sobrien		  && modified[i] != RELOAD_READ && no_output_reloads
330150605Sobrien		  && ! find_reg_note (insn, REG_UNUSED, operand))
330250605Sobrien		bad = 1;
330350605Sobrien	      else if (modified[i] != RELOAD_WRITE && no_input_reloads
330450605Sobrien		       && ! const_to_mem)
330550605Sobrien		bad = 1;
330650605Sobrien
330750605Sobrien
330818334Speter	      /* We prefer to reload pseudos over reloading other things,
330918334Speter		 since such reloads may be able to be eliminated later.
331018334Speter		 If we are reloading a SCRATCH, we won't be generating any
331118334Speter		 insns, just using a register, so it is also preferred.
331218334Speter		 So bump REJECT in other cases.  Don't do this in the
331318334Speter		 case where we are forcing a constant into memory and
331418334Speter		 it will then win since we don't want to have a different
331518334Speter		 alternative match then.  */
331618334Speter	      if (! (GET_CODE (operand) == REG
331718334Speter		     && REGNO (operand) >= FIRST_PSEUDO_REGISTER)
331818334Speter		  && GET_CODE (operand) != SCRATCH
331918334Speter		  && ! (const_to_mem && constmemok))
332050605Sobrien		reject += 2;
332150605Sobrien
332250605Sobrien	      /* Input reloads can be inherited more often than output
332350605Sobrien		 reloads can be removed, so penalize output reloads.  */
332450605Sobrien	      if (operand_type[i] != RELOAD_FOR_INPUT
332550605Sobrien		  && GET_CODE (operand) != SCRATCH)
332618334Speter		reject++;
332718334Speter	    }
332818334Speter
332918334Speter	  /* If this operand is a pseudo register that didn't get a hard
333018334Speter	     reg and this alternative accepts some register, see if the
333118334Speter	     class that we want is a subset of the preferred class for this
333218334Speter	     register.  If not, but it intersects that class, use the
333318334Speter	     preferred class instead.  If it does not intersect the preferred
333418334Speter	     class, show that usage of this alternative should be discouraged;
333518334Speter	     it will be discouraged more still if the register is `preferred
333618334Speter	     or nothing'.  We do this because it increases the chance of
333718334Speter	     reusing our spill register in a later insn and avoiding a pair
333818334Speter	     of memory stores and loads.
333918334Speter
334018334Speter	     Don't bother with this if this alternative will accept this
334118334Speter	     operand.
334218334Speter
334318334Speter	     Don't do this for a multiword operand, since it is only a
334418334Speter	     small win and has the risk of requiring more spill registers,
334518334Speter	     which could cause a large loss.
334618334Speter
334718334Speter	     Don't do this if the preferred class has only one register
334818334Speter	     because we might otherwise exhaust the class.  */
334918334Speter
335018334Speter
335118334Speter	  if (! win && this_alternative[i] != (int) NO_REGS
335218334Speter	      && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
335318334Speter	      && reg_class_size[(int) preferred_class[i]] > 1)
335418334Speter	    {
335518334Speter	      if (! reg_class_subset_p (this_alternative[i],
335618334Speter					preferred_class[i]))
335718334Speter		{
335818334Speter		  /* Since we don't have a way of forming the intersection,
335918334Speter		     we just do something special if the preferred class
336018334Speter		     is a subset of the class we have; that's the most
336118334Speter		     common case anyway.  */
336218334Speter		  if (reg_class_subset_p (preferred_class[i],
336318334Speter					  this_alternative[i]))
336418334Speter		    this_alternative[i] = (int) preferred_class[i];
336518334Speter		  else
336650605Sobrien		    reject += (2 + 2 * pref_or_nothing[i]);
336718334Speter		}
336818334Speter	    }
336918334Speter	}
337018334Speter
337118334Speter      /* Now see if any output operands that are marked "earlyclobber"
337218334Speter	 in this alternative conflict with any input operands
337318334Speter	 or any memory addresses.  */
337418334Speter
337518334Speter      for (i = 0; i < noperands; i++)
337618334Speter	if (this_alternative_earlyclobber[i]
337718334Speter	    && this_alternative_win[i])
337818334Speter	  {
337918334Speter	    struct decomposition early_data;
338018334Speter
338118334Speter	    early_data = decompose (recog_operand[i]);
338218334Speter
338318334Speter	    if (modified[i] == RELOAD_READ)
338452557Sobrien	      abort ();
338518334Speter
338618334Speter	    if (this_alternative[i] == NO_REGS)
338718334Speter	      {
338818334Speter		this_alternative_earlyclobber[i] = 0;
338918334Speter		if (this_insn_is_asm)
339018334Speter		  error_for_asm (this_insn,
339118334Speter				 "`&' constraint used with no register class");
339218334Speter		else
339318334Speter		  abort ();
339418334Speter	      }
339518334Speter
339618334Speter	    for (j = 0; j < noperands; j++)
339718334Speter	      /* Is this an input operand or a memory ref?  */
339818334Speter	      if ((GET_CODE (recog_operand[j]) == MEM
339918334Speter		   || modified[j] != RELOAD_WRITE)
340018334Speter		  && j != i
340118334Speter		  /* Ignore things like match_operator operands.  */
340252557Sobrien		  && *recog_constraints[j] != 0
340318334Speter		  /* Don't count an input operand that is constrained to match
340418334Speter		     the early clobber operand.  */
340518334Speter		  && ! (this_alternative_matches[j] == i
340618334Speter			&& rtx_equal_p (recog_operand[i], recog_operand[j]))
340718334Speter		  /* Is it altered by storing the earlyclobber operand?  */
340818334Speter		  && !immune_p (recog_operand[j], recog_operand[i], early_data))
340918334Speter		{
341018334Speter		  /* If the output is in a single-reg class,
341118334Speter		     it's costly to reload it, so reload the input instead.  */
341218334Speter		  if (reg_class_size[this_alternative[i]] == 1
341318334Speter		      && (GET_CODE (recog_operand[j]) == REG
341418334Speter			  || GET_CODE (recog_operand[j]) == SUBREG))
341518334Speter		    {
341618334Speter		      losers++;
341718334Speter		      this_alternative_win[j] = 0;
341818334Speter		    }
341918334Speter		  else
342018334Speter		    break;
342118334Speter		}
342218334Speter	    /* If an earlyclobber operand conflicts with something,
342318334Speter	       it must be reloaded, so request this and count the cost.  */
342418334Speter	    if (j != noperands)
342518334Speter	      {
342618334Speter		losers++;
342718334Speter		this_alternative_win[i] = 0;
342818334Speter		for (j = 0; j < noperands; j++)
342918334Speter		  if (this_alternative_matches[j] == i
343018334Speter		      && this_alternative_win[j])
343118334Speter		    {
343218334Speter		      this_alternative_win[j] = 0;
343318334Speter		      losers++;
343418334Speter		    }
343518334Speter	      }
343618334Speter	  }
343718334Speter
343818334Speter      /* If one alternative accepts all the operands, no reload required,
343918334Speter	 choose that alternative; don't consider the remaining ones.  */
344018334Speter      if (losers == 0)
344118334Speter	{
344218334Speter	  /* Unswap these so that they are never swapped at `finish'.  */
344318334Speter	  if (commutative >= 0)
344418334Speter	    {
344518334Speter	      recog_operand[commutative] = substed_operand[commutative];
344618334Speter	      recog_operand[commutative + 1]
344718334Speter		= substed_operand[commutative + 1];
344818334Speter	    }
344918334Speter	  for (i = 0; i < noperands; i++)
345018334Speter	    {
345118334Speter	      goal_alternative_win[i] = 1;
345218334Speter	      goal_alternative[i] = this_alternative[i];
345318334Speter	      goal_alternative_offmemok[i] = this_alternative_offmemok[i];
345418334Speter	      goal_alternative_matches[i] = this_alternative_matches[i];
345518334Speter	      goal_alternative_earlyclobber[i]
345618334Speter		= this_alternative_earlyclobber[i];
345718334Speter	    }
345818334Speter	  goal_alternative_number = this_alternative_number;
345918334Speter	  goal_alternative_swapped = swapped;
346018334Speter	  goal_earlyclobber = this_earlyclobber;
346118334Speter	  goto finish;
346218334Speter	}
346318334Speter
346418334Speter      /* REJECT, set by the ! and ? constraint characters and when a register
346518334Speter	 would be reloaded into a non-preferred class, discourages the use of
346650605Sobrien	 this alternative for a reload goal.  REJECT is incremented by six
346750605Sobrien	 for each ? and two for each non-preferred class.  */
346850605Sobrien      losers = losers * 6 + reject;
346918334Speter
347018334Speter      /* If this alternative can be made to work by reloading,
347118334Speter	 and it needs less reloading than the others checked so far,
347218334Speter	 record it as the chosen goal for reloading.  */
347318334Speter      if (! bad && best > losers)
347418334Speter	{
347518334Speter	  for (i = 0; i < noperands; i++)
347618334Speter	    {
347718334Speter	      goal_alternative[i] = this_alternative[i];
347818334Speter	      goal_alternative_win[i] = this_alternative_win[i];
347918334Speter	      goal_alternative_offmemok[i] = this_alternative_offmemok[i];
348018334Speter	      goal_alternative_matches[i] = this_alternative_matches[i];
348118334Speter	      goal_alternative_earlyclobber[i]
348218334Speter		= this_alternative_earlyclobber[i];
348318334Speter	    }
348418334Speter	  goal_alternative_swapped = swapped;
348518334Speter	  best = losers;
348618334Speter	  goal_alternative_number = this_alternative_number;
348718334Speter	  goal_earlyclobber = this_earlyclobber;
348818334Speter	}
348918334Speter    }
349018334Speter
349118334Speter  /* If insn is commutative (it's safe to exchange a certain pair of operands)
349218334Speter     then we need to try each alternative twice,
349318334Speter     the second time matching those two operands
349418334Speter     as if we had exchanged them.
349518334Speter     To do this, really exchange them in operands.
349618334Speter
349718334Speter     If we have just tried the alternatives the second time,
349818334Speter     return operands to normal and drop through.  */
349918334Speter
350018334Speter  if (commutative >= 0)
350118334Speter    {
350218334Speter      swapped = !swapped;
350318334Speter      if (swapped)
350418334Speter	{
350518334Speter	  register enum reg_class tclass;
350618334Speter	  register int t;
350718334Speter
350818334Speter	  recog_operand[commutative] = substed_operand[commutative + 1];
350918334Speter	  recog_operand[commutative + 1] = substed_operand[commutative];
351018334Speter
351118334Speter	  tclass = preferred_class[commutative];
351218334Speter	  preferred_class[commutative] = preferred_class[commutative + 1];
351318334Speter	  preferred_class[commutative + 1] = tclass;
351418334Speter
351518334Speter	  t = pref_or_nothing[commutative];
351618334Speter	  pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
351718334Speter	  pref_or_nothing[commutative + 1] = t;
351818334Speter
351952557Sobrien	  bcopy ((char *) recog_constraints, (char *) constraints,
352018334Speter		 noperands * sizeof (char *));
352118334Speter	  goto try_swapped;
352218334Speter	}
352318334Speter      else
352418334Speter	{
352518334Speter	  recog_operand[commutative] = substed_operand[commutative];
352618334Speter	  recog_operand[commutative + 1] = substed_operand[commutative + 1];
352718334Speter	}
352818334Speter    }
352918334Speter
353018334Speter  /* The operands don't meet the constraints.
353118334Speter     goal_alternative describes the alternative
353218334Speter     that we could reach by reloading the fewest operands.
353318334Speter     Reload so as to fit it.  */
353418334Speter
353550605Sobrien  if (best == MAX_RECOG_OPERANDS * 2 + 600)
353618334Speter    {
353718334Speter      /* No alternative works with reloads??  */
353818334Speter      if (insn_code_number >= 0)
353952557Sobrien	fatal_insn ("Unable to generate reloads for:", insn);
354018334Speter      error_for_asm (insn, "inconsistent operand constraints in an `asm'");
354118334Speter      /* Avoid further trouble with this insn.  */
354250605Sobrien      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
354318334Speter      n_reloads = 0;
354452557Sobrien      return 0;
354518334Speter    }
354618334Speter
354718334Speter  /* Jump to `finish' from above if all operands are valid already.
354818334Speter     In that case, goal_alternative_win is all 1.  */
354918334Speter finish:
355018334Speter
355118334Speter  /* Right now, for any pair of operands I and J that are required to match,
355218334Speter     with I < J,
355318334Speter     goal_alternative_matches[J] is I.
355418334Speter     Set up goal_alternative_matched as the inverse function:
355518334Speter     goal_alternative_matched[I] = J.  */
355618334Speter
355718334Speter  for (i = 0; i < noperands; i++)
355818334Speter    goal_alternative_matched[i] = -1;
355918334Speter
356018334Speter  for (i = 0; i < noperands; i++)
356118334Speter    if (! goal_alternative_win[i]
356218334Speter	&& goal_alternative_matches[i] >= 0)
356318334Speter      goal_alternative_matched[goal_alternative_matches[i]] = i;
356418334Speter
356518334Speter  /* If the best alternative is with operands 1 and 2 swapped,
356618334Speter     consider them swapped before reporting the reloads.  Update the
356718334Speter     operand numbers of any reloads already pushed.  */
356818334Speter
356918334Speter  if (goal_alternative_swapped)
357018334Speter    {
357118334Speter      register rtx tem;
357218334Speter
357318334Speter      tem = substed_operand[commutative];
357418334Speter      substed_operand[commutative] = substed_operand[commutative + 1];
357518334Speter      substed_operand[commutative + 1] = tem;
357618334Speter      tem = recog_operand[commutative];
357718334Speter      recog_operand[commutative] = recog_operand[commutative + 1];
357818334Speter      recog_operand[commutative + 1] = tem;
357952557Sobrien      tem = *recog_operand_loc[commutative];
358052557Sobrien      *recog_operand_loc[commutative] = *recog_operand_loc[commutative+1];
358152557Sobrien      *recog_operand_loc[commutative+1] = tem;
358218334Speter
358318334Speter      for (i = 0; i < n_reloads; i++)
358418334Speter	{
358518334Speter	  if (reload_opnum[i] == commutative)
358618334Speter	    reload_opnum[i] = commutative + 1;
358718334Speter	  else if (reload_opnum[i] == commutative + 1)
358818334Speter	    reload_opnum[i] = commutative;
358918334Speter	}
359018334Speter    }
359118334Speter
359218334Speter  for (i = 0; i < noperands; i++)
359318334Speter    {
359418334Speter      operand_reloadnum[i] = -1;
359518334Speter
359618334Speter      /* If this is an earlyclobber operand, we need to widen the scope.
359718334Speter	 The reload must remain valid from the start of the insn being
359818334Speter	 reloaded until after the operand is stored into its destination.
359918334Speter	 We approximate this with RELOAD_OTHER even though we know that we
360018334Speter	 do not conflict with RELOAD_FOR_INPUT_ADDRESS reloads.
360118334Speter
360218334Speter	 One special case that is worth checking is when we have an
360318334Speter	 output that is earlyclobber but isn't used past the insn (typically
360418334Speter	 a SCRATCH).  In this case, we only need have the reload live
360518334Speter	 through the insn itself, but not for any of our input or output
360618334Speter	 reloads.
360750605Sobrien	 But we must not accidentally narrow the scope of an existing
360850605Sobrien	 RELOAD_OTHER reload - leave these alone.
360918334Speter
361018334Speter	 In any case, anything needed to address this operand can remain
361118334Speter	 however they were previously categorized.  */
361218334Speter
361350605Sobrien      if (goal_alternative_earlyclobber[i] && operand_type[i] != RELOAD_OTHER)
361418334Speter	operand_type[i]
361518334Speter	  = (find_reg_note (insn, REG_UNUSED, recog_operand[i])
361618334Speter	     ? RELOAD_FOR_INSN : RELOAD_OTHER);
361718334Speter    }
361818334Speter
361918334Speter  /* Any constants that aren't allowed and can't be reloaded
362018334Speter     into registers are here changed into memory references.  */
362118334Speter  for (i = 0; i < noperands; i++)
362218334Speter    if (! goal_alternative_win[i]
362318334Speter	&& CONSTANT_P (recog_operand[i])
362418334Speter	/* force_const_mem does not accept HIGH.  */
362518334Speter	&& GET_CODE (recog_operand[i]) != HIGH
362650605Sobrien	&& ((PREFERRED_RELOAD_CLASS (recog_operand[i],
362718334Speter				    (enum reg_class) goal_alternative[i])
362850605Sobrien	     == NO_REGS)
362950605Sobrien	    || no_input_reloads)
363018334Speter	&& operand_mode[i] != VOIDmode)
363118334Speter      {
363252557Sobrien	substed_operand[i] = recog_operand[i]
363318334Speter	  = find_reloads_toplev (force_const_mem (operand_mode[i],
363418334Speter						  recog_operand[i]),
363552557Sobrien				 i, address_type[i], ind_levels, 0, insn);
363652557Sobrien	if (alternative_allows_memconst (recog_constraints[i],
363718334Speter					 goal_alternative_number))
363818334Speter	  goal_alternative_win[i] = 1;
363918334Speter      }
364018334Speter
364118334Speter  /* Record the values of the earlyclobber operands for the caller.  */
364218334Speter  if (goal_earlyclobber)
364318334Speter    for (i = 0; i < noperands; i++)
364418334Speter      if (goal_alternative_earlyclobber[i])
364518334Speter	reload_earlyclobbers[n_earlyclobbers++] = recog_operand[i];
364618334Speter
364718334Speter  /* Now record reloads for all the operands that need them.  */
364850605Sobrien  last_output_reload_regno = -1;
364918334Speter  for (i = 0; i < noperands; i++)
365018334Speter    if (! goal_alternative_win[i])
365118334Speter      {
365218334Speter	/* Operands that match previous ones have already been handled.  */
365318334Speter	if (goal_alternative_matches[i] >= 0)
365418334Speter	  ;
365518334Speter	/* Handle an operand with a nonoffsettable address
365618334Speter	   appearing where an offsettable address will do
365718334Speter	   by reloading the address into a base register.
365818334Speter
365918334Speter	   ??? We can also do this when the operand is a register and
366018334Speter	   reg_equiv_mem is not offsettable, but this is a bit tricky,
366118334Speter	   so we don't bother with it.  It may not be worth doing.  */
366218334Speter	else if (goal_alternative_matched[i] == -1
366318334Speter		 && goal_alternative_offmemok[i]
366418334Speter		 && GET_CODE (recog_operand[i]) == MEM)
366518334Speter	  {
366618334Speter	    operand_reloadnum[i]
366718334Speter	      = push_reload (XEXP (recog_operand[i], 0), NULL_RTX,
366818334Speter			     &XEXP (recog_operand[i], 0), NULL_PTR,
366918334Speter			     BASE_REG_CLASS, GET_MODE (XEXP (recog_operand[i], 0)),
367018334Speter			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
367118334Speter	    reload_inc[operand_reloadnum[i]]
367218334Speter	      = GET_MODE_SIZE (GET_MODE (recog_operand[i]));
367318334Speter
367418334Speter	    /* If this operand is an output, we will have made any
367518334Speter	       reloads for its address as RELOAD_FOR_OUTPUT_ADDRESS, but
367618334Speter	       now we are treating part of the operand as an input, so
367718334Speter	       we must change these to RELOAD_FOR_INPUT_ADDRESS.  */
367818334Speter
367918334Speter	    if (modified[i] == RELOAD_WRITE)
368050605Sobrien	      {
368150605Sobrien		for (j = 0; j < n_reloads; j++)
368250605Sobrien		  {
368350605Sobrien		    if (reload_opnum[j] == i)
368450605Sobrien		      {
368550605Sobrien			if (reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS)
368650605Sobrien			  reload_when_needed[j] = RELOAD_FOR_INPUT_ADDRESS;
368750605Sobrien			else if (reload_when_needed[j]
368850605Sobrien				 == RELOAD_FOR_OUTADDR_ADDRESS)
368950605Sobrien			  reload_when_needed[j] = RELOAD_FOR_INPADDR_ADDRESS;
369050605Sobrien		      }
369150605Sobrien		  }
369250605Sobrien	      }
369318334Speter	  }
369418334Speter	else if (goal_alternative_matched[i] == -1)
369550605Sobrien	  {
369650605Sobrien	    operand_reloadnum[i]
369750605Sobrien	      = push_reload ((modified[i] != RELOAD_WRITE
369850605Sobrien			      ? recog_operand[i] : 0),
369950605Sobrien			     modified[i] != RELOAD_READ ? recog_operand[i] : 0,
370050605Sobrien			     (modified[i] != RELOAD_WRITE
370150605Sobrien			      ? recog_operand_loc[i] : 0),
370250605Sobrien			     (modified[i] != RELOAD_READ
370350605Sobrien			      ? recog_operand_loc[i] : 0),
370450605Sobrien			     (enum reg_class) goal_alternative[i],
370550605Sobrien			     (modified[i] == RELOAD_WRITE
370650605Sobrien			      ? VOIDmode : operand_mode[i]),
370750605Sobrien			     (modified[i] == RELOAD_READ
370850605Sobrien			      ? VOIDmode : operand_mode[i]),
370950605Sobrien			     (insn_code_number < 0 ? 0
371050605Sobrien			      : insn_operand_strict_low[insn_code_number][i]),
371150605Sobrien			     0, i, operand_type[i]);
371250605Sobrien	    if (modified[i] != RELOAD_READ
371350605Sobrien		&& GET_CODE (recog_operand[i]) == REG)
371450605Sobrien	      last_output_reload_regno = REGNO (recog_operand[i]);
371550605Sobrien	  }
371618334Speter	/* In a matching pair of operands, one must be input only
371718334Speter	   and the other must be output only.
371818334Speter	   Pass the input operand as IN and the other as OUT.  */
371918334Speter	else if (modified[i] == RELOAD_READ
372018334Speter		 && modified[goal_alternative_matched[i]] == RELOAD_WRITE)
372118334Speter	  {
372218334Speter	    operand_reloadnum[i]
372318334Speter	      = push_reload (recog_operand[i],
372418334Speter			     recog_operand[goal_alternative_matched[i]],
372518334Speter			     recog_operand_loc[i],
372618334Speter			     recog_operand_loc[goal_alternative_matched[i]],
372718334Speter			     (enum reg_class) goal_alternative[i],
372818334Speter			     operand_mode[i],
372918334Speter			     operand_mode[goal_alternative_matched[i]],
373018334Speter			     0, 0, i, RELOAD_OTHER);
373118334Speter	    operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
373250605Sobrien	    if (GET_CODE (recog_operand[goal_alternative_matched[i]]) == REG)
373350605Sobrien	      last_output_reload_regno
373450605Sobrien		= REGNO (recog_operand[goal_alternative_matched[i]]);
373518334Speter	  }
373618334Speter	else if (modified[i] == RELOAD_WRITE
373718334Speter		 && modified[goal_alternative_matched[i]] == RELOAD_READ)
373818334Speter	  {
373918334Speter	    operand_reloadnum[goal_alternative_matched[i]]
374018334Speter	      = push_reload (recog_operand[goal_alternative_matched[i]],
374118334Speter			     recog_operand[i],
374218334Speter			     recog_operand_loc[goal_alternative_matched[i]],
374318334Speter			     recog_operand_loc[i],
374418334Speter			     (enum reg_class) goal_alternative[i],
374518334Speter			     operand_mode[goal_alternative_matched[i]],
374618334Speter			     operand_mode[i],
374718334Speter			     0, 0, i, RELOAD_OTHER);
374818334Speter	    operand_reloadnum[i] = output_reloadnum;
374950605Sobrien	    if (GET_CODE (recog_operand[i]) == REG)
375050605Sobrien	      last_output_reload_regno = REGNO (recog_operand[i]);
375118334Speter	  }
375218334Speter	else if (insn_code_number >= 0)
375318334Speter	  abort ();
375418334Speter	else
375518334Speter	  {
375618334Speter	    error_for_asm (insn, "inconsistent operand constraints in an `asm'");
375718334Speter	    /* Avoid further trouble with this insn.  */
375850605Sobrien	    PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
375918334Speter	    n_reloads = 0;
376052557Sobrien	    return 0;
376118334Speter	  }
376218334Speter      }
376318334Speter    else if (goal_alternative_matched[i] < 0
376418334Speter	     && goal_alternative_matches[i] < 0
376518334Speter	     && optimize)
376618334Speter      {
376718334Speter	/* For each non-matching operand that's a MEM or a pseudo-register
376818334Speter	   that didn't get a hard register, make an optional reload.
376918334Speter	   This may get done even if the insn needs no reloads otherwise.  */
377018334Speter
377118334Speter	rtx operand = recog_operand[i];
377218334Speter
377318334Speter	while (GET_CODE (operand) == SUBREG)
377418334Speter	  operand = XEXP (operand, 0);
377518334Speter	if ((GET_CODE (operand) == MEM
377618334Speter	     || (GET_CODE (operand) == REG
377718334Speter		 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
377852557Sobrien	    /* If this is only for an output, the optional reload would not
377952557Sobrien	       actually cause us to use a register now, just note that
378052557Sobrien	       something is stored here.  */
378152557Sobrien	    && ((enum reg_class) goal_alternative[i] != NO_REGS
378252557Sobrien		|| modified[i] == RELOAD_WRITE)
378318334Speter	    && ! no_input_reloads
378452557Sobrien	    /* An optional output reload might allow to delete INSN later.
378552557Sobrien	       We mustn't make in-out reloads on insns that are not permitted
378652557Sobrien	       output reloads.
378752557Sobrien	       If this is an asm, we can't delete it; we must not even call
378852557Sobrien	       push_reload for an optional output reload in this case,
378952557Sobrien	       because we can't be sure that the constraint allows a register,
379052557Sobrien	       and push_reload verifies the constraints for asms.  */
379118334Speter	    && (modified[i] == RELOAD_READ
379252557Sobrien		|| (! no_output_reloads && ! this_insn_is_asm)))
379318334Speter	  operand_reloadnum[i]
379418334Speter	    = push_reload (modified[i] != RELOAD_WRITE ? recog_operand[i] : 0,
379518334Speter			   modified[i] != RELOAD_READ ? recog_operand[i] : 0,
379618334Speter			   (modified[i] != RELOAD_WRITE
379718334Speter			    ? recog_operand_loc[i] : 0),
379818334Speter			   (modified[i] != RELOAD_READ
379918334Speter			    ? recog_operand_loc[i] : 0),
380018334Speter			   (enum reg_class) goal_alternative[i],
380118334Speter			   (modified[i] == RELOAD_WRITE
380218334Speter			    ? VOIDmode : operand_mode[i]),
380318334Speter			   (modified[i] == RELOAD_READ
380418334Speter			    ? VOIDmode : operand_mode[i]),
380518334Speter			   (insn_code_number < 0 ? 0
380618334Speter			    : insn_operand_strict_low[insn_code_number][i]),
380718334Speter			   1, i, operand_type[i]);
380852557Sobrien	/* If a memory reference remains (either as a MEM or a pseudo that
380952557Sobrien	   did not get a hard register), yet we can't make an optional
381052557Sobrien	   reload, check if this is actually a pseudo register reference;
381152557Sobrien	   we then need to emit a USE and/or a CLOBBER so that reload
381252557Sobrien	   inheritance will do the right thing.  */
381352557Sobrien	else if (replace
381452557Sobrien		 && (GET_CODE (operand) == MEM
381552557Sobrien		     || (GET_CODE (operand) == REG
381652557Sobrien			 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
381752557Sobrien			 && reg_renumber [REGNO (operand)] < 0)))
381852557Sobrien	  {
381952557Sobrien	    operand = *recog_operand_loc[i];
382052557Sobrien
382152557Sobrien	    while (GET_CODE (operand) == SUBREG)
382252557Sobrien	      operand = XEXP (operand, 0);
382352557Sobrien	    if (GET_CODE (operand) == REG)
382452557Sobrien	      {
382552557Sobrien		if (modified[i] != RELOAD_WRITE)
382652557Sobrien		  emit_insn_before (gen_rtx_USE (VOIDmode, operand), insn);
382752557Sobrien		if (modified[i] != RELOAD_READ)
382852557Sobrien		  emit_insn_after (gen_rtx_CLOBBER (VOIDmode, operand), insn);
382952557Sobrien	      }
383052557Sobrien	  }
383118334Speter      }
383218334Speter    else if (goal_alternative_matches[i] >= 0
383318334Speter	     && goal_alternative_win[goal_alternative_matches[i]]
383418334Speter	     && modified[i] == RELOAD_READ
383518334Speter	     && modified[goal_alternative_matches[i]] == RELOAD_WRITE
383618334Speter	     && ! no_input_reloads && ! no_output_reloads
383718334Speter	     && optimize)
383818334Speter      {
383918334Speter	/* Similarly, make an optional reload for a pair of matching
384018334Speter	   objects that are in MEM or a pseudo that didn't get a hard reg.  */
384118334Speter
384218334Speter	rtx operand = recog_operand[i];
384318334Speter
384418334Speter	while (GET_CODE (operand) == SUBREG)
384518334Speter	  operand = XEXP (operand, 0);
384618334Speter	if ((GET_CODE (operand) == MEM
384718334Speter	     || (GET_CODE (operand) == REG
384818334Speter		 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
384918334Speter	    && ((enum reg_class) goal_alternative[goal_alternative_matches[i]]
385018334Speter		!= NO_REGS))
385118334Speter	  operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]]
385218334Speter	    = push_reload (recog_operand[goal_alternative_matches[i]],
385318334Speter			   recog_operand[i],
385418334Speter			   recog_operand_loc[goal_alternative_matches[i]],
385518334Speter			   recog_operand_loc[i],
385618334Speter			   (enum reg_class) goal_alternative[goal_alternative_matches[i]],
385718334Speter			   operand_mode[goal_alternative_matches[i]],
385818334Speter			   operand_mode[i],
385918334Speter			   0, 1, goal_alternative_matches[i], RELOAD_OTHER);
386018334Speter      }
386118334Speter
386252557Sobrien  /* Perform whatever substitutions on the operands we are supposed
386352557Sobrien     to make due to commutativity or replacement of registers
386452557Sobrien     with equivalent constants or memory slots.  */
386552557Sobrien
386652557Sobrien  for (i = 0; i < noperands; i++)
386752557Sobrien    {
386852557Sobrien      /* We only do this on the last pass through reload, because it is
386952557Sobrien       possible for some data (like reg_equiv_address) to be changed during
387052557Sobrien       later passes.  Moreover, we loose the opportunity to get a useful
387152557Sobrien       reload_{in,out}_reg when we do these replacements.  */
387252557Sobrien
387352557Sobrien      if (replace)
387452557Sobrien	{
387552557Sobrien	  rtx substitution = substed_operand[i];
387652557Sobrien
387752557Sobrien	  *recog_operand_loc[i] = substitution;
387852557Sobrien
387952557Sobrien	  /* If we're replacing an operand with a LABEL_REF, we need
388052557Sobrien	     to make sure that there's a REG_LABEL note attached to
388152557Sobrien	     this instruction.  */
388252557Sobrien	  if (GET_CODE (insn) != JUMP_INSN
388352557Sobrien	      && GET_CODE (substitution) == LABEL_REF
388452557Sobrien	      && !find_reg_note (insn, REG_LABEL, XEXP (substitution, 0)))
388552557Sobrien	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL,
388652557Sobrien						  XEXP (substitution, 0),
388752557Sobrien						  REG_NOTES (insn));
388852557Sobrien	}
388952557Sobrien      else
389052557Sobrien	retval |= (substed_operand[i] != *recog_operand_loc[i]);
389152557Sobrien    }
389252557Sobrien
389318334Speter  /* If this insn pattern contains any MATCH_DUP's, make sure that
389418334Speter     they will be substituted if the operands they match are substituted.
389518334Speter     Also do now any substitutions we already did on the operands.
389618334Speter
389718334Speter     Don't do this if we aren't making replacements because we might be
389818334Speter     propagating things allocated by frame pointer elimination into places
389918334Speter     it doesn't expect.  */
390018334Speter
390118334Speter  if (insn_code_number >= 0 && replace)
390218334Speter    for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
390318334Speter      {
390418334Speter	int opno = recog_dup_num[i];
390518334Speter	*recog_dup_loc[i] = *recog_operand_loc[opno];
390618334Speter	if (operand_reloadnum[opno] >= 0)
390718334Speter	  push_replacement (recog_dup_loc[i], operand_reloadnum[opno],
390818334Speter			    insn_operand_mode[insn_code_number][opno]);
390918334Speter      }
391018334Speter
391118334Speter#if 0
391218334Speter  /* This loses because reloading of prior insns can invalidate the equivalence
391318334Speter     (or at least find_equiv_reg isn't smart enough to find it any more),
391418334Speter     causing this insn to need more reload regs than it needed before.
391518334Speter     It may be too late to make the reload regs available.
391618334Speter     Now this optimization is done safely in choose_reload_regs.  */
391718334Speter
391818334Speter  /* For each reload of a reg into some other class of reg,
391918334Speter     search for an existing equivalent reg (same value now) in the right class.
392018334Speter     We can use it as long as we don't need to change its contents.  */
392118334Speter  for (i = 0; i < n_reloads; i++)
392218334Speter    if (reload_reg_rtx[i] == 0
392318334Speter	&& reload_in[i] != 0
392418334Speter	&& GET_CODE (reload_in[i]) == REG
392518334Speter	&& reload_out[i] == 0)
392618334Speter      {
392718334Speter	reload_reg_rtx[i]
392818334Speter	  = find_equiv_reg (reload_in[i], insn, reload_reg_class[i], -1,
392918334Speter			    static_reload_reg_p, 0, reload_inmode[i]);
393018334Speter	/* Prevent generation of insn to load the value
393118334Speter	   because the one we found already has the value.  */
393218334Speter	if (reload_reg_rtx[i])
393318334Speter	  reload_in[i] = reload_reg_rtx[i];
393418334Speter      }
393518334Speter#endif
393618334Speter
393718334Speter  /* Perhaps an output reload can be combined with another
393818334Speter     to reduce needs by one.  */
393918334Speter  if (!goal_earlyclobber)
394018334Speter    combine_reloads ();
394118334Speter
394218334Speter  /* If we have a pair of reloads for parts of an address, they are reloading
394318334Speter     the same object, the operands themselves were not reloaded, and they
394418334Speter     are for two operands that are supposed to match, merge the reloads and
394550605Sobrien     change the type of the surviving reload to RELOAD_FOR_OPERAND_ADDRESS.  */
394618334Speter
394718334Speter  for (i = 0; i < n_reloads; i++)
394818334Speter    {
394918334Speter      int k;
395018334Speter
395118334Speter      for (j = i + 1; j < n_reloads; j++)
395218334Speter	if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
395350605Sobrien	     || reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
395450605Sobrien	     || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
395550605Sobrien	     || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
395618334Speter	    && (reload_when_needed[j] == RELOAD_FOR_INPUT_ADDRESS
395750605Sobrien		|| reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS
395850605Sobrien		|| reload_when_needed[j] == RELOAD_FOR_INPADDR_ADDRESS
395950605Sobrien		|| reload_when_needed[j] == RELOAD_FOR_OUTADDR_ADDRESS)
396018334Speter	    && rtx_equal_p (reload_in[i], reload_in[j])
396118334Speter	    && (operand_reloadnum[reload_opnum[i]] < 0
396218334Speter		|| reload_optional[operand_reloadnum[reload_opnum[i]]])
396318334Speter	    && (operand_reloadnum[reload_opnum[j]] < 0
396418334Speter		|| reload_optional[operand_reloadnum[reload_opnum[j]]])
396518334Speter	    && (goal_alternative_matches[reload_opnum[i]] == reload_opnum[j]
396618334Speter		|| (goal_alternative_matches[reload_opnum[j]]
396718334Speter		    == reload_opnum[i])))
396818334Speter	  {
396918334Speter	    for (k = 0; k < n_replacements; k++)
397018334Speter	      if (replacements[k].what == j)
397118334Speter		replacements[k].what = i;
397218334Speter
397350605Sobrien	    if (reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
397450605Sobrien		|| reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
397550605Sobrien	      reload_when_needed[i] = RELOAD_FOR_OPADDR_ADDR;
397650605Sobrien	    else
397750605Sobrien	      reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
397818334Speter	    reload_in[j] = 0;
397918334Speter	  }
398018334Speter    }
398118334Speter
398218334Speter  /* Scan all the reloads and update their type.
398318334Speter     If a reload is for the address of an operand and we didn't reload
398418334Speter     that operand, change the type.  Similarly, change the operand number
398518334Speter     of a reload when two operands match.  If a reload is optional, treat it
398618334Speter     as though the operand isn't reloaded.
398718334Speter
398818334Speter     ??? This latter case is somewhat odd because if we do the optional
398918334Speter     reload, it means the object is hanging around.  Thus we need only
399018334Speter     do the address reload if the optional reload was NOT done.
399118334Speter
399218334Speter     Change secondary reloads to be the address type of their operand, not
399318334Speter     the normal type.
399418334Speter
399518334Speter     If an operand's reload is now RELOAD_OTHER, change any
399618334Speter     RELOAD_FOR_INPUT_ADDRESS reloads of that operand to
399718334Speter     RELOAD_FOR_OTHER_ADDRESS.  */
399818334Speter
399918334Speter  for (i = 0; i < n_reloads; i++)
400018334Speter    {
400118334Speter      if (reload_secondary_p[i]
400218334Speter	  && reload_when_needed[i] == operand_type[reload_opnum[i]])
400318334Speter	reload_when_needed[i] = address_type[reload_opnum[i]];
400418334Speter
400518334Speter      if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
400650605Sobrien	   || reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
400750605Sobrien	   || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
400850605Sobrien	   || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
400918334Speter	  && (operand_reloadnum[reload_opnum[i]] < 0
401018334Speter	      || reload_optional[operand_reloadnum[reload_opnum[i]]]))
401118334Speter	{
401218334Speter	  /* If we have a secondary reload to go along with this reload,
401350605Sobrien	     change its type to RELOAD_FOR_OPADDR_ADDR.  */
401418334Speter
401550605Sobrien	  if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
401650605Sobrien	       || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
401718334Speter	      && reload_secondary_in_reload[i] != -1)
401818334Speter	    {
401918334Speter	      int secondary_in_reload = reload_secondary_in_reload[i];
402018334Speter
402150605Sobrien	      reload_when_needed[secondary_in_reload]
402250605Sobrien		= RELOAD_FOR_OPADDR_ADDR;
402318334Speter
402450605Sobrien	      /* If there's a tertiary reload we have to change it also.  */
402518334Speter	      if (secondary_in_reload > 0
402618334Speter		  && reload_secondary_in_reload[secondary_in_reload] != -1)
402718334Speter		reload_when_needed[reload_secondary_in_reload[secondary_in_reload]]
402818334Speter		  = RELOAD_FOR_OPADDR_ADDR;
402918334Speter	    }
403018334Speter
403150605Sobrien	  if ((reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
403250605Sobrien	       || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
403318334Speter	      && reload_secondary_out_reload[i] != -1)
403418334Speter	    {
403518334Speter	      int secondary_out_reload = reload_secondary_out_reload[i];
403618334Speter
403750605Sobrien	      reload_when_needed[secondary_out_reload]
403850605Sobrien		= RELOAD_FOR_OPADDR_ADDR;
403918334Speter
404050605Sobrien	      /* If there's a tertiary reload we have to change it also.  */
404118334Speter	      if (secondary_out_reload
404218334Speter		  && reload_secondary_out_reload[secondary_out_reload] != -1)
404318334Speter		reload_when_needed[reload_secondary_out_reload[secondary_out_reload]]
404418334Speter		  = RELOAD_FOR_OPADDR_ADDR;
404518334Speter	    }
404650605Sobrien
404752557Sobrien	  if (reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
404852557Sobrien	      || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
404952557Sobrien	    reload_when_needed[i] = RELOAD_FOR_OPADDR_ADDR;
405052557Sobrien	  else
405152557Sobrien	    reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
405218334Speter	}
405318334Speter
405450605Sobrien      if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
405550605Sobrien	   || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
405618334Speter	  && operand_reloadnum[reload_opnum[i]] >= 0
405718334Speter	  && (reload_when_needed[operand_reloadnum[reload_opnum[i]]]
405818334Speter	      == RELOAD_OTHER))
405918334Speter	reload_when_needed[i] = RELOAD_FOR_OTHER_ADDRESS;
406018334Speter
406118334Speter      if (goal_alternative_matches[reload_opnum[i]] >= 0)
406218334Speter	reload_opnum[i] = goal_alternative_matches[reload_opnum[i]];
406318334Speter    }
406418334Speter
406550605Sobrien  /* Scan all the reloads, and check for RELOAD_FOR_OPERAND_ADDRESS reloads.
406650605Sobrien     If we have more than one, then convert all RELOAD_FOR_OPADDR_ADDR
406750605Sobrien     reloads to RELOAD_FOR_OPERAND_ADDRESS reloads.
406850605Sobrien
406950605Sobrien     choose_reload_regs assumes that RELOAD_FOR_OPADDR_ADDR reloads never
407050605Sobrien     conflict with RELOAD_FOR_OPERAND_ADDRESS reloads.  This is true for a
407150605Sobrien     single pair of RELOAD_FOR_OPADDR_ADDR/RELOAD_FOR_OPERAND_ADDRESS reloads.
407250605Sobrien     However, if there is more than one RELOAD_FOR_OPERAND_ADDRESS reload,
407350605Sobrien     then a RELOAD_FOR_OPADDR_ADDR reload conflicts with all
407450605Sobrien     RELOAD_FOR_OPERAND_ADDRESS reloads other than the one that uses it.
407550605Sobrien     This is complicated by the fact that a single operand can have more
407650605Sobrien     than one RELOAD_FOR_OPERAND_ADDRESS reload.  It is very difficult to fix
407750605Sobrien     choose_reload_regs without affecting code quality, and cases that
407850605Sobrien     actually fail are extremely rare, so it turns out to be better to fix
407950605Sobrien     the problem here by not generating cases that choose_reload_regs will
408050605Sobrien     fail for.  */
408152557Sobrien  /* There is a similar problem with RELOAD_FOR_INPUT_ADDRESS /
408250605Sobrien     RELOAD_FOR_OUTPUT_ADDRESS when there is more than one of a kind for
408350605Sobrien     a single operand.
408450605Sobrien     We can reduce the register pressure by exploiting that a
408550605Sobrien     RELOAD_FOR_X_ADDR_ADDR that precedes all RELOAD_FOR_X_ADDRESS reloads
408652557Sobrien     does not conflict with any of them, if it is only used for the first of
408752557Sobrien     the RELOAD_FOR_X_ADDRESS reloads.  */
408850605Sobrien  {
408950605Sobrien    int first_op_addr_num = -2;
409050605Sobrien    int first_inpaddr_num[MAX_RECOG_OPERANDS];
409150605Sobrien    int first_outpaddr_num[MAX_RECOG_OPERANDS];
409250605Sobrien    int need_change= 0;
409350605Sobrien    /* We use last_op_addr_reload and the contents of the above arrays
409450605Sobrien       first as flags - -2 means no instance encountered, -1 means exactly
409550605Sobrien       one instance encountered.
409650605Sobrien       If more than one instance has been encountered, we store the reload
409750605Sobrien       number of the first reload of the kind in question; reload numbers
409850605Sobrien       are known to be non-negative.  */
409950605Sobrien    for (i = 0; i < noperands; i++)
410050605Sobrien      first_inpaddr_num[i] = first_outpaddr_num[i] = -2;
410150605Sobrien    for (i = n_reloads - 1; i >= 0; i--)
410250605Sobrien      {
410350605Sobrien	switch (reload_when_needed[i])
410450605Sobrien	  {
410550605Sobrien	  case RELOAD_FOR_OPERAND_ADDRESS:
410652557Sobrien	    if (++first_op_addr_num >= 0)
410750605Sobrien	      {
410852557Sobrien		first_op_addr_num = i;
410950605Sobrien		need_change = 1;
411050605Sobrien	      }
411150605Sobrien	    break;
411250605Sobrien	  case RELOAD_FOR_INPUT_ADDRESS:
411352557Sobrien	    if (++first_inpaddr_num[reload_opnum[i]] >= 0)
411450605Sobrien	      {
411550605Sobrien		first_inpaddr_num[reload_opnum[i]] = i;
411650605Sobrien		need_change = 1;
411750605Sobrien	      }
411850605Sobrien	    break;
411950605Sobrien	  case RELOAD_FOR_OUTPUT_ADDRESS:
412052557Sobrien	    if (++first_outpaddr_num[reload_opnum[i]] >= 0)
412150605Sobrien	      {
412250605Sobrien		first_outpaddr_num[reload_opnum[i]] = i;
412350605Sobrien		need_change = 1;
412450605Sobrien	      }
412550605Sobrien	    break;
412650605Sobrien	  default:
412750605Sobrien	    break;
412850605Sobrien	  }
412950605Sobrien      }
413050605Sobrien
413150605Sobrien    if (need_change)
413250605Sobrien      {
413350605Sobrien	for (i = 0; i < n_reloads; i++)
413450605Sobrien	  {
413550605Sobrien	    int first_num, type;
413650605Sobrien
413750605Sobrien	    switch (reload_when_needed[i])
413850605Sobrien	      {
413950605Sobrien	      case RELOAD_FOR_OPADDR_ADDR:
414050605Sobrien		first_num = first_op_addr_num;
414150605Sobrien		type = RELOAD_FOR_OPERAND_ADDRESS;
414250605Sobrien		break;
414350605Sobrien	      case RELOAD_FOR_INPADDR_ADDRESS:
414450605Sobrien		first_num = first_inpaddr_num[reload_opnum[i]];
414550605Sobrien		type = RELOAD_FOR_INPUT_ADDRESS;
414650605Sobrien		break;
414750605Sobrien	      case RELOAD_FOR_OUTADDR_ADDRESS:
414850605Sobrien		first_num = first_outpaddr_num[reload_opnum[i]];
414950605Sobrien		type = RELOAD_FOR_OUTPUT_ADDRESS;
415050605Sobrien		break;
415150605Sobrien	      default:
415250605Sobrien		continue;
415350605Sobrien	      }
415452557Sobrien	    if (first_num < 0)
415552557Sobrien	      continue;
415652557Sobrien	    else if (i > first_num)
415750605Sobrien	      reload_when_needed[i] = type;
415852557Sobrien	    else
415952557Sobrien	      {
416052557Sobrien		/* Check if the only TYPE reload that uses reload I is
416152557Sobrien		   reload FIRST_NUM.  */
416252557Sobrien		for (j = n_reloads - 1; j > first_num; j--)
416352557Sobrien		  {
416452557Sobrien		    if (reload_when_needed[j] == type
416552557Sobrien			&& (reload_secondary_p[i]
416652557Sobrien			    ? reload_secondary_in_reload[j] == i
416752557Sobrien			    : reg_mentioned_p (reload_in[i], reload_in[j])))
416852557Sobrien		      {
416952557Sobrien			reload_when_needed[i] = type;
417052557Sobrien			break;
417152557Sobrien		      }
417252557Sobrien		  }
417352557Sobrien	      }
417450605Sobrien	  }
417550605Sobrien      }
417650605Sobrien  }
417750605Sobrien
417818334Speter  /* See if we have any reloads that are now allowed to be merged
417918334Speter     because we've changed when the reload is needed to
418018334Speter     RELOAD_FOR_OPERAND_ADDRESS or RELOAD_FOR_OTHER_ADDRESS.  Only
418118334Speter     check for the most common cases.  */
418218334Speter
418318334Speter  for (i = 0; i < n_reloads; i++)
418418334Speter    if (reload_in[i] != 0 && reload_out[i] == 0
418518334Speter	&& (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS
418650605Sobrien	    || reload_when_needed[i] == RELOAD_FOR_OPADDR_ADDR
418718334Speter	    || reload_when_needed[i] == RELOAD_FOR_OTHER_ADDRESS))
418818334Speter      for (j = 0; j < n_reloads; j++)
418918334Speter	if (i != j && reload_in[j] != 0 && reload_out[j] == 0
419018334Speter	    && reload_when_needed[j] == reload_when_needed[i]
419118334Speter	    && MATCHES (reload_in[i], reload_in[j])
419218334Speter	    && reload_reg_class[i] == reload_reg_class[j]
419318334Speter	    && !reload_nocombine[i] && !reload_nocombine[j]
419418334Speter	    && reload_reg_rtx[i] == reload_reg_rtx[j])
419518334Speter	  {
419618334Speter	    reload_opnum[i] = MIN (reload_opnum[i], reload_opnum[j]);
419718334Speter	    transfer_replacements (i, j);
419818334Speter	    reload_in[j] = 0;
419918334Speter	  }
420018334Speter
420150605Sobrien  /* Set which reloads must use registers not used in any group.  Start
420250605Sobrien     with those that conflict with a group and then include ones that
420350605Sobrien     conflict with ones that are already known to conflict with a group.  */
420450605Sobrien
420550605Sobrien  changed = 0;
420650605Sobrien  for (i = 0; i < n_reloads; i++)
420750605Sobrien    {
420850605Sobrien      enum machine_mode mode = reload_inmode[i];
420950605Sobrien      enum reg_class class = reload_reg_class[i];
421050605Sobrien      int size;
421150605Sobrien
421250605Sobrien      if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))
421350605Sobrien	mode = reload_outmode[i];
421450605Sobrien      size = CLASS_MAX_NREGS (class, mode);
421550605Sobrien
421650605Sobrien      if (size == 1)
421750605Sobrien	for (j = 0; j < n_reloads; j++)
421850605Sobrien	  if ((CLASS_MAX_NREGS (reload_reg_class[j],
421950605Sobrien				(GET_MODE_SIZE (reload_outmode[j])
422050605Sobrien				 > GET_MODE_SIZE (reload_inmode[j]))
422150605Sobrien				? reload_outmode[j] : reload_inmode[j])
422250605Sobrien	       > 1)
422350605Sobrien	      && !reload_optional[j]
422450605Sobrien	      && (reload_in[j] != 0 || reload_out[j] != 0
422550605Sobrien		  || reload_secondary_p[j])
422650605Sobrien	      && reloads_conflict (i, j)
422750605Sobrien	      && reg_classes_intersect_p (class, reload_reg_class[j]))
422850605Sobrien	    {
422950605Sobrien	      reload_nongroup[i] = 1;
423050605Sobrien	      changed = 1;
423150605Sobrien	      break;
423250605Sobrien	    }
423350605Sobrien    }
423450605Sobrien
423550605Sobrien  while (changed)
423650605Sobrien    {
423750605Sobrien      changed = 0;
423850605Sobrien
423950605Sobrien      for (i = 0; i < n_reloads; i++)
424050605Sobrien	{
424150605Sobrien	  enum machine_mode mode = reload_inmode[i];
424250605Sobrien	  enum reg_class class = reload_reg_class[i];
424350605Sobrien	  int size;
424450605Sobrien
424550605Sobrien	  if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))
424650605Sobrien	    mode = reload_outmode[i];
424750605Sobrien	  size = CLASS_MAX_NREGS (class, mode);
424850605Sobrien
424950605Sobrien	  if (! reload_nongroup[i] && size == 1)
425050605Sobrien	    for (j = 0; j < n_reloads; j++)
425150605Sobrien	      if (reload_nongroup[j]
425250605Sobrien		  && reloads_conflict (i, j)
425350605Sobrien		  && reg_classes_intersect_p (class, reload_reg_class[j]))
425450605Sobrien		{
425550605Sobrien		  reload_nongroup[i] = 1;
425650605Sobrien		  changed = 1;
425750605Sobrien		  break;
425850605Sobrien		}
425950605Sobrien	}
426050605Sobrien    }
426150605Sobrien
426218334Speter#else /* no REGISTER_CONSTRAINTS */
426318334Speter  int noperands;
426418334Speter  int insn_code_number;
426518334Speter  int goal_earlyclobber = 0; /* Always 0, to make combine_reloads happen.  */
426618334Speter  register int i;
426718334Speter  rtx body = PATTERN (insn);
426852557Sobrien  int retval = 0;
426918334Speter
427018334Speter  n_reloads = 0;
427118334Speter  n_replacements = 0;
427218334Speter  n_earlyclobbers = 0;
427318334Speter  replace_reloads = replace;
427418334Speter  this_insn = insn;
427518334Speter
427652557Sobrien  extract_insn (insn);
427718334Speter
427852557Sobrien  noperands = reload_n_operands = recog_n_operands;
427918334Speter
428052557Sobrien  /* Return if the insn needs no reload processing.  */
428118334Speter  if (noperands == 0)
428218334Speter    return;
428318334Speter
428418334Speter  for (i = 0; i < noperands; i++)
428518334Speter    {
428618334Speter      register RTX_CODE code = GET_CODE (recog_operand[i]);
428718334Speter      int is_set_dest = GET_CODE (body) == SET && (i == 0);
428818334Speter
428918334Speter      if (insn_code_number >= 0)
429018334Speter	if (insn_operand_address_p[insn_code_number][i])
429118334Speter	  find_reloads_address (VOIDmode, NULL_PTR,
429218334Speter				recog_operand[i], recog_operand_loc[i],
429350605Sobrien				i, RELOAD_FOR_INPUT, ind_levels, insn);
429418334Speter
429518334Speter      /* In these cases, we can't tell if the operand is an input
429618334Speter	 or an output, so be conservative.  In practice it won't be
429718334Speter	 problem.  */
429818334Speter
429918334Speter      if (code == MEM)
430018334Speter	find_reloads_address (GET_MODE (recog_operand[i]),
430118334Speter			      recog_operand_loc[i],
430218334Speter			      XEXP (recog_operand[i], 0),
430318334Speter			      &XEXP (recog_operand[i], 0),
430450605Sobrien			      i, RELOAD_OTHER, ind_levels, insn);
430518334Speter      if (code == SUBREG)
430618334Speter	recog_operand[i] = *recog_operand_loc[i]
430718334Speter	  = find_reloads_toplev (recog_operand[i], i, RELOAD_OTHER,
430818334Speter				 ind_levels, is_set_dest);
430918334Speter      if (code == REG)
431018334Speter	{
431118334Speter	  register int regno = REGNO (recog_operand[i]);
431218334Speter	  if (reg_equiv_constant[regno] != 0 && !is_set_dest)
431318334Speter	    recog_operand[i] = *recog_operand_loc[i]
431418334Speter	      = reg_equiv_constant[regno];
431518334Speter#if 0 /* This might screw code in reload1.c to delete prior output-reload
431618334Speter	 that feeds this insn.  */
431718334Speter	  if (reg_equiv_mem[regno] != 0)
431818334Speter	    recog_operand[i] = *recog_operand_loc[i]
431918334Speter	      = reg_equiv_mem[regno];
432018334Speter#endif
432118334Speter	}
432218334Speter    }
432318334Speter
432418334Speter  /* Perhaps an output reload can be combined with another
432518334Speter     to reduce needs by one.  */
432618334Speter  if (!goal_earlyclobber)
432718334Speter    combine_reloads ();
432818334Speter#endif /* no REGISTER_CONSTRAINTS */
432952557Sobrien  return retval;
433018334Speter}
433118334Speter
433218334Speter/* Return 1 if alternative number ALTNUM in constraint-string CONSTRAINT
433318334Speter   accepts a memory operand with constant address.  */
433418334Speter
433518334Speterstatic int
433618334Speteralternative_allows_memconst (constraint, altnum)
433752557Sobrien     const char *constraint;
433818334Speter     int altnum;
433918334Speter{
434018334Speter  register int c;
434118334Speter  /* Skip alternatives before the one requested.  */
434218334Speter  while (altnum > 0)
434318334Speter    {
434418334Speter      while (*constraint++ != ',');
434518334Speter      altnum--;
434618334Speter    }
434718334Speter  /* Scan the requested alternative for 'm' or 'o'.
434818334Speter     If one of them is present, this alternative accepts memory constants.  */
434918334Speter  while ((c = *constraint++) && c != ',' && c != '#')
435018334Speter    if (c == 'm' || c == 'o')
435118334Speter      return 1;
435218334Speter  return 0;
435318334Speter}
435418334Speter
435518334Speter/* Scan X for memory references and scan the addresses for reloading.
435618334Speter   Also checks for references to "constant" regs that we want to eliminate
435718334Speter   and replaces them with the values they stand for.
435818334Speter   We may alter X destructively if it contains a reference to such.
435918334Speter   If X is just a constant reg, we return the equivalent value
436018334Speter   instead of X.
436118334Speter
436218334Speter   IND_LEVELS says how many levels of indirect addressing this machine
436318334Speter   supports.
436418334Speter
436518334Speter   OPNUM and TYPE identify the purpose of the reload.
436618334Speter
436718334Speter   IS_SET_DEST is true if X is the destination of a SET, which is not
436852557Sobrien   appropriate to be replaced by a constant.
436918334Speter
437052557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
437152557Sobrien   to determine if we may generate output reloads, and where to put USEs
437252557Sobrien   for pseudos that we have to replace with stack slots.  */
437352557Sobrien
437418334Speterstatic rtx
437552557Sobrienfind_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn)
437618334Speter     rtx x;
437718334Speter     int opnum;
437818334Speter     enum reload_type type;
437918334Speter     int ind_levels;
438018334Speter     int is_set_dest;
438152557Sobrien     rtx insn;
438218334Speter{
438318334Speter  register RTX_CODE code = GET_CODE (x);
438418334Speter
438518334Speter  register char *fmt = GET_RTX_FORMAT (code);
438618334Speter  register int i;
438752557Sobrien  int copied;
438818334Speter
438918334Speter  if (code == REG)
439018334Speter    {
439118334Speter      /* This code is duplicated for speed in find_reloads.  */
439218334Speter      register int regno = REGNO (x);
439318334Speter      if (reg_equiv_constant[regno] != 0 && !is_set_dest)
439418334Speter	x = reg_equiv_constant[regno];
439518334Speter#if 0
439618334Speter/*  This creates (subreg (mem...)) which would cause an unnecessary
439718334Speter    reload of the mem.  */
439818334Speter      else if (reg_equiv_mem[regno] != 0)
439918334Speter	x = reg_equiv_mem[regno];
440018334Speter#endif
440152557Sobrien      else if (reg_equiv_memory_loc[regno]
440252557Sobrien	       && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
440318334Speter	{
440452557Sobrien	  rtx mem = make_memloc (x, regno);
440552557Sobrien	  if (reg_equiv_address[regno]
440652557Sobrien	      || ! rtx_equal_p (mem, reg_equiv_mem[regno]))
440752557Sobrien	    {
440852557Sobrien	      /* If this is not a toplevel operand, find_reloads doesn't see
440952557Sobrien		 this substitution.  We have to emit a USE of the pseudo so
441052557Sobrien		 that delete_output_reload can see it.  */
441152557Sobrien	      if (replace_reloads && recog_operand[opnum] != x)
441252557Sobrien		emit_insn_before (gen_rtx_USE (VOIDmode, x), insn);
441352557Sobrien	      x = mem;
441452557Sobrien	      find_reloads_address (GET_MODE (x), &x, XEXP (x, 0), &XEXP (x, 0),
441552557Sobrien				    opnum, type, ind_levels, insn);
441652557Sobrien	    }
441718334Speter	}
441818334Speter      return x;
441918334Speter    }
442018334Speter  if (code == MEM)
442118334Speter    {
442218334Speter      rtx tem = x;
442318334Speter      find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0),
442452557Sobrien			    opnum, type, ind_levels, insn);
442518334Speter      return tem;
442618334Speter    }
442718334Speter
442818334Speter  if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)
442918334Speter    {
443018334Speter      /* Check for SUBREG containing a REG that's equivalent to a constant.
443118334Speter	 If the constant has a known value, truncate it right now.
443218334Speter	 Similarly if we are extracting a single-word of a multi-word
443318334Speter	 constant.  If the constant is symbolic, allow it to be substituted
443418334Speter	 normally.  push_reload will strip the subreg later.  If the
443518334Speter	 constant is VOIDmode, abort because we will lose the mode of
443618334Speter	 the register (this should never happen because one of the cases
443718334Speter	 above should handle it).  */
443818334Speter
443918334Speter      register int regno = REGNO (SUBREG_REG (x));
444018334Speter      rtx tem;
444118334Speter
444218334Speter      if (subreg_lowpart_p (x)
444318334Speter	  && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
444418334Speter	  && reg_equiv_constant[regno] != 0
444518334Speter	  && (tem = gen_lowpart_common (GET_MODE (x),
444618334Speter					reg_equiv_constant[regno])) != 0)
444718334Speter	return tem;
444818334Speter
444918334Speter      if (GET_MODE_BITSIZE (GET_MODE (x)) == BITS_PER_WORD
445018334Speter	  && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
445118334Speter	  && reg_equiv_constant[regno] != 0
445218334Speter	  && (tem = operand_subword (reg_equiv_constant[regno],
445318334Speter				     SUBREG_WORD (x), 0,
445418334Speter				     GET_MODE (SUBREG_REG (x)))) != 0)
445550605Sobrien	{
445650605Sobrien	  /* TEM is now a word sized constant for the bits from X that
445750605Sobrien	     we wanted.  However, TEM may be the wrong representation.
445818334Speter
445950605Sobrien	     Use gen_lowpart_common to convert a CONST_INT into a
446050605Sobrien	     CONST_DOUBLE and vice versa as needed according to by the mode
446150605Sobrien	     of the SUBREG.  */
446250605Sobrien	  tem = gen_lowpart_common (GET_MODE (x), tem);
446350605Sobrien	  if (!tem)
446450605Sobrien	    abort ();
446550605Sobrien	  return tem;
446650605Sobrien	}
446750605Sobrien
446850605Sobrien      /* If the SUBREG is wider than a word, the above test will fail.
446950605Sobrien	 For example, we might have a SImode SUBREG of a DImode SUBREG_REG
447050605Sobrien	 for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
447150605Sobrien	 a 32 bit target.  We still can - and have to - handle this
447250605Sobrien	 for non-paradoxical subregs of CONST_INTs.  */
447318334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
447418334Speter	  && reg_equiv_constant[regno] != 0
447550605Sobrien	  && GET_CODE (reg_equiv_constant[regno]) == CONST_INT
447650605Sobrien	  && (GET_MODE_SIZE (GET_MODE (x))
447750605Sobrien	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
447850605Sobrien	  {
447950605Sobrien	    int shift = SUBREG_WORD (x) * BITS_PER_WORD;
448050605Sobrien	    if (WORDS_BIG_ENDIAN)
448150605Sobrien	      shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
448250605Sobrien		       - GET_MODE_BITSIZE (GET_MODE (x))
448350605Sobrien		       - shift);
448450605Sobrien	    /* Here we use the knowledge that CONST_INTs have a
448550605Sobrien	       HOST_WIDE_INT field.  */
448650605Sobrien	    if (shift >= HOST_BITS_PER_WIDE_INT)
448750605Sobrien	      shift = HOST_BITS_PER_WIDE_INT - 1;
448850605Sobrien	    return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
448950605Sobrien	  }
449050605Sobrien
449150605Sobrien      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
449250605Sobrien	  && reg_equiv_constant[regno] != 0
449318334Speter	  && GET_MODE (reg_equiv_constant[regno]) == VOIDmode)
449418334Speter	abort ();
449518334Speter
449618334Speter      /* If the subreg contains a reg that will be converted to a mem,
449718334Speter	 convert the subreg to a narrower memref now.
449818334Speter	 Otherwise, we would get (subreg (mem ...) ...),
449918334Speter	 which would force reload of the mem.
450018334Speter
450118334Speter	 We also need to do this if there is an equivalent MEM that is
450218334Speter	 not offsettable.  In that case, alter_subreg would produce an
450318334Speter	 invalid address on big-endian machines.
450418334Speter
450518334Speter	 For machines that extend byte loads, we must not reload using
450618334Speter	 a wider mode if we have a paradoxical SUBREG.  find_reloads will
450718334Speter	 force a reload in that case.  So we should not do anything here.  */
450818334Speter
450918334Speter      else if (regno >= FIRST_PSEUDO_REGISTER
451018334Speter#ifdef LOAD_EXTEND_OP
451118334Speter	       && (GET_MODE_SIZE (GET_MODE (x))
451218334Speter		   <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
451318334Speter#endif
451418334Speter	       && (reg_equiv_address[regno] != 0
451518334Speter		   || (reg_equiv_mem[regno] != 0
451618334Speter		       && (! strict_memory_address_p (GET_MODE (x),
451718334Speter						      XEXP (reg_equiv_mem[regno], 0))
451852557Sobrien			   || ! offsettable_memref_p (reg_equiv_mem[regno])
451952557Sobrien			   || num_not_at_initial_offset))))
452052557Sobrien	x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
452152557Sobrien					 insn);
452252557Sobrien    }
452352557Sobrien
452452557Sobrien  for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
452552557Sobrien    {
452652557Sobrien      if (fmt[i] == 'e')
452718334Speter	{
452852557Sobrien	  rtx new_part = find_reloads_toplev (XEXP (x, i), opnum, type,
452952557Sobrien					      ind_levels, is_set_dest, insn);
453052557Sobrien	  /* If we have replaced a reg with it's equivalent memory loc -
453152557Sobrien	     that can still be handled here e.g. if it's in a paradoxical
453252557Sobrien	     subreg - we must make the change in a copy, rather than using
453352557Sobrien	     a destructive change.  This way, find_reloads can still elect
453452557Sobrien	     not to do the change.  */
453552557Sobrien	  if (new_part != XEXP (x, i) && ! CONSTANT_P (new_part) && ! copied)
453618334Speter	    {
453752557Sobrien	      x = shallow_copy_rtx (x);
453852557Sobrien	      copied = 1;
453918334Speter	    }
454052557Sobrien	  XEXP (x, i) = new_part;
454118334Speter	}
454218334Speter    }
454318334Speter  return x;
454418334Speter}
454518334Speter
454618334Speter/* Return a mem ref for the memory equivalent of reg REGNO.
454718334Speter   This mem ref is not shared with anything.  */
454818334Speter
454918334Speterstatic rtx
455018334Spetermake_memloc (ad, regno)
455118334Speter     rtx ad;
455218334Speter     int regno;
455318334Speter{
455418334Speter  /* We must rerun eliminate_regs, in case the elimination
455518334Speter     offsets have changed.  */
455652557Sobrien  rtx tem
455752557Sobrien    = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0, NULL_RTX), 0);
455818334Speter
455918334Speter  /* If TEM might contain a pseudo, we must copy it to avoid
456018334Speter     modifying it when we do the substitution for the reload.  */
456118334Speter  if (rtx_varies_p (tem))
456218334Speter    tem = copy_rtx (tem);
456318334Speter
456450605Sobrien  tem = gen_rtx_MEM (GET_MODE (ad), tem);
456518334Speter  RTX_UNCHANGING_P (tem) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
456618334Speter  return tem;
456718334Speter}
456818334Speter
456918334Speter/* Record all reloads needed for handling memory address AD
457018334Speter   which appears in *LOC in a memory reference to mode MODE
457118334Speter   which itself is found in location  *MEMREFLOC.
457218334Speter   Note that we take shortcuts assuming that no multi-reg machine mode
457318334Speter   occurs as part of an address.
457418334Speter
457518334Speter   OPNUM and TYPE specify the purpose of this reload.
457618334Speter
457718334Speter   IND_LEVELS says how many levels of indirect addressing this machine
457818334Speter   supports.
457918334Speter
458050605Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
458152557Sobrien   to determine if we may generate output reloads, and where to put USEs
458252557Sobrien   for pseudos that we have to replace with stack slots.
458350605Sobrien
458418334Speter   Value is nonzero if this address is reloaded or replaced as a whole.
458518334Speter   This is interesting to the caller if the address is an autoincrement.
458618334Speter
458718334Speter   Note that there is no verification that the address will be valid after
458818334Speter   this routine does its work.  Instead, we rely on the fact that the address
458918334Speter   was valid when reload started.  So we need only undo things that reload
459018334Speter   could have broken.  These are wrong register types, pseudos not allocated
459118334Speter   to a hard register, and frame pointer elimination.  */
459218334Speter
459318334Speterstatic int
459450605Sobrienfind_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
459518334Speter     enum machine_mode mode;
459618334Speter     rtx *memrefloc;
459718334Speter     rtx ad;
459818334Speter     rtx *loc;
459918334Speter     int opnum;
460018334Speter     enum reload_type type;
460118334Speter     int ind_levels;
460250605Sobrien     rtx insn;
460318334Speter{
460418334Speter  register int regno;
460552557Sobrien  int removed_and = 0;
460618334Speter  rtx tem;
460718334Speter
460818334Speter  /* If the address is a register, see if it is a legitimate address and
460918334Speter     reload if not.  We first handle the cases where we need not reload
461018334Speter     or where we must reload in a non-standard way.  */
461118334Speter
461218334Speter  if (GET_CODE (ad) == REG)
461318334Speter    {
461418334Speter      regno = REGNO (ad);
461518334Speter
461618334Speter      if (reg_equiv_constant[regno] != 0
461718334Speter	  && strict_memory_address_p (mode, reg_equiv_constant[regno]))
461818334Speter	{
461918334Speter	  *loc = ad = reg_equiv_constant[regno];
462052557Sobrien	  return 0;
462118334Speter	}
462218334Speter
462352557Sobrien      tem = reg_equiv_memory_loc[regno];
462452557Sobrien      if (tem != 0)
462518334Speter	{
462652557Sobrien	  if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
462752557Sobrien	    {
462852557Sobrien	      tem = make_memloc (ad, regno);
462952557Sobrien	      if (! strict_memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
463052557Sobrien		{
463152557Sobrien		  find_reloads_address (GET_MODE (tem), NULL_PTR, XEXP (tem, 0),
463252557Sobrien					&XEXP (tem, 0), opnum, ADDR_TYPE (type),
463352557Sobrien					ind_levels, insn);
463452557Sobrien		}
463552557Sobrien	      /* We can avoid a reload if the register's equivalent memory
463652557Sobrien		 expression is valid as an indirect memory address.
463752557Sobrien		 But not all addresses are valid in a mem used as an indirect
463852557Sobrien		 address: only reg or reg+constant.  */
463952557Sobrien
464052557Sobrien	      if (ind_levels > 0
464152557Sobrien		  && strict_memory_address_p (mode, tem)
464252557Sobrien		  && (GET_CODE (XEXP (tem, 0)) == REG
464352557Sobrien		      || (GET_CODE (XEXP (tem, 0)) == PLUS
464452557Sobrien			  && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
464552557Sobrien			  && CONSTANT_P (XEXP (XEXP (tem, 0), 1)))))
464652557Sobrien		{
464752557Sobrien		  /* TEM is not the same as what we'll be replacing the
464852557Sobrien		     pseudo with after reload, put a USE in front of INSN
464952557Sobrien		     in the final reload pass.  */
465052557Sobrien		  if (replace_reloads
465152557Sobrien		      && num_not_at_initial_offset
465252557Sobrien		      && ! rtx_equal_p (tem, reg_equiv_mem[regno]))
465352557Sobrien		    {
465452557Sobrien		      *loc = tem;
465552557Sobrien		      emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn);
465652557Sobrien		      /* This doesn't really count as replacing the address
465752557Sobrien			 as a whole, since it is still a memory access.  */
465852557Sobrien		    }
465952557Sobrien		  return 0;
466052557Sobrien		}
466152557Sobrien	      ad = tem;
466252557Sobrien	    }
466318334Speter	}
466418334Speter
466518334Speter      /* The only remaining case where we can avoid a reload is if this is a
466618334Speter	 hard register that is valid as a base register and which is not the
466718334Speter	 subject of a CLOBBER in this insn.  */
466818334Speter
466950605Sobrien      else if (regno < FIRST_PSEUDO_REGISTER
467050605Sobrien	       && REGNO_MODE_OK_FOR_BASE_P (regno, mode)
467118334Speter	       && ! regno_clobbered_p (regno, this_insn))
467218334Speter	return 0;
467318334Speter
467418334Speter      /* If we do not have one of the cases above, we must do the reload.  */
467552557Sobrien      push_reload (ad, NULL_RTX, loc, NULL_PTR, BASE_REG_CLASS,
467618334Speter		   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
467718334Speter      return 1;
467818334Speter    }
467918334Speter
468018334Speter  if (strict_memory_address_p (mode, ad))
468118334Speter    {
468218334Speter      /* The address appears valid, so reloads are not needed.
468318334Speter	 But the address may contain an eliminable register.
468418334Speter	 This can happen because a machine with indirect addressing
468518334Speter	 may consider a pseudo register by itself a valid address even when
468618334Speter	 it has failed to get a hard reg.
468718334Speter	 So do a tree-walk to find and eliminate all such regs.  */
468818334Speter
468918334Speter      /* But first quickly dispose of a common case.  */
469018334Speter      if (GET_CODE (ad) == PLUS
469118334Speter	  && GET_CODE (XEXP (ad, 1)) == CONST_INT
469218334Speter	  && GET_CODE (XEXP (ad, 0)) == REG
469318334Speter	  && reg_equiv_constant[REGNO (XEXP (ad, 0))] == 0)
469418334Speter	return 0;
469518334Speter
469618334Speter      subst_reg_equivs_changed = 0;
469752557Sobrien      *loc = subst_reg_equivs (ad, insn);
469818334Speter
469918334Speter      if (! subst_reg_equivs_changed)
470018334Speter	return 0;
470118334Speter
470218334Speter      /* Check result for validity after substitution.  */
470318334Speter      if (strict_memory_address_p (mode, ad))
470418334Speter	return 0;
470518334Speter    }
470618334Speter
470750605Sobrien#ifdef LEGITIMIZE_RELOAD_ADDRESS
470850605Sobrien  do
470950605Sobrien    {
471050605Sobrien      if (memrefloc)
471150605Sobrien	{
471250605Sobrien	  LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
471350605Sobrien				     ind_levels, win);
471450605Sobrien	}
471550605Sobrien      break;
471650605Sobrien    win:
471750605Sobrien      *memrefloc = copy_rtx (*memrefloc);
471850605Sobrien      XEXP (*memrefloc, 0) = ad;
471950605Sobrien      move_replacements (&ad, &XEXP (*memrefloc, 0));
472050605Sobrien      return 1;
472150605Sobrien    }
472250605Sobrien  while (0);
472350605Sobrien#endif
472450605Sobrien
472552557Sobrien  /* The address is not valid.  We have to figure out why.  First see if
472652557Sobrien     we have an outer AND and remove it if so.  Then analyze what's inside.  */
472752557Sobrien
472852557Sobrien  if (GET_CODE (ad) == AND)
472952557Sobrien    {
473052557Sobrien      removed_and = 1;
473152557Sobrien      loc = &XEXP (ad, 0);
473252557Sobrien      ad = *loc;
473352557Sobrien    }
473452557Sobrien
473552557Sobrien  /* One possibility for why the address is invalid is that it is itself
473652557Sobrien     a MEM.  This can happen when the frame pointer is being eliminated, a
473752557Sobrien     pseudo is not allocated to a hard register, and the offset between the
473852557Sobrien     frame and stack pointers is not its initial value.  In that case the
473952557Sobrien     pseudo will have been replaced by a MEM referring to the
474052557Sobrien     stack pointer.  */
474118334Speter  if (GET_CODE (ad) == MEM)
474218334Speter    {
474318334Speter      /* First ensure that the address in this MEM is valid.  Then, unless
474418334Speter	 indirect addresses are valid, reload the MEM into a register.  */
474518334Speter      tem = ad;
474618334Speter      find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0),
474750605Sobrien			    opnum, ADDR_TYPE (type),
474850605Sobrien			    ind_levels == 0 ? 0 : ind_levels - 1, insn);
474918334Speter
475018334Speter      /* If tem was changed, then we must create a new memory reference to
475118334Speter	 hold it and store it back into memrefloc.  */
475218334Speter      if (tem != ad && memrefloc)
475318334Speter	{
475418334Speter	  *memrefloc = copy_rtx (*memrefloc);
475518334Speter	  copy_replacements (tem, XEXP (*memrefloc, 0));
475618334Speter	  loc = &XEXP (*memrefloc, 0);
475752557Sobrien	  if (removed_and)
475852557Sobrien	    loc = &XEXP (*loc, 0);
475918334Speter	}
476018334Speter
476118334Speter      /* Check similar cases as for indirect addresses as above except
476218334Speter	 that we can allow pseudos and a MEM since they should have been
476318334Speter	 taken care of above.  */
476418334Speter
476518334Speter      if (ind_levels == 0
476618334Speter	  || (GET_CODE (XEXP (tem, 0)) == SYMBOL_REF && ! indirect_symref_ok)
476718334Speter	  || GET_CODE (XEXP (tem, 0)) == MEM
476818334Speter	  || ! (GET_CODE (XEXP (tem, 0)) == REG
476918334Speter		|| (GET_CODE (XEXP (tem, 0)) == PLUS
477018334Speter		    && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
477118334Speter		    && GET_CODE (XEXP (XEXP (tem, 0), 1)) == CONST_INT)))
477218334Speter	{
477318334Speter	  /* Must use TEM here, not AD, since it is the one that will
477418334Speter	     have any subexpressions reloaded, if needed.  */
477518334Speter	  push_reload (tem, NULL_RTX, loc, NULL_PTR,
477652557Sobrien		       BASE_REG_CLASS, GET_MODE (tem),
477750605Sobrien		       VOIDmode, 0,
477818334Speter		       0, opnum, type);
477952557Sobrien	  return ! removed_and;
478018334Speter	}
478118334Speter      else
478218334Speter	return 0;
478318334Speter    }
478418334Speter
478518334Speter  /* If we have address of a stack slot but it's not valid because the
478618334Speter     displacement is too large, compute the sum in a register.
478718334Speter     Handle all base registers here, not just fp/ap/sp, because on some
478818334Speter     targets (namely SH) we can also get too large displacements from
478918334Speter     big-endian corrections.  */
479018334Speter  else if (GET_CODE (ad) == PLUS
479118334Speter	   && GET_CODE (XEXP (ad, 0)) == REG
479218334Speter	   && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
479350605Sobrien	   && REG_MODE_OK_FOR_BASE_P (XEXP (ad, 0), mode)
479418334Speter	   && GET_CODE (XEXP (ad, 1)) == CONST_INT)
479518334Speter    {
479618334Speter      /* Unshare the MEM rtx so we can safely alter it.  */
479718334Speter      if (memrefloc)
479818334Speter	{
479918334Speter	  *memrefloc = copy_rtx (*memrefloc);
480018334Speter	  loc = &XEXP (*memrefloc, 0);
480152557Sobrien	  if (removed_and)
480252557Sobrien	    loc = &XEXP (*loc, 0);
480318334Speter	}
480452557Sobrien
480518334Speter      if (double_reg_address_ok)
480618334Speter	{
480718334Speter	  /* Unshare the sum as well.  */
480818334Speter	  *loc = ad = copy_rtx (ad);
480952557Sobrien
481018334Speter	  /* Reload the displacement into an index reg.
481118334Speter	     We assume the frame pointer or arg pointer is a base reg.  */
481218334Speter	  find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
481352557Sobrien				     INDEX_REG_CLASS, GET_MODE (ad), opnum,
481452557Sobrien				     type, ind_levels);
481552557Sobrien	  return 0;
481618334Speter	}
481718334Speter      else
481818334Speter	{
481918334Speter	  /* If the sum of two regs is not necessarily valid,
482018334Speter	     reload the sum into a base reg.
482118334Speter	     That will at least work.  */
482252557Sobrien	  find_reloads_address_part (ad, loc, BASE_REG_CLASS,
482350605Sobrien				     Pmode, opnum, type, ind_levels);
482418334Speter	}
482552557Sobrien      return ! removed_and;
482618334Speter    }
482718334Speter
482818334Speter  /* If we have an indexed stack slot, there are three possible reasons why
482918334Speter     it might be invalid: The index might need to be reloaded, the address
483018334Speter     might have been made by frame pointer elimination and hence have a
483118334Speter     constant out of range, or both reasons might apply.
483218334Speter
483318334Speter     We can easily check for an index needing reload, but even if that is the
483418334Speter     case, we might also have an invalid constant.  To avoid making the
483518334Speter     conservative assumption and requiring two reloads, we see if this address
483618334Speter     is valid when not interpreted strictly.  If it is, the only problem is
483718334Speter     that the index needs a reload and find_reloads_address_1 will take care
483818334Speter     of it.
483918334Speter
484018334Speter     There is still a case when we might generate an extra reload,
484118334Speter     however.  In certain cases eliminate_regs will return a MEM for a REG
484218334Speter     (see the code there for details).  In those cases, memory_address_p
484318334Speter     applied to our address will return 0 so we will think that our offset
484418334Speter     must be too large.  But it might indeed be valid and the only problem
484518334Speter     is that a MEM is present where a REG should be.  This case should be
484618334Speter     very rare and there doesn't seem to be any way to avoid it.
484718334Speter
484818334Speter     If we decide to do something here, it must be that
484918334Speter     `double_reg_address_ok' is true and that this address rtl was made by
485018334Speter     eliminate_regs.  We generate a reload of the fp/sp/ap + constant and
485118334Speter     rework the sum so that the reload register will be added to the index.
485218334Speter     This is safe because we know the address isn't shared.
485318334Speter
485418334Speter     We check for fp/ap/sp as both the first and second operand of the
485518334Speter     innermost PLUS.  */
485618334Speter
485718334Speter  else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
485818334Speter	   && GET_CODE (XEXP (ad, 0)) == PLUS
485918334Speter	   && (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
486018334Speter#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
486118334Speter	       || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
486218334Speter#endif
486318334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
486418334Speter	       || XEXP (XEXP (ad, 0), 0) == arg_pointer_rtx
486518334Speter#endif
486618334Speter	       || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
486718334Speter	   && ! memory_address_p (mode, ad))
486818334Speter    {
486950605Sobrien      *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
487050605Sobrien				plus_constant (XEXP (XEXP (ad, 0), 0),
487150605Sobrien					       INTVAL (XEXP (ad, 1))),
487218334Speter			   XEXP (XEXP (ad, 0), 1));
487352557Sobrien      find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0), BASE_REG_CLASS,
487418334Speter				 GET_MODE (ad), opnum, type, ind_levels);
487550605Sobrien      find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
487650605Sobrien			      type, 0, insn);
487718334Speter
487852557Sobrien      return 0;
487918334Speter    }
488018334Speter
488118334Speter  else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
488218334Speter	   && GET_CODE (XEXP (ad, 0)) == PLUS
488318334Speter	   && (XEXP (XEXP (ad, 0), 1) == frame_pointer_rtx
488418334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
488518334Speter	       || XEXP (XEXP (ad, 0), 1) == hard_frame_pointer_rtx
488618334Speter#endif
488718334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
488818334Speter	       || XEXP (XEXP (ad, 0), 1) == arg_pointer_rtx
488918334Speter#endif
489018334Speter	       || XEXP (XEXP (ad, 0), 1) == stack_pointer_rtx)
489118334Speter	   && ! memory_address_p (mode, ad))
489218334Speter    {
489350605Sobrien      *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
489450605Sobrien				XEXP (XEXP (ad, 0), 0),
489550605Sobrien				plus_constant (XEXP (XEXP (ad, 0), 1),
489650605Sobrien					       INTVAL (XEXP (ad, 1))));
489752557Sobrien      find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1), BASE_REG_CLASS,
489818334Speter				 GET_MODE (ad), opnum, type, ind_levels);
489950605Sobrien      find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
490050605Sobrien			      type, 0, insn);
490118334Speter
490252557Sobrien      return 0;
490318334Speter    }
490418334Speter
490518334Speter  /* See if address becomes valid when an eliminable register
490618334Speter     in a sum is replaced.  */
490718334Speter
490818334Speter  tem = ad;
490918334Speter  if (GET_CODE (ad) == PLUS)
491018334Speter    tem = subst_indexed_address (ad);
491118334Speter  if (tem != ad && strict_memory_address_p (mode, tem))
491218334Speter    {
491318334Speter      /* Ok, we win that way.  Replace any additional eliminable
491418334Speter	 registers.  */
491518334Speter
491618334Speter      subst_reg_equivs_changed = 0;
491752557Sobrien      tem = subst_reg_equivs (tem, insn);
491818334Speter
491918334Speter      /* Make sure that didn't make the address invalid again.  */
492018334Speter
492118334Speter      if (! subst_reg_equivs_changed || strict_memory_address_p (mode, tem))
492218334Speter	{
492318334Speter	  *loc = tem;
492418334Speter	  return 0;
492518334Speter	}
492618334Speter    }
492718334Speter
492818334Speter  /* If constants aren't valid addresses, reload the constant address
492918334Speter     into a register.  */
493018334Speter  if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
493118334Speter    {
493218334Speter      /* If AD is in address in the constant pool, the MEM rtx may be shared.
493318334Speter	 Unshare it so we can safely alter it.  */
493418334Speter      if (memrefloc && GET_CODE (ad) == SYMBOL_REF
493518334Speter	  && CONSTANT_POOL_ADDRESS_P (ad))
493618334Speter	{
493718334Speter	  *memrefloc = copy_rtx (*memrefloc);
493818334Speter	  loc = &XEXP (*memrefloc, 0);
493952557Sobrien	  if (removed_and)
494052557Sobrien	    loc = &XEXP (*loc, 0);
494118334Speter	}
494218334Speter
494352557Sobrien      find_reloads_address_part (ad, loc, BASE_REG_CLASS, Pmode, opnum, type,
494418334Speter				 ind_levels);
494552557Sobrien      return ! removed_and;
494618334Speter    }
494718334Speter
494850605Sobrien  return find_reloads_address_1 (mode, ad, 0, loc, opnum, type, ind_levels,
494950605Sobrien				 insn);
495018334Speter}
495118334Speter
495218334Speter/* Find all pseudo regs appearing in AD
495318334Speter   that are eliminable in favor of equivalent values
495452557Sobrien   and do not have hard regs; replace them by their equivalents.
495552557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  We put USEs in
495652557Sobrien   front of it for pseudos that we have to replace with stack slots.  */
495718334Speter
495818334Speterstatic rtx
495952557Sobriensubst_reg_equivs (ad, insn)
496018334Speter     rtx ad;
496152557Sobrien     rtx insn;
496218334Speter{
496318334Speter  register RTX_CODE code = GET_CODE (ad);
496418334Speter  register int i;
496518334Speter  register char *fmt;
496618334Speter
496718334Speter  switch (code)
496818334Speter    {
496918334Speter    case HIGH:
497018334Speter    case CONST_INT:
497118334Speter    case CONST:
497218334Speter    case CONST_DOUBLE:
497318334Speter    case SYMBOL_REF:
497418334Speter    case LABEL_REF:
497518334Speter    case PC:
497618334Speter    case CC0:
497718334Speter      return ad;
497818334Speter
497918334Speter    case REG:
498018334Speter      {
498118334Speter	register int regno = REGNO (ad);
498218334Speter
498318334Speter	if (reg_equiv_constant[regno] != 0)
498418334Speter	  {
498518334Speter	    subst_reg_equivs_changed = 1;
498618334Speter	    return reg_equiv_constant[regno];
498718334Speter	  }
498852557Sobrien	if (reg_equiv_memory_loc[regno] && num_not_at_initial_offset)
498952557Sobrien	  {
499052557Sobrien	    rtx mem = make_memloc (ad, regno);
499152557Sobrien	    if (! rtx_equal_p (mem, reg_equiv_mem[regno]))
499252557Sobrien	      {
499352557Sobrien		subst_reg_equivs_changed = 1;
499452557Sobrien		emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn);
499552557Sobrien		return mem;
499652557Sobrien	      }
499752557Sobrien	  }
499818334Speter      }
499918334Speter      return ad;
500018334Speter
500118334Speter    case PLUS:
500218334Speter      /* Quickly dispose of a common case.  */
500318334Speter      if (XEXP (ad, 0) == frame_pointer_rtx
500418334Speter	  && GET_CODE (XEXP (ad, 1)) == CONST_INT)
500518334Speter	return ad;
500650605Sobrien      break;
500750605Sobrien
500850605Sobrien    default:
500950605Sobrien      break;
501018334Speter    }
501118334Speter
501218334Speter  fmt = GET_RTX_FORMAT (code);
501318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
501418334Speter    if (fmt[i] == 'e')
501552557Sobrien      XEXP (ad, i) = subst_reg_equivs (XEXP (ad, i), insn);
501618334Speter  return ad;
501718334Speter}
501818334Speter
501918334Speter/* Compute the sum of X and Y, making canonicalizations assumed in an
502018334Speter   address, namely: sum constant integers, surround the sum of two
502118334Speter   constants with a CONST, put the constant as the second operand, and
502218334Speter   group the constant on the outermost sum.
502318334Speter
502418334Speter   This routine assumes both inputs are already in canonical form.  */
502518334Speter
502618334Speterrtx
502718334Speterform_sum (x, y)
502818334Speter     rtx x, y;
502918334Speter{
503018334Speter  rtx tem;
503118334Speter  enum machine_mode mode = GET_MODE (x);
503218334Speter
503318334Speter  if (mode == VOIDmode)
503418334Speter    mode = GET_MODE (y);
503518334Speter
503618334Speter  if (mode == VOIDmode)
503718334Speter    mode = Pmode;
503818334Speter
503918334Speter  if (GET_CODE (x) == CONST_INT)
504018334Speter    return plus_constant (y, INTVAL (x));
504118334Speter  else if (GET_CODE (y) == CONST_INT)
504218334Speter    return plus_constant (x, INTVAL (y));
504318334Speter  else if (CONSTANT_P (x))
504418334Speter    tem = x, x = y, y = tem;
504518334Speter
504618334Speter  if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
504718334Speter    return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
504818334Speter
504918334Speter  /* Note that if the operands of Y are specified in the opposite
505018334Speter     order in the recursive calls below, infinite recursion will occur.  */
505118334Speter  if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
505218334Speter    return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
505318334Speter
505418334Speter  /* If both constant, encapsulate sum.  Otherwise, just form sum.  A
505518334Speter     constant will have been placed second.  */
505618334Speter  if (CONSTANT_P (x) && CONSTANT_P (y))
505718334Speter    {
505818334Speter      if (GET_CODE (x) == CONST)
505918334Speter	x = XEXP (x, 0);
506018334Speter      if (GET_CODE (y) == CONST)
506118334Speter	y = XEXP (y, 0);
506218334Speter
506350605Sobrien      return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y));
506418334Speter    }
506518334Speter
506650605Sobrien  return gen_rtx_PLUS (mode, x, y);
506718334Speter}
506818334Speter
506918334Speter/* If ADDR is a sum containing a pseudo register that should be
507018334Speter   replaced with a constant (from reg_equiv_constant),
507118334Speter   return the result of doing so, and also apply the associative
507218334Speter   law so that the result is more likely to be a valid address.
507318334Speter   (But it is not guaranteed to be one.)
507418334Speter
507518334Speter   Note that at most one register is replaced, even if more are
507618334Speter   replaceable.  Also, we try to put the result into a canonical form
507718334Speter   so it is more likely to be a valid address.
507818334Speter
507918334Speter   In all other cases, return ADDR.  */
508018334Speter
508118334Speterstatic rtx
508218334Spetersubst_indexed_address (addr)
508318334Speter     rtx addr;
508418334Speter{
508518334Speter  rtx op0 = 0, op1 = 0, op2 = 0;
508618334Speter  rtx tem;
508718334Speter  int regno;
508818334Speter
508918334Speter  if (GET_CODE (addr) == PLUS)
509018334Speter    {
509118334Speter      /* Try to find a register to replace.  */
509218334Speter      op0 = XEXP (addr, 0), op1 = XEXP (addr, 1), op2 = 0;
509318334Speter      if (GET_CODE (op0) == REG
509418334Speter	  && (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
509518334Speter	  && reg_renumber[regno] < 0
509618334Speter	  && reg_equiv_constant[regno] != 0)
509718334Speter	op0 = reg_equiv_constant[regno];
509818334Speter      else if (GET_CODE (op1) == REG
509918334Speter	  && (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
510018334Speter	  && reg_renumber[regno] < 0
510118334Speter	  && reg_equiv_constant[regno] != 0)
510218334Speter	op1 = reg_equiv_constant[regno];
510318334Speter      else if (GET_CODE (op0) == PLUS
510418334Speter	       && (tem = subst_indexed_address (op0)) != op0)
510518334Speter	op0 = tem;
510618334Speter      else if (GET_CODE (op1) == PLUS
510718334Speter	       && (tem = subst_indexed_address (op1)) != op1)
510818334Speter	op1 = tem;
510918334Speter      else
511018334Speter	return addr;
511118334Speter
511218334Speter      /* Pick out up to three things to add.  */
511318334Speter      if (GET_CODE (op1) == PLUS)
511418334Speter	op2 = XEXP (op1, 1), op1 = XEXP (op1, 0);
511518334Speter      else if (GET_CODE (op0) == PLUS)
511618334Speter	op2 = op1, op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
511718334Speter
511818334Speter      /* Compute the sum.  */
511918334Speter      if (op2 != 0)
512018334Speter	op1 = form_sum (op1, op2);
512118334Speter      if (op1 != 0)
512218334Speter	op0 = form_sum (op0, op1);
512318334Speter
512418334Speter      return op0;
512518334Speter    }
512618334Speter  return addr;
512718334Speter}
512818334Speter
512950605Sobrien/* Record the pseudo registers we must reload into hard registers in a
513050605Sobrien   subexpression of a would-be memory address, X referring to a value
513150605Sobrien   in mode MODE.  (This function is not called if the address we find
513250605Sobrien   is strictly valid.)
513350605Sobrien
513418334Speter   CONTEXT = 1 means we are considering regs as index regs,
513518334Speter   = 0 means we are considering them as base regs.
513618334Speter
513718334Speter   OPNUM and TYPE specify the purpose of any reloads made.
513818334Speter
513918334Speter   IND_LEVELS says how many levels of indirect addressing are
514018334Speter   supported at this point in the address.
514118334Speter
514250605Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
514350605Sobrien   to determine if we may generate output reloads.
514450605Sobrien
514518334Speter   We return nonzero if X, as a whole, is reloaded or replaced.  */
514618334Speter
514718334Speter/* Note that we take shortcuts assuming that no multi-reg machine mode
514818334Speter   occurs as part of an address.
514918334Speter   Also, this is not fully machine-customizable; it works for machines
515018334Speter   such as vaxes and 68000's and 32000's, but other possible machines
515118334Speter   could have addressing modes that this does not handle right.  */
515218334Speter
515318334Speterstatic int
515450605Sobrienfind_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
515550605Sobrien     enum machine_mode mode;
515618334Speter     rtx x;
515718334Speter     int context;
515818334Speter     rtx *loc;
515918334Speter     int opnum;
516018334Speter     enum reload_type type;
516118334Speter     int ind_levels;
516250605Sobrien     rtx insn;
516318334Speter{
516418334Speter  register RTX_CODE code = GET_CODE (x);
516518334Speter
516618334Speter  switch (code)
516718334Speter    {
516818334Speter    case PLUS:
516918334Speter      {
517018334Speter	register rtx orig_op0 = XEXP (x, 0);
517118334Speter	register rtx orig_op1 = XEXP (x, 1);
517218334Speter	register RTX_CODE code0 = GET_CODE (orig_op0);
517318334Speter	register RTX_CODE code1 = GET_CODE (orig_op1);
517418334Speter	register rtx op0 = orig_op0;
517518334Speter	register rtx op1 = orig_op1;
517618334Speter
517718334Speter	if (GET_CODE (op0) == SUBREG)
517818334Speter	  {
517918334Speter	    op0 = SUBREG_REG (op0);
518018334Speter	    code0 = GET_CODE (op0);
518118334Speter	    if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
518250605Sobrien	      op0 = gen_rtx_REG (word_mode,
518350605Sobrien				 REGNO (op0) + SUBREG_WORD (orig_op0));
518418334Speter	  }
518518334Speter
518618334Speter	if (GET_CODE (op1) == SUBREG)
518718334Speter	  {
518818334Speter	    op1 = SUBREG_REG (op1);
518918334Speter	    code1 = GET_CODE (op1);
519018334Speter	    if (code1 == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER)
519150605Sobrien	      op1 = gen_rtx_REG (GET_MODE (op1),
519250605Sobrien				 REGNO (op1) + SUBREG_WORD (orig_op1));
519318334Speter	  }
519418334Speter
519518334Speter	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
519618334Speter	    || code0 == ZERO_EXTEND || code1 == MEM)
519718334Speter	  {
519850605Sobrien	    find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
519950605Sobrien				    type, ind_levels, insn);
520050605Sobrien	    find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
520150605Sobrien				    type, ind_levels, insn);
520218334Speter	  }
520318334Speter
520418334Speter	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
520518334Speter		 || code1 == ZERO_EXTEND || code0 == MEM)
520618334Speter	  {
520750605Sobrien	    find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
520850605Sobrien				    type, ind_levels, insn);
520950605Sobrien	    find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
521050605Sobrien				    type, ind_levels, insn);
521118334Speter	  }
521218334Speter
521318334Speter	else if (code0 == CONST_INT || code0 == CONST
521418334Speter		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
521550605Sobrien	  find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
521650605Sobrien				  type, ind_levels, insn);
521718334Speter
521818334Speter	else if (code1 == CONST_INT || code1 == CONST
521918334Speter		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
522050605Sobrien	  find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
522150605Sobrien				  type, ind_levels, insn);
522218334Speter
522318334Speter	else if (code0 == REG && code1 == REG)
522418334Speter	  {
522518334Speter	    if (REG_OK_FOR_INDEX_P (op0)
522650605Sobrien		&& REG_MODE_OK_FOR_BASE_P (op1, mode))
522718334Speter	      return 0;
522818334Speter	    else if (REG_OK_FOR_INDEX_P (op1)
522950605Sobrien		     && REG_MODE_OK_FOR_BASE_P (op0, mode))
523018334Speter	      return 0;
523150605Sobrien	    else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
523250605Sobrien	      find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
523350605Sobrien				      type, ind_levels, insn);
523450605Sobrien	    else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
523550605Sobrien	      find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
523650605Sobrien				      type, ind_levels, insn);
523718334Speter	    else if (REG_OK_FOR_INDEX_P (op1))
523850605Sobrien	      find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
523950605Sobrien				      type, ind_levels, insn);
524018334Speter	    else if (REG_OK_FOR_INDEX_P (op0))
524150605Sobrien	      find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
524250605Sobrien				      type, ind_levels, insn);
524318334Speter	    else
524418334Speter	      {
524550605Sobrien		find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
524650605Sobrien					type, ind_levels, insn);
524750605Sobrien		find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
524850605Sobrien					type, ind_levels, insn);
524918334Speter	      }
525018334Speter	  }
525118334Speter
525218334Speter	else if (code0 == REG)
525318334Speter	  {
525450605Sobrien	    find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
525550605Sobrien				    type, ind_levels, insn);
525650605Sobrien	    find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
525750605Sobrien				    type, ind_levels, insn);
525818334Speter	  }
525918334Speter
526018334Speter	else if (code1 == REG)
526118334Speter	  {
526250605Sobrien	    find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
526350605Sobrien				    type, ind_levels, insn);
526450605Sobrien	    find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
526550605Sobrien				    type, ind_levels, insn);
526618334Speter	  }
526718334Speter      }
526818334Speter
526918334Speter      return 0;
527018334Speter
527118334Speter    case POST_INC:
527218334Speter    case POST_DEC:
527318334Speter    case PRE_INC:
527418334Speter    case PRE_DEC:
527518334Speter      if (GET_CODE (XEXP (x, 0)) == REG)
527618334Speter	{
527718334Speter	  register int regno = REGNO (XEXP (x, 0));
527818334Speter	  int value = 0;
527918334Speter	  rtx x_orig = x;
528018334Speter
528118334Speter	  /* A register that is incremented cannot be constant!  */
528218334Speter	  if (regno >= FIRST_PSEUDO_REGISTER
528318334Speter	      && reg_equiv_constant[regno] != 0)
528418334Speter	    abort ();
528518334Speter
528618334Speter	  /* Handle a register that is equivalent to a memory location
528718334Speter	     which cannot be addressed directly.  */
528852557Sobrien	  if (reg_equiv_memory_loc[regno] != 0
528952557Sobrien	      && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
529018334Speter	    {
529118334Speter	      rtx tem = make_memloc (XEXP (x, 0), regno);
529252557Sobrien	      if (reg_equiv_address[regno]
529352557Sobrien		  || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
529452557Sobrien		{
529552557Sobrien		  /* First reload the memory location's address.
529652557Sobrien		     We can't use ADDR_TYPE (type) here, because we need to
529752557Sobrien		     write back the value after reading it, hence we actually
529852557Sobrien		     need two registers.  */
529952557Sobrien		  find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
530052557Sobrien					&XEXP (tem, 0), opnum, type,
530152557Sobrien					ind_levels, insn);
530252557Sobrien		  /* Put this inside a new increment-expression.  */
530352557Sobrien		  x = gen_rtx_fmt_e (GET_CODE (x), GET_MODE (x), tem);
530452557Sobrien		  /* Proceed to reload that, as if it contained a register.  */
530552557Sobrien		}
530618334Speter	    }
530718334Speter
530818334Speter	  /* If we have a hard register that is ok as an index,
530918334Speter	     don't make a reload.  If an autoincrement of a nice register
531018334Speter	     isn't "valid", it must be that no autoincrement is "valid".
531118334Speter	     If that is true and something made an autoincrement anyway,
531218334Speter	     this must be a special context where one is allowed.
531318334Speter	     (For example, a "push" instruction.)
531418334Speter	     We can't improve this address, so leave it alone.  */
531518334Speter
531618334Speter	  /* Otherwise, reload the autoincrement into a suitable hard reg
531718334Speter	     and record how much to increment by.  */
531818334Speter
531918334Speter	  if (reg_renumber[regno] >= 0)
532018334Speter	    regno = reg_renumber[regno];
532118334Speter	  if ((regno >= FIRST_PSEUDO_REGISTER
532218334Speter	       || !(context ? REGNO_OK_FOR_INDEX_P (regno)
532350605Sobrien		    : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
532418334Speter	    {
532550605Sobrien#ifdef AUTO_INC_DEC
532618334Speter	      register rtx link;
532750605Sobrien#endif
532850605Sobrien	      int reloadnum;
532918334Speter
533050605Sobrien	      /* If we can output the register afterwards, do so, this
533150605Sobrien		 saves the extra update.
533250605Sobrien		 We can do so if we have an INSN - i.e. no JUMP_INSN nor
533350605Sobrien		 CALL_INSN - and it does not set CC0.
533450605Sobrien		 But don't do this if we cannot directly address the
533550605Sobrien		 memory location, since this will make it harder to
533650605Sobrien		 reuse address reloads, and increases register pressure.
533750605Sobrien		 Also don't do this if we can probably update x directly.  */
533852557Sobrien	      rtx equiv = (GET_CODE (XEXP (x, 0)) == MEM
533952557Sobrien			   ? XEXP (x, 0)
534052557Sobrien			   : reg_equiv_mem[regno]);
534150605Sobrien	      int icode = (int) add_optab->handlers[(int) Pmode].insn_code;
534250605Sobrien	      if (insn && GET_CODE (insn) == INSN && equiv
534352557Sobrien		  && memory_operand (equiv, GET_MODE (equiv))
534450605Sobrien#ifdef HAVE_cc0
534550605Sobrien		  && ! sets_cc0_p (PATTERN (insn))
534650605Sobrien#endif
534750605Sobrien		  && ! (icode != CODE_FOR_nothing
534850605Sobrien			&& (*insn_operand_predicate[icode][0]) (equiv, Pmode)
534950605Sobrien			&& (*insn_operand_predicate[icode][1]) (equiv, Pmode)))
535050605Sobrien		{
535150605Sobrien		  loc = &XEXP (x, 0);
535250605Sobrien		  x = XEXP (x, 0);
535350605Sobrien		  reloadnum
535450605Sobrien		    = push_reload (x, x, loc, loc,
535552557Sobrien				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
535650605Sobrien				    GET_MODE (x), GET_MODE (x), 0, 0,
535750605Sobrien				    opnum, RELOAD_OTHER);
535852557Sobrien
535952557Sobrien		  /* If we created a new MEM based on reg_equiv_mem[REGNO], then
536052557Sobrien		     LOC above is part of the new MEM, not the MEM in INSN.
536152557Sobrien
536252557Sobrien		     We must also replace the address of the MEM in INSN.  */
536352557Sobrien		  if (&XEXP (x_orig, 0) != loc)
536452557Sobrien		    push_replacement (&XEXP (x_orig, 0), reloadnum, VOIDmode);
536552557Sobrien
536650605Sobrien		}
536750605Sobrien	      else
536850605Sobrien		{
536950605Sobrien		  reloadnum
537050605Sobrien		    = push_reload (x, NULL_RTX, loc, NULL_PTR,
537152557Sobrien				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
537250605Sobrien				   GET_MODE (x), GET_MODE (x), 0, 0,
537350605Sobrien				   opnum, type);
537450605Sobrien		  reload_inc[reloadnum]
537550605Sobrien		    = find_inc_amount (PATTERN (this_insn), XEXP (x_orig, 0));
537650605Sobrien
537750605Sobrien		  value = 1;
537850605Sobrien		}
537918334Speter
538018334Speter#ifdef AUTO_INC_DEC
538118334Speter	      /* Update the REG_INC notes.  */
538218334Speter
538318334Speter	      for (link = REG_NOTES (this_insn);
538418334Speter		   link; link = XEXP (link, 1))
538518334Speter		if (REG_NOTE_KIND (link) == REG_INC
538618334Speter		    && REGNO (XEXP (link, 0)) == REGNO (XEXP (x_orig, 0)))
538718334Speter		  push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
538818334Speter#endif
538918334Speter	    }
539018334Speter	  return value;
539118334Speter	}
539218334Speter
539318334Speter      else if (GET_CODE (XEXP (x, 0)) == MEM)
539418334Speter	{
539518334Speter	  /* This is probably the result of a substitution, by eliminate_regs,
539618334Speter	     of an equivalent address for a pseudo that was not allocated to a
539718334Speter	     hard register.  Verify that the specified address is valid and
539818334Speter	     reload it into a register.  */
539952557Sobrien	  /* Variable `tem' might or might not be used in FIND_REG_INC_NOTE. */
540052557Sobrien	  rtx tem ATTRIBUTE_UNUSED = XEXP (x, 0);
540118334Speter	  register rtx link;
540218334Speter	  int reloadnum;
540318334Speter
540418334Speter	  /* Since we know we are going to reload this item, don't decrement
540518334Speter	     for the indirection level.
540618334Speter
540718334Speter	     Note that this is actually conservative:  it would be slightly
540818334Speter	     more efficient to use the value of SPILL_INDIRECT_LEVELS from
540918334Speter	     reload1.c here.  */
541050605Sobrien	  /* We can't use ADDR_TYPE (type) here, because we need to
541150605Sobrien	     write back the value after reading it, hence we actually
541250605Sobrien	     need two registers.  */
541318334Speter	  find_reloads_address (GET_MODE (x), &XEXP (x, 0),
541418334Speter				XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 0),
541550605Sobrien				opnum, type, ind_levels, insn);
541618334Speter
541718334Speter	  reloadnum = push_reload (x, NULL_RTX, loc, NULL_PTR,
541852557Sobrien				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
541918334Speter				   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
542018334Speter	  reload_inc[reloadnum]
542118334Speter	    = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
542218334Speter
542318334Speter	  link = FIND_REG_INC_NOTE (this_insn, tem);
542418334Speter	  if (link != 0)
542518334Speter	    push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
542618334Speter
542718334Speter	  return 1;
542818334Speter	}
542918334Speter      return 0;
543018334Speter
543118334Speter    case MEM:
543218334Speter      /* This is probably the result of a substitution, by eliminate_regs, of
543318334Speter	 an equivalent address for a pseudo that was not allocated to a hard
543418334Speter	 register.  Verify that the specified address is valid and reload it
543518334Speter	 into a register.
543618334Speter
543718334Speter	 Since we know we are going to reload this item, don't decrement for
543818334Speter	 the indirection level.
543918334Speter
544018334Speter	 Note that this is actually conservative:  it would be slightly more
544118334Speter	 efficient to use the value of SPILL_INDIRECT_LEVELS from
544218334Speter	 reload1.c here.  */
544318334Speter
544418334Speter      find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
544550605Sobrien			    opnum, ADDR_TYPE (type), ind_levels, insn);
544618334Speter      push_reload (*loc, NULL_RTX, loc, NULL_PTR,
544752557Sobrien		   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
544818334Speter		   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
544918334Speter      return 1;
545018334Speter
545118334Speter    case REG:
545218334Speter      {
545318334Speter	register int regno = REGNO (x);
545418334Speter
545518334Speter	if (reg_equiv_constant[regno] != 0)
545618334Speter	  {
545752557Sobrien	    find_reloads_address_part (reg_equiv_constant[regno], loc,
545852557Sobrien				       (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
545918334Speter				       GET_MODE (x), opnum, type, ind_levels);
546018334Speter	    return 1;
546118334Speter	  }
546218334Speter
546318334Speter#if 0 /* This might screw code in reload1.c to delete prior output-reload
546418334Speter	 that feeds this insn.  */
546518334Speter	if (reg_equiv_mem[regno] != 0)
546618334Speter	  {
546718334Speter	    push_reload (reg_equiv_mem[regno], NULL_RTX, loc, NULL_PTR,
546852557Sobrien			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
546918334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
547018334Speter	    return 1;
547118334Speter	  }
547218334Speter#endif
547318334Speter
547452557Sobrien	if (reg_equiv_memory_loc[regno]
547552557Sobrien	    && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
547618334Speter	  {
547752557Sobrien	    rtx tem = make_memloc (x, regno);
547852557Sobrien	    if (reg_equiv_address[regno] != 0
547952557Sobrien		|| ! rtx_equal_p (tem, reg_equiv_mem[regno]))
548052557Sobrien	      {
548152557Sobrien		x = tem;
548252557Sobrien		find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
548352557Sobrien				      &XEXP (x, 0), opnum, ADDR_TYPE (type),
548452557Sobrien				      ind_levels, insn);
548552557Sobrien	      }
548618334Speter	  }
548718334Speter
548818334Speter	if (reg_renumber[regno] >= 0)
548918334Speter	  regno = reg_renumber[regno];
549018334Speter
549118334Speter	if ((regno >= FIRST_PSEUDO_REGISTER
549218334Speter	     || !(context ? REGNO_OK_FOR_INDEX_P (regno)
549350605Sobrien		  : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
549418334Speter	  {
549518334Speter	    push_reload (x, NULL_RTX, loc, NULL_PTR,
549652557Sobrien			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
549718334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
549818334Speter	    return 1;
549918334Speter	  }
550018334Speter
550118334Speter	/* If a register appearing in an address is the subject of a CLOBBER
550218334Speter	   in this insn, reload it into some other register to be safe.
550318334Speter	   The CLOBBER is supposed to make the register unavailable
550418334Speter	   from before this insn to after it.  */
550518334Speter	if (regno_clobbered_p (regno, this_insn))
550618334Speter	  {
550718334Speter	    push_reload (x, NULL_RTX, loc, NULL_PTR,
550852557Sobrien			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
550918334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
551018334Speter	    return 1;
551118334Speter	  }
551218334Speter      }
551318334Speter      return 0;
551418334Speter
551518334Speter    case SUBREG:
551618334Speter      if (GET_CODE (SUBREG_REG (x)) == REG)
551718334Speter	{
551818334Speter	  /* If this is a SUBREG of a hard register and the resulting register
551918334Speter	     is of the wrong class, reload the whole SUBREG.  This avoids
552018334Speter	     needless copies if SUBREG_REG is multi-word.  */
552118334Speter	  if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
552218334Speter	    {
552318334Speter	      int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
552418334Speter
552518334Speter	      if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
552650605Sobrien		     : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
552718334Speter		{
552818334Speter		  push_reload (x, NULL_RTX, loc, NULL_PTR,
552952557Sobrien			       (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
553018334Speter			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
553118334Speter		  return 1;
553218334Speter		}
553318334Speter	    }
553418334Speter	  /* If this is a SUBREG of a pseudo-register, and the pseudo-register
553518334Speter	     is larger than the class size, then reload the whole SUBREG.  */
553618334Speter	  else
553718334Speter	    {
553852557Sobrien	      enum reg_class class = (context ? INDEX_REG_CLASS
553952557Sobrien				      : BASE_REG_CLASS);
554018334Speter	      if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
554118334Speter		  > reg_class_size[class])
554218334Speter		{
554352557Sobrien		  x = find_reloads_subreg_address (x, 0, opnum, type,
554452557Sobrien						   ind_levels, insn);
554518334Speter		  push_reload (x, NULL_RTX, loc, NULL_PTR, class,
554618334Speter			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
554718334Speter		  return 1;
554818334Speter		}
554918334Speter	    }
555018334Speter	}
555118334Speter      break;
555250605Sobrien
555350605Sobrien    default:
555450605Sobrien      break;
555518334Speter    }
555618334Speter
555718334Speter  {
555818334Speter    register char *fmt = GET_RTX_FORMAT (code);
555918334Speter    register int i;
556018334Speter
556118334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
556218334Speter      {
556318334Speter	if (fmt[i] == 'e')
556450605Sobrien	  find_reloads_address_1 (mode, XEXP (x, i), context, &XEXP (x, i),
556550605Sobrien				  opnum, type, ind_levels, insn);
556618334Speter      }
556718334Speter  }
556818334Speter
556918334Speter  return 0;
557018334Speter}
557118334Speter
557218334Speter/* X, which is found at *LOC, is a part of an address that needs to be
557318334Speter   reloaded into a register of class CLASS.  If X is a constant, or if
557418334Speter   X is a PLUS that contains a constant, check that the constant is a
557518334Speter   legitimate operand and that we are supposed to be able to load
557618334Speter   it into the register.
557718334Speter
557818334Speter   If not, force the constant into memory and reload the MEM instead.
557918334Speter
558018334Speter   MODE is the mode to use, in case X is an integer constant.
558118334Speter
558218334Speter   OPNUM and TYPE describe the purpose of any reloads made.
558318334Speter
558418334Speter   IND_LEVELS says how many levels of indirect addressing this machine
558518334Speter   supports.  */
558618334Speter
558718334Speterstatic void
558818334Speterfind_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
558918334Speter     rtx x;
559018334Speter     rtx *loc;
559118334Speter     enum reg_class class;
559218334Speter     enum machine_mode mode;
559318334Speter     int opnum;
559418334Speter     enum reload_type type;
559518334Speter     int ind_levels;
559618334Speter{
559718334Speter  if (CONSTANT_P (x)
559818334Speter      && (! LEGITIMATE_CONSTANT_P (x)
559918334Speter	  || PREFERRED_RELOAD_CLASS (x, class) == NO_REGS))
560018334Speter    {
560152557Sobrien      rtx tem;
560252557Sobrien
560352557Sobrien      /* If this is a CONST_INT, it could have been created by a
560452557Sobrien	 plus_constant call in eliminate_regs, which means it may be
560552557Sobrien	 on the reload_obstack.  reload_obstack will be freed later, so
560652557Sobrien	 we can't allow such RTL to be put in the constant pool.  There
560752557Sobrien	 is code in force_const_mem to check for this case, but it doesn't
560852557Sobrien	 work because we have already popped off the reload_obstack, so
560952557Sobrien	 rtl_obstack == saveable_obstack is true at this point.  */
561052557Sobrien      if (GET_CODE (x) == CONST_INT)
561152557Sobrien	tem = x = force_const_mem (mode, GEN_INT (INTVAL (x)));
561252557Sobrien      else
561352557Sobrien	tem = x = force_const_mem (mode, x);
561452557Sobrien
561518334Speter      find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
561650605Sobrien			    opnum, type, ind_levels, 0);
561718334Speter    }
561818334Speter
561918334Speter  else if (GET_CODE (x) == PLUS
562018334Speter	   && CONSTANT_P (XEXP (x, 1))
562118334Speter	   && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
562218334Speter	       || PREFERRED_RELOAD_CLASS (XEXP (x, 1), class) == NO_REGS))
562318334Speter    {
562452557Sobrien      rtx tem;
562518334Speter
562652557Sobrien      /* See comment above.  */
562752557Sobrien      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
562852557Sobrien	tem = force_const_mem (GET_MODE (x), GEN_INT (INTVAL (XEXP (x, 1))));
562952557Sobrien      else
563052557Sobrien	tem = force_const_mem (GET_MODE (x), XEXP (x, 1));
563152557Sobrien
563250605Sobrien      x = gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), tem);
563318334Speter      find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
563450605Sobrien			    opnum, type, ind_levels, 0);
563518334Speter    }
563618334Speter
563718334Speter  push_reload (x, NULL_RTX, loc, NULL_PTR, class,
563818334Speter	       mode, VOIDmode, 0, 0, opnum, type);
563918334Speter}
564018334Speter
564152557Sobrien/* X, a subreg of a pseudo, is a part of an address that needs to be
564252557Sobrien   reloaded.
564352557Sobrien
564452557Sobrien   If the pseudo is equivalent to a memory location that cannot be directly
564552557Sobrien   addressed, make the necessary address reloads.
564652557Sobrien
564752557Sobrien   If address reloads have been necessary, or if the address is changed
564852557Sobrien   by register elimination, return the rtx of the memory location;
564952557Sobrien   otherwise, return X.
565052557Sobrien
565152557Sobrien   If FORCE_REPLACE is nonzero, unconditionally replace the subreg with the
565252557Sobrien   memory location.
565352557Sobrien
565452557Sobrien   OPNUM and TYPE identify the purpose of the reload.
565552557Sobrien
565652557Sobrien   IND_LEVELS says how many levels of indirect addressing are
565752557Sobrien   supported at this point in the address.
565852557Sobrien
565952557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
566052557Sobrien   to determine where to put USEs for pseudos that we have to replace with
566152557Sobrien   stack slots.  */
566252557Sobrien
566352557Sobrienstatic rtx
566452557Sobrienfind_reloads_subreg_address (x, force_replace, opnum, type,
566552557Sobrien			     ind_levels, insn)
566652557Sobrien     rtx x;
566752557Sobrien     int force_replace;
566852557Sobrien     int opnum;
566952557Sobrien     enum reload_type type;
567052557Sobrien     int ind_levels;
567152557Sobrien     rtx insn;
567252557Sobrien{
567352557Sobrien  int regno = REGNO (SUBREG_REG (x));
567452557Sobrien
567552557Sobrien  if (reg_equiv_memory_loc[regno])
567652557Sobrien    {
567752557Sobrien      /* If the address is not directly addressable, or if the address is not
567852557Sobrien	 offsettable, then it must be replaced.  */
567952557Sobrien      if (! force_replace
568052557Sobrien	  && (reg_equiv_address[regno]
568152557Sobrien	      || ! offsettable_memref_p (reg_equiv_mem[regno])))
568252557Sobrien	force_replace = 1;
568352557Sobrien
568452557Sobrien      if (force_replace || num_not_at_initial_offset)
568552557Sobrien	{
568652557Sobrien	  rtx tem = make_memloc (SUBREG_REG (x), regno);
568752557Sobrien
568852557Sobrien	  /* If the address changes because of register elimination, then
568952557Sobrien	     it must be replaced.  */
569052557Sobrien	  if (force_replace
569152557Sobrien	      || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
569252557Sobrien	    {
569352557Sobrien	      int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
569452557Sobrien
569552557Sobrien	      if (BYTES_BIG_ENDIAN)
569652557Sobrien		{
569752557Sobrien		  int size;
569852557Sobrien
569952557Sobrien		  size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
570052557Sobrien		  offset += MIN (size, UNITS_PER_WORD);
570152557Sobrien		  size = GET_MODE_SIZE (GET_MODE (x));
570252557Sobrien		  offset -= MIN (size, UNITS_PER_WORD);
570352557Sobrien		}
570452557Sobrien	      XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
570552557Sobrien	      PUT_MODE (tem, GET_MODE (x));
570652557Sobrien	      find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
570752557Sobrien				    &XEXP (tem, 0), opnum, ADDR_TYPE (type),
570852557Sobrien				    ind_levels, insn);
570952557Sobrien	      /* If this is not a toplevel operand, find_reloads doesn't see
571052557Sobrien		 this substitution.  We have to emit a USE of the pseudo so
571152557Sobrien		 that delete_output_reload can see it.  */
571252557Sobrien	      if (replace_reloads && recog_operand[opnum] != x)
571352557Sobrien		emit_insn_before (gen_rtx_USE (VOIDmode, SUBREG_REG (x)), insn);
571452557Sobrien	      x = tem;
571552557Sobrien	    }
571652557Sobrien	}
571752557Sobrien    }
571852557Sobrien  return x;
571952557Sobrien}
572052557Sobrien
572118334Speter/* Substitute into the current INSN the registers into which we have reloaded
572218334Speter   the things that need reloading.  The array `replacements'
572318334Speter   says contains the locations of all pointers that must be changed
572418334Speter   and says what to replace them with.
572518334Speter
572618334Speter   Return the rtx that X translates into; usually X, but modified.  */
572718334Speter
572818334Spetervoid
572918334Spetersubst_reloads ()
573018334Speter{
573118334Speter  register int i;
573218334Speter
573318334Speter  for (i = 0; i < n_replacements; i++)
573418334Speter    {
573518334Speter      register struct replacement *r = &replacements[i];
573618334Speter      register rtx reloadreg = reload_reg_rtx[r->what];
573718334Speter      if (reloadreg)
573818334Speter	{
573918334Speter	  /* Encapsulate RELOADREG so its machine mode matches what
574018334Speter	     used to be there.  Note that gen_lowpart_common will
574118334Speter	     do the wrong thing if RELOADREG is multi-word.  RELOADREG
574218334Speter	     will always be a REG here.  */
574318334Speter	  if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
574450605Sobrien	    reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
574518334Speter
574618334Speter	  /* If we are putting this into a SUBREG and RELOADREG is a
574718334Speter	     SUBREG, we would be making nested SUBREGs, so we have to fix
574818334Speter	     this up.  Note that r->where == &SUBREG_REG (*r->subreg_loc).  */
574918334Speter
575018334Speter	  if (r->subreg_loc != 0 && GET_CODE (reloadreg) == SUBREG)
575118334Speter	    {
575218334Speter	      if (GET_MODE (*r->subreg_loc)
575318334Speter		  == GET_MODE (SUBREG_REG (reloadreg)))
575418334Speter		*r->subreg_loc = SUBREG_REG (reloadreg);
575518334Speter	      else
575618334Speter		{
575718334Speter		  *r->where = SUBREG_REG (reloadreg);
575818334Speter		  SUBREG_WORD (*r->subreg_loc) += SUBREG_WORD (reloadreg);
575918334Speter		}
576018334Speter	    }
576118334Speter	  else
576218334Speter	    *r->where = reloadreg;
576318334Speter	}
576418334Speter      /* If reload got no reg and isn't optional, something's wrong.  */
576518334Speter      else if (! reload_optional[r->what])
576618334Speter	abort ();
576718334Speter    }
576818334Speter}
576918334Speter
577018334Speter/* Make a copy of any replacements being done into X and move those copies
577118334Speter   to locations in Y, a copy of X.  We only look at the highest level of
577218334Speter   the RTL.  */
577318334Speter
577418334Spetervoid
577518334Spetercopy_replacements (x, y)
577618334Speter     rtx x;
577718334Speter     rtx y;
577818334Speter{
577918334Speter  int i, j;
578018334Speter  enum rtx_code code = GET_CODE (x);
578118334Speter  char *fmt = GET_RTX_FORMAT (code);
578218334Speter  struct replacement *r;
578318334Speter
578418334Speter  /* We can't support X being a SUBREG because we might then need to know its
578518334Speter     location if something inside it was replaced.  */
578618334Speter  if (code == SUBREG)
578718334Speter    abort ();
578818334Speter
578918334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
579018334Speter    if (fmt[i] == 'e')
579118334Speter      for (j = 0; j < n_replacements; j++)
579218334Speter	{
579318334Speter	  if (replacements[j].subreg_loc == &XEXP (x, i))
579418334Speter	    {
579518334Speter	      r = &replacements[n_replacements++];
579618334Speter	      r->where = replacements[j].where;
579718334Speter	      r->subreg_loc = &XEXP (y, i);
579818334Speter	      r->what = replacements[j].what;
579918334Speter	      r->mode = replacements[j].mode;
580018334Speter	    }
580118334Speter	  else if (replacements[j].where == &XEXP (x, i))
580218334Speter	    {
580318334Speter	      r = &replacements[n_replacements++];
580418334Speter	      r->where = &XEXP (y, i);
580518334Speter	      r->subreg_loc = 0;
580618334Speter	      r->what = replacements[j].what;
580718334Speter	      r->mode = replacements[j].mode;
580818334Speter	    }
580918334Speter	}
581018334Speter}
581150605Sobrien
581250605Sobrien/* Change any replacements being done to *X to be done to *Y */
581350605Sobrien
581450605Sobrienvoid
581550605Sobrienmove_replacements (x, y)
581650605Sobrien     rtx *x;
581750605Sobrien     rtx *y;
581850605Sobrien{
581950605Sobrien  int i;
582050605Sobrien
582150605Sobrien  for (i = 0; i < n_replacements; i++)
582250605Sobrien    if (replacements[i].subreg_loc == x)
582350605Sobrien      replacements[i].subreg_loc = y;
582450605Sobrien    else if (replacements[i].where == x)
582550605Sobrien      {
582650605Sobrien	replacements[i].where = y;
582750605Sobrien	replacements[i].subreg_loc = 0;
582850605Sobrien      }
582950605Sobrien}
583018334Speter
583118334Speter/* If LOC was scheduled to be replaced by something, return the replacement.
583218334Speter   Otherwise, return *LOC.  */
583318334Speter
583418334Speterrtx
583518334Speterfind_replacement (loc)
583618334Speter     rtx *loc;
583718334Speter{
583818334Speter  struct replacement *r;
583918334Speter
584018334Speter  for (r = &replacements[0]; r < &replacements[n_replacements]; r++)
584118334Speter    {
584218334Speter      rtx reloadreg = reload_reg_rtx[r->what];
584318334Speter
584418334Speter      if (reloadreg && r->where == loc)
584518334Speter	{
584618334Speter	  if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
584750605Sobrien	    reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
584818334Speter
584918334Speter	  return reloadreg;
585018334Speter	}
585118334Speter      else if (reloadreg && r->subreg_loc == loc)
585218334Speter	{
585318334Speter	  /* RELOADREG must be either a REG or a SUBREG.
585418334Speter
585518334Speter	     ??? Is it actually still ever a SUBREG?  If so, why?  */
585618334Speter
585718334Speter	  if (GET_CODE (reloadreg) == REG)
585850605Sobrien	    return gen_rtx_REG (GET_MODE (*loc),
585950605Sobrien				REGNO (reloadreg) + SUBREG_WORD (*loc));
586018334Speter	  else if (GET_MODE (reloadreg) == GET_MODE (*loc))
586118334Speter	    return reloadreg;
586218334Speter	  else
586350605Sobrien	    return gen_rtx_SUBREG (GET_MODE (*loc), SUBREG_REG (reloadreg),
586450605Sobrien				   SUBREG_WORD (reloadreg) + SUBREG_WORD (*loc));
586518334Speter	}
586618334Speter    }
586718334Speter
586850605Sobrien  /* If *LOC is a PLUS, MINUS, or MULT, see if a replacement is scheduled for
586950605Sobrien     what's inside and make a new rtl if so.  */
587050605Sobrien  if (GET_CODE (*loc) == PLUS || GET_CODE (*loc) == MINUS
587150605Sobrien      || GET_CODE (*loc) == MULT)
587250605Sobrien    {
587350605Sobrien      rtx x = find_replacement (&XEXP (*loc, 0));
587450605Sobrien      rtx y = find_replacement (&XEXP (*loc, 1));
587550605Sobrien
587650605Sobrien      if (x != XEXP (*loc, 0) || y != XEXP (*loc, 1))
587750605Sobrien	return gen_rtx_fmt_ee (GET_CODE (*loc), GET_MODE (*loc), x, y);
587850605Sobrien    }
587950605Sobrien
588018334Speter  return *loc;
588118334Speter}
588218334Speter
588318334Speter/* Return nonzero if register in range [REGNO, ENDREGNO)
588418334Speter   appears either explicitly or implicitly in X
588518334Speter   other than being stored into (except for earlyclobber operands).
588618334Speter
588718334Speter   References contained within the substructure at LOC do not count.
588818334Speter   LOC may be zero, meaning don't ignore anything.
588918334Speter
589018334Speter   This is similar to refers_to_regno_p in rtlanal.c except that we
589118334Speter   look at equivalences for pseudos that didn't get hard registers.  */
589218334Speter
589318334Speterint
589418334Speterrefers_to_regno_for_reload_p (regno, endregno, x, loc)
589518334Speter     int regno, endregno;
589618334Speter     rtx x;
589718334Speter     rtx *loc;
589818334Speter{
589918334Speter  register int i;
590018334Speter  register RTX_CODE code;
590118334Speter  register char *fmt;
590218334Speter
590318334Speter  if (x == 0)
590418334Speter    return 0;
590518334Speter
590618334Speter repeat:
590718334Speter  code = GET_CODE (x);
590818334Speter
590918334Speter  switch (code)
591018334Speter    {
591118334Speter    case REG:
591218334Speter      i = REGNO (x);
591318334Speter
591418334Speter      /* If this is a pseudo, a hard register must not have been allocated.
591518334Speter	 X must therefore either be a constant or be in memory.  */
591618334Speter      if (i >= FIRST_PSEUDO_REGISTER)
591718334Speter	{
591818334Speter	  if (reg_equiv_memory_loc[i])
591918334Speter	    return refers_to_regno_for_reload_p (regno, endregno,
592018334Speter						 reg_equiv_memory_loc[i],
592118334Speter						 NULL_PTR);
592218334Speter
592318334Speter	  if (reg_equiv_constant[i])
592418334Speter	    return 0;
592518334Speter
592618334Speter	  abort ();
592718334Speter	}
592818334Speter
592918334Speter      return (endregno > i
593018334Speter	      && regno < i + (i < FIRST_PSEUDO_REGISTER
593118334Speter			      ? HARD_REGNO_NREGS (i, GET_MODE (x))
593218334Speter			      : 1));
593318334Speter
593418334Speter    case SUBREG:
593518334Speter      /* If this is a SUBREG of a hard reg, we can see exactly which
593618334Speter	 registers are being modified.  Otherwise, handle normally.  */
593718334Speter      if (GET_CODE (SUBREG_REG (x)) == REG
593818334Speter	  && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
593918334Speter	{
594018334Speter	  int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
594118334Speter	  int inner_endregno
594218334Speter	    = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
594318334Speter			     ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
594418334Speter
594518334Speter	  return endregno > inner_regno && regno < inner_endregno;
594618334Speter	}
594718334Speter      break;
594818334Speter
594918334Speter    case CLOBBER:
595018334Speter    case SET:
595118334Speter      if (&SET_DEST (x) != loc
595218334Speter	  /* Note setting a SUBREG counts as referring to the REG it is in for
595318334Speter	     a pseudo but not for hard registers since we can
595418334Speter	     treat each word individually.  */
595518334Speter	  && ((GET_CODE (SET_DEST (x)) == SUBREG
595618334Speter	       && loc != &SUBREG_REG (SET_DEST (x))
595718334Speter	       && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
595818334Speter	       && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
595918334Speter	       && refers_to_regno_for_reload_p (regno, endregno,
596018334Speter						SUBREG_REG (SET_DEST (x)),
596118334Speter						loc))
596218334Speter	      /* If the output is an earlyclobber operand, this is
596318334Speter		 a conflict.  */
596418334Speter	      || ((GET_CODE (SET_DEST (x)) != REG
596518334Speter		   || earlyclobber_operand_p (SET_DEST (x)))
596618334Speter		  && refers_to_regno_for_reload_p (regno, endregno,
596718334Speter						   SET_DEST (x), loc))))
596818334Speter	return 1;
596918334Speter
597018334Speter      if (code == CLOBBER || loc == &SET_SRC (x))
597118334Speter	return 0;
597218334Speter      x = SET_SRC (x);
597318334Speter      goto repeat;
597450605Sobrien
597550605Sobrien    default:
597650605Sobrien      break;
597718334Speter    }
597818334Speter
597918334Speter  /* X does not match, so try its subexpressions.  */
598018334Speter
598118334Speter  fmt = GET_RTX_FORMAT (code);
598218334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
598318334Speter    {
598418334Speter      if (fmt[i] == 'e' && loc != &XEXP (x, i))
598518334Speter	{
598618334Speter	  if (i == 0)
598718334Speter	    {
598818334Speter	      x = XEXP (x, 0);
598918334Speter	      goto repeat;
599018334Speter	    }
599118334Speter	  else
599218334Speter	    if (refers_to_regno_for_reload_p (regno, endregno,
599318334Speter					      XEXP (x, i), loc))
599418334Speter	      return 1;
599518334Speter	}
599618334Speter      else if (fmt[i] == 'E')
599718334Speter	{
599818334Speter	  register int j;
599918334Speter	  for (j = XVECLEN (x, i) - 1; j >=0; j--)
600018334Speter	    if (loc != &XVECEXP (x, i, j)
600118334Speter		&& refers_to_regno_for_reload_p (regno, endregno,
600218334Speter						 XVECEXP (x, i, j), loc))
600318334Speter	      return 1;
600418334Speter	}
600518334Speter    }
600618334Speter  return 0;
600718334Speter}
600818334Speter
600918334Speter/* Nonzero if modifying X will affect IN.  If X is a register or a SUBREG,
601018334Speter   we check if any register number in X conflicts with the relevant register
601118334Speter   numbers.  If X is a constant, return 0.  If X is a MEM, return 1 iff IN
601218334Speter   contains a MEM (we don't bother checking for memory addresses that can't
601318334Speter   conflict because we expect this to be a rare case.
601418334Speter
601518334Speter   This function is similar to reg_overlap_mention_p in rtlanal.c except
601618334Speter   that we look at equivalences for pseudos that didn't get hard registers.  */
601718334Speter
601818334Speterint
601918334Speterreg_overlap_mentioned_for_reload_p (x, in)
602018334Speter     rtx x, in;
602118334Speter{
602218334Speter  int regno, endregno;
602318334Speter
602450605Sobrien  /* Overly conservative.  */
602550605Sobrien  if (GET_CODE (x) == STRICT_LOW_PART)
602650605Sobrien    x = XEXP (x, 0);
602750605Sobrien
602850605Sobrien  /* If either argument is a constant, then modifying X can not affect IN.  */
602950605Sobrien  if (CONSTANT_P (x) || CONSTANT_P (in))
603050605Sobrien    return 0;
603150605Sobrien  else if (GET_CODE (x) == SUBREG)
603218334Speter    {
603318334Speter      regno = REGNO (SUBREG_REG (x));
603418334Speter      if (regno < FIRST_PSEUDO_REGISTER)
603518334Speter	regno += SUBREG_WORD (x);
603618334Speter    }
603718334Speter  else if (GET_CODE (x) == REG)
603818334Speter    {
603918334Speter      regno = REGNO (x);
604018334Speter
604118334Speter      /* If this is a pseudo, it must not have been assigned a hard register.
604218334Speter	 Therefore, it must either be in memory or be a constant.  */
604318334Speter
604418334Speter      if (regno >= FIRST_PSEUDO_REGISTER)
604518334Speter	{
604618334Speter	  if (reg_equiv_memory_loc[regno])
604718334Speter	    return refers_to_mem_for_reload_p (in);
604818334Speter	  else if (reg_equiv_constant[regno])
604918334Speter	    return 0;
605018334Speter	  abort ();
605118334Speter	}
605218334Speter    }
605318334Speter  else if (GET_CODE (x) == MEM)
605418334Speter    return refers_to_mem_for_reload_p (in);
605518334Speter  else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
605618334Speter	   || GET_CODE (x) == CC0)
605718334Speter    return reg_mentioned_p (x, in);
605818334Speter  else
605918334Speter    abort ();
606018334Speter
606118334Speter  endregno = regno + (regno < FIRST_PSEUDO_REGISTER
606218334Speter		      ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
606318334Speter
606418334Speter  return refers_to_regno_for_reload_p (regno, endregno, in, NULL_PTR);
606518334Speter}
606618334Speter
606718334Speter/* Return nonzero if anything in X contains a MEM.  Look also for pseudo
606818334Speter   registers.  */
606918334Speter
607018334Speterint
607118334Speterrefers_to_mem_for_reload_p (x)
607218334Speter     rtx x;
607318334Speter{
607418334Speter  char *fmt;
607518334Speter  int i;
607618334Speter
607718334Speter  if (GET_CODE (x) == MEM)
607818334Speter    return 1;
607918334Speter
608018334Speter  if (GET_CODE (x) == REG)
608118334Speter    return (REGNO (x) >= FIRST_PSEUDO_REGISTER
608218334Speter	    && reg_equiv_memory_loc[REGNO (x)]);
608318334Speter
608418334Speter  fmt = GET_RTX_FORMAT (GET_CODE (x));
608518334Speter  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
608618334Speter    if (fmt[i] == 'e'
608718334Speter	&& (GET_CODE (XEXP (x, i)) == MEM
608818334Speter	    || refers_to_mem_for_reload_p (XEXP (x, i))))
608918334Speter      return 1;
609018334Speter
609118334Speter  return 0;
609218334Speter}
609318334Speter
609418334Speter/* Check the insns before INSN to see if there is a suitable register
609518334Speter   containing the same value as GOAL.
609618334Speter   If OTHER is -1, look for a register in class CLASS.
609718334Speter   Otherwise, just see if register number OTHER shares GOAL's value.
609818334Speter
609918334Speter   Return an rtx for the register found, or zero if none is found.
610018334Speter
610118334Speter   If RELOAD_REG_P is (short *)1,
610218334Speter   we reject any hard reg that appears in reload_reg_rtx
610318334Speter   because such a hard reg is also needed coming into this insn.
610418334Speter
610518334Speter   If RELOAD_REG_P is any other nonzero value,
610618334Speter   it is a vector indexed by hard reg number
610718334Speter   and we reject any hard reg whose element in the vector is nonnegative
610818334Speter   as well as any that appears in reload_reg_rtx.
610918334Speter
611018334Speter   If GOAL is zero, then GOALREG is a register number; we look
611118334Speter   for an equivalent for that register.
611218334Speter
611318334Speter   MODE is the machine mode of the value we want an equivalence for.
611418334Speter   If GOAL is nonzero and not VOIDmode, then it must have mode MODE.
611518334Speter
611618334Speter   This function is used by jump.c as well as in the reload pass.
611718334Speter
611818334Speter   If GOAL is the sum of the stack pointer and a constant, we treat it
611918334Speter   as if it were a constant except that sp is required to be unchanging.  */
612018334Speter
612118334Speterrtx
612218334Speterfind_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
612318334Speter     register rtx goal;
612418334Speter     rtx insn;
612518334Speter     enum reg_class class;
612618334Speter     register int other;
612718334Speter     short *reload_reg_p;
612818334Speter     int goalreg;
612918334Speter     enum machine_mode mode;
613018334Speter{
613118334Speter  register rtx p = insn;
613218334Speter  rtx goaltry, valtry, value, where;
613318334Speter  register rtx pat;
613418334Speter  register int regno = -1;
613518334Speter  int valueno;
613618334Speter  int goal_mem = 0;
613718334Speter  int goal_const = 0;
613818334Speter  int goal_mem_addr_varies = 0;
613918334Speter  int need_stable_sp = 0;
614018334Speter  int nregs;
614118334Speter  int valuenregs;
614218334Speter
614318334Speter  if (goal == 0)
614418334Speter    regno = goalreg;
614518334Speter  else if (GET_CODE (goal) == REG)
614618334Speter    regno = REGNO (goal);
614718334Speter  else if (GET_CODE (goal) == MEM)
614818334Speter    {
614918334Speter      enum rtx_code code = GET_CODE (XEXP (goal, 0));
615018334Speter      if (MEM_VOLATILE_P (goal))
615118334Speter	return 0;
615218334Speter      if (flag_float_store && GET_MODE_CLASS (GET_MODE (goal)) == MODE_FLOAT)
615318334Speter	return 0;
615418334Speter      /* An address with side effects must be reexecuted.  */
615518334Speter      switch (code)
615618334Speter	{
615718334Speter	case POST_INC:
615818334Speter	case PRE_INC:
615918334Speter	case POST_DEC:
616018334Speter	case PRE_DEC:
616118334Speter	  return 0;
616250605Sobrien	default:
616350605Sobrien	  break;
616418334Speter	}
616518334Speter      goal_mem = 1;
616618334Speter    }
616718334Speter  else if (CONSTANT_P (goal))
616818334Speter    goal_const = 1;
616918334Speter  else if (GET_CODE (goal) == PLUS
617018334Speter	   && XEXP (goal, 0) == stack_pointer_rtx
617118334Speter	   && CONSTANT_P (XEXP (goal, 1)))
617218334Speter    goal_const = need_stable_sp = 1;
617350605Sobrien  else if (GET_CODE (goal) == PLUS
617450605Sobrien	   && XEXP (goal, 0) == frame_pointer_rtx
617550605Sobrien	   && CONSTANT_P (XEXP (goal, 1)))
617650605Sobrien    goal_const = 1;
617718334Speter  else
617818334Speter    return 0;
617918334Speter
618018334Speter  /* On some machines, certain regs must always be rejected
618118334Speter     because they don't behave the way ordinary registers do.  */
618218334Speter
618318334Speter#ifdef OVERLAPPING_REGNO_P
618418334Speter   if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
618518334Speter       && OVERLAPPING_REGNO_P (regno))
618618334Speter     return 0;
618718334Speter#endif
618818334Speter
618918334Speter  /* Scan insns back from INSN, looking for one that copies
619018334Speter     a value into or out of GOAL.
619118334Speter     Stop and give up if we reach a label.  */
619218334Speter
619318334Speter  while (1)
619418334Speter    {
619518334Speter      p = PREV_INSN (p);
619618334Speter      if (p == 0 || GET_CODE (p) == CODE_LABEL)
619718334Speter	return 0;
619818334Speter      if (GET_CODE (p) == INSN
619950605Sobrien	  /* If we don't want spill regs ...  */
620018334Speter	  && (! (reload_reg_p != 0
620118334Speter		 && reload_reg_p != (short *) (HOST_WIDE_INT) 1)
620218334Speter	  /* ... then ignore insns introduced by reload; they aren't useful
620318334Speter	     and can cause results in reload_as_needed to be different
620418334Speter	     from what they were when calculating the need for spills.
620518334Speter	     If we notice an input-reload insn here, we will reject it below,
620618334Speter	     but it might hide a usable equivalent.  That makes bad code.
620718334Speter	     It may even abort: perhaps no reg was spilled for this insn
620818334Speter	     because it was assumed we would find that equivalent.  */
620918334Speter	      || INSN_UID (p) < reload_first_uid))
621018334Speter	{
621118334Speter	  rtx tem;
621218334Speter	  pat = single_set (p);
621318334Speter	  /* First check for something that sets some reg equal to GOAL.  */
621418334Speter	  if (pat != 0
621518334Speter	      && ((regno >= 0
621618334Speter		   && true_regnum (SET_SRC (pat)) == regno
621718334Speter		   && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
621818334Speter		  ||
621918334Speter		  (regno >= 0
622018334Speter		   && true_regnum (SET_DEST (pat)) == regno
622118334Speter		   && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0)
622218334Speter		  ||
622318334Speter		  (goal_const && rtx_equal_p (SET_SRC (pat), goal)
622450605Sobrien		   /* When looking for stack pointer + const,
622550605Sobrien		      make sure we don't use a stack adjust.  */
622650605Sobrien		   && !reg_overlap_mentioned_for_reload_p (SET_DEST (pat), goal)
622718334Speter		   && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
622818334Speter		  || (goal_mem
622918334Speter		      && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0
623018334Speter		      && rtx_renumbered_equal_p (goal, SET_SRC (pat)))
623118334Speter		  || (goal_mem
623218334Speter		      && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0
623318334Speter		      && rtx_renumbered_equal_p (goal, SET_DEST (pat)))
623418334Speter		  /* If we are looking for a constant,
623518334Speter		     and something equivalent to that constant was copied
623618334Speter		     into a reg, we can use that reg.  */
623718334Speter		  || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
623818334Speter							  NULL_RTX))
623918334Speter		      && rtx_equal_p (XEXP (tem, 0), goal)
624018334Speter		      && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
624118334Speter		  || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
624218334Speter							  NULL_RTX))
624318334Speter		      && GET_CODE (SET_DEST (pat)) == REG
624418334Speter		      && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
624518334Speter		      && GET_MODE_CLASS (GET_MODE (XEXP (tem, 0))) == MODE_FLOAT
624618334Speter		      && GET_CODE (goal) == CONST_INT
624718334Speter		      && 0 != (goaltry = operand_subword (XEXP (tem, 0), 0, 0,
624818334Speter							  VOIDmode))
624918334Speter		      && rtx_equal_p (goal, goaltry)
625018334Speter		      && (valtry = operand_subword (SET_DEST (pat), 0, 0,
625118334Speter						    VOIDmode))
625218334Speter		      && (valueno = true_regnum (valtry)) >= 0)
625318334Speter		  || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
625418334Speter							  NULL_RTX))
625518334Speter		      && GET_CODE (SET_DEST (pat)) == REG
625618334Speter		      && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
625718334Speter		      && GET_MODE_CLASS (GET_MODE (XEXP (tem, 0))) == MODE_FLOAT
625818334Speter		      && GET_CODE (goal) == CONST_INT
625918334Speter		      && 0 != (goaltry = operand_subword (XEXP (tem, 0), 1, 0,
626018334Speter							  VOIDmode))
626118334Speter		      && rtx_equal_p (goal, goaltry)
626218334Speter		      && (valtry
626318334Speter			  = operand_subword (SET_DEST (pat), 1, 0, VOIDmode))
626418334Speter		      && (valueno = true_regnum (valtry)) >= 0)))
626518334Speter	    if (other >= 0
626618334Speter		? valueno == other
626718334Speter		: ((unsigned) valueno < FIRST_PSEUDO_REGISTER
626818334Speter		   && TEST_HARD_REG_BIT (reg_class_contents[(int) class],
626918334Speter					 valueno)))
627018334Speter	      {
627118334Speter		value = valtry;
627218334Speter		where = p;
627318334Speter		break;
627418334Speter	      }
627518334Speter	}
627618334Speter    }
627718334Speter
627818334Speter  /* We found a previous insn copying GOAL into a suitable other reg VALUE
627918334Speter     (or copying VALUE into GOAL, if GOAL is also a register).
628018334Speter     Now verify that VALUE is really valid.  */
628118334Speter
628218334Speter  /* VALUENO is the register number of VALUE; a hard register.  */
628318334Speter
628418334Speter  /* Don't try to re-use something that is killed in this insn.  We want
628518334Speter     to be able to trust REG_UNUSED notes.  */
628618334Speter  if (find_reg_note (where, REG_UNUSED, value))
628718334Speter    return 0;
628818334Speter
628918334Speter  /* If we propose to get the value from the stack pointer or if GOAL is
629018334Speter     a MEM based on the stack pointer, we need a stable SP.  */
629150605Sobrien  if (valueno == STACK_POINTER_REGNUM || regno == STACK_POINTER_REGNUM
629218334Speter      || (goal_mem && reg_overlap_mentioned_for_reload_p (stack_pointer_rtx,
629318334Speter							  goal)))
629418334Speter    need_stable_sp = 1;
629518334Speter
629618334Speter  /* Reject VALUE if the copy-insn moved the wrong sort of datum.  */
629718334Speter  if (GET_MODE (value) != mode)
629818334Speter    return 0;
629918334Speter
630018334Speter  /* Reject VALUE if it was loaded from GOAL
630118334Speter     and is also a register that appears in the address of GOAL.  */
630218334Speter
630350605Sobrien  if (goal_mem && value == SET_DEST (single_set (where))
630418334Speter      && refers_to_regno_for_reload_p (valueno,
630518334Speter				       (valueno
630618334Speter					+ HARD_REGNO_NREGS (valueno, mode)),
630718334Speter				       goal, NULL_PTR))
630818334Speter    return 0;
630918334Speter
631018334Speter  /* Reject registers that overlap GOAL.  */
631118334Speter
631218334Speter  if (!goal_mem && !goal_const
631318334Speter      && regno + HARD_REGNO_NREGS (regno, mode) > valueno
631418334Speter      && regno < valueno + HARD_REGNO_NREGS (valueno, mode))
631518334Speter    return 0;
631618334Speter
631718334Speter  /* Reject VALUE if it is one of the regs reserved for reloads.
631818334Speter     Reload1 knows how to reuse them anyway, and it would get
631918334Speter     confused if we allocated one without its knowledge.
632018334Speter     (Now that insns introduced by reload are ignored above,
632118334Speter     this case shouldn't happen, but I'm not positive.)  */
632218334Speter
632318334Speter  if (reload_reg_p != 0 && reload_reg_p != (short *) (HOST_WIDE_INT) 1
632418334Speter      && reload_reg_p[valueno] >= 0)
632518334Speter    return 0;
632618334Speter
632718334Speter  /* On some machines, certain regs must always be rejected
632818334Speter     because they don't behave the way ordinary registers do.  */
632918334Speter
633018334Speter#ifdef OVERLAPPING_REGNO_P
633118334Speter  if (OVERLAPPING_REGNO_P (valueno))
633218334Speter    return 0;
633318334Speter#endif
633418334Speter
633518334Speter  nregs = HARD_REGNO_NREGS (regno, mode);
633618334Speter  valuenregs = HARD_REGNO_NREGS (valueno, mode);
633718334Speter
633818334Speter  /* Reject VALUE if it is a register being used for an input reload
633918334Speter     even if it is not one of those reserved.  */
634018334Speter
634118334Speter  if (reload_reg_p != 0)
634218334Speter    {
634318334Speter      int i;
634418334Speter      for (i = 0; i < n_reloads; i++)
634518334Speter	if (reload_reg_rtx[i] != 0 && reload_in[i])
634618334Speter	  {
634718334Speter	    int regno1 = REGNO (reload_reg_rtx[i]);
634818334Speter	    int nregs1 = HARD_REGNO_NREGS (regno1,
634918334Speter					   GET_MODE (reload_reg_rtx[i]));
635018334Speter	    if (regno1 < valueno + valuenregs
635118334Speter		&& regno1 + nregs1 > valueno)
635218334Speter	      return 0;
635318334Speter	  }
635418334Speter    }
635518334Speter
635618334Speter  if (goal_mem)
635718334Speter    /* We must treat frame pointer as varying here,
635818334Speter       since it can vary--in a nonlocal goto as generated by expand_goto.  */
635918334Speter    goal_mem_addr_varies = !CONSTANT_ADDRESS_P (XEXP (goal, 0));
636018334Speter
636118334Speter  /* Now verify that the values of GOAL and VALUE remain unaltered
636218334Speter     until INSN is reached.  */
636318334Speter
636418334Speter  p = insn;
636518334Speter  while (1)
636618334Speter    {
636718334Speter      p = PREV_INSN (p);
636818334Speter      if (p == where)
636918334Speter	return value;
637018334Speter
637118334Speter      /* Don't trust the conversion past a function call
637218334Speter	 if either of the two is in a call-clobbered register, or memory.  */
637318334Speter      if (GET_CODE (p) == CALL_INSN
637418334Speter	  && ((regno >= 0 && regno < FIRST_PSEUDO_REGISTER
637518334Speter	       && call_used_regs[regno])
637618334Speter	      ||
637718334Speter	      (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER
637818334Speter	       && call_used_regs[valueno])
637918334Speter	      ||
638018334Speter	      goal_mem
638118334Speter	      || need_stable_sp))
638218334Speter	return 0;
638318334Speter
638418334Speter#ifdef NON_SAVING_SETJMP
638518334Speter      if (NON_SAVING_SETJMP && GET_CODE (p) == NOTE
638618334Speter	  && NOTE_LINE_NUMBER (p) == NOTE_INSN_SETJMP)
638718334Speter	return 0;
638818334Speter#endif
638918334Speter
639018334Speter#ifdef INSN_CLOBBERS_REGNO_P
639118334Speter      if ((valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER
639218334Speter	  && INSN_CLOBBERS_REGNO_P (p, valueno))
639318334Speter	  || (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
639418334Speter	  && INSN_CLOBBERS_REGNO_P (p, regno)))
639518334Speter	return 0;
639618334Speter#endif
639718334Speter
639818334Speter      if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
639918334Speter	{
640050605Sobrien	  pat = PATTERN (p);
640150605Sobrien
640250605Sobrien          /* Watch out for unspec_volatile, and volatile asms.  */
640350605Sobrien          if (volatile_insn_p (pat))
640450605Sobrien	    return 0;
640550605Sobrien
640618334Speter	  /* If this insn P stores in either GOAL or VALUE, return 0.
640718334Speter	     If GOAL is a memory ref and this insn writes memory, return 0.
640818334Speter	     If GOAL is a memory ref and its address is not constant,
640918334Speter	     and this insn P changes a register used in GOAL, return 0.  */
641018334Speter
641118334Speter	  if (GET_CODE (pat) == SET || GET_CODE (pat) == CLOBBER)
641218334Speter	    {
641318334Speter	      register rtx dest = SET_DEST (pat);
641418334Speter	      while (GET_CODE (dest) == SUBREG
641518334Speter		     || GET_CODE (dest) == ZERO_EXTRACT
641618334Speter		     || GET_CODE (dest) == SIGN_EXTRACT
641718334Speter		     || GET_CODE (dest) == STRICT_LOW_PART)
641818334Speter		dest = XEXP (dest, 0);
641918334Speter	      if (GET_CODE (dest) == REG)
642018334Speter		{
642118334Speter		  register int xregno = REGNO (dest);
642218334Speter		  int xnregs;
642318334Speter		  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
642418334Speter		    xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
642518334Speter		  else
642618334Speter		    xnregs = 1;
642718334Speter		  if (xregno < regno + nregs && xregno + xnregs > regno)
642818334Speter		    return 0;
642918334Speter		  if (xregno < valueno + valuenregs
643018334Speter		      && xregno + xnregs > valueno)
643118334Speter		    return 0;
643218334Speter		  if (goal_mem_addr_varies
643318334Speter		      && reg_overlap_mentioned_for_reload_p (dest, goal))
643418334Speter		    return 0;
643550605Sobrien		  if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
643650605Sobrien		    return 0;
643718334Speter		}
643818334Speter	      else if (goal_mem && GET_CODE (dest) == MEM
643918334Speter		       && ! push_operand (dest, GET_MODE (dest)))
644018334Speter		return 0;
644118334Speter	      else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
644218334Speter		       && reg_equiv_memory_loc[regno] != 0)
644318334Speter		return 0;
644418334Speter	      else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
644518334Speter		return 0;
644618334Speter	    }
644718334Speter	  else if (GET_CODE (pat) == PARALLEL)
644818334Speter	    {
644918334Speter	      register int i;
645018334Speter	      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
645118334Speter		{
645218334Speter		  register rtx v1 = XVECEXP (pat, 0, i);
645318334Speter		  if (GET_CODE (v1) == SET || GET_CODE (v1) == CLOBBER)
645418334Speter		    {
645518334Speter		      register rtx dest = SET_DEST (v1);
645618334Speter		      while (GET_CODE (dest) == SUBREG
645718334Speter			     || GET_CODE (dest) == ZERO_EXTRACT
645818334Speter			     || GET_CODE (dest) == SIGN_EXTRACT
645918334Speter			     || GET_CODE (dest) == STRICT_LOW_PART)
646018334Speter			dest = XEXP (dest, 0);
646118334Speter		      if (GET_CODE (dest) == REG)
646218334Speter			{
646318334Speter			  register int xregno = REGNO (dest);
646418334Speter			  int xnregs;
646518334Speter			  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
646618334Speter			    xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
646718334Speter			  else
646818334Speter			    xnregs = 1;
646918334Speter			  if (xregno < regno + nregs
647018334Speter			      && xregno + xnregs > regno)
647118334Speter			    return 0;
647218334Speter			  if (xregno < valueno + valuenregs
647318334Speter			      && xregno + xnregs > valueno)
647418334Speter			    return 0;
647518334Speter			  if (goal_mem_addr_varies
647618334Speter			      && reg_overlap_mentioned_for_reload_p (dest,
647718334Speter								     goal))
647818334Speter			    return 0;
647950605Sobrien			  if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
648050605Sobrien			    return 0;
648118334Speter			}
648218334Speter		      else if (goal_mem && GET_CODE (dest) == MEM
648318334Speter			       && ! push_operand (dest, GET_MODE (dest)))
648418334Speter			return 0;
648550605Sobrien		      else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
648650605Sobrien			       && reg_equiv_memory_loc[regno] != 0)
648750605Sobrien			return 0;
648818334Speter		      else if (need_stable_sp
648918334Speter			       && push_operand (dest, GET_MODE (dest)))
649018334Speter			return 0;
649118334Speter		    }
649218334Speter		}
649318334Speter	    }
649418334Speter
649518334Speter	  if (GET_CODE (p) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (p))
649618334Speter	    {
649718334Speter	      rtx link;
649818334Speter
649918334Speter	      for (link = CALL_INSN_FUNCTION_USAGE (p); XEXP (link, 1) != 0;
650018334Speter		   link = XEXP (link, 1))
650118334Speter		{
650218334Speter		  pat = XEXP (link, 0);
650318334Speter		  if (GET_CODE (pat) == CLOBBER)
650418334Speter		    {
650518334Speter		      register rtx dest = SET_DEST (pat);
650618334Speter		      while (GET_CODE (dest) == SUBREG
650718334Speter			     || GET_CODE (dest) == ZERO_EXTRACT
650818334Speter			     || GET_CODE (dest) == SIGN_EXTRACT
650918334Speter			     || GET_CODE (dest) == STRICT_LOW_PART)
651018334Speter			dest = XEXP (dest, 0);
651118334Speter		      if (GET_CODE (dest) == REG)
651218334Speter			{
651318334Speter			  register int xregno = REGNO (dest);
651418334Speter			  int xnregs;
651518334Speter			  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
651618334Speter			    xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
651718334Speter			  else
651818334Speter			    xnregs = 1;
651918334Speter			  if (xregno < regno + nregs
652018334Speter			      && xregno + xnregs > regno)
652118334Speter			    return 0;
652218334Speter			  if (xregno < valueno + valuenregs
652318334Speter			      && xregno + xnregs > valueno)
652418334Speter			    return 0;
652518334Speter			  if (goal_mem_addr_varies
652618334Speter			      && reg_overlap_mentioned_for_reload_p (dest,
652718334Speter								     goal))
652818334Speter			    return 0;
652918334Speter			}
653018334Speter		      else if (goal_mem && GET_CODE (dest) == MEM
653118334Speter			       && ! push_operand (dest, GET_MODE (dest)))
653218334Speter			return 0;
653318334Speter		      else if (need_stable_sp
653418334Speter			       && push_operand (dest, GET_MODE (dest)))
653518334Speter			return 0;
653618334Speter		    }
653718334Speter		}
653818334Speter	    }
653918334Speter
654018334Speter#ifdef AUTO_INC_DEC
654118334Speter	  /* If this insn auto-increments or auto-decrements
654218334Speter	     either regno or valueno, return 0 now.
654318334Speter	     If GOAL is a memory ref and its address is not constant,
654418334Speter	     and this insn P increments a register used in GOAL, return 0.  */
654518334Speter	  {
654618334Speter	    register rtx link;
654718334Speter
654818334Speter	    for (link = REG_NOTES (p); link; link = XEXP (link, 1))
654918334Speter	      if (REG_NOTE_KIND (link) == REG_INC
655018334Speter		  && GET_CODE (XEXP (link, 0)) == REG)
655118334Speter		{
655218334Speter		  register int incno = REGNO (XEXP (link, 0));
655318334Speter		  if (incno < regno + nregs && incno >= regno)
655418334Speter		    return 0;
655518334Speter		  if (incno < valueno + valuenregs && incno >= valueno)
655618334Speter		    return 0;
655718334Speter		  if (goal_mem_addr_varies
655818334Speter		      && reg_overlap_mentioned_for_reload_p (XEXP (link, 0),
655918334Speter							     goal))
656018334Speter		    return 0;
656118334Speter		}
656218334Speter	  }
656318334Speter#endif
656418334Speter	}
656518334Speter    }
656618334Speter}
656718334Speter
656818334Speter/* Find a place where INCED appears in an increment or decrement operator
656918334Speter   within X, and return the amount INCED is incremented or decremented by.
657018334Speter   The value is always positive.  */
657118334Speter
657218334Speterstatic int
657318334Speterfind_inc_amount (x, inced)
657418334Speter     rtx x, inced;
657518334Speter{
657618334Speter  register enum rtx_code code = GET_CODE (x);
657718334Speter  register char *fmt;
657818334Speter  register int i;
657918334Speter
658018334Speter  if (code == MEM)
658118334Speter    {
658218334Speter      register rtx addr = XEXP (x, 0);
658318334Speter      if ((GET_CODE (addr) == PRE_DEC
658418334Speter	   || GET_CODE (addr) == POST_DEC
658518334Speter	   || GET_CODE (addr) == PRE_INC
658618334Speter	   || GET_CODE (addr) == POST_INC)
658718334Speter	  && XEXP (addr, 0) == inced)
658818334Speter	return GET_MODE_SIZE (GET_MODE (x));
658918334Speter    }
659018334Speter
659118334Speter  fmt = GET_RTX_FORMAT (code);
659218334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
659318334Speter    {
659418334Speter      if (fmt[i] == 'e')
659518334Speter	{
659618334Speter	  register int tem = find_inc_amount (XEXP (x, i), inced);
659718334Speter	  if (tem != 0)
659818334Speter	    return tem;
659918334Speter	}
660018334Speter      if (fmt[i] == 'E')
660118334Speter	{
660218334Speter	  register int j;
660318334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
660418334Speter	    {
660518334Speter	      register int tem = find_inc_amount (XVECEXP (x, i, j), inced);
660618334Speter	      if (tem != 0)
660718334Speter		return tem;
660818334Speter	    }
660918334Speter	}
661018334Speter    }
661118334Speter
661218334Speter  return 0;
661318334Speter}
661418334Speter
661518334Speter/* Return 1 if register REGNO is the subject of a clobber in insn INSN.  */
661618334Speter
661718334Speterint
661818334Speterregno_clobbered_p (regno, insn)
661918334Speter     int regno;
662018334Speter     rtx insn;
662118334Speter{
662218334Speter  if (GET_CODE (PATTERN (insn)) == CLOBBER
662318334Speter      && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
662418334Speter    return REGNO (XEXP (PATTERN (insn), 0)) == regno;
662518334Speter
662618334Speter  if (GET_CODE (PATTERN (insn)) == PARALLEL)
662718334Speter    {
662818334Speter      int i = XVECLEN (PATTERN (insn), 0) - 1;
662918334Speter
663018334Speter      for (; i >= 0; i--)
663118334Speter	{
663218334Speter	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
663318334Speter	  if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG
663418334Speter	      && REGNO (XEXP (elt, 0)) == regno)
663518334Speter	    return 1;
663618334Speter	}
663718334Speter    }
663818334Speter
663918334Speter  return 0;
664018334Speter}
664118334Speter
664218334Speterstatic char *reload_when_needed_name[] =
664318334Speter{
664418334Speter  "RELOAD_FOR_INPUT",
664518334Speter  "RELOAD_FOR_OUTPUT",
664618334Speter  "RELOAD_FOR_INSN",
664750605Sobrien  "RELOAD_FOR_INPUT_ADDRESS",
664850605Sobrien  "RELOAD_FOR_INPADDR_ADDRESS",
664918334Speter  "RELOAD_FOR_OUTPUT_ADDRESS",
665050605Sobrien  "RELOAD_FOR_OUTADDR_ADDRESS",
665118334Speter  "RELOAD_FOR_OPERAND_ADDRESS",
665218334Speter  "RELOAD_FOR_OPADDR_ADDR",
665318334Speter  "RELOAD_OTHER",
665418334Speter  "RELOAD_FOR_OTHER_ADDRESS"
665518334Speter};
665618334Speter
665718334Speterstatic char *reg_class_names[] = REG_CLASS_NAMES;
665818334Speter
665950605Sobrien/* These functions are used to print the variables set by 'find_reloads' */
666018334Speter
666118334Spetervoid
666250605Sobriendebug_reload_to_stream (f)
666350605Sobrien     FILE *f;
666418334Speter{
666518334Speter  int r;
666650605Sobrien  char *prefix;
666718334Speter
666850605Sobrien  if (! f)
666950605Sobrien    f = stderr;
667018334Speter  for (r = 0; r < n_reloads; r++)
667118334Speter    {
667250605Sobrien      fprintf (f, "Reload %d: ", r);
667318334Speter
667450605Sobrien      if (reload_in[r] != 0)
667518334Speter	{
667650605Sobrien	  fprintf (f, "reload_in (%s) = ",
667718334Speter		   GET_MODE_NAME (reload_inmode[r]));
667850605Sobrien	  print_inline_rtx (f, reload_in[r], 24);
667950605Sobrien	  fprintf (f, "\n\t");
668018334Speter	}
668118334Speter
668250605Sobrien      if (reload_out[r] != 0)
668318334Speter	{
668450605Sobrien	  fprintf (f, "reload_out (%s) = ",
668518334Speter		   GET_MODE_NAME (reload_outmode[r]));
668650605Sobrien	  print_inline_rtx (f, reload_out[r], 24);
668750605Sobrien	  fprintf (f, "\n\t");
668818334Speter	}
668918334Speter
669050605Sobrien      fprintf (f, "%s, ", reg_class_names[(int) reload_reg_class[r]]);
669118334Speter
669250605Sobrien      fprintf (f, "%s (opnum = %d)",
669350605Sobrien	       reload_when_needed_name[(int) reload_when_needed[r]],
669418334Speter	       reload_opnum[r]);
669518334Speter
669618334Speter      if (reload_optional[r])
669750605Sobrien	fprintf (f, ", optional");
669818334Speter
669950605Sobrien      if (reload_nongroup[r])
670050605Sobrien	fprintf (stderr, ", nongroup");
670118334Speter
670250605Sobrien      if (reload_inc[r] != 0)
670350605Sobrien	fprintf (f, ", inc by %d", reload_inc[r]);
670450605Sobrien
670518334Speter      if (reload_nocombine[r])
670650605Sobrien	fprintf (f, ", can't combine");
670718334Speter
670818334Speter      if (reload_secondary_p[r])
670950605Sobrien	fprintf (f, ", secondary_reload_p");
671018334Speter
671150605Sobrien      if (reload_in_reg[r] != 0)
671218334Speter	{
671350605Sobrien	  fprintf (f, "\n\treload_in_reg: ");
671450605Sobrien	  print_inline_rtx (f, reload_in_reg[r], 24);
671518334Speter	}
671618334Speter
671752557Sobrien      if (reload_out_reg[r] != 0)
671852557Sobrien	{
671952557Sobrien	  fprintf (f, "\n\treload_out_reg: ");
672052557Sobrien	  print_inline_rtx (f, reload_out_reg[r], 24);
672152557Sobrien	}
672252557Sobrien
672350605Sobrien      if (reload_reg_rtx[r] != 0)
672418334Speter	{
672550605Sobrien	  fprintf (f, "\n\treload_reg_rtx: ");
672650605Sobrien	  print_inline_rtx (f, reload_reg_rtx[r], 24);
672718334Speter	}
672818334Speter
672950605Sobrien      prefix = "\n\t";
673018334Speter      if (reload_secondary_in_reload[r] != -1)
673118334Speter	{
673250605Sobrien	  fprintf (f, "%ssecondary_in_reload = %d",
673350605Sobrien		   prefix, reload_secondary_in_reload[r]);
673450605Sobrien	  prefix = ", ";
673518334Speter	}
673618334Speter
673718334Speter      if (reload_secondary_out_reload[r] != -1)
673850605Sobrien	fprintf (f, "%ssecondary_out_reload = %d\n",
673950605Sobrien		 prefix, reload_secondary_out_reload[r]);
674018334Speter
674150605Sobrien      prefix = "\n\t";
674218334Speter      if (reload_secondary_in_icode[r] != CODE_FOR_nothing)
674318334Speter	{
674450605Sobrien	  fprintf (stderr, "%ssecondary_in_icode = %s", prefix,
674550605Sobrien		   insn_name[reload_secondary_in_icode[r]]);
674650605Sobrien	  prefix = ", ";
674718334Speter	}
674818334Speter
674918334Speter      if (reload_secondary_out_icode[r] != CODE_FOR_nothing)
675050605Sobrien	fprintf (stderr, "%ssecondary_out_icode = %s", prefix,
675150605Sobrien		 insn_name[reload_secondary_out_icode[r]]);
675218334Speter
675350605Sobrien      fprintf (f, "\n");
675418334Speter    }
675550605Sobrien}
675618334Speter
675750605Sobrienvoid
675850605Sobriendebug_reload ()
675950605Sobrien{
676050605Sobrien  debug_reload_to_stream (stderr);
676118334Speter}
6762