reload.c revision 70639
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 70639 2001-01-03 17:17:01Z 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 hard_reg_set_here_p	PROTO((int, int, rtx));
32818334Speterstatic struct decomposition decompose PROTO((rtx));
32918334Speterstatic int immune_p		PROTO((rtx, rtx, struct decomposition));
33052557Sobrienstatic int alternative_allows_memconst PROTO((const char *, int));
33152557Sobrienstatic rtx find_reloads_toplev	PROTO((rtx, int, enum reload_type, int, int, rtx));
33218334Speterstatic rtx make_memloc		PROTO((rtx, int));
33318334Speterstatic int find_reloads_address	PROTO((enum machine_mode, rtx *, rtx, rtx *,
33450605Sobrien				       int, enum reload_type, int, rtx));
33552557Sobrienstatic rtx subst_reg_equivs	PROTO((rtx, rtx));
33618334Speterstatic rtx subst_indexed_address PROTO((rtx));
33750605Sobrienstatic int find_reloads_address_1 PROTO((enum machine_mode, rtx, int, rtx *,
33850605Sobrien					 int, enum reload_type,int, rtx));
33918334Speterstatic void find_reloads_address_part PROTO((rtx, rtx *, enum reg_class,
34018334Speter					     enum machine_mode, int,
34118334Speter					     enum reload_type, int));
34252557Sobrienstatic rtx find_reloads_subreg_address PROTO((rtx, int, int, enum reload_type,
34352557Sobrien					      int, rtx));
34418334Speterstatic int find_inc_amount	PROTO((rtx, rtx));
34552557Sobrienstatic int loc_mentioned_in_p	PROTO((rtx *, rtx));
34618334Speter
34718334Speter#ifdef HAVE_SECONDARY_RELOADS
34818334Speter
34918334Speter/* Determine if any secondary reloads are needed for loading (if IN_P is
35018334Speter   non-zero) or storing (if IN_P is zero) X to or from a reload register of
35118334Speter   register class RELOAD_CLASS in mode RELOAD_MODE.  If secondary reloads
35218334Speter   are needed, push them.
35318334Speter
35418334Speter   Return the reload number of the secondary reload we made, or -1 if
35518334Speter   we didn't need one.  *PICODE is set to the insn_code to use if we do
35618334Speter   need a secondary reload.  */
35718334Speter
35818334Speterstatic int
35918334Speterpush_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
36018334Speter		       type, picode)
36118334Speter     int in_p;
36218334Speter     rtx x;
36318334Speter     int opnum;
36418334Speter     int optional;
36518334Speter     enum reg_class reload_class;
36618334Speter     enum machine_mode reload_mode;
36718334Speter     enum reload_type type;
36818334Speter     enum insn_code *picode;
36918334Speter{
37018334Speter  enum reg_class class = NO_REGS;
37118334Speter  enum machine_mode mode = reload_mode;
37218334Speter  enum insn_code icode = CODE_FOR_nothing;
37318334Speter  enum reg_class t_class = NO_REGS;
37418334Speter  enum machine_mode t_mode = VOIDmode;
37518334Speter  enum insn_code t_icode = CODE_FOR_nothing;
37618334Speter  enum reload_type secondary_type;
37718334Speter  int s_reload, t_reload = -1;
37818334Speter
37950605Sobrien  if (type == RELOAD_FOR_INPUT_ADDRESS
38050605Sobrien      || type == RELOAD_FOR_OUTPUT_ADDRESS
38150605Sobrien      || type == RELOAD_FOR_INPADDR_ADDRESS
38250605Sobrien      || type == RELOAD_FOR_OUTADDR_ADDRESS)
38318334Speter    secondary_type = type;
38418334Speter  else
38518334Speter    secondary_type = in_p ? RELOAD_FOR_INPUT_ADDRESS : RELOAD_FOR_OUTPUT_ADDRESS;
38618334Speter
38718334Speter  *picode = CODE_FOR_nothing;
38818334Speter
38918334Speter  /* If X is a paradoxical SUBREG, use the inner value to determine both the
39018334Speter     mode and object being reloaded.  */
39118334Speter  if (GET_CODE (x) == SUBREG
39218334Speter      && (GET_MODE_SIZE (GET_MODE (x))
39318334Speter	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
39418334Speter    {
39518334Speter      x = SUBREG_REG (x);
39618334Speter      reload_mode = GET_MODE (x);
39718334Speter    }
39818334Speter
39918334Speter  /* If X is a pseudo-register that has an equivalent MEM (actually, if it
40018334Speter     is still a pseudo-register by now, it *must* have an equivalent MEM
40118334Speter     but we don't want to assume that), use that equivalent when seeing if
40218334Speter     a secondary reload is needed since whether or not a reload is needed
40318334Speter     might be sensitive to the form of the MEM.  */
40418334Speter
40518334Speter  if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
40618334Speter      && reg_equiv_mem[REGNO (x)] != 0)
40718334Speter    x = reg_equiv_mem[REGNO (x)];
40818334Speter
40918334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
41018334Speter  if (in_p)
41118334Speter    class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
41218334Speter#endif
41318334Speter
41418334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
41518334Speter  if (! in_p)
41618334Speter    class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
41718334Speter#endif
41818334Speter
41918334Speter  /* If we don't need any secondary registers, done.  */
42018334Speter  if (class == NO_REGS)
42118334Speter    return -1;
42218334Speter
42318334Speter  /* Get a possible insn to use.  If the predicate doesn't accept X, don't
42418334Speter     use the insn.  */
42518334Speter
42618334Speter  icode = (in_p ? reload_in_optab[(int) reload_mode]
42718334Speter	   : reload_out_optab[(int) reload_mode]);
42818334Speter
42918334Speter  if (icode != CODE_FOR_nothing
43018334Speter      && insn_operand_predicate[(int) icode][in_p]
43118334Speter      && (! (insn_operand_predicate[(int) icode][in_p]) (x, reload_mode)))
43218334Speter    icode = CODE_FOR_nothing;
43318334Speter
43418334Speter  /* If we will be using an insn, see if it can directly handle the reload
43518334Speter     register we will be using.  If it can, the secondary reload is for a
43618334Speter     scratch register.  If it can't, we will use the secondary reload for
43718334Speter     an intermediate register and require a tertiary reload for the scratch
43818334Speter     register.  */
43918334Speter
44018334Speter  if (icode != CODE_FOR_nothing)
44118334Speter    {
44218334Speter      /* If IN_P is non-zero, the reload register will be the output in
44318334Speter	 operand 0.  If IN_P is zero, the reload register will be the input
44418334Speter	 in operand 1.  Outputs should have an initial "=", which we must
44518334Speter	 skip.  */
44618334Speter
44718334Speter      char insn_letter = insn_operand_constraint[(int) icode][!in_p][in_p];
44818334Speter      enum reg_class insn_class
44918334Speter	= (insn_letter == 'r' ? GENERAL_REGS
45052557Sobrien	   : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
45118334Speter
45218334Speter      if (insn_class == NO_REGS
45318334Speter	  || (in_p && insn_operand_constraint[(int) icode][!in_p][0] != '=')
45418334Speter	  /* The scratch register's constraint must start with "=&".  */
45518334Speter	  || insn_operand_constraint[(int) icode][2][0] != '='
45618334Speter	  || insn_operand_constraint[(int) icode][2][1] != '&')
45718334Speter	abort ();
45818334Speter
45918334Speter      if (reg_class_subset_p (reload_class, insn_class))
46018334Speter	mode = insn_operand_mode[(int) icode][2];
46118334Speter      else
46218334Speter	{
46318334Speter	  char t_letter = insn_operand_constraint[(int) icode][2][2];
46418334Speter	  class = insn_class;
46518334Speter	  t_mode = insn_operand_mode[(int) icode][2];
46618334Speter	  t_class = (t_letter == 'r' ? GENERAL_REGS
46752557Sobrien		     : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
46818334Speter	  t_icode = icode;
46918334Speter	  icode = CODE_FOR_nothing;
47018334Speter	}
47118334Speter    }
47218334Speter
47318334Speter  /* This case isn't valid, so fail.  Reload is allowed to use the same
47418334Speter     register for RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_INPUT reloads, but
47518334Speter     in the case of a secondary register, we actually need two different
47618334Speter     registers for correct code.  We fail here to prevent the possibility of
47718334Speter     silently generating incorrect code later.
47818334Speter
47918334Speter     The convention is that secondary input reloads are valid only if the
48018334Speter     secondary_class is different from class.  If you have such a case, you
48118334Speter     can not use secondary reloads, you must work around the problem some
48218334Speter     other way.
48318334Speter
48418334Speter     Allow this when MODE is not reload_mode and assume that the generated
48518334Speter     code handles this case (it does on the Alpha, which is the only place
48618334Speter     this currently happens).  */
48718334Speter
48818334Speter  if (in_p && class == reload_class && mode == reload_mode)
48918334Speter    abort ();
49018334Speter
49118334Speter  /* If we need a tertiary reload, see if we have one we can reuse or else
49218334Speter     make a new one.  */
49318334Speter
49418334Speter  if (t_class != NO_REGS)
49518334Speter    {
49618334Speter      for (t_reload = 0; t_reload < n_reloads; t_reload++)
49718334Speter	if (reload_secondary_p[t_reload]
49818334Speter	    && (reg_class_subset_p (t_class, reload_reg_class[t_reload])
49918334Speter		|| reg_class_subset_p (reload_reg_class[t_reload], t_class))
50018334Speter	    && ((in_p && reload_inmode[t_reload] == t_mode)
50118334Speter		|| (! in_p && reload_outmode[t_reload] == t_mode))
50218334Speter	    && ((in_p && (reload_secondary_in_icode[t_reload]
50318334Speter			  == CODE_FOR_nothing))
50418334Speter		|| (! in_p &&(reload_secondary_out_icode[t_reload]
50518334Speter			      == CODE_FOR_nothing)))
50650605Sobrien	    && (reg_class_size[(int) t_class] == 1 || SMALL_REGISTER_CLASSES)
50718334Speter	    && MERGABLE_RELOADS (secondary_type,
50818334Speter				 reload_when_needed[t_reload],
50918334Speter				 opnum, reload_opnum[t_reload]))
51018334Speter	  {
51118334Speter	    if (in_p)
51218334Speter	      reload_inmode[t_reload] = t_mode;
51318334Speter	    if (! in_p)
51418334Speter	      reload_outmode[t_reload] = t_mode;
51518334Speter
51618334Speter	    if (reg_class_subset_p (t_class, reload_reg_class[t_reload]))
51718334Speter	      reload_reg_class[t_reload] = t_class;
51818334Speter
51918334Speter	    reload_opnum[t_reload] = MIN (reload_opnum[t_reload], opnum);
52018334Speter	    reload_optional[t_reload] &= optional;
52118334Speter	    reload_secondary_p[t_reload] = 1;
52218334Speter	    if (MERGE_TO_OTHER (secondary_type, reload_when_needed[t_reload],
52318334Speter				opnum, reload_opnum[t_reload]))
52418334Speter	      reload_when_needed[t_reload] = RELOAD_OTHER;
52518334Speter	  }
52618334Speter
52718334Speter      if (t_reload == n_reloads)
52818334Speter	{
52918334Speter	  /* We need to make a new tertiary reload for this register class.  */
53018334Speter	  reload_in[t_reload] = reload_out[t_reload] = 0;
53118334Speter	  reload_reg_class[t_reload] = t_class;
53218334Speter	  reload_inmode[t_reload] = in_p ? t_mode : VOIDmode;
53318334Speter	  reload_outmode[t_reload] = ! in_p ? t_mode : VOIDmode;
53418334Speter	  reload_reg_rtx[t_reload] = 0;
53518334Speter	  reload_optional[t_reload] = optional;
53650605Sobrien	  reload_nongroup[t_reload] = 0;
53718334Speter	  reload_inc[t_reload] = 0;
53818334Speter	  /* Maybe we could combine these, but it seems too tricky.  */
53918334Speter	  reload_nocombine[t_reload] = 1;
54018334Speter	  reload_in_reg[t_reload] = 0;
54152557Sobrien	  reload_out_reg[t_reload] = 0;
54218334Speter	  reload_opnum[t_reload] = opnum;
54318334Speter	  reload_when_needed[t_reload] = secondary_type;
54418334Speter	  reload_secondary_in_reload[t_reload] = -1;
54518334Speter	  reload_secondary_out_reload[t_reload] = -1;
54618334Speter	  reload_secondary_in_icode[t_reload] = CODE_FOR_nothing;
54718334Speter	  reload_secondary_out_icode[t_reload] = CODE_FOR_nothing;
54818334Speter	  reload_secondary_p[t_reload] = 1;
54918334Speter
55018334Speter	  n_reloads++;
55118334Speter	}
55218334Speter    }
55318334Speter
55418334Speter  /* See if we can reuse an existing secondary reload.  */
55518334Speter  for (s_reload = 0; s_reload < n_reloads; s_reload++)
55618334Speter    if (reload_secondary_p[s_reload]
55718334Speter	&& (reg_class_subset_p (class, reload_reg_class[s_reload])
55818334Speter	    || reg_class_subset_p (reload_reg_class[s_reload], class))
55918334Speter	&& ((in_p && reload_inmode[s_reload] == mode)
56018334Speter	    || (! in_p && reload_outmode[s_reload] == mode))
56118334Speter	&& ((in_p && reload_secondary_in_reload[s_reload] == t_reload)
56218334Speter	    || (! in_p && reload_secondary_out_reload[s_reload] == t_reload))
56318334Speter	&& ((in_p && reload_secondary_in_icode[s_reload] == t_icode)
56418334Speter	    || (! in_p && reload_secondary_out_icode[s_reload] == t_icode))
56550605Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
56618334Speter	&& MERGABLE_RELOADS (secondary_type, reload_when_needed[s_reload],
56718334Speter			     opnum, reload_opnum[s_reload]))
56818334Speter      {
56918334Speter	if (in_p)
57018334Speter	  reload_inmode[s_reload] = mode;
57118334Speter	if (! in_p)
57218334Speter	  reload_outmode[s_reload] = mode;
57318334Speter
57418334Speter	if (reg_class_subset_p (class, reload_reg_class[s_reload]))
57518334Speter	  reload_reg_class[s_reload] = class;
57618334Speter
57718334Speter	reload_opnum[s_reload] = MIN (reload_opnum[s_reload], opnum);
57818334Speter	reload_optional[s_reload] &= optional;
57918334Speter	reload_secondary_p[s_reload] = 1;
58018334Speter	if (MERGE_TO_OTHER (secondary_type, reload_when_needed[s_reload],
58118334Speter			    opnum, reload_opnum[s_reload]))
58218334Speter	  reload_when_needed[s_reload] = RELOAD_OTHER;
58318334Speter      }
58418334Speter
58518334Speter  if (s_reload == n_reloads)
58618334Speter    {
58750605Sobrien#ifdef SECONDARY_MEMORY_NEEDED
58850605Sobrien      /* If we need a memory location to copy between the two reload regs,
58950605Sobrien	 set it up now.  Note that we do the input case before making
59050605Sobrien	 the reload and the output case after.  This is due to the
59150605Sobrien	 way reloads are output.  */
59250605Sobrien
59350605Sobrien      if (in_p && icode == CODE_FOR_nothing
59450605Sobrien	  && SECONDARY_MEMORY_NEEDED (class, reload_class, mode))
59570639Sobrien	{
59670639Sobrien	  get_secondary_mem (x, reload_mode, opnum, type);
59770639Sobrien
59870639Sobrien	  /* We may have just added new reloads.  Make sure we add
59970639Sobrien	     the new reload at the end.  */
60070639Sobrien	  s_reload = n_reloads;
60170639Sobrien	}
60250605Sobrien#endif
60350605Sobrien
60418334Speter      /* We need to make a new secondary reload for this register class.  */
60518334Speter      reload_in[s_reload] = reload_out[s_reload] = 0;
60618334Speter      reload_reg_class[s_reload] = class;
60718334Speter
60818334Speter      reload_inmode[s_reload] = in_p ? mode : VOIDmode;
60918334Speter      reload_outmode[s_reload] = ! in_p ? mode : VOIDmode;
61018334Speter      reload_reg_rtx[s_reload] = 0;
61118334Speter      reload_optional[s_reload] = optional;
61250605Sobrien      reload_nongroup[s_reload] = 0;
61318334Speter      reload_inc[s_reload] = 0;
61418334Speter      /* Maybe we could combine these, but it seems too tricky.  */
61518334Speter      reload_nocombine[s_reload] = 1;
61618334Speter      reload_in_reg[s_reload] = 0;
61752557Sobrien      reload_out_reg[s_reload] = 0;
61818334Speter      reload_opnum[s_reload] = opnum;
61918334Speter      reload_when_needed[s_reload] = secondary_type;
62018334Speter      reload_secondary_in_reload[s_reload] = in_p ? t_reload : -1;
62118334Speter      reload_secondary_out_reload[s_reload] = ! in_p ? t_reload : -1;
62218334Speter      reload_secondary_in_icode[s_reload] = in_p ? t_icode : CODE_FOR_nothing;
62318334Speter      reload_secondary_out_icode[s_reload]
62418334Speter	= ! in_p ? t_icode : CODE_FOR_nothing;
62518334Speter      reload_secondary_p[s_reload] = 1;
62618334Speter
62718334Speter      n_reloads++;
62818334Speter
62918334Speter#ifdef SECONDARY_MEMORY_NEEDED
63018334Speter      if (! in_p && icode == CODE_FOR_nothing
63150605Sobrien	  && SECONDARY_MEMORY_NEEDED (reload_class, class, mode))
63250605Sobrien	get_secondary_mem (x, mode, opnum, type);
63318334Speter#endif
63418334Speter    }
63518334Speter
63618334Speter  *picode = icode;
63718334Speter  return s_reload;
63818334Speter}
63918334Speter#endif /* HAVE_SECONDARY_RELOADS */
64018334Speter
64118334Speter#ifdef SECONDARY_MEMORY_NEEDED
64218334Speter
64318334Speter/* Return a memory location that will be used to copy X in mode MODE.
64418334Speter   If we haven't already made a location for this mode in this insn,
64518334Speter   call find_reloads_address on the location being returned.  */
64618334Speter
64718334Speterrtx
64818334Speterget_secondary_mem (x, mode, opnum, type)
64918334Speter     rtx x;
65018334Speter     enum machine_mode mode;
65118334Speter     int opnum;
65218334Speter     enum reload_type type;
65318334Speter{
65418334Speter  rtx loc;
65518334Speter  int mem_valid;
65618334Speter
65718334Speter  /* By default, if MODE is narrower than a word, widen it to a word.
65818334Speter     This is required because most machines that require these memory
65918334Speter     locations do not support short load and stores from all registers
66018334Speter     (e.g., FP registers).  */
66118334Speter
66218334Speter#ifdef SECONDARY_MEMORY_NEEDED_MODE
66318334Speter  mode = SECONDARY_MEMORY_NEEDED_MODE (mode);
66418334Speter#else
66518334Speter  if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
66618334Speter    mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0);
66718334Speter#endif
66818334Speter
66918334Speter  /* If we already have made a MEM for this operand in MODE, return it.  */
67018334Speter  if (secondary_memlocs_elim[(int) mode][opnum] != 0)
67118334Speter    return secondary_memlocs_elim[(int) mode][opnum];
67218334Speter
67318334Speter  /* If this is the first time we've tried to get a MEM for this mode,
67418334Speter     allocate a new one.  `something_changed' in reload will get set
67518334Speter     by noticing that the frame size has changed.  */
67618334Speter
67718334Speter  if (secondary_memlocs[(int) mode] == 0)
67818334Speter    {
67918334Speter#ifdef SECONDARY_MEMORY_NEEDED_RTX
68018334Speter      secondary_memlocs[(int) mode] = SECONDARY_MEMORY_NEEDED_RTX (mode);
68118334Speter#else
68218334Speter      secondary_memlocs[(int) mode]
68318334Speter	= assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
68418334Speter#endif
68518334Speter    }
68618334Speter
68718334Speter  /* Get a version of the address doing any eliminations needed.  If that
68818334Speter     didn't give us a new MEM, make a new one if it isn't valid.  */
68918334Speter
69018334Speter  loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX);
69118334Speter  mem_valid = strict_memory_address_p (mode, XEXP (loc, 0));
69218334Speter
69318334Speter  if (! mem_valid && loc == secondary_memlocs[(int) mode])
69418334Speter    loc = copy_rtx (loc);
69518334Speter
69618334Speter  /* The only time the call below will do anything is if the stack
69718334Speter     offset is too large.  In that case IND_LEVELS doesn't matter, so we
69818334Speter     can just pass a zero.  Adjust the type to be the address of the
69918334Speter     corresponding object.  If the address was valid, save the eliminated
70018334Speter     address.  If it wasn't valid, we need to make a reload each time, so
70118334Speter     don't save it.  */
70218334Speter
70318334Speter  if (! mem_valid)
70418334Speter    {
70518334Speter      type =  (type == RELOAD_FOR_INPUT ? RELOAD_FOR_INPUT_ADDRESS
70618334Speter	       : type == RELOAD_FOR_OUTPUT ? RELOAD_FOR_OUTPUT_ADDRESS
70718334Speter	       : RELOAD_OTHER);
70818334Speter
70918334Speter      find_reloads_address (mode, NULL_PTR, XEXP (loc, 0), &XEXP (loc, 0),
71050605Sobrien			    opnum, type, 0, 0);
71118334Speter    }
71218334Speter
71318334Speter  secondary_memlocs_elim[(int) mode][opnum] = loc;
71418334Speter  return loc;
71518334Speter}
71618334Speter
71718334Speter/* Clear any secondary memory locations we've made.  */
71818334Speter
71918334Spetervoid
72018334Speterclear_secondary_mem ()
72118334Speter{
72218334Speter  bzero ((char *) secondary_memlocs, sizeof secondary_memlocs);
72318334Speter}
72418334Speter#endif /* SECONDARY_MEMORY_NEEDED */
72518334Speter
72650605Sobrien/* Find the largest class for which every register number plus N is valid in
72750605Sobrien   M1 (if in range).  Abort if no such class exists.  */
72850605Sobrien
72950605Sobrienstatic enum reg_class
73050605Sobrienfind_valid_class (m1, n)
73150605Sobrien     enum machine_mode  m1;
73250605Sobrien     int n;
73350605Sobrien{
73450605Sobrien  int class;
73550605Sobrien  int regno;
73650605Sobrien  enum reg_class best_class;
73750605Sobrien  int best_size = 0;
73850605Sobrien
73950605Sobrien  for (class = 1; class < N_REG_CLASSES; class++)
74050605Sobrien    {
74150605Sobrien      int bad = 0;
74250605Sobrien      for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++)
74350605Sobrien	if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
74450605Sobrien	    && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
74550605Sobrien	    && ! HARD_REGNO_MODE_OK (regno + n, m1))
74650605Sobrien	  bad = 1;
74750605Sobrien
74850605Sobrien      if (! bad && reg_class_size[class] > best_size)
74950605Sobrien	best_class = class, best_size = reg_class_size[class];
75050605Sobrien    }
75150605Sobrien
75250605Sobrien  if (best_size == 0)
75350605Sobrien    abort ();
75450605Sobrien
75550605Sobrien  return best_class;
75650605Sobrien}
75750605Sobrien
75852557Sobrien/* Return the number of a previously made reload that can be combined with
75952557Sobrien   a new one, or n_reloads if none of the existing reloads can be used.
76052557Sobrien   OUT, CLASS, TYPE and OPNUM are the same arguments as passed to
76152557Sobrien   push_reload, they determine the kind of the new reload that we try to
76252557Sobrien   combine.  P_IN points to the corresponding value of IN, which can be
76352557Sobrien   modified by this function.
76452557Sobrien   DONT_SHARE is nonzero if we can't share any input-only reload for IN.  */
76552557Sobrienstatic int
76652557Sobrienfind_reusable_reload (p_in, out, class, type, opnum, dont_share)
76752557Sobrien     rtx *p_in, out;
76852557Sobrien     enum reg_class class;
76952557Sobrien     enum reload_type type;
77052557Sobrien     int opnum, dont_share;
77152557Sobrien{
77252557Sobrien  rtx in = *p_in;
77352557Sobrien  int i;
77452557Sobrien  /* We can't merge two reloads if the output of either one is
77552557Sobrien     earlyclobbered.  */
77652557Sobrien
77752557Sobrien  if (earlyclobber_operand_p (out))
77852557Sobrien    return n_reloads;
77952557Sobrien
78052557Sobrien  /* We can use an existing reload if the class is right
78152557Sobrien     and at least one of IN and OUT is a match
78252557Sobrien     and the other is at worst neutral.
78352557Sobrien     (A zero compared against anything is neutral.)
78452557Sobrien
78552557Sobrien     If SMALL_REGISTER_CLASSES, don't use existing reloads unless they are
78652557Sobrien     for the same thing since that can cause us to need more reload registers
78752557Sobrien     than we otherwise would.  */
78852557Sobrien
78952557Sobrien  for (i = 0; i < n_reloads; i++)
79052557Sobrien    if ((reg_class_subset_p (class, reload_reg_class[i])
79152557Sobrien	 || reg_class_subset_p (reload_reg_class[i], class))
79252557Sobrien	/* If the existing reload has a register, it must fit our class.  */
79352557Sobrien	&& (reload_reg_rtx[i] == 0
79452557Sobrien	    || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
79552557Sobrien				  true_regnum (reload_reg_rtx[i])))
79652557Sobrien	&& ((in != 0 && MATCHES (reload_in[i], in) && ! dont_share
79752557Sobrien	     && (out == 0 || reload_out[i] == 0 || MATCHES (reload_out[i], out)))
79852557Sobrien	    ||
79952557Sobrien	    (out != 0 && MATCHES (reload_out[i], out)
80052557Sobrien	     && (in == 0 || reload_in[i] == 0 || MATCHES (reload_in[i], in))))
80152557Sobrien	&& (reload_out[i] == 0 || ! earlyclobber_operand_p (reload_out[i]))
80252557Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
80352557Sobrien	    && MERGABLE_RELOADS (type, reload_when_needed[i],
80452557Sobrien				 opnum, reload_opnum[i]))
80552557Sobrien      return i;
80652557Sobrien
80752557Sobrien  /* Reloading a plain reg for input can match a reload to postincrement
80852557Sobrien     that reg, since the postincrement's value is the right value.
80952557Sobrien     Likewise, it can match a preincrement reload, since we regard
81052557Sobrien     the preincrementation as happening before any ref in this insn
81152557Sobrien     to that register.  */
81252557Sobrien  for (i = 0; i < n_reloads; i++)
81352557Sobrien    if ((reg_class_subset_p (class, reload_reg_class[i])
81452557Sobrien	 || reg_class_subset_p (reload_reg_class[i], class))
81552557Sobrien	/* If the existing reload has a register, it must fit our
81652557Sobrien	   class.  */
81752557Sobrien	&& (reload_reg_rtx[i] == 0
81852557Sobrien	    || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
81952557Sobrien				  true_regnum (reload_reg_rtx[i])))
82052557Sobrien	&& out == 0 && reload_out[i] == 0 && reload_in[i] != 0
82152557Sobrien	&& ((GET_CODE (in) == REG
82252557Sobrien	     && (GET_CODE (reload_in[i]) == POST_INC
82352557Sobrien		 || GET_CODE (reload_in[i]) == POST_DEC
82452557Sobrien		 || GET_CODE (reload_in[i]) == PRE_INC
82552557Sobrien		 || GET_CODE (reload_in[i]) == PRE_DEC)
82652557Sobrien	     && MATCHES (XEXP (reload_in[i], 0), in))
82752557Sobrien	    ||
82852557Sobrien	    (GET_CODE (reload_in[i]) == REG
82952557Sobrien	     && (GET_CODE (in) == POST_INC
83052557Sobrien		 || GET_CODE (in) == POST_DEC
83152557Sobrien		 || GET_CODE (in) == PRE_INC
83252557Sobrien		 || GET_CODE (in) == PRE_DEC)
83352557Sobrien	     && MATCHES (XEXP (in, 0), reload_in[i])))
83452557Sobrien	&& (reload_out[i] == 0 || ! earlyclobber_operand_p (reload_out[i]))
83552557Sobrien	&& (reg_class_size[(int) class] == 1 || SMALL_REGISTER_CLASSES)
83652557Sobrien	&& MERGABLE_RELOADS (type, reload_when_needed[i],
83752557Sobrien			     opnum, reload_opnum[i]))
83852557Sobrien      {
83952557Sobrien	/* Make sure reload_in ultimately has the increment,
84052557Sobrien	   not the plain register.  */
84152557Sobrien	if (GET_CODE (in) == REG)
84252557Sobrien	  *p_in = reload_in[i];
84352557Sobrien	return i;
84452557Sobrien      }
84552557Sobrien  return n_reloads;
84652557Sobrien}
84752557Sobrien
84818334Speter/* Record one reload that needs to be performed.
84918334Speter   IN is an rtx saying where the data are to be found before this instruction.
85018334Speter   OUT says where they must be stored after the instruction.
85118334Speter   (IN is zero for data not read, and OUT is zero for data not written.)
85218334Speter   INLOC and OUTLOC point to the places in the instructions where
85318334Speter   IN and OUT were found.
85418334Speter   If IN and OUT are both non-zero, it means the same register must be used
85518334Speter   to reload both IN and OUT.
85618334Speter
85718334Speter   CLASS is a register class required for the reloaded data.
85818334Speter   INMODE is the machine mode that the instruction requires
85918334Speter   for the reg that replaces IN and OUTMODE is likewise for OUT.
86018334Speter
86118334Speter   If IN is zero, then OUT's location and mode should be passed as
86218334Speter   INLOC and INMODE.
86318334Speter
86418334Speter   STRICT_LOW is the 1 if there is a containing STRICT_LOW_PART rtx.
86518334Speter
86618334Speter   OPTIONAL nonzero means this reload does not need to be performed:
86718334Speter   it can be discarded if that is more convenient.
86818334Speter
86918334Speter   OPNUM and TYPE say what the purpose of this reload is.
87018334Speter
87118334Speter   The return value is the reload-number for this reload.
87218334Speter
87318334Speter   If both IN and OUT are nonzero, in some rare cases we might
87418334Speter   want to make two separate reloads.  (Actually we never do this now.)
87518334Speter   Therefore, the reload-number for OUT is stored in
87618334Speter   output_reloadnum when we return; the return value applies to IN.
87718334Speter   Usually (presently always), when IN and OUT are nonzero,
87818334Speter   the two reload-numbers are equal, but the caller should be careful to
87918334Speter   distinguish them.  */
88018334Speter
88118334Speterstatic int
88218334Speterpush_reload (in, out, inloc, outloc, class,
88318334Speter	     inmode, outmode, strict_low, optional, opnum, type)
88452557Sobrien     rtx in, out;
88518334Speter     rtx *inloc, *outloc;
88618334Speter     enum reg_class class;
88718334Speter     enum machine_mode inmode, outmode;
88818334Speter     int strict_low;
88918334Speter     int optional;
89018334Speter     int opnum;
89118334Speter     enum reload_type type;
89218334Speter{
89318334Speter  register int i;
89418334Speter  int dont_share = 0;
89518334Speter  int dont_remove_subreg = 0;
89618334Speter  rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
89718334Speter  int secondary_in_reload = -1, secondary_out_reload = -1;
89818334Speter  enum insn_code secondary_in_icode = CODE_FOR_nothing;
89918334Speter  enum insn_code secondary_out_icode = CODE_FOR_nothing;
90018334Speter
90118334Speter  /* INMODE and/or OUTMODE could be VOIDmode if no mode
90218334Speter     has been specified for the operand.  In that case,
90318334Speter     use the operand's mode as the mode to reload.  */
90418334Speter  if (inmode == VOIDmode && in != 0)
90518334Speter    inmode = GET_MODE (in);
90618334Speter  if (outmode == VOIDmode && out != 0)
90718334Speter    outmode = GET_MODE (out);
90818334Speter
90918334Speter  /* If IN is a pseudo register everywhere-equivalent to a constant, and
91018334Speter     it is not in a hard register, reload straight from the constant,
91118334Speter     since we want to get rid of such pseudo registers.
91218334Speter     Often this is done earlier, but not always in find_reloads_address.  */
91318334Speter  if (in != 0 && GET_CODE (in) == REG)
91418334Speter    {
91518334Speter      register int regno = REGNO (in);
91618334Speter
91718334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
91818334Speter	  && reg_equiv_constant[regno] != 0)
91918334Speter	in = reg_equiv_constant[regno];
92018334Speter    }
92118334Speter
92218334Speter  /* Likewise for OUT.  Of course, OUT will never be equivalent to
92318334Speter     an actual constant, but it might be equivalent to a memory location
92418334Speter     (in the case of a parameter).  */
92518334Speter  if (out != 0 && GET_CODE (out) == REG)
92618334Speter    {
92718334Speter      register int regno = REGNO (out);
92818334Speter
92918334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
93018334Speter	  && reg_equiv_constant[regno] != 0)
93118334Speter	out = reg_equiv_constant[regno];
93218334Speter    }
93318334Speter
93418334Speter  /* If we have a read-write operand with an address side-effect,
93518334Speter     change either IN or OUT so the side-effect happens only once.  */
93618334Speter  if (in != 0 && out != 0 && GET_CODE (in) == MEM && rtx_equal_p (in, out))
93718334Speter    {
93818334Speter      if (GET_CODE (XEXP (in, 0)) == POST_INC
93918334Speter	  || GET_CODE (XEXP (in, 0)) == POST_DEC)
94050605Sobrien	in = gen_rtx_MEM (GET_MODE (in), XEXP (XEXP (in, 0), 0));
94118334Speter      if (GET_CODE (XEXP (in, 0)) == PRE_INC
94218334Speter	  || GET_CODE (XEXP (in, 0)) == PRE_DEC)
94350605Sobrien	out = gen_rtx_MEM (GET_MODE (out), XEXP (XEXP (out, 0), 0));
94418334Speter    }
94518334Speter
94618334Speter  /* If we are reloading a (SUBREG constant ...), really reload just the
94718334Speter     inside expression in its own mode.  Similarly for (SUBREG (PLUS ...)).
94818334Speter     If we have (SUBREG:M1 (MEM:M2 ...) ...) (or an inner REG that is still
94918334Speter     a pseudo and hence will become a MEM) with M1 wider than M2 and the
95018334Speter     register is a pseudo, also reload the inside expression.
95118334Speter     For machines that extend byte loads, do this for any SUBREG of a pseudo
95218334Speter     where both M1 and M2 are a word or smaller, M1 is wider than M2, and
95318334Speter     M2 is an integral mode that gets extended when loaded.
95418334Speter     Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
95518334Speter     either M1 is not valid for R or M2 is wider than a word but we only
95618334Speter     need one word to store an M2-sized quantity in R.
95718334Speter     (However, if OUT is nonzero, we need to reload the reg *and*
95818334Speter     the subreg, so do nothing here, and let following statement handle it.)
95918334Speter
96018334Speter     Note that the case of (SUBREG (CONST_INT...)...) is handled elsewhere;
96118334Speter     we can't handle it here because CONST_INT does not indicate a mode.
96218334Speter
96318334Speter     Similarly, we must reload the inside expression if we have a
96418334Speter     STRICT_LOW_PART (presumably, in == out in the cas).
96518334Speter
96618334Speter     Also reload the inner expression if it does not require a secondary
96718334Speter     reload but the SUBREG does.
96818334Speter
96918334Speter     Finally, reload the inner expression if it is a register that is in
97018334Speter     the class whose registers cannot be referenced in a different size
97118334Speter     and M1 is not the same size as M2.  If SUBREG_WORD is nonzero, we
97218334Speter     cannot reload just the inside since we might end up with the wrong
97352557Sobrien     register class.  But if it is inside a STRICT_LOW_PART, we have
97452557Sobrien     no choice, so we hope we do get the right register class there.  */
97518334Speter
97652557Sobrien  if (in != 0 && GET_CODE (in) == SUBREG
97752557Sobrien      && (SUBREG_WORD (in) == 0 || strict_low)
97818334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
97918334Speter      && class != CLASS_CANNOT_CHANGE_SIZE
98018334Speter#endif
98118334Speter      && (CONSTANT_P (SUBREG_REG (in))
98218334Speter	  || GET_CODE (SUBREG_REG (in)) == PLUS
98318334Speter	  || strict_low
98418334Speter	  || (((GET_CODE (SUBREG_REG (in)) == REG
98518334Speter		&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
98618334Speter	       || GET_CODE (SUBREG_REG (in)) == MEM)
98718334Speter	      && ((GET_MODE_SIZE (inmode)
98818334Speter		   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
98918334Speter#ifdef LOAD_EXTEND_OP
99018334Speter		  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
99118334Speter		      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
99218334Speter			  <= UNITS_PER_WORD)
99318334Speter		      && (GET_MODE_SIZE (inmode)
99418334Speter			  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
99518334Speter		      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
99618334Speter		      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != NIL)
99718334Speter#endif
99850605Sobrien#ifdef WORD_REGISTER_OPERATIONS
99950605Sobrien		  || ((GET_MODE_SIZE (inmode)
100050605Sobrien		       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
100150605Sobrien		      && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
100250605Sobrien			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
100350605Sobrien			   / UNITS_PER_WORD)))
100450605Sobrien#endif
100518334Speter		  ))
100618334Speter	  || (GET_CODE (SUBREG_REG (in)) == REG
100718334Speter	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
100818334Speter	      /* The case where out is nonzero
100918334Speter		 is handled differently in the following statement.  */
101018334Speter	      && (out == 0 || SUBREG_WORD (in) == 0)
101118334Speter	      && ((GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
101218334Speter		   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
101318334Speter		       > UNITS_PER_WORD)
101418334Speter		   && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
101518334Speter			/ UNITS_PER_WORD)
101618334Speter		       != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
101718334Speter					    GET_MODE (SUBREG_REG (in)))))
101818334Speter		  || ! HARD_REGNO_MODE_OK ((REGNO (SUBREG_REG (in))
101918334Speter					    + SUBREG_WORD (in)),
102018334Speter					   inmode)))
102118334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
102218334Speter	  || (SECONDARY_INPUT_RELOAD_CLASS (class, inmode, in) != NO_REGS
102318334Speter	      && (SECONDARY_INPUT_RELOAD_CLASS (class,
102418334Speter						GET_MODE (SUBREG_REG (in)),
102518334Speter						SUBREG_REG (in))
102618334Speter		  == NO_REGS))
102718334Speter#endif
102818334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
102918334Speter	  || (GET_CODE (SUBREG_REG (in)) == REG
103018334Speter	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
103118334Speter	      && (TEST_HARD_REG_BIT
103218334Speter		  (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
103318334Speter		   REGNO (SUBREG_REG (in))))
103418334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
103518334Speter		  != GET_MODE_SIZE (inmode)))
103618334Speter#endif
103718334Speter	  ))
103818334Speter    {
103918334Speter      in_subreg_loc = inloc;
104018334Speter      inloc = &SUBREG_REG (in);
104118334Speter      in = *inloc;
104250605Sobrien#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
104318334Speter      if (GET_CODE (in) == MEM)
104418334Speter	/* This is supposed to happen only for paradoxical subregs made by
104518334Speter	   combine.c.  (SUBREG (MEM)) isn't supposed to occur other ways.  */
104618334Speter	if (GET_MODE_SIZE (GET_MODE (in)) > GET_MODE_SIZE (inmode))
104718334Speter	  abort ();
104818334Speter#endif
104918334Speter      inmode = GET_MODE (in);
105018334Speter    }
105118334Speter
105218334Speter  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
105318334Speter     either M1 is not valid for R or M2 is wider than a word but we only
105418334Speter     need one word to store an M2-sized quantity in R.
105518334Speter
105618334Speter     However, we must reload the inner reg *as well as* the subreg in
105718334Speter     that case.  */
105818334Speter
105950605Sobrien  /* Similar issue for (SUBREG constant ...) if it was not handled by the
106050605Sobrien     code above.  This can happen if SUBREG_WORD != 0.  */
106150605Sobrien
106218334Speter  if (in != 0 && GET_CODE (in) == SUBREG
106350605Sobrien      && (CONSTANT_P (SUBREG_REG (in))
106450605Sobrien	  || (GET_CODE (SUBREG_REG (in)) == REG
106550605Sobrien	      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
106650605Sobrien	      && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (in))
106750605Sobrien					+ SUBREG_WORD (in),
106850605Sobrien					inmode)
106950605Sobrien		  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
107050605Sobrien		      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
107150605Sobrien			  > UNITS_PER_WORD)
107250605Sobrien		      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
107350605Sobrien			   / UNITS_PER_WORD)
107450605Sobrien			  != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
107550605Sobrien					       GET_MODE (SUBREG_REG (in)))))))))
107618334Speter    {
107718334Speter      /* This relies on the fact that emit_reload_insns outputs the
107818334Speter	 instructions for input reloads of type RELOAD_OTHER in the same
107918334Speter	 order as the reloads.  Thus if the outer reload is also of type
108018334Speter	 RELOAD_OTHER, we are guaranteed that this inner reload will be
108118334Speter	 output before the outer reload.  */
108218334Speter      push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR,
108350605Sobrien		   find_valid_class (inmode, SUBREG_WORD (in)),
108450605Sobrien		   VOIDmode, VOIDmode, 0, 0, opnum, type);
108518334Speter      dont_remove_subreg = 1;
108618334Speter    }
108718334Speter
108818334Speter  /* Similarly for paradoxical and problematical SUBREGs on the output.
108918334Speter     Note that there is no reason we need worry about the previous value
109018334Speter     of SUBREG_REG (out); even if wider than out,
109118334Speter     storing in a subreg is entitled to clobber it all
109218334Speter     (except in the case of STRICT_LOW_PART,
109318334Speter     and in that case the constraint should label it input-output.)  */
109452557Sobrien  if (out != 0 && GET_CODE (out) == SUBREG
109552557Sobrien      && (SUBREG_WORD (out) == 0 || strict_low)
109618334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
109718334Speter      && class != CLASS_CANNOT_CHANGE_SIZE
109818334Speter#endif
109918334Speter      && (CONSTANT_P (SUBREG_REG (out))
110018334Speter	  || strict_low
110118334Speter	  || (((GET_CODE (SUBREG_REG (out)) == REG
110218334Speter		&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
110318334Speter	       || GET_CODE (SUBREG_REG (out)) == MEM)
110418334Speter	      && ((GET_MODE_SIZE (outmode)
110550605Sobrien		   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
110650605Sobrien#ifdef WORD_REGISTER_OPERATIONS
110750605Sobrien		  || ((GET_MODE_SIZE (outmode)
110850605Sobrien		       < GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
110950605Sobrien		      && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
111050605Sobrien			  ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
111150605Sobrien			   / UNITS_PER_WORD)))
111250605Sobrien#endif
111350605Sobrien	          ))
111418334Speter	  || (GET_CODE (SUBREG_REG (out)) == REG
111518334Speter	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
111618334Speter	      && ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
111718334Speter		   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
111818334Speter		       > UNITS_PER_WORD)
111918334Speter		   && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
112018334Speter			/ UNITS_PER_WORD)
112118334Speter		       != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
112218334Speter					    GET_MODE (SUBREG_REG (out)))))
112318334Speter		  || ! HARD_REGNO_MODE_OK ((REGNO (SUBREG_REG (out))
112418334Speter					    + SUBREG_WORD (out)),
112518334Speter					   outmode)))
112618334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
112718334Speter	  || (SECONDARY_OUTPUT_RELOAD_CLASS (class, outmode, out) != NO_REGS
112818334Speter	      && (SECONDARY_OUTPUT_RELOAD_CLASS (class,
112918334Speter						 GET_MODE (SUBREG_REG (out)),
113018334Speter						 SUBREG_REG (out))
113118334Speter		  == NO_REGS))
113218334Speter#endif
113318334Speter#ifdef CLASS_CANNOT_CHANGE_SIZE
113418334Speter	  || (GET_CODE (SUBREG_REG (out)) == REG
113518334Speter	      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
113618334Speter	      && (TEST_HARD_REG_BIT
113718334Speter		  (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
113818334Speter		   REGNO (SUBREG_REG (out))))
113918334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
114018334Speter		  != GET_MODE_SIZE (outmode)))
114118334Speter#endif
114218334Speter	  ))
114318334Speter    {
114418334Speter      out_subreg_loc = outloc;
114518334Speter      outloc = &SUBREG_REG (out);
114618334Speter      out = *outloc;
114750605Sobrien#if ! defined (LOAD_EXTEND_OP) && ! defined (WORD_REGISTER_OPERATIONS)
114818334Speter     if (GET_CODE (out) == MEM
114918334Speter	  && GET_MODE_SIZE (GET_MODE (out)) > GET_MODE_SIZE (outmode))
115018334Speter	abort ();
115118334Speter#endif
115218334Speter      outmode = GET_MODE (out);
115318334Speter    }
115418334Speter
115518334Speter  /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
115618334Speter     either M1 is not valid for R or M2 is wider than a word but we only
115718334Speter     need one word to store an M2-sized quantity in R.
115818334Speter
115918334Speter     However, we must reload the inner reg *as well as* the subreg in
116018334Speter     that case.  In this case, the inner reg is an in-out reload.  */
116118334Speter
116218334Speter  if (out != 0 && GET_CODE (out) == SUBREG
116318334Speter      && GET_CODE (SUBREG_REG (out)) == REG
116418334Speter      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
116550605Sobrien      && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)) + SUBREG_WORD (out),
116650605Sobrien				outmode)
116718334Speter	  || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
116818334Speter	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
116918334Speter		  > UNITS_PER_WORD)
117018334Speter	      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
117118334Speter		   / UNITS_PER_WORD)
117218334Speter		  != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
117318334Speter				       GET_MODE (SUBREG_REG (out)))))))
117418334Speter    {
117518334Speter      /* This relies on the fact that emit_reload_insns outputs the
117618334Speter	 instructions for output reloads of type RELOAD_OTHER in reverse
117718334Speter	 order of the reloads.  Thus if the outer reload is also of type
117818334Speter	 RELOAD_OTHER, we are guaranteed that this inner reload will be
117918334Speter	 output after the outer reload.  */
118018334Speter      dont_remove_subreg = 1;
118118334Speter      push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
118250605Sobrien		   &SUBREG_REG (out),
118350605Sobrien		   find_valid_class (outmode, SUBREG_WORD (out)),
118450605Sobrien		   VOIDmode, VOIDmode, 0, 0,
118518334Speter		   opnum, RELOAD_OTHER);
118618334Speter    }
118718334Speter
118818334Speter  /* If IN appears in OUT, we can't share any input-only reload for IN.  */
118918334Speter  if (in != 0 && out != 0 && GET_CODE (out) == MEM
119018334Speter      && (GET_CODE (in) == REG || GET_CODE (in) == MEM)
119118334Speter      && reg_overlap_mentioned_for_reload_p (in, XEXP (out, 0)))
119218334Speter    dont_share = 1;
119318334Speter
119418334Speter  /* If IN is a SUBREG of a hard register, make a new REG.  This
119518334Speter     simplifies some of the cases below.  */
119618334Speter
119718334Speter  if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
119818334Speter      && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
119918334Speter      && ! dont_remove_subreg)
120050605Sobrien    in = gen_rtx_REG (GET_MODE (in),
120150605Sobrien		      REGNO (SUBREG_REG (in)) + SUBREG_WORD (in));
120218334Speter
120318334Speter  /* Similarly for OUT.  */
120418334Speter  if (out != 0 && GET_CODE (out) == SUBREG
120518334Speter      && GET_CODE (SUBREG_REG (out)) == REG
120618334Speter      && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
120718334Speter      && ! dont_remove_subreg)
120850605Sobrien    out = gen_rtx_REG (GET_MODE (out),
120950605Sobrien		       REGNO (SUBREG_REG (out)) + SUBREG_WORD (out));
121018334Speter
121118334Speter  /* Narrow down the class of register wanted if that is
121218334Speter     desirable on this machine for efficiency.  */
121318334Speter  if (in != 0)
121418334Speter    class = PREFERRED_RELOAD_CLASS (in, class);
121518334Speter
121618334Speter  /* Output reloads may need analogous treatment, different in detail.  */
121718334Speter#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
121818334Speter  if (out != 0)
121918334Speter    class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class);
122018334Speter#endif
122118334Speter
122218334Speter  /* Make sure we use a class that can handle the actual pseudo
122318334Speter     inside any subreg.  For example, on the 386, QImode regs
122418334Speter     can appear within SImode subregs.  Although GENERAL_REGS
122518334Speter     can handle SImode, QImode needs a smaller class.  */
122618334Speter#ifdef LIMIT_RELOAD_CLASS
122718334Speter  if (in_subreg_loc)
122818334Speter    class = LIMIT_RELOAD_CLASS (inmode, class);
122918334Speter  else if (in != 0 && GET_CODE (in) == SUBREG)
123018334Speter    class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), class);
123118334Speter
123218334Speter  if (out_subreg_loc)
123318334Speter    class = LIMIT_RELOAD_CLASS (outmode, class);
123418334Speter  if (out != 0 && GET_CODE (out) == SUBREG)
123518334Speter    class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), class);
123618334Speter#endif
123718334Speter
123818334Speter  /* Verify that this class is at least possible for the mode that
123918334Speter     is specified.  */
124018334Speter  if (this_insn_is_asm)
124118334Speter    {
124218334Speter      enum machine_mode mode;
124318334Speter      if (GET_MODE_SIZE (inmode) > GET_MODE_SIZE (outmode))
124418334Speter	mode = inmode;
124518334Speter      else
124618334Speter	mode = outmode;
124718334Speter      if (mode == VOIDmode)
124818334Speter	{
124918334Speter	  error_for_asm (this_insn, "cannot reload integer constant operand in `asm'");
125018334Speter	  mode = word_mode;
125118334Speter	  if (in != 0)
125218334Speter	    inmode = word_mode;
125318334Speter	  if (out != 0)
125418334Speter	    outmode = word_mode;
125518334Speter	}
125618334Speter      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
125718334Speter	if (HARD_REGNO_MODE_OK (i, mode)
125818334Speter	    && TEST_HARD_REG_BIT (reg_class_contents[(int) class], i))
125918334Speter	  {
126018334Speter	    int nregs = HARD_REGNO_NREGS (i, mode);
126118334Speter
126218334Speter	    int j;
126318334Speter	    for (j = 1; j < nregs; j++)
126418334Speter	      if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class], i + j))
126518334Speter		break;
126618334Speter	    if (j == nregs)
126718334Speter	      break;
126818334Speter	  }
126918334Speter      if (i == FIRST_PSEUDO_REGISTER)
127018334Speter	{
127118334Speter	  error_for_asm (this_insn, "impossible register constraint in `asm'");
127218334Speter	  class = ALL_REGS;
127318334Speter	}
127418334Speter    }
127518334Speter
127652557Sobrien  /* Optional output reloads are always OK even if we have no register class,
127752557Sobrien     since the function of these reloads is only to have spill_reg_store etc.
127852557Sobrien     set, so that the storing insn can be deleted later.  */
127952557Sobrien  if (class == NO_REGS
128052557Sobrien      && (optional == 0 || type != RELOAD_FOR_OUTPUT))
128118334Speter    abort ();
128218334Speter
128352557Sobrien  i = find_reusable_reload (&in, out, class, type, opnum, dont_share);
128418334Speter
128518334Speter  if (i == n_reloads)
128618334Speter    {
128718334Speter      /* See if we need a secondary reload register to move between CLASS
128818334Speter	 and IN or CLASS and OUT.  Get the icode and push any required reloads
128918334Speter	 needed for each of them if so.  */
129018334Speter
129118334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS
129218334Speter      if (in != 0)
129318334Speter	secondary_in_reload
129418334Speter	  = push_secondary_reload (1, in, opnum, optional, class, inmode, type,
129518334Speter				   &secondary_in_icode);
129618334Speter#endif
129718334Speter
129818334Speter#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
129918334Speter      if (out != 0 && GET_CODE (out) != SCRATCH)
130018334Speter	secondary_out_reload
130118334Speter	  = push_secondary_reload (0, out, opnum, optional, class, outmode,
130218334Speter				   type, &secondary_out_icode);
130318334Speter#endif
130418334Speter
130518334Speter      /* We found no existing reload suitable for re-use.
130618334Speter	 So add an additional reload.  */
130718334Speter
130850605Sobrien#ifdef SECONDARY_MEMORY_NEEDED
130950605Sobrien      /* If a memory location is needed for the copy, make one.  */
131050605Sobrien      if (in != 0 && GET_CODE (in) == REG
131150605Sobrien	  && REGNO (in) < FIRST_PSEUDO_REGISTER
131250605Sobrien	  && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
131350605Sobrien				     class, inmode))
131450605Sobrien	get_secondary_mem (in, inmode, opnum, type);
131550605Sobrien#endif
131650605Sobrien
131718334Speter      i = n_reloads;
131818334Speter      reload_in[i] = in;
131918334Speter      reload_out[i] = out;
132018334Speter      reload_reg_class[i] = class;
132118334Speter      reload_inmode[i] = inmode;
132218334Speter      reload_outmode[i] = outmode;
132318334Speter      reload_reg_rtx[i] = 0;
132418334Speter      reload_optional[i] = optional;
132550605Sobrien      reload_nongroup[i] = 0;
132618334Speter      reload_inc[i] = 0;
132718334Speter      reload_nocombine[i] = 0;
132818334Speter      reload_in_reg[i] = inloc ? *inloc : 0;
132952557Sobrien      reload_out_reg[i] = outloc ? *outloc : 0;
133018334Speter      reload_opnum[i] = opnum;
133118334Speter      reload_when_needed[i] = type;
133218334Speter      reload_secondary_in_reload[i] = secondary_in_reload;
133318334Speter      reload_secondary_out_reload[i] = secondary_out_reload;
133418334Speter      reload_secondary_in_icode[i] = secondary_in_icode;
133518334Speter      reload_secondary_out_icode[i] = secondary_out_icode;
133618334Speter      reload_secondary_p[i] = 0;
133718334Speter
133818334Speter      n_reloads++;
133918334Speter
134018334Speter#ifdef SECONDARY_MEMORY_NEEDED
134118334Speter      if (out != 0 && GET_CODE (out) == REG
134218334Speter	  && REGNO (out) < FIRST_PSEUDO_REGISTER
134318334Speter	  && SECONDARY_MEMORY_NEEDED (class, REGNO_REG_CLASS (REGNO (out)),
134418334Speter				      outmode))
134518334Speter	get_secondary_mem (out, outmode, opnum, type);
134618334Speter#endif
134718334Speter    }
134818334Speter  else
134918334Speter    {
135018334Speter      /* We are reusing an existing reload,
135118334Speter	 but we may have additional information for it.
135218334Speter	 For example, we may now have both IN and OUT
135318334Speter	 while the old one may have just one of them.  */
135418334Speter
135550605Sobrien      /* The modes can be different.  If they are, we want to reload in
135650605Sobrien	 the larger mode, so that the value is valid for both modes.  */
135750605Sobrien      if (inmode != VOIDmode
135850605Sobrien	  && GET_MODE_SIZE (inmode) > GET_MODE_SIZE (reload_inmode[i]))
135918334Speter	reload_inmode[i] = inmode;
136050605Sobrien      if (outmode != VOIDmode
136150605Sobrien	  && GET_MODE_SIZE (outmode) > GET_MODE_SIZE (reload_outmode[i]))
136218334Speter	reload_outmode[i] = outmode;
136318334Speter      if (in != 0)
136452557Sobrien	{
136552557Sobrien	  rtx in_reg = inloc ? *inloc : 0;
136652557Sobrien	  /* If we merge reloads for two distinct rtl expressions that
136752557Sobrien	     are identical in content, there might be duplicate address
136852557Sobrien	     reloads.  Remove the extra set now, so that if we later find
136952557Sobrien	     that we can inherit this reload, we can get rid of the
137052557Sobrien	     address reloads altogether.
137152557Sobrien
137252557Sobrien	     Do not do this if both reloads are optional since the result
137352557Sobrien	     would be an optional reload which could potentially leave
137452557Sobrien	     unresolved address replacements.
137552557Sobrien
137652557Sobrien	     It is not sufficient to call transfer_replacements since
137752557Sobrien	     choose_reload_regs will remove the replacements for address
137852557Sobrien	     reloads of inherited reloads which results in the same
137952557Sobrien	     problem.  */
138052557Sobrien	  if (reload_in[i] != in && rtx_equal_p (in, reload_in[i])
138152557Sobrien	      && ! (reload_optional[i] && optional))
138252557Sobrien	    {
138352557Sobrien	      /* We must keep the address reload with the lower operand
138452557Sobrien		 number alive.  */
138552557Sobrien	      if (opnum > reload_opnum[i])
138652557Sobrien		{
138752557Sobrien		  remove_address_replacements (in);
138852557Sobrien		  in = reload_in[i];
138952557Sobrien		  in_reg = reload_in_reg[i];
139052557Sobrien		}
139152557Sobrien	      else
139252557Sobrien		remove_address_replacements (reload_in[i]);
139352557Sobrien	    }
139452557Sobrien	  reload_in[i] = in;
139552557Sobrien	  reload_in_reg[i] = in_reg;
139652557Sobrien	}
139718334Speter      if (out != 0)
139852557Sobrien	{
139952557Sobrien	  reload_out[i] = out;
140052557Sobrien	  reload_out_reg[i] = outloc ? *outloc : 0;
140152557Sobrien	}
140218334Speter      if (reg_class_subset_p (class, reload_reg_class[i]))
140318334Speter	reload_reg_class[i] = class;
140418334Speter      reload_optional[i] &= optional;
140518334Speter      if (MERGE_TO_OTHER (type, reload_when_needed[i],
140618334Speter			  opnum, reload_opnum[i]))
140718334Speter	reload_when_needed[i] = RELOAD_OTHER;
140818334Speter      reload_opnum[i] = MIN (reload_opnum[i], opnum);
140918334Speter    }
141018334Speter
141118334Speter  /* If the ostensible rtx being reload differs from the rtx found
141218334Speter     in the location to substitute, this reload is not safe to combine
141318334Speter     because we cannot reliably tell whether it appears in the insn.  */
141418334Speter
141518334Speter  if (in != 0 && in != *inloc)
141618334Speter    reload_nocombine[i] = 1;
141718334Speter
141818334Speter#if 0
141918334Speter  /* This was replaced by changes in find_reloads_address_1 and the new
142018334Speter     function inc_for_reload, which go with a new meaning of reload_inc.  */
142118334Speter
142218334Speter  /* If this is an IN/OUT reload in an insn that sets the CC,
142318334Speter     it must be for an autoincrement.  It doesn't work to store
142418334Speter     the incremented value after the insn because that would clobber the CC.
142518334Speter     So we must do the increment of the value reloaded from,
142618334Speter     increment it, store it back, then decrement again.  */
142718334Speter  if (out != 0 && sets_cc0_p (PATTERN (this_insn)))
142818334Speter    {
142918334Speter      out = 0;
143018334Speter      reload_out[i] = 0;
143118334Speter      reload_inc[i] = find_inc_amount (PATTERN (this_insn), in);
143218334Speter      /* If we did not find a nonzero amount-to-increment-by,
143318334Speter	 that contradicts the belief that IN is being incremented
143418334Speter	 in an address in this insn.  */
143518334Speter      if (reload_inc[i] == 0)
143618334Speter	abort ();
143718334Speter    }
143818334Speter#endif
143918334Speter
144018334Speter  /* If we will replace IN and OUT with the reload-reg,
144118334Speter     record where they are located so that substitution need
144218334Speter     not do a tree walk.  */
144318334Speter
144418334Speter  if (replace_reloads)
144518334Speter    {
144618334Speter      if (inloc != 0)
144718334Speter	{
144818334Speter	  register struct replacement *r = &replacements[n_replacements++];
144918334Speter	  r->what = i;
145018334Speter	  r->subreg_loc = in_subreg_loc;
145118334Speter	  r->where = inloc;
145218334Speter	  r->mode = inmode;
145318334Speter	}
145418334Speter      if (outloc != 0 && outloc != inloc)
145518334Speter	{
145618334Speter	  register struct replacement *r = &replacements[n_replacements++];
145718334Speter	  r->what = i;
145818334Speter	  r->where = outloc;
145918334Speter	  r->subreg_loc = out_subreg_loc;
146018334Speter	  r->mode = outmode;
146118334Speter	}
146218334Speter    }
146318334Speter
146418334Speter  /* If this reload is just being introduced and it has both
146518334Speter     an incoming quantity and an outgoing quantity that are
146618334Speter     supposed to be made to match, see if either one of the two
146718334Speter     can serve as the place to reload into.
146818334Speter
146918334Speter     If one of them is acceptable, set reload_reg_rtx[i]
147018334Speter     to that one.  */
147118334Speter
147218334Speter  if (in != 0 && out != 0 && in != out && reload_reg_rtx[i] == 0)
147318334Speter    {
147418334Speter      reload_reg_rtx[i] = find_dummy_reload (in, out, inloc, outloc,
147518334Speter					     inmode, outmode,
147650605Sobrien					     reload_reg_class[i], i,
147750605Sobrien					     earlyclobber_operand_p (out));
147818334Speter
147918334Speter      /* If the outgoing register already contains the same value
148018334Speter	 as the incoming one, we can dispense with loading it.
148118334Speter	 The easiest way to tell the caller that is to give a phony
148218334Speter	 value for the incoming operand (same as outgoing one).  */
148318334Speter      if (reload_reg_rtx[i] == out
148418334Speter	  && (GET_CODE (in) == REG || CONSTANT_P (in))
148518334Speter	  && 0 != find_equiv_reg (in, this_insn, 0, REGNO (out),
148618334Speter				  static_reload_reg_p, i, inmode))
148718334Speter	reload_in[i] = out;
148818334Speter    }
148918334Speter
149018334Speter  /* If this is an input reload and the operand contains a register that
149118334Speter     dies in this insn and is used nowhere else, see if it is the right class
149218334Speter     to be used for this reload.  Use it if so.  (This occurs most commonly
149318334Speter     in the case of paradoxical SUBREGs and in-out reloads).  We cannot do
149418334Speter     this if it is also an output reload that mentions the register unless
149518334Speter     the output is a SUBREG that clobbers an entire register.
149618334Speter
149718334Speter     Note that the operand might be one of the spill regs, if it is a
149818334Speter     pseudo reg and we are in a block where spilling has not taken place.
149918334Speter     But if there is no spilling in this block, that is OK.
150018334Speter     An explicitly used hard reg cannot be a spill reg.  */
150118334Speter
150218334Speter  if (reload_reg_rtx[i] == 0 && in != 0)
150318334Speter    {
150418334Speter      rtx note;
150518334Speter      int regno;
150618334Speter
150718334Speter      for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
150818334Speter	if (REG_NOTE_KIND (note) == REG_DEAD
150918334Speter	    && GET_CODE (XEXP (note, 0)) == REG
151018334Speter	    && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
151118334Speter	    && reg_mentioned_p (XEXP (note, 0), in)
151218334Speter	    && ! refers_to_regno_for_reload_p (regno,
151318334Speter					       (regno
151418334Speter						+ HARD_REGNO_NREGS (regno,
151518334Speter								    inmode)),
151618334Speter					       PATTERN (this_insn), inloc)
151718334Speter	    /* If this is also an output reload, IN cannot be used as
151818334Speter	       the reload register if it is set in this insn unless IN
151918334Speter	       is also OUT.  */
152018334Speter	    && (out == 0 || in == out
152118334Speter		|| ! hard_reg_set_here_p (regno,
152218334Speter					  (regno
152318334Speter					   + HARD_REGNO_NREGS (regno,
152418334Speter							       inmode)),
152518334Speter					  PATTERN (this_insn)))
152618334Speter	    /* ??? Why is this code so different from the previous?
152718334Speter	       Is there any simple coherent way to describe the two together?
152818334Speter	       What's going on here.  */
152918334Speter	    && (in != out
153018334Speter		|| (GET_CODE (in) == SUBREG
153118334Speter		    && (((GET_MODE_SIZE (GET_MODE (in)) + (UNITS_PER_WORD - 1))
153218334Speter			 / UNITS_PER_WORD)
153318334Speter			== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
153418334Speter			     + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
153518334Speter	    /* Make sure the operand fits in the reg that dies.  */
153618334Speter	    && GET_MODE_SIZE (inmode) <= GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
153718334Speter	    && HARD_REGNO_MODE_OK (regno, inmode)
153818334Speter	    && GET_MODE_SIZE (outmode) <= GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
153970639Sobrien	    && HARD_REGNO_MODE_OK (regno, outmode))
154018334Speter	  {
154170639Sobrien	    unsigned int offs;
154270639Sobrien	    unsigned int nregs = MAX (HARD_REGNO_NREGS (regno, inmode),
154370639Sobrien				      HARD_REGNO_NREGS (regno, outmode));
154470639Sobrien
154570639Sobrien	    for (offs = 0; offs < nregs; offs++)
154670639Sobrien	      if (fixed_regs[regno + offs]
154770639Sobrien		  || ! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
154870639Sobrien					  regno + offs))
154970639Sobrien		break;
155070639Sobrien
155170639Sobrien	    if (offs == nregs)
155270639Sobrien	      {
155370639Sobrien		reload_reg_rtx[i] = gen_rtx_REG (inmode, regno);
155470639Sobrien		break;
155570639Sobrien	      }
155618334Speter	  }
155718334Speter    }
155818334Speter
155918334Speter  if (out)
156018334Speter    output_reloadnum = i;
156118334Speter
156218334Speter  return i;
156318334Speter}
156418334Speter
156518334Speter/* Record an additional place we must replace a value
156618334Speter   for which we have already recorded a reload.
156718334Speter   RELOADNUM is the value returned by push_reload
156818334Speter   when the reload was recorded.
156918334Speter   This is used in insn patterns that use match_dup.  */
157018334Speter
157118334Speterstatic void
157218334Speterpush_replacement (loc, reloadnum, mode)
157318334Speter     rtx *loc;
157418334Speter     int reloadnum;
157518334Speter     enum machine_mode mode;
157618334Speter{
157718334Speter  if (replace_reloads)
157818334Speter    {
157918334Speter      register struct replacement *r = &replacements[n_replacements++];
158018334Speter      r->what = reloadnum;
158118334Speter      r->where = loc;
158218334Speter      r->subreg_loc = 0;
158318334Speter      r->mode = mode;
158418334Speter    }
158518334Speter}
158618334Speter
158718334Speter/* Transfer all replacements that used to be in reload FROM to be in
158818334Speter   reload TO.  */
158918334Speter
159018334Spetervoid
159118334Spetertransfer_replacements (to, from)
159218334Speter     int to, from;
159318334Speter{
159418334Speter  int i;
159518334Speter
159618334Speter  for (i = 0; i < n_replacements; i++)
159718334Speter    if (replacements[i].what == from)
159818334Speter      replacements[i].what = to;
159918334Speter}
160018334Speter
160152557Sobrien/* IN_RTX is the value loaded by a reload that we now decided to inherit,
160252557Sobrien   or a subpart of it.  If we have any replacements registered for IN_RTX,
160352557Sobrien   cancel the reloads that were supposed to load them.
160452557Sobrien   Return non-zero if we canceled any reloads.  */
160552557Sobrienint
160652557Sobrienremove_address_replacements (in_rtx)
160752557Sobrien     rtx in_rtx;
160850605Sobrien{
160950605Sobrien  int i, j;
161052557Sobrien  char reload_flags[MAX_RELOADS];
161152557Sobrien  int something_changed = 0;
161250605Sobrien
161352557Sobrien  bzero (reload_flags, sizeof reload_flags);
161450605Sobrien  for (i = 0, j = 0; i < n_replacements; i++)
161550605Sobrien    {
161652557Sobrien      if (loc_mentioned_in_p (replacements[i].where, in_rtx))
161752557Sobrien	reload_flags[replacements[i].what] |= 1;
161852557Sobrien      else
161952557Sobrien	{
162052557Sobrien	  replacements[j++] = replacements[i];
162152557Sobrien	  reload_flags[replacements[i].what] |= 2;
162252557Sobrien	}
162350605Sobrien    }
162452557Sobrien  /* Note that the following store must be done before the recursive calls.  */
162552557Sobrien  n_replacements = j;
162652557Sobrien
162752557Sobrien  for (i = n_reloads - 1; i >= 0; i--)
162852557Sobrien    {
162952557Sobrien      if (reload_flags[i] == 1)
163052557Sobrien	{
163152557Sobrien	  deallocate_reload_reg (i);
163252557Sobrien	  remove_address_replacements (reload_in[i]);
163352557Sobrien	  reload_in[i] = 0;
163452557Sobrien	  something_changed = 1;
163552557Sobrien	}
163652557Sobrien    }
163752557Sobrien  return something_changed;
163850605Sobrien}
163952557Sobrien
164052557Sobrien/* Return non-zero if IN contains a piece of rtl that has the address LOC */
164152557Sobrienstatic int
164252557Sobrienloc_mentioned_in_p (loc, in)
164352557Sobrien     rtx *loc, in;
164452557Sobrien{
164552557Sobrien  enum rtx_code code = GET_CODE (in);
164652557Sobrien  char *fmt = GET_RTX_FORMAT (code);
164752557Sobrien  int i, j;
164852557Sobrien
164952557Sobrien  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
165052557Sobrien    {
165152557Sobrien      if (loc == &XEXP (in, i))
165252557Sobrien	return 1;
165352557Sobrien      if (fmt[i] == 'e')
165452557Sobrien        {
165552557Sobrien	  if (loc_mentioned_in_p (loc, XEXP (in, i)))
165652557Sobrien	    return 1;
165752557Sobrien        }
165852557Sobrien      else if (fmt[i] == 'E')
165952557Sobrien	for (j = XVECLEN (in, i) - 1; i >= 0; i--)
166052557Sobrien	  if (loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
166152557Sobrien	    return 1;
166252557Sobrien    }
166352557Sobrien  return 0;
166452557Sobrien}
166550605Sobrien
166618334Speter/* If there is only one output reload, and it is not for an earlyclobber
166718334Speter   operand, try to combine it with a (logically unrelated) input reload
166818334Speter   to reduce the number of reload registers needed.
166918334Speter
167018334Speter   This is safe if the input reload does not appear in
167118334Speter   the value being output-reloaded, because this implies
167218334Speter   it is not needed any more once the original insn completes.
167318334Speter
167418334Speter   If that doesn't work, see we can use any of the registers that
167518334Speter   die in this insn as a reload register.  We can if it is of the right
167618334Speter   class and does not appear in the value being output-reloaded.  */
167718334Speter
167818334Speterstatic void
167918334Spetercombine_reloads ()
168018334Speter{
168118334Speter  int i;
168218334Speter  int output_reload = -1;
168318334Speter  int secondary_out = -1;
168418334Speter  rtx note;
168518334Speter
168618334Speter  /* Find the output reload; return unless there is exactly one
168718334Speter     and that one is mandatory.  */
168818334Speter
168918334Speter  for (i = 0; i < n_reloads; i++)
169018334Speter    if (reload_out[i] != 0)
169118334Speter      {
169218334Speter	if (output_reload >= 0)
169318334Speter	  return;
169418334Speter	output_reload = i;
169518334Speter      }
169618334Speter
169718334Speter  if (output_reload < 0 || reload_optional[output_reload])
169818334Speter    return;
169918334Speter
170018334Speter  /* An input-output reload isn't combinable.  */
170118334Speter
170218334Speter  if (reload_in[output_reload] != 0)
170318334Speter    return;
170418334Speter
170518334Speter  /* If this reload is for an earlyclobber operand, we can't do anything.  */
170618334Speter  if (earlyclobber_operand_p (reload_out[output_reload]))
170718334Speter    return;
170818334Speter
170918334Speter  /* Check each input reload; can we combine it?  */
171018334Speter
171118334Speter  for (i = 0; i < n_reloads; i++)
171218334Speter    if (reload_in[i] && ! reload_optional[i] && ! reload_nocombine[i]
171318334Speter	/* Life span of this reload must not extend past main insn.  */
171418334Speter	&& reload_when_needed[i] != RELOAD_FOR_OUTPUT_ADDRESS
171550605Sobrien	&& reload_when_needed[i] != RELOAD_FOR_OUTADDR_ADDRESS
171618334Speter	&& reload_when_needed[i] != RELOAD_OTHER
171718334Speter	&& (CLASS_MAX_NREGS (reload_reg_class[i], reload_inmode[i])
171818334Speter	    == CLASS_MAX_NREGS (reload_reg_class[output_reload],
171918334Speter				reload_outmode[output_reload]))
172018334Speter	&& reload_inc[i] == 0
172118334Speter	&& reload_reg_rtx[i] == 0
172218334Speter#ifdef SECONDARY_MEMORY_NEEDED
172318334Speter	/* Don't combine two reloads with different secondary
172418334Speter	   memory locations.  */
172518334Speter	&& (secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[i]] == 0
172618334Speter	    || secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[output_reload]] == 0
172718334Speter	    || rtx_equal_p (secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[i]],
172818334Speter			    secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[output_reload]]))
172918334Speter#endif
173050605Sobrien	&& (SMALL_REGISTER_CLASSES
173150605Sobrien	    ? (reload_reg_class[i] == reload_reg_class[output_reload])
173250605Sobrien	    : (reg_class_subset_p (reload_reg_class[i],
173350605Sobrien				   reload_reg_class[output_reload])
173450605Sobrien	       || reg_class_subset_p (reload_reg_class[output_reload],
173550605Sobrien				      reload_reg_class[i])))
173618334Speter	&& (MATCHES (reload_in[i], reload_out[output_reload])
173718334Speter	    /* Args reversed because the first arg seems to be
173818334Speter	       the one that we imagine being modified
173918334Speter	       while the second is the one that might be affected.  */
174018334Speter	    || (! reg_overlap_mentioned_for_reload_p (reload_out[output_reload],
174118334Speter						      reload_in[i])
174218334Speter		/* However, if the input is a register that appears inside
174318334Speter		   the output, then we also can't share.
174418334Speter		   Imagine (set (mem (reg 69)) (plus (reg 69) ...)).
174518334Speter		   If the same reload reg is used for both reg 69 and the
174618334Speter		   result to be stored in memory, then that result
174718334Speter		   will clobber the address of the memory ref.  */
174818334Speter		&& ! (GET_CODE (reload_in[i]) == REG
174918334Speter		      && reg_overlap_mentioned_for_reload_p (reload_in[i],
175018334Speter							     reload_out[output_reload]))))
175118334Speter	&& (reg_class_size[(int) reload_reg_class[i]]
175250605Sobrien	    || SMALL_REGISTER_CLASSES)
175318334Speter	/* We will allow making things slightly worse by combining an
175418334Speter	   input and an output, but no worse than that.  */
175518334Speter	&& (reload_when_needed[i] == RELOAD_FOR_INPUT
175618334Speter	    || reload_when_needed[i] == RELOAD_FOR_OUTPUT))
175718334Speter      {
175818334Speter	int j;
175918334Speter
176018334Speter	/* We have found a reload to combine with!  */
176118334Speter	reload_out[i] = reload_out[output_reload];
176252557Sobrien	reload_out_reg[i] = reload_out_reg[output_reload];
176318334Speter	reload_outmode[i] = reload_outmode[output_reload];
176418334Speter	/* Mark the old output reload as inoperative.  */
176518334Speter	reload_out[output_reload] = 0;
176618334Speter	/* The combined reload is needed for the entire insn.  */
176718334Speter	reload_when_needed[i] = RELOAD_OTHER;
176850605Sobrien	/* If the output reload had a secondary reload, copy it.  */
176918334Speter	if (reload_secondary_out_reload[output_reload] != -1)
177018334Speter	  {
177118334Speter	    reload_secondary_out_reload[i]
177218334Speter	      = reload_secondary_out_reload[output_reload];
177318334Speter	    reload_secondary_out_icode[i]
177418334Speter	      = reload_secondary_out_icode[output_reload];
177518334Speter	  }
177618334Speter
177718334Speter#ifdef SECONDARY_MEMORY_NEEDED
177818334Speter	/* Copy any secondary MEM.  */
177918334Speter	if (secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[output_reload]] != 0)
178018334Speter	  secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[i]]
178118334Speter	    = secondary_memlocs_elim[(int) reload_outmode[output_reload]][reload_opnum[output_reload]];
178218334Speter#endif
178350605Sobrien	/* If required, minimize the register class.  */
178418334Speter	if (reg_class_subset_p (reload_reg_class[output_reload],
178518334Speter				reload_reg_class[i]))
178618334Speter	  reload_reg_class[i] = reload_reg_class[output_reload];
178718334Speter
178818334Speter	/* Transfer all replacements from the old reload to the combined.  */
178918334Speter	for (j = 0; j < n_replacements; j++)
179018334Speter	  if (replacements[j].what == output_reload)
179118334Speter	    replacements[j].what = i;
179218334Speter
179318334Speter	return;
179418334Speter      }
179518334Speter
179618334Speter  /* If this insn has only one operand that is modified or written (assumed
179718334Speter     to be the first),  it must be the one corresponding to this reload.  It
179818334Speter     is safe to use anything that dies in this insn for that output provided
179918334Speter     that it does not occur in the output (we already know it isn't an
180018334Speter     earlyclobber.  If this is an asm insn, give up.  */
180118334Speter
180218334Speter  if (INSN_CODE (this_insn) == -1)
180318334Speter    return;
180418334Speter
180518334Speter  for (i = 1; i < insn_n_operands[INSN_CODE (this_insn)]; i++)
180618334Speter    if (insn_operand_constraint[INSN_CODE (this_insn)][i][0] == '='
180718334Speter	|| insn_operand_constraint[INSN_CODE (this_insn)][i][0] == '+')
180818334Speter      return;
180918334Speter
181018334Speter  /* See if some hard register that dies in this insn and is not used in
181118334Speter     the output is the right class.  Only works if the register we pick
181218334Speter     up can fully hold our output reload.  */
181318334Speter  for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
181418334Speter    if (REG_NOTE_KIND (note) == REG_DEAD
181518334Speter	&& GET_CODE (XEXP (note, 0)) == REG
181618334Speter	&& ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
181718334Speter						 reload_out[output_reload])
181818334Speter	&& REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
181918334Speter	&& HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), reload_outmode[output_reload])
182018334Speter	&& TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[output_reload]],
182118334Speter			      REGNO (XEXP (note, 0)))
182218334Speter	&& (HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), reload_outmode[output_reload])
182318334Speter	    <= HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), GET_MODE (XEXP (note, 0))))
182418334Speter	/* Ensure that a secondary or tertiary reload for this output
182518334Speter	   won't want this register.  */
182618334Speter        && ((secondary_out = reload_secondary_out_reload[output_reload]) == -1
182718334Speter            || (! (TEST_HARD_REG_BIT
182818334Speter		    (reg_class_contents[(int) reload_reg_class[secondary_out]],
182918334Speter		     REGNO (XEXP (note, 0))))
183018334Speter		&& ((secondary_out = reload_secondary_out_reload[secondary_out]) == -1
183118334Speter		    ||  ! (TEST_HARD_REG_BIT
183218334Speter			   (reg_class_contents[(int) reload_reg_class[secondary_out]],
183318334Speter			    REGNO (XEXP (note, 0)))))))
183418334Speter	&& ! fixed_regs[REGNO (XEXP (note, 0))])
183518334Speter      {
183650605Sobrien	reload_reg_rtx[output_reload]
183750605Sobrien	  = gen_rtx_REG (reload_outmode[output_reload],
183850605Sobrien			 REGNO (XEXP (note, 0)));
183918334Speter	return;
184018334Speter      }
184118334Speter}
184218334Speter
184318334Speter/* Try to find a reload register for an in-out reload (expressions IN and OUT).
184418334Speter   See if one of IN and OUT is a register that may be used;
184518334Speter   this is desirable since a spill-register won't be needed.
184618334Speter   If so, return the register rtx that proves acceptable.
184718334Speter
184818334Speter   INLOC and OUTLOC are locations where IN and OUT appear in the insn.
184918334Speter   CLASS is the register class required for the reload.
185018334Speter
185118334Speter   If FOR_REAL is >= 0, it is the number of the reload,
185218334Speter   and in some cases when it can be discovered that OUT doesn't need
185318334Speter   to be computed, clear out reload_out[FOR_REAL].
185418334Speter
185518334Speter   If FOR_REAL is -1, this should not be done, because this call
185650605Sobrien   is just to see if a register can be found, not to find and install it.
185718334Speter
185850605Sobrien   EARLYCLOBBER is non-zero if OUT is an earlyclobber operand.  This
185950605Sobrien   puts an additional constraint on being able to use IN for OUT since
186050605Sobrien   IN must not appear elsewhere in the insn (it is assumed that IN itself
186150605Sobrien   is safe from the earlyclobber).  */
186250605Sobrien
186318334Speterstatic rtx
186418334Speterfind_dummy_reload (real_in, real_out, inloc, outloc,
186550605Sobrien		   inmode, outmode, class, for_real, earlyclobber)
186618334Speter     rtx real_in, real_out;
186718334Speter     rtx *inloc, *outloc;
186818334Speter     enum machine_mode inmode, outmode;
186918334Speter     enum reg_class class;
187018334Speter     int for_real;
187150605Sobrien     int earlyclobber;
187218334Speter{
187318334Speter  rtx in = real_in;
187418334Speter  rtx out = real_out;
187518334Speter  int in_offset = 0;
187618334Speter  int out_offset = 0;
187718334Speter  rtx value = 0;
187818334Speter
187918334Speter  /* If operands exceed a word, we can't use either of them
188018334Speter     unless they have the same size.  */
188118334Speter  if (GET_MODE_SIZE (outmode) != GET_MODE_SIZE (inmode)
188218334Speter      && (GET_MODE_SIZE (outmode) > UNITS_PER_WORD
188318334Speter	  || GET_MODE_SIZE (inmode) > UNITS_PER_WORD))
188418334Speter    return 0;
188518334Speter
188618334Speter  /* Find the inside of any subregs.  */
188718334Speter  while (GET_CODE (out) == SUBREG)
188818334Speter    {
188918334Speter      out_offset = SUBREG_WORD (out);
189018334Speter      out = SUBREG_REG (out);
189118334Speter    }
189218334Speter  while (GET_CODE (in) == SUBREG)
189318334Speter    {
189418334Speter      in_offset = SUBREG_WORD (in);
189518334Speter      in = SUBREG_REG (in);
189618334Speter    }
189718334Speter
189818334Speter  /* Narrow down the reg class, the same way push_reload will;
189918334Speter     otherwise we might find a dummy now, but push_reload won't.  */
190018334Speter  class = PREFERRED_RELOAD_CLASS (in, class);
190118334Speter
190218334Speter  /* See if OUT will do.  */
190318334Speter  if (GET_CODE (out) == REG
190418334Speter      && REGNO (out) < FIRST_PSEUDO_REGISTER)
190518334Speter    {
190618334Speter      register int regno = REGNO (out) + out_offset;
190718334Speter      int nwords = HARD_REGNO_NREGS (regno, outmode);
190818334Speter      rtx saved_rtx;
190918334Speter
191018334Speter      /* When we consider whether the insn uses OUT,
191118334Speter	 ignore references within IN.  They don't prevent us
191218334Speter	 from copying IN into OUT, because those refs would
191318334Speter	 move into the insn that reloads IN.
191418334Speter
191518334Speter	 However, we only ignore IN in its role as this reload.
191618334Speter	 If the insn uses IN elsewhere and it contains OUT,
191718334Speter	 that counts.  We can't be sure it's the "same" operand
191818334Speter	 so it might not go through this reload.  */
191918334Speter      saved_rtx = *inloc;
192018334Speter      *inloc = const0_rtx;
192118334Speter
192218334Speter      if (regno < FIRST_PSEUDO_REGISTER
192318334Speter	  /* A fixed reg that can overlap other regs better not be used
192418334Speter	     for reloading in any way.  */
192518334Speter#ifdef OVERLAPPING_REGNO_P
192618334Speter	  && ! (fixed_regs[regno] && OVERLAPPING_REGNO_P (regno))
192718334Speter#endif
192818334Speter	  && ! refers_to_regno_for_reload_p (regno, regno + nwords,
192918334Speter					     PATTERN (this_insn), outloc))
193018334Speter	{
193118334Speter	  int i;
193218334Speter	  for (i = 0; i < nwords; i++)
193318334Speter	    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
193418334Speter				     regno + i))
193518334Speter	      break;
193618334Speter
193718334Speter	  if (i == nwords)
193818334Speter	    {
193918334Speter	      if (GET_CODE (real_out) == REG)
194018334Speter		value = real_out;
194118334Speter	      else
194250605Sobrien		value = gen_rtx_REG (outmode, regno);
194318334Speter	    }
194418334Speter	}
194518334Speter
194618334Speter      *inloc = saved_rtx;
194718334Speter    }
194818334Speter
194918334Speter  /* Consider using IN if OUT was not acceptable
195018334Speter     or if OUT dies in this insn (like the quotient in a divmod insn).
195118334Speter     We can't use IN unless it is dies in this insn,
195218334Speter     which means we must know accurately which hard regs are live.
195350605Sobrien     Also, the result can't go in IN if IN is used within OUT,
195450605Sobrien     or if OUT is an earlyclobber and IN appears elsewhere in the insn.  */
195518334Speter  if (hard_regs_live_known
195618334Speter      && GET_CODE (in) == REG
195718334Speter      && REGNO (in) < FIRST_PSEUDO_REGISTER
195818334Speter      && (value == 0
195918334Speter	  || find_reg_note (this_insn, REG_UNUSED, real_out))
196018334Speter      && find_reg_note (this_insn, REG_DEAD, real_in)
196118334Speter      && !fixed_regs[REGNO (in)]
196218334Speter      && HARD_REGNO_MODE_OK (REGNO (in),
196318334Speter			     /* The only case where out and real_out might
196418334Speter				have different modes is where real_out
196518334Speter				is a subreg, and in that case, out
196618334Speter				has a real mode.  */
196718334Speter			     (GET_MODE (out) != VOIDmode
196818334Speter			      ? GET_MODE (out) : outmode)))
196918334Speter    {
197018334Speter      register int regno = REGNO (in) + in_offset;
197118334Speter      int nwords = HARD_REGNO_NREGS (regno, inmode);
197218334Speter
197318334Speter      if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, NULL_PTR)
197418334Speter	  && ! hard_reg_set_here_p (regno, regno + nwords,
197550605Sobrien				    PATTERN (this_insn))
197650605Sobrien	  && (! earlyclobber
197750605Sobrien	      || ! refers_to_regno_for_reload_p (regno, regno + nwords,
197850605Sobrien						 PATTERN (this_insn), inloc)))
197918334Speter	{
198018334Speter	  int i;
198118334Speter	  for (i = 0; i < nwords; i++)
198218334Speter	    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
198318334Speter				     regno + i))
198418334Speter	      break;
198518334Speter
198618334Speter	  if (i == nwords)
198718334Speter	    {
198818334Speter	      /* If we were going to use OUT as the reload reg
198918334Speter		 and changed our mind, it means OUT is a dummy that
199018334Speter		 dies here.  So don't bother copying value to it.  */
199118334Speter	      if (for_real >= 0 && value == real_out)
199218334Speter		reload_out[for_real] = 0;
199318334Speter	      if (GET_CODE (real_in) == REG)
199418334Speter		value = real_in;
199518334Speter	      else
199650605Sobrien		value = gen_rtx_REG (inmode, regno);
199718334Speter	    }
199818334Speter	}
199918334Speter    }
200018334Speter
200118334Speter  return value;
200218334Speter}
200318334Speter
200418334Speter/* This page contains subroutines used mainly for determining
200518334Speter   whether the IN or an OUT of a reload can serve as the
200618334Speter   reload register.  */
200718334Speter
200818334Speter/* Return 1 if X is an operand of an insn that is being earlyclobbered.  */
200918334Speter
201070639Sobrienint
201118334Speterearlyclobber_operand_p (x)
201218334Speter     rtx x;
201318334Speter{
201418334Speter  int i;
201518334Speter
201618334Speter  for (i = 0; i < n_earlyclobbers; i++)
201718334Speter    if (reload_earlyclobbers[i] == x)
201818334Speter      return 1;
201918334Speter
202018334Speter  return 0;
202118334Speter}
202218334Speter
202318334Speter/* Return 1 if expression X alters a hard reg in the range
202418334Speter   from BEG_REGNO (inclusive) to END_REGNO (exclusive),
202518334Speter   either explicitly or in the guise of a pseudo-reg allocated to REGNO.
202618334Speter   X should be the body of an instruction.  */
202718334Speter
202818334Speterstatic int
202918334Speterhard_reg_set_here_p (beg_regno, end_regno, x)
203018334Speter     register int beg_regno, end_regno;
203118334Speter     rtx x;
203218334Speter{
203318334Speter  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
203418334Speter    {
203518334Speter      register rtx op0 = SET_DEST (x);
203618334Speter      while (GET_CODE (op0) == SUBREG)
203718334Speter	op0 = SUBREG_REG (op0);
203818334Speter      if (GET_CODE (op0) == REG)
203918334Speter	{
204018334Speter	  register int r = REGNO (op0);
204118334Speter	  /* See if this reg overlaps range under consideration.  */
204218334Speter	  if (r < end_regno
204318334Speter	      && r + HARD_REGNO_NREGS (r, GET_MODE (op0)) > beg_regno)
204418334Speter	    return 1;
204518334Speter	}
204618334Speter    }
204718334Speter  else if (GET_CODE (x) == PARALLEL)
204818334Speter    {
204918334Speter      register int i = XVECLEN (x, 0) - 1;
205018334Speter      for (; i >= 0; i--)
205118334Speter	if (hard_reg_set_here_p (beg_regno, end_regno, XVECEXP (x, 0, i)))
205218334Speter	  return 1;
205318334Speter    }
205418334Speter
205518334Speter  return 0;
205618334Speter}
205718334Speter
205818334Speter/* Return 1 if ADDR is a valid memory address for mode MODE,
205918334Speter   and check that each pseudo reg has the proper kind of
206018334Speter   hard reg.  */
206118334Speter
206218334Speterint
206318334Speterstrict_memory_address_p (mode, addr)
206418334Speter     enum machine_mode mode;
206518334Speter     register rtx addr;
206618334Speter{
206718334Speter  GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
206818334Speter  return 0;
206918334Speter
207018334Speter win:
207118334Speter  return 1;
207218334Speter}
207318334Speter
207418334Speter/* Like rtx_equal_p except that it allows a REG and a SUBREG to match
207518334Speter   if they are the same hard reg, and has special hacks for
207618334Speter   autoincrement and autodecrement.
207718334Speter   This is specifically intended for find_reloads to use
207818334Speter   in determining whether two operands match.
207918334Speter   X is the operand whose number is the lower of the two.
208018334Speter
208118334Speter   The value is 2 if Y contains a pre-increment that matches
208218334Speter   a non-incrementing address in X.  */
208318334Speter
208418334Speter/* ??? To be completely correct, we should arrange to pass
208518334Speter   for X the output operand and for Y the input operand.
208618334Speter   For now, we assume that the output operand has the lower number
208718334Speter   because that is natural in (SET output (... input ...)).  */
208818334Speter
208918334Speterint
209018334Speteroperands_match_p (x, y)
209118334Speter     register rtx x, y;
209218334Speter{
209318334Speter  register int i;
209418334Speter  register RTX_CODE code = GET_CODE (x);
209518334Speter  register char *fmt;
209618334Speter  int success_2;
209718334Speter
209818334Speter  if (x == y)
209918334Speter    return 1;
210018334Speter  if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
210118334Speter      && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
210218334Speter				  && GET_CODE (SUBREG_REG (y)) == REG)))
210318334Speter    {
210418334Speter      register int j;
210518334Speter
210618334Speter      if (code == SUBREG)
210718334Speter	{
210818334Speter	  i = REGNO (SUBREG_REG (x));
210918334Speter	  if (i >= FIRST_PSEUDO_REGISTER)
211018334Speter	    goto slow;
211118334Speter	  i += SUBREG_WORD (x);
211218334Speter	}
211318334Speter      else
211418334Speter	i = REGNO (x);
211518334Speter
211618334Speter      if (GET_CODE (y) == SUBREG)
211718334Speter	{
211818334Speter	  j = REGNO (SUBREG_REG (y));
211918334Speter	  if (j >= FIRST_PSEUDO_REGISTER)
212018334Speter	    goto slow;
212118334Speter	  j += SUBREG_WORD (y);
212218334Speter	}
212318334Speter      else
212418334Speter	j = REGNO (y);
212518334Speter
212618334Speter      /* On a WORDS_BIG_ENDIAN machine, point to the last register of a
212718334Speter	 multiple hard register group, so that for example (reg:DI 0) and
212818334Speter	 (reg:SI 1) will be considered the same register.  */
212918334Speter      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
213018334Speter	  && i < FIRST_PSEUDO_REGISTER)
213118334Speter	i += (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD) - 1;
213218334Speter      if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
213318334Speter	  && j < FIRST_PSEUDO_REGISTER)
213418334Speter	j += (GET_MODE_SIZE (GET_MODE (y)) / UNITS_PER_WORD) - 1;
213518334Speter
213618334Speter      return i == j;
213718334Speter    }
213818334Speter  /* If two operands must match, because they are really a single
213918334Speter     operand of an assembler insn, then two postincrements are invalid
214018334Speter     because the assembler insn would increment only once.
214118334Speter     On the other hand, an postincrement matches ordinary indexing
214218334Speter     if the postincrement is the output operand.  */
214318334Speter  if (code == POST_DEC || code == POST_INC)
214418334Speter    return operands_match_p (XEXP (x, 0), y);
214518334Speter  /* Two preincrements are invalid
214618334Speter     because the assembler insn would increment only once.
214718334Speter     On the other hand, an preincrement matches ordinary indexing
214818334Speter     if the preincrement is the input operand.
214918334Speter     In this case, return 2, since some callers need to do special
215018334Speter     things when this happens.  */
215118334Speter  if (GET_CODE (y) == PRE_DEC || GET_CODE (y) == PRE_INC)
215218334Speter    return operands_match_p (x, XEXP (y, 0)) ? 2 : 0;
215318334Speter
215418334Speter slow:
215518334Speter
215618334Speter  /* Now we have disposed of all the cases
215718334Speter     in which different rtx codes can match.  */
215818334Speter  if (code != GET_CODE (y))
215918334Speter    return 0;
216018334Speter  if (code == LABEL_REF)
216118334Speter    return XEXP (x, 0) == XEXP (y, 0);
216218334Speter  if (code == SYMBOL_REF)
216318334Speter    return XSTR (x, 0) == XSTR (y, 0);
216418334Speter
216518334Speter  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
216618334Speter
216718334Speter  if (GET_MODE (x) != GET_MODE (y))
216818334Speter    return 0;
216918334Speter
217018334Speter  /* Compare the elements.  If any pair of corresponding elements
217118334Speter     fail to match, return 0 for the whole things.  */
217218334Speter
217318334Speter  success_2 = 0;
217418334Speter  fmt = GET_RTX_FORMAT (code);
217518334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
217618334Speter    {
217752557Sobrien      int val, j;
217818334Speter      switch (fmt[i])
217918334Speter	{
218018334Speter	case 'w':
218118334Speter	  if (XWINT (x, i) != XWINT (y, i))
218218334Speter	    return 0;
218318334Speter	  break;
218418334Speter
218518334Speter	case 'i':
218618334Speter	  if (XINT (x, i) != XINT (y, i))
218718334Speter	    return 0;
218818334Speter	  break;
218918334Speter
219018334Speter	case 'e':
219118334Speter	  val = operands_match_p (XEXP (x, i), XEXP (y, i));
219218334Speter	  if (val == 0)
219318334Speter	    return 0;
219418334Speter	  /* If any subexpression returns 2,
219518334Speter	     we should return 2 if we are successful.  */
219618334Speter	  if (val == 2)
219718334Speter	    success_2 = 1;
219818334Speter	  break;
219918334Speter
220018334Speter	case '0':
220118334Speter	  break;
220218334Speter
220352557Sobrien	case 'E':
220452557Sobrien	  if (XVECLEN (x, i) != XVECLEN (y, i))
220552557Sobrien	    return 0;
220652557Sobrien	  for (j = XVECLEN (x, i) - 1; j >= 0; --j)
220752557Sobrien	    {
220852557Sobrien	      val = operands_match_p (XVECEXP (x, i, j), XVECEXP (y, i, j));
220952557Sobrien	      if (val == 0)
221052557Sobrien		return 0;
221152557Sobrien	      if (val == 2)
221252557Sobrien		success_2 = 1;
221352557Sobrien	    }
221452557Sobrien	  break;
221552557Sobrien
221618334Speter	  /* It is believed that rtx's at this level will never
221718334Speter	     contain anything but integers and other rtx's,
221818334Speter	     except for within LABEL_REFs and SYMBOL_REFs.  */
221918334Speter	default:
222018334Speter	  abort ();
222118334Speter	}
222218334Speter    }
222318334Speter  return 1 + success_2;
222418334Speter}
222518334Speter
222618334Speter/* Describe the range of registers or memory referenced by X.
222718334Speter   If X is a register, set REG_FLAG and put the first register
222818334Speter   number into START and the last plus one into END.
222918334Speter   If X is a memory reference, put a base address into BASE
223018334Speter   and a range of integer offsets into START and END.
223118334Speter   If X is pushing on the stack, we can assume it causes no trouble,
223218334Speter   so we set the SAFE field.  */
223318334Speter
223418334Speterstatic struct decomposition
223518334Speterdecompose (x)
223618334Speter     rtx x;
223718334Speter{
223818334Speter  struct decomposition val;
223918334Speter  int all_const = 0;
224018334Speter
224118334Speter  val.reg_flag = 0;
224218334Speter  val.safe = 0;
224350605Sobrien  val.base = 0;
224418334Speter  if (GET_CODE (x) == MEM)
224518334Speter    {
224618334Speter      rtx base, offset = 0;
224718334Speter      rtx addr = XEXP (x, 0);
224818334Speter
224918334Speter      if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
225018334Speter	  || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
225118334Speter	{
225218334Speter	  val.base = XEXP (addr, 0);
225318334Speter	  val.start = - GET_MODE_SIZE (GET_MODE (x));
225418334Speter	  val.end = GET_MODE_SIZE (GET_MODE (x));
225518334Speter	  val.safe = REGNO (val.base) == STACK_POINTER_REGNUM;
225618334Speter	  return val;
225718334Speter	}
225818334Speter
225918334Speter      if (GET_CODE (addr) == CONST)
226018334Speter	{
226118334Speter	  addr = XEXP (addr, 0);
226218334Speter	  all_const = 1;
226318334Speter	}
226418334Speter      if (GET_CODE (addr) == PLUS)
226518334Speter	{
226618334Speter	  if (CONSTANT_P (XEXP (addr, 0)))
226718334Speter	    {
226818334Speter	      base = XEXP (addr, 1);
226918334Speter	      offset = XEXP (addr, 0);
227018334Speter	    }
227118334Speter	  else if (CONSTANT_P (XEXP (addr, 1)))
227218334Speter	    {
227318334Speter	      base = XEXP (addr, 0);
227418334Speter	      offset = XEXP (addr, 1);
227518334Speter	    }
227618334Speter	}
227718334Speter
227818334Speter      if (offset == 0)
227918334Speter	{
228018334Speter	  base = addr;
228118334Speter	  offset = const0_rtx;
228218334Speter	}
228318334Speter      if (GET_CODE (offset) == CONST)
228418334Speter	offset = XEXP (offset, 0);
228518334Speter      if (GET_CODE (offset) == PLUS)
228618334Speter	{
228718334Speter	  if (GET_CODE (XEXP (offset, 0)) == CONST_INT)
228818334Speter	    {
228950605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 1));
229018334Speter	      offset = XEXP (offset, 0);
229118334Speter	    }
229218334Speter	  else if (GET_CODE (XEXP (offset, 1)) == CONST_INT)
229318334Speter	    {
229450605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, XEXP (offset, 0));
229518334Speter	      offset = XEXP (offset, 1);
229618334Speter	    }
229718334Speter	  else
229818334Speter	    {
229950605Sobrien	      base = gen_rtx_PLUS (GET_MODE (base), base, offset);
230018334Speter	      offset = const0_rtx;
230118334Speter	    }
230218334Speter	}
230318334Speter      else if (GET_CODE (offset) != CONST_INT)
230418334Speter	{
230550605Sobrien	  base = gen_rtx_PLUS (GET_MODE (base), base, offset);
230618334Speter	  offset = const0_rtx;
230718334Speter	}
230818334Speter
230918334Speter      if (all_const && GET_CODE (base) == PLUS)
231050605Sobrien	base = gen_rtx_CONST (GET_MODE (base), base);
231118334Speter
231218334Speter      if (GET_CODE (offset) != CONST_INT)
231318334Speter	abort ();
231418334Speter
231518334Speter      val.start = INTVAL (offset);
231618334Speter      val.end = val.start + GET_MODE_SIZE (GET_MODE (x));
231718334Speter      val.base = base;
231818334Speter      return val;
231918334Speter    }
232018334Speter  else if (GET_CODE (x) == REG)
232118334Speter    {
232218334Speter      val.reg_flag = 1;
232318334Speter      val.start = true_regnum (x);
232418334Speter      if (val.start < 0)
232518334Speter	{
232618334Speter	  /* A pseudo with no hard reg.  */
232718334Speter	  val.start = REGNO (x);
232818334Speter	  val.end = val.start + 1;
232918334Speter	}
233018334Speter      else
233118334Speter	/* A hard reg.  */
233218334Speter	val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
233318334Speter    }
233418334Speter  else if (GET_CODE (x) == SUBREG)
233518334Speter    {
233618334Speter      if (GET_CODE (SUBREG_REG (x)) != REG)
233718334Speter	/* This could be more precise, but it's good enough.  */
233818334Speter	return decompose (SUBREG_REG (x));
233918334Speter      val.reg_flag = 1;
234018334Speter      val.start = true_regnum (x);
234118334Speter      if (val.start < 0)
234218334Speter	return decompose (SUBREG_REG (x));
234318334Speter      else
234418334Speter	/* A hard reg.  */
234518334Speter	val.end = val.start + HARD_REGNO_NREGS (val.start, GET_MODE (x));
234618334Speter    }
234718334Speter  else if (CONSTANT_P (x)
234818334Speter	   /* This hasn't been assigned yet, so it can't conflict yet.  */
234918334Speter	   || GET_CODE (x) == SCRATCH)
235018334Speter    val.safe = 1;
235118334Speter  else
235218334Speter    abort ();
235318334Speter  return val;
235418334Speter}
235518334Speter
235618334Speter/* Return 1 if altering Y will not modify the value of X.
235718334Speter   Y is also described by YDATA, which should be decompose (Y).  */
235818334Speter
235918334Speterstatic int
236018334Speterimmune_p (x, y, ydata)
236118334Speter     rtx x, y;
236218334Speter     struct decomposition ydata;
236318334Speter{
236418334Speter  struct decomposition xdata;
236518334Speter
236618334Speter  if (ydata.reg_flag)
236718334Speter    return !refers_to_regno_for_reload_p (ydata.start, ydata.end, x, NULL_PTR);
236818334Speter  if (ydata.safe)
236918334Speter    return 1;
237018334Speter
237118334Speter  if (GET_CODE (y) != MEM)
237218334Speter    abort ();
237318334Speter  /* If Y is memory and X is not, Y can't affect X.  */
237418334Speter  if (GET_CODE (x) != MEM)
237518334Speter    return 1;
237618334Speter
237718334Speter  xdata =  decompose (x);
237818334Speter
237918334Speter  if (! rtx_equal_p (xdata.base, ydata.base))
238018334Speter    {
238118334Speter      /* If bases are distinct symbolic constants, there is no overlap.  */
238218334Speter      if (CONSTANT_P (xdata.base) && CONSTANT_P (ydata.base))
238318334Speter	return 1;
238418334Speter      /* Constants and stack slots never overlap.  */
238518334Speter      if (CONSTANT_P (xdata.base)
238618334Speter	  && (ydata.base == frame_pointer_rtx
238718334Speter	      || ydata.base == hard_frame_pointer_rtx
238818334Speter	      || ydata.base == stack_pointer_rtx))
238918334Speter	return 1;
239018334Speter      if (CONSTANT_P (ydata.base)
239118334Speter	  && (xdata.base == frame_pointer_rtx
239218334Speter	      || xdata.base == hard_frame_pointer_rtx
239318334Speter	      || xdata.base == stack_pointer_rtx))
239418334Speter	return 1;
239518334Speter      /* If either base is variable, we don't know anything.  */
239618334Speter      return 0;
239718334Speter    }
239818334Speter
239918334Speter
240018334Speter  return (xdata.start >= ydata.end || ydata.start >= xdata.end);
240118334Speter}
240218334Speter
240318334Speter/* Similar, but calls decompose.  */
240418334Speter
240518334Speterint
240618334Spetersafe_from_earlyclobber (op, clobber)
240718334Speter     rtx op, clobber;
240818334Speter{
240918334Speter  struct decomposition early_data;
241018334Speter
241118334Speter  early_data = decompose (clobber);
241218334Speter  return immune_p (op, clobber, early_data);
241318334Speter}
241418334Speter
241518334Speter/* Main entry point of this file: search the body of INSN
241618334Speter   for values that need reloading and record them with push_reload.
241718334Speter   REPLACE nonzero means record also where the values occur
241818334Speter   so that subst_reloads can be used.
241918334Speter
242018334Speter   IND_LEVELS says how many levels of indirection are supported by this
242118334Speter   machine; a value of zero means that a memory reference is not a valid
242218334Speter   memory address.
242318334Speter
242418334Speter   LIVE_KNOWN says we have valid information about which hard
242518334Speter   regs are live at each point in the program; this is true when
242618334Speter   we are called from global_alloc but false when stupid register
242718334Speter   allocation has been done.
242818334Speter
242918334Speter   RELOAD_REG_P if nonzero is a vector indexed by hard reg number
243018334Speter   which is nonnegative if the reg has been commandeered for reloading into.
243118334Speter   It is copied into STATIC_RELOAD_REG_P and referenced from there
243252557Sobrien   by various subroutines.
243318334Speter
243452557Sobrien   Return TRUE if some operands need to be changed, because of swapping
243552557Sobrien   commutative operands, reg_equiv_address substitution, or whatever.  */
243652557Sobrien
243752557Sobrienint
243818334Speterfind_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
243918334Speter     rtx insn;
244018334Speter     int replace, ind_levels;
244118334Speter     int live_known;
244218334Speter     short *reload_reg_p;
244318334Speter{
244418334Speter#ifdef REGISTER_CONSTRAINTS
244518334Speter
244618334Speter  register int insn_code_number;
244718334Speter  register int i, j;
244818334Speter  int noperands;
244918334Speter  /* These start out as the constraints for the insn
245018334Speter     and they are chewed up as we consider alternatives.  */
245118334Speter  char *constraints[MAX_RECOG_OPERANDS];
245218334Speter  /* These are the preferred classes for an operand, or NO_REGS if it isn't
245318334Speter     a register.  */
245418334Speter  enum reg_class preferred_class[MAX_RECOG_OPERANDS];
245518334Speter  char pref_or_nothing[MAX_RECOG_OPERANDS];
245618334Speter  /* Nonzero for a MEM operand whose entire address needs a reload.  */
245718334Speter  int address_reloaded[MAX_RECOG_OPERANDS];
245818334Speter  /* Value of enum reload_type to use for operand.  */
245918334Speter  enum reload_type operand_type[MAX_RECOG_OPERANDS];
246018334Speter  /* Value of enum reload_type to use within address of operand.  */
246118334Speter  enum reload_type address_type[MAX_RECOG_OPERANDS];
246218334Speter  /* Save the usage of each operand.  */
246318334Speter  enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS];
246418334Speter  int no_input_reloads = 0, no_output_reloads = 0;
246518334Speter  int n_alternatives;
246618334Speter  int this_alternative[MAX_RECOG_OPERANDS];
246718334Speter  char this_alternative_win[MAX_RECOG_OPERANDS];
246818334Speter  char this_alternative_offmemok[MAX_RECOG_OPERANDS];
246918334Speter  char this_alternative_earlyclobber[MAX_RECOG_OPERANDS];
247018334Speter  int this_alternative_matches[MAX_RECOG_OPERANDS];
247118334Speter  int swapped;
247218334Speter  int goal_alternative[MAX_RECOG_OPERANDS];
247318334Speter  int this_alternative_number;
247418334Speter  int goal_alternative_number;
247518334Speter  int operand_reloadnum[MAX_RECOG_OPERANDS];
247618334Speter  int goal_alternative_matches[MAX_RECOG_OPERANDS];
247718334Speter  int goal_alternative_matched[MAX_RECOG_OPERANDS];
247818334Speter  char goal_alternative_win[MAX_RECOG_OPERANDS];
247918334Speter  char goal_alternative_offmemok[MAX_RECOG_OPERANDS];
248018334Speter  char goal_alternative_earlyclobber[MAX_RECOG_OPERANDS];
248118334Speter  int goal_alternative_swapped;
248218334Speter  int best;
248318334Speter  int commutative;
248450605Sobrien  int changed;
248518334Speter  char operands_match[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
248618334Speter  rtx substed_operand[MAX_RECOG_OPERANDS];
248718334Speter  rtx body = PATTERN (insn);
248818334Speter  rtx set = single_set (insn);
248918334Speter  int goal_earlyclobber, this_earlyclobber;
249018334Speter  enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
249152557Sobrien  int retval = 0;
249250605Sobrien  /* Cache the last regno for the last pseudo we did an output reload
249350605Sobrien     for in case the next insn uses it.  */
249450605Sobrien  static int last_output_reload_regno = -1;
249518334Speter
249618334Speter  this_insn = insn;
249718334Speter  n_reloads = 0;
249818334Speter  n_replacements = 0;
249918334Speter  n_earlyclobbers = 0;
250018334Speter  replace_reloads = replace;
250118334Speter  hard_regs_live_known = live_known;
250218334Speter  static_reload_reg_p = reload_reg_p;
250318334Speter
250418334Speter  /* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
250518334Speter     neither are insns that SET cc0.  Insns that use CC0 are not allowed
250618334Speter     to have any input reloads.  */
250718334Speter  if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)
250818334Speter    no_output_reloads = 1;
250918334Speter
251018334Speter#ifdef HAVE_cc0
251118334Speter  if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
251218334Speter    no_input_reloads = 1;
251318334Speter  if (reg_set_p (cc0_rtx, PATTERN (insn)))
251418334Speter    no_output_reloads = 1;
251518334Speter#endif
251618334Speter
251718334Speter#ifdef SECONDARY_MEMORY_NEEDED
251818334Speter  /* The eliminated forms of any secondary memory locations are per-insn, so
251918334Speter     clear them out here.  */
252018334Speter
252118334Speter  bzero ((char *) secondary_memlocs_elim, sizeof secondary_memlocs_elim);
252218334Speter#endif
252318334Speter
252452557Sobrien  /* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
252552557Sobrien     is cheap to move between them.  If it is not, there may not be an insn
252652557Sobrien     to do the copy, so we may need a reload.  */
252752557Sobrien  if (GET_CODE (body) == SET
252852557Sobrien      && GET_CODE (SET_DEST (body)) == REG
252952557Sobrien      && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
253052557Sobrien      && GET_CODE (SET_SRC (body)) == REG
253152557Sobrien      && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
253252557Sobrien      && REGISTER_MOVE_COST (REGNO_REG_CLASS (REGNO (SET_SRC (body))),
253352557Sobrien			     REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
253452557Sobrien    return 0;
253518334Speter
253652557Sobrien  extract_insn (insn);
253718334Speter
253852557Sobrien  noperands = reload_n_operands = recog_n_operands;
253952557Sobrien  n_alternatives = recog_n_alternatives;
254018334Speter
254152557Sobrien  /* Just return "no reloads" if insn has no operands with constraints.  */
254252557Sobrien  if (noperands == 0 || n_alternatives == 0)
254352557Sobrien    return 0;
254418334Speter
254552557Sobrien  insn_code_number = INSN_CODE (insn);
254652557Sobrien  this_insn_is_asm = insn_code_number < 0;
254718334Speter
254852557Sobrien  bcopy ((char *) recog_operand_mode, (char *) operand_mode,
254952557Sobrien	 noperands * sizeof (enum machine_mode));
255052557Sobrien  bcopy ((char *) recog_constraints, (char *) constraints,
255152557Sobrien	 noperands * sizeof (char *));
255218334Speter
255318334Speter  commutative = -1;
255418334Speter
255518334Speter  /* If we will need to know, later, whether some pair of operands
255618334Speter     are the same, we must compare them now and save the result.
255718334Speter     Reloading the base and index registers will clobber them
255818334Speter     and afterward they will fail to match.  */
255918334Speter
256018334Speter  for (i = 0; i < noperands; i++)
256118334Speter    {
256218334Speter      register char *p;
256318334Speter      register int c;
256418334Speter
256518334Speter      substed_operand[i] = recog_operand[i];
256618334Speter      p = constraints[i];
256718334Speter
256818334Speter      modified[i] = RELOAD_READ;
256918334Speter
257018334Speter      /* Scan this operand's constraint to see if it is an output operand,
257118334Speter	 an in-out operand, is commutative, or should match another.  */
257218334Speter
257350605Sobrien      while ((c = *p++))
257418334Speter	{
257518334Speter	  if (c == '=')
257618334Speter	    modified[i] = RELOAD_WRITE;
257718334Speter	  else if (c == '+')
257818334Speter	    modified[i] = RELOAD_READ_WRITE;
257918334Speter	  else if (c == '%')
258018334Speter	    {
258118334Speter	      /* The last operand should not be marked commutative.  */
258218334Speter	      if (i == noperands - 1)
258352557Sobrien		abort ();
258452557Sobrien
258552557Sobrien	      commutative = i;
258618334Speter	    }
258718334Speter	  else if (c >= '0' && c <= '9')
258818334Speter	    {
258918334Speter	      c -= '0';
259018334Speter	      operands_match[c][i]
259118334Speter		= operands_match_p (recog_operand[c], recog_operand[i]);
259218334Speter
259318334Speter	      /* An operand may not match itself.  */
259418334Speter	      if (c == i)
259552557Sobrien		abort ();
259618334Speter
259718334Speter	      /* If C can be commuted with C+1, and C might need to match I,
259818334Speter		 then C+1 might also need to match I.  */
259918334Speter	      if (commutative >= 0)
260018334Speter		{
260118334Speter		  if (c == commutative || c == commutative + 1)
260218334Speter		    {
260318334Speter		      int other = c + (c == commutative ? 1 : -1);
260418334Speter		      operands_match[other][i]
260518334Speter			= operands_match_p (recog_operand[other], recog_operand[i]);
260618334Speter		    }
260718334Speter		  if (i == commutative || i == commutative + 1)
260818334Speter		    {
260918334Speter		      int other = i + (i == commutative ? 1 : -1);
261018334Speter		      operands_match[c][other]
261118334Speter			= operands_match_p (recog_operand[c], recog_operand[other]);
261218334Speter		    }
261318334Speter		  /* Note that C is supposed to be less than I.
261418334Speter		     No need to consider altering both C and I because in
261518334Speter		     that case we would alter one into the other.  */
261618334Speter		}
261718334Speter	    }
261818334Speter	}
261918334Speter    }
262018334Speter
262118334Speter  /* Examine each operand that is a memory reference or memory address
262218334Speter     and reload parts of the addresses into index registers.
262318334Speter     Also here any references to pseudo regs that didn't get hard regs
262418334Speter     but are equivalent to constants get replaced in the insn itself
262518334Speter     with those constants.  Nobody will ever see them again.
262618334Speter
262718334Speter     Finally, set up the preferred classes of each operand.  */
262818334Speter
262918334Speter  for (i = 0; i < noperands; i++)
263018334Speter    {
263118334Speter      register RTX_CODE code = GET_CODE (recog_operand[i]);
263218334Speter
263318334Speter      address_reloaded[i] = 0;
263418334Speter      operand_type[i] = (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT
263518334Speter			 : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT
263618334Speter			 : RELOAD_OTHER);
263718334Speter      address_type[i]
263818334Speter	= (modified[i] == RELOAD_READ ? RELOAD_FOR_INPUT_ADDRESS
263918334Speter	   : modified[i] == RELOAD_WRITE ? RELOAD_FOR_OUTPUT_ADDRESS
264018334Speter	   : RELOAD_OTHER);
264118334Speter
264218334Speter      if (*constraints[i] == 0)
264318334Speter	/* Ignore things like match_operator operands.  */
264418334Speter	;
264518334Speter      else if (constraints[i][0] == 'p')
264618334Speter	{
264718334Speter	  find_reloads_address (VOIDmode, NULL_PTR,
264818334Speter				recog_operand[i], recog_operand_loc[i],
264950605Sobrien				i, operand_type[i], ind_levels, insn);
265050605Sobrien
265150605Sobrien	  /* If we now have a simple operand where we used to have a
265250605Sobrien	     PLUS or MULT, re-recognize and try again.  */
265350605Sobrien	  if ((GET_RTX_CLASS (GET_CODE (*recog_operand_loc[i])) == 'o'
265450605Sobrien	       || GET_CODE (*recog_operand_loc[i]) == SUBREG)
265550605Sobrien	      && (GET_CODE (recog_operand[i]) == MULT
265650605Sobrien		  || GET_CODE (recog_operand[i]) == PLUS))
265750605Sobrien	    {
265850605Sobrien	      INSN_CODE (insn) = -1;
265952557Sobrien	      retval = find_reloads (insn, replace, ind_levels, live_known,
266052557Sobrien				     reload_reg_p);
266152557Sobrien	      return retval;
266250605Sobrien	    }
266350605Sobrien
266418334Speter	  substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
266518334Speter	}
266618334Speter      else if (code == MEM)
266718334Speter	{
266852557Sobrien	  address_reloaded[i]
266952557Sobrien	    = find_reloads_address (GET_MODE (recog_operand[i]),
267018334Speter				    recog_operand_loc[i],
267118334Speter				    XEXP (recog_operand[i], 0),
267218334Speter				    &XEXP (recog_operand[i], 0),
267352557Sobrien				    i, address_type[i], ind_levels, insn);
267418334Speter	  substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
267518334Speter	}
267618334Speter      else if (code == SUBREG)
267750605Sobrien	{
267850605Sobrien	  rtx reg = SUBREG_REG (recog_operand[i]);
267950605Sobrien	  rtx op
268050605Sobrien	    = find_reloads_toplev (recog_operand[i], i, address_type[i],
268150605Sobrien				   ind_levels,
268250605Sobrien				   set != 0
268352557Sobrien				   && &SET_DEST (set) == recog_operand_loc[i],
268452557Sobrien				   insn);
268550605Sobrien
268650605Sobrien	  /* If we made a MEM to load (a part of) the stackslot of a pseudo
268750605Sobrien	     that didn't get a hard register, emit a USE with a REG_EQUAL
268850605Sobrien	     note in front so that we might inherit a previous, possibly
268950605Sobrien	     wider reload.  */
269050605Sobrien
269152557Sobrien	  if (replace
269252557Sobrien	      && GET_CODE (op) == MEM
269350605Sobrien	      && GET_CODE (reg) == REG
269450605Sobrien	      && (GET_MODE_SIZE (GET_MODE (reg))
269550605Sobrien		  >= GET_MODE_SIZE (GET_MODE (op))))
269650605Sobrien            REG_NOTES (emit_insn_before (gen_rtx_USE (VOIDmode, reg), insn))
269750605Sobrien              = gen_rtx_EXPR_LIST (REG_EQUAL,
269850605Sobrien				   reg_equiv_memory_loc[REGNO (reg)], NULL_RTX);
269950605Sobrien
270052557Sobrien	  substed_operand[i] = recog_operand[i] = op;
270150605Sobrien	}
270250605Sobrien      else if (code == PLUS || GET_RTX_CLASS (code) == '1')
270350605Sobrien	/* We can get a PLUS as an "operand" as a result of register
270450605Sobrien	   elimination.  See eliminate_regs and gen_reload.  We handle
270550605Sobrien	   a unary operator by reloading the operand.  */
270652557Sobrien	substed_operand[i] = recog_operand[i]
270718334Speter	  = find_reloads_toplev (recog_operand[i], i, address_type[i],
270852557Sobrien				 ind_levels, 0, insn);
270918334Speter      else if (code == REG)
271018334Speter	{
271118334Speter	  /* This is equivalent to calling find_reloads_toplev.
271218334Speter	     The code is duplicated for speed.
271318334Speter	     When we find a pseudo always equivalent to a constant,
271418334Speter	     we replace it by the constant.  We must be sure, however,
271518334Speter	     that we don't try to replace it in the insn in which it
271618334Speter	     is being set.   */
271718334Speter	  register int regno = REGNO (recog_operand[i]);
271818334Speter	  if (reg_equiv_constant[regno] != 0
271918334Speter	      && (set == 0 || &SET_DEST (set) != recog_operand_loc[i]))
272050605Sobrien	    {
272150605Sobrien	      /* Record the existing mode so that the check if constants are
272250605Sobrien	         allowed will work when operand_mode isn't specified. */
272350605Sobrien
272450605Sobrien	      if (operand_mode[i] == VOIDmode)
272550605Sobrien		operand_mode[i] = GET_MODE (recog_operand[i]);
272650605Sobrien
272750605Sobrien	      substed_operand[i] = recog_operand[i]
272850605Sobrien	        = reg_equiv_constant[regno];
272950605Sobrien	    }
273052557Sobrien	  if (reg_equiv_memory_loc[regno] != 0
273152557Sobrien	      && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
273252557Sobrien	    /* We need not give a valid is_set_dest argument since the case
273352557Sobrien	       of a constant equivalence was checked above.  */
273418334Speter	    substed_operand[i] = recog_operand[i]
273552557Sobrien	      = find_reloads_toplev (recog_operand[i], i, address_type[i],
273652557Sobrien				     ind_levels, 0, insn);
273718334Speter	}
273818334Speter      /* If the operand is still a register (we didn't replace it with an
273918334Speter	 equivalent), get the preferred class to reload it into.  */
274018334Speter      code = GET_CODE (recog_operand[i]);
274118334Speter      preferred_class[i]
274218334Speter	= ((code == REG && REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER)
274318334Speter	   ? reg_preferred_class (REGNO (recog_operand[i])) : NO_REGS);
274418334Speter      pref_or_nothing[i]
274518334Speter	= (code == REG && REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER
274618334Speter	   && reg_alternate_class (REGNO (recog_operand[i])) == NO_REGS);
274718334Speter    }
274818334Speter
274952557Sobrien#ifdef HAVE_cc0
275052557Sobrien  /* If we made any reloads for addresses, see if they violate a
275152557Sobrien     "no input reloads" requirement for this insn.  */
275252557Sobrien  if (no_input_reloads)
275352557Sobrien    for (i = 0; i < n_reloads; i++)
275452557Sobrien      if (reload_in[i] != 0)
275552557Sobrien	abort ();
275652557Sobrien#endif
275752557Sobrien
275818334Speter  /* If this is simply a copy from operand 1 to operand 0, merge the
275918334Speter     preferred classes for the operands.  */
276018334Speter  if (set != 0 && noperands >= 2 && recog_operand[0] == SET_DEST (set)
276118334Speter      && recog_operand[1] == SET_SRC (set))
276218334Speter    {
276318334Speter      preferred_class[0] = preferred_class[1]
276418334Speter	= reg_class_subunion[(int) preferred_class[0]][(int) preferred_class[1]];
276518334Speter      pref_or_nothing[0] |= pref_or_nothing[1];
276618334Speter      pref_or_nothing[1] |= pref_or_nothing[0];
276718334Speter    }
276818334Speter
276918334Speter  /* Now see what we need for pseudo-regs that didn't get hard regs
277018334Speter     or got the wrong kind of hard reg.  For this, we must consider
277118334Speter     all the operands together against the register constraints.  */
277218334Speter
277350605Sobrien  best = MAX_RECOG_OPERANDS * 2 + 600;
277418334Speter
277518334Speter  swapped = 0;
277618334Speter  goal_alternative_swapped = 0;
277718334Speter try_swapped:
277818334Speter
277918334Speter  /* The constraints are made of several alternatives.
278018334Speter     Each operand's constraint looks like foo,bar,... with commas
278118334Speter     separating the alternatives.  The first alternatives for all
278218334Speter     operands go together, the second alternatives go together, etc.
278318334Speter
278418334Speter     First loop over alternatives.  */
278518334Speter
278618334Speter  for (this_alternative_number = 0;
278718334Speter       this_alternative_number < n_alternatives;
278818334Speter       this_alternative_number++)
278918334Speter    {
279018334Speter      /* Loop over operands for one constraint alternative.  */
279118334Speter      /* LOSERS counts those that don't fit this alternative
279218334Speter	 and would require loading.  */
279318334Speter      int losers = 0;
279418334Speter      /* BAD is set to 1 if it some operand can't fit this alternative
279518334Speter	 even after reloading.  */
279618334Speter      int bad = 0;
279718334Speter      /* REJECT is a count of how undesirable this alternative says it is
279818334Speter	 if any reloading is required.  If the alternative matches exactly
279918334Speter	 then REJECT is ignored, but otherwise it gets this much
280018334Speter	 counted against it in addition to the reloading needed.  Each
280118334Speter	 ? counts three times here since we want the disparaging caused by
280218334Speter	 a bad register class to only count 1/3 as much.  */
280318334Speter      int reject = 0;
280418334Speter
280518334Speter      this_earlyclobber = 0;
280618334Speter
280718334Speter      for (i = 0; i < noperands; i++)
280818334Speter	{
280918334Speter	  register char *p = constraints[i];
281018334Speter	  register int win = 0;
281118334Speter	  /* 0 => this operand can be reloaded somehow for this alternative */
281218334Speter	  int badop = 1;
281318334Speter	  /* 0 => this operand can be reloaded if the alternative allows regs.  */
281418334Speter	  int winreg = 0;
281518334Speter	  int c;
281618334Speter	  register rtx operand = recog_operand[i];
281718334Speter	  int offset = 0;
281818334Speter	  /* Nonzero means this is a MEM that must be reloaded into a reg
281918334Speter	     regardless of what the constraint says.  */
282018334Speter	  int force_reload = 0;
282118334Speter	  int offmemok = 0;
282218334Speter	  /* Nonzero if a constant forced into memory would be OK for this
282318334Speter	     operand.  */
282418334Speter	  int constmemok = 0;
282518334Speter	  int earlyclobber = 0;
282618334Speter
282750605Sobrien	  /* If the predicate accepts a unary operator, it means that
282850605Sobrien             we need to reload the operand, but do not do this for
282950605Sobrien	     match_operator and friends.  */
283050605Sobrien	  if (GET_RTX_CLASS (GET_CODE (operand)) == '1' && *p != 0)
283150605Sobrien	    operand = XEXP (operand, 0);
283250605Sobrien
283318334Speter	  /* If the operand is a SUBREG, extract
283418334Speter	     the REG or MEM (or maybe even a constant) within.
283518334Speter	     (Constants can occur as a result of reg_equiv_constant.)  */
283618334Speter
283718334Speter	  while (GET_CODE (operand) == SUBREG)
283818334Speter	    {
283918334Speter	      offset += SUBREG_WORD (operand);
284018334Speter	      operand = SUBREG_REG (operand);
284150605Sobrien	      /* Force reload if this is a constant or PLUS or if there may
284218334Speter		 be a problem accessing OPERAND in the outer mode.  */
284318334Speter	      if (CONSTANT_P (operand)
284418334Speter		  || GET_CODE (operand) == PLUS
284518334Speter		  /* We must force a reload of paradoxical SUBREGs
284618334Speter		     of a MEM because the alignment of the inner value
284718334Speter		     may not be enough to do the outer reference.  On
284818334Speter		     big-endian machines, it may also reference outside
284918334Speter		     the object.
285018334Speter
285118334Speter		     On machines that extend byte operations and we have a
285218334Speter		     SUBREG where both the inner and outer modes are no wider
285318334Speter		     than a word and the inner mode is narrower, is integral,
285418334Speter		     and gets extended when loaded from memory, combine.c has
285518334Speter		     made assumptions about the behavior of the machine in such
285618334Speter		     register access.  If the data is, in fact, in memory we
285718334Speter		     must always load using the size assumed to be in the
285818334Speter		     register and let the insn do the different-sized
285950605Sobrien		     accesses.
286050605Sobrien
286150605Sobrien		     This is doubly true if WORD_REGISTER_OPERATIONS.  In
286250605Sobrien		     this case eliminate_regs has left non-paradoxical
286350605Sobrien		     subregs for push_reloads to see.  Make sure it does
286450605Sobrien		     by forcing the reload.
286550605Sobrien
286650605Sobrien		     ??? When is it right at this stage to have a subreg
286750605Sobrien		     of a mem that is _not_ to be handled specialy?  IMO
286850605Sobrien		     those should have been reduced to just a mem.  */
286918334Speter		  || ((GET_CODE (operand) == MEM
287018334Speter		       || (GET_CODE (operand)== REG
287118334Speter			   && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
287250605Sobrien#ifndef WORD_REGISTER_OPERATIONS
287318334Speter		      && (((GET_MODE_BITSIZE (GET_MODE (operand))
287418334Speter			    < BIGGEST_ALIGNMENT)
287518334Speter			   && (GET_MODE_SIZE (operand_mode[i])
287618334Speter			       > GET_MODE_SIZE (GET_MODE (operand))))
287718334Speter			  || (GET_CODE (operand) == MEM && BYTES_BIG_ENDIAN)
287818334Speter#ifdef LOAD_EXTEND_OP
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 (operand_mode[i])
288318334Speter				  > GET_MODE_SIZE (GET_MODE (operand)))
288418334Speter			      && INTEGRAL_MODE_P (GET_MODE (operand))
288518334Speter			      && LOAD_EXTEND_OP (GET_MODE (operand)) != NIL)
288618334Speter#endif
288750605Sobrien			  )
288850605Sobrien#endif
288950605Sobrien		      )
289018334Speter		  /* Subreg of a hard reg which can't handle the subreg's mode
289118334Speter		     or which would handle that mode in the wrong number of
289218334Speter		     registers for subregging to work.  */
289318334Speter		  || (GET_CODE (operand) == REG
289418334Speter		      && REGNO (operand) < FIRST_PSEUDO_REGISTER
289518334Speter		      && ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
289618334Speter			   && (GET_MODE_SIZE (GET_MODE (operand))
289718334Speter			       > UNITS_PER_WORD)
289818334Speter			   && ((GET_MODE_SIZE (GET_MODE (operand))
289918334Speter				/ UNITS_PER_WORD)
290018334Speter			       != HARD_REGNO_NREGS (REGNO (operand),
290118334Speter						    GET_MODE (operand))))
290218334Speter			  || ! HARD_REGNO_MODE_OK (REGNO (operand) + offset,
290318334Speter						   operand_mode[i]))))
290418334Speter		force_reload = 1;
290518334Speter	    }
290618334Speter
290718334Speter	  this_alternative[i] = (int) NO_REGS;
290818334Speter	  this_alternative_win[i] = 0;
290918334Speter	  this_alternative_offmemok[i] = 0;
291018334Speter	  this_alternative_earlyclobber[i] = 0;
291118334Speter	  this_alternative_matches[i] = -1;
291218334Speter
291318334Speter	  /* An empty constraint or empty alternative
291418334Speter	     allows anything which matched the pattern.  */
291518334Speter	  if (*p == 0 || *p == ',')
291618334Speter	    win = 1, badop = 0;
291718334Speter
291818334Speter	  /* Scan this alternative's specs for this operand;
291918334Speter	     set WIN if the operand fits any letter in this alternative.
292018334Speter	     Otherwise, clear BADOP if this operand could
292118334Speter	     fit some letter after reloads,
292218334Speter	     or set WINREG if this operand could fit after reloads
292318334Speter	     provided the constraint allows some registers.  */
292418334Speter
292518334Speter	  while (*p && (c = *p++) != ',')
292618334Speter	    switch (c)
292718334Speter	      {
292818334Speter	      case '=':
292918334Speter	      case '+':
293018334Speter	      case '*':
293118334Speter		break;
293218334Speter
293318334Speter	      case '%':
293418334Speter		/* The last operand should not be marked commutative.  */
293518334Speter		if (i != noperands - 1)
293618334Speter		  commutative = i;
293718334Speter		break;
293818334Speter
293918334Speter	      case '?':
294050605Sobrien		reject += 6;
294118334Speter		break;
294218334Speter
294318334Speter	      case '!':
294450605Sobrien		reject = 600;
294518334Speter		break;
294618334Speter
294718334Speter	      case '#':
294818334Speter		/* Ignore rest of this alternative as far as
294918334Speter		   reloading is concerned.  */
295018334Speter		while (*p && *p != ',') p++;
295118334Speter		break;
295218334Speter
295318334Speter	      case '0':
295418334Speter	      case '1':
295518334Speter	      case '2':
295618334Speter	      case '3':
295718334Speter	      case '4':
295818334Speter		c -= '0';
295918334Speter		this_alternative_matches[i] = c;
296018334Speter		/* We are supposed to match a previous operand.
296118334Speter		   If we do, we win if that one did.
296218334Speter		   If we do not, count both of the operands as losers.
296318334Speter		   (This is too conservative, since most of the time
296418334Speter		   only a single reload insn will be needed to make
296518334Speter		   the two operands win.  As a result, this alternative
296618334Speter		   may be rejected when it is actually desirable.)  */
296718334Speter		if ((swapped && (c != commutative || i != commutative + 1))
296818334Speter		    /* If we are matching as if two operands were swapped,
296918334Speter		       also pretend that operands_match had been computed
297018334Speter		       with swapped.
297118334Speter		       But if I is the second of those and C is the first,
297218334Speter		       don't exchange them, because operands_match is valid
297318334Speter		       only on one side of its diagonal.  */
297418334Speter		    ? (operands_match
297518334Speter		        [(c == commutative || c == commutative + 1)
297618334Speter			 ? 2*commutative + 1 - c : c]
297718334Speter		        [(i == commutative || i == commutative + 1)
297818334Speter			 ? 2*commutative + 1 - i : i])
297918334Speter		    : operands_match[c][i])
298050605Sobrien		  {
298150605Sobrien		    /* If we are matching a non-offsettable address where an
298250605Sobrien		       offsettable address was expected, then we must reject
298350605Sobrien		       this combination, because we can't reload it.  */
298450605Sobrien		    if (this_alternative_offmemok[c]
298550605Sobrien			&& GET_CODE (recog_operand[c]) == MEM
298650605Sobrien			&& this_alternative[c] == (int) NO_REGS
298750605Sobrien			&& ! this_alternative_win[c])
298850605Sobrien		      bad = 1;
298950605Sobrien
299050605Sobrien		    win = this_alternative_win[c];
299150605Sobrien		  }
299218334Speter		else
299318334Speter		  {
299418334Speter		    /* Operands don't match.  */
299518334Speter		    rtx value;
299618334Speter		    /* Retroactively mark the operand we had to match
299718334Speter		       as a loser, if it wasn't already.  */
299818334Speter		    if (this_alternative_win[c])
299918334Speter		      losers++;
300018334Speter		    this_alternative_win[c] = 0;
300118334Speter		    if (this_alternative[c] == (int) NO_REGS)
300218334Speter		      bad = 1;
300318334Speter		    /* But count the pair only once in the total badness of
300418334Speter		       this alternative, if the pair can be a dummy reload.  */
300518334Speter		    value
300618334Speter		      = find_dummy_reload (recog_operand[i], recog_operand[c],
300718334Speter					   recog_operand_loc[i], recog_operand_loc[c],
300818334Speter					   operand_mode[i], operand_mode[c],
300950605Sobrien					   this_alternative[c], -1,
301050605Sobrien					   this_alternative_earlyclobber[c]);
301118334Speter
301218334Speter		    if (value != 0)
301318334Speter		      losers--;
301418334Speter		  }
301518334Speter		/* This can be fixed with reloads if the operand
301618334Speter		   we are supposed to match can be fixed with reloads.  */
301718334Speter		badop = 0;
301818334Speter		this_alternative[i] = this_alternative[c];
301918334Speter
302018334Speter		/* If we have to reload this operand and some previous
302118334Speter		   operand also had to match the same thing as this
302218334Speter		   operand, we don't know how to do that.  So reject this
302318334Speter		   alternative.  */
302418334Speter		if (! win || force_reload)
302518334Speter		  for (j = 0; j < i; j++)
302618334Speter		    if (this_alternative_matches[j]
302718334Speter			== this_alternative_matches[i])
302818334Speter		      badop = 1;
302918334Speter
303018334Speter		break;
303118334Speter
303218334Speter	      case 'p':
303318334Speter		/* All necessary reloads for an address_operand
303418334Speter		   were handled in find_reloads_address.  */
303518334Speter		this_alternative[i] = (int) BASE_REG_CLASS;
303618334Speter		win = 1;
303718334Speter		break;
303818334Speter
303918334Speter	      case 'm':
304018334Speter		if (force_reload)
304118334Speter		  break;
304218334Speter		if (GET_CODE (operand) == MEM
304318334Speter		    || (GET_CODE (operand) == REG
304418334Speter			&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
304518334Speter			&& reg_renumber[REGNO (operand)] < 0))
304618334Speter		  win = 1;
304750605Sobrien		if (CONSTANT_P (operand)
304850605Sobrien		    /* force_const_mem does not accept HIGH.  */
304950605Sobrien		    && GET_CODE (operand) != HIGH)
305018334Speter		  badop = 0;
305118334Speter		constmemok = 1;
305218334Speter		break;
305318334Speter
305418334Speter	      case '<':
305518334Speter		if (GET_CODE (operand) == MEM
305618334Speter		    && ! address_reloaded[i]
305718334Speter		    && (GET_CODE (XEXP (operand, 0)) == PRE_DEC
305818334Speter			|| GET_CODE (XEXP (operand, 0)) == POST_DEC))
305918334Speter		  win = 1;
306018334Speter		break;
306118334Speter
306218334Speter	      case '>':
306318334Speter		if (GET_CODE (operand) == MEM
306418334Speter		    && ! address_reloaded[i]
306518334Speter		    && (GET_CODE (XEXP (operand, 0)) == PRE_INC
306618334Speter			|| GET_CODE (XEXP (operand, 0)) == POST_INC))
306718334Speter		  win = 1;
306818334Speter		break;
306918334Speter
307018334Speter		/* Memory operand whose address is not offsettable.  */
307118334Speter	      case 'V':
307218334Speter		if (force_reload)
307318334Speter		  break;
307418334Speter		if (GET_CODE (operand) == MEM
307518334Speter		    && ! (ind_levels ? offsettable_memref_p (operand)
307618334Speter			  : offsettable_nonstrict_memref_p (operand))
307718334Speter		    /* Certain mem addresses will become offsettable
307818334Speter		       after they themselves are reloaded.  This is important;
307918334Speter		       we don't want our own handling of unoffsettables
308018334Speter		       to override the handling of reg_equiv_address.  */
308118334Speter		    && !(GET_CODE (XEXP (operand, 0)) == REG
308218334Speter			 && (ind_levels == 0
308318334Speter			     || reg_equiv_address[REGNO (XEXP (operand, 0))] != 0)))
308418334Speter		  win = 1;
308518334Speter		break;
308618334Speter
308718334Speter		/* Memory operand whose address is offsettable.  */
308818334Speter	      case 'o':
308918334Speter		if (force_reload)
309018334Speter		  break;
309118334Speter		if ((GET_CODE (operand) == MEM
309218334Speter		     /* If IND_LEVELS, find_reloads_address won't reload a
309318334Speter			pseudo that didn't get a hard reg, so we have to
309418334Speter			reject that case.  */
309552557Sobrien		     && ((ind_levels ? offsettable_memref_p (operand)
309652557Sobrien			  : offsettable_nonstrict_memref_p (operand))
309752557Sobrien			 /* A reloaded address is offsettable because it is now
309852557Sobrien			    just a simple register indirect.  */
309952557Sobrien			 || address_reloaded[i]))
310018334Speter		    || (GET_CODE (operand) == REG
310118334Speter			&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
310218334Speter			&& reg_renumber[REGNO (operand)] < 0
310318334Speter			/* If reg_equiv_address is nonzero, we will be
310418334Speter			   loading it into a register; hence it will be
310518334Speter			   offsettable, but we cannot say that reg_equiv_mem
310618334Speter			   is offsettable without checking.  */
310718334Speter			&& ((reg_equiv_mem[REGNO (operand)] != 0
310818334Speter			     && offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
310918334Speter			    || (reg_equiv_address[REGNO (operand)] != 0))))
311018334Speter		  win = 1;
311150605Sobrien		/* force_const_mem does not accept HIGH.  */
311250605Sobrien		if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
311350605Sobrien		    || GET_CODE (operand) == MEM)
311418334Speter		  badop = 0;
311518334Speter		constmemok = 1;
311618334Speter		offmemok = 1;
311718334Speter		break;
311818334Speter
311918334Speter	      case '&':
312018334Speter		/* Output operand that is stored before the need for the
312118334Speter		   input operands (and their index registers) is over.  */
312218334Speter		earlyclobber = 1, this_earlyclobber = 1;
312318334Speter		break;
312418334Speter
312518334Speter	      case 'E':
312618334Speter#ifndef REAL_ARITHMETIC
312718334Speter		/* Match any floating double constant, but only if
312818334Speter		   we can examine the bits of it reliably.  */
312918334Speter		if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
313018334Speter		     || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
313118334Speter		    && GET_MODE (operand) != VOIDmode && ! flag_pretend_float)
313218334Speter		  break;
313318334Speter#endif
313418334Speter		if (GET_CODE (operand) == CONST_DOUBLE)
313518334Speter		  win = 1;
313618334Speter		break;
313718334Speter
313818334Speter	      case 'F':
313918334Speter		if (GET_CODE (operand) == CONST_DOUBLE)
314018334Speter		  win = 1;
314118334Speter		break;
314218334Speter
314318334Speter	      case 'G':
314418334Speter	      case 'H':
314518334Speter		if (GET_CODE (operand) == CONST_DOUBLE
314618334Speter		    && CONST_DOUBLE_OK_FOR_LETTER_P (operand, c))
314718334Speter		  win = 1;
314818334Speter		break;
314918334Speter
315018334Speter	      case 's':
315118334Speter		if (GET_CODE (operand) == CONST_INT
315218334Speter		    || (GET_CODE (operand) == CONST_DOUBLE
315318334Speter			&& GET_MODE (operand) == VOIDmode))
315418334Speter		  break;
315518334Speter	      case 'i':
315618334Speter		if (CONSTANT_P (operand)
315718334Speter#ifdef LEGITIMATE_PIC_OPERAND_P
315818334Speter		    && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (operand))
315918334Speter#endif
316018334Speter		    )
316118334Speter		  win = 1;
316218334Speter		break;
316318334Speter
316418334Speter	      case 'n':
316518334Speter		if (GET_CODE (operand) == CONST_INT
316618334Speter		    || (GET_CODE (operand) == CONST_DOUBLE
316718334Speter			&& GET_MODE (operand) == VOIDmode))
316818334Speter		  win = 1;
316918334Speter		break;
317018334Speter
317118334Speter	      case 'I':
317218334Speter	      case 'J':
317318334Speter	      case 'K':
317418334Speter	      case 'L':
317518334Speter	      case 'M':
317618334Speter	      case 'N':
317718334Speter	      case 'O':
317818334Speter	      case 'P':
317918334Speter		if (GET_CODE (operand) == CONST_INT
318018334Speter		    && CONST_OK_FOR_LETTER_P (INTVAL (operand), c))
318118334Speter		  win = 1;
318218334Speter		break;
318318334Speter
318418334Speter	      case 'X':
318518334Speter		win = 1;
318618334Speter		break;
318718334Speter
318818334Speter	      case 'g':
318918334Speter		if (! force_reload
319018334Speter		    /* A PLUS is never a valid operand, but reload can make
319118334Speter		       it from a register when eliminating registers.  */
319218334Speter		    && GET_CODE (operand) != PLUS
319318334Speter		    /* A SCRATCH is not a valid operand.  */
319418334Speter		    && GET_CODE (operand) != SCRATCH
319518334Speter#ifdef LEGITIMATE_PIC_OPERAND_P
319618334Speter		    && (! CONSTANT_P (operand)
319718334Speter			|| ! flag_pic
319818334Speter			|| LEGITIMATE_PIC_OPERAND_P (operand))
319918334Speter#endif
320018334Speter		    && (GENERAL_REGS == ALL_REGS
320118334Speter			|| GET_CODE (operand) != REG
320218334Speter			|| (REGNO (operand) >= FIRST_PSEUDO_REGISTER
320318334Speter			    && reg_renumber[REGNO (operand)] < 0)))
320418334Speter		  win = 1;
320518334Speter		/* Drop through into 'r' case */
320618334Speter
320718334Speter	      case 'r':
320818334Speter		this_alternative[i]
320918334Speter		  = (int) reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS];
321018334Speter		goto reg;
321118334Speter
321218334Speter#ifdef EXTRA_CONSTRAINT
321318334Speter              case 'Q':
321418334Speter              case 'R':
321518334Speter              case 'S':
321618334Speter              case 'T':
321718334Speter              case 'U':
321818334Speter		if (EXTRA_CONSTRAINT (operand, c))
321918334Speter		  win = 1;
322018334Speter		break;
322118334Speter#endif
322218334Speter
322318334Speter	      default:
322418334Speter		this_alternative[i]
322518334Speter		  = (int) reg_class_subunion[this_alternative[i]][(int) REG_CLASS_FROM_LETTER (c)];
322618334Speter
322718334Speter	      reg:
322818334Speter		if (GET_MODE (operand) == BLKmode)
322918334Speter		  break;
323018334Speter		winreg = 1;
323118334Speter		if (GET_CODE (operand) == REG
323218334Speter		    && reg_fits_class_p (operand, this_alternative[i],
323318334Speter					 offset, GET_MODE (recog_operand[i])))
323418334Speter		  win = 1;
323518334Speter		break;
323618334Speter	      }
323718334Speter
323818334Speter	  constraints[i] = p;
323918334Speter
324018334Speter	  /* If this operand could be handled with a reg,
324118334Speter	     and some reg is allowed, then this operand can be handled.  */
324218334Speter	  if (winreg && this_alternative[i] != (int) NO_REGS)
324318334Speter	    badop = 0;
324418334Speter
324518334Speter	  /* Record which operands fit this alternative.  */
324618334Speter	  this_alternative_earlyclobber[i] = earlyclobber;
324718334Speter	  if (win && ! force_reload)
324818334Speter	    this_alternative_win[i] = 1;
324918334Speter	  else
325018334Speter	    {
325118334Speter	      int const_to_mem = 0;
325218334Speter
325318334Speter	      this_alternative_offmemok[i] = offmemok;
325418334Speter	      losers++;
325518334Speter	      if (badop)
325618334Speter		bad = 1;
325718334Speter	      /* Alternative loses if it has no regs for a reg operand.  */
325818334Speter	      if (GET_CODE (operand) == REG
325918334Speter		  && this_alternative[i] == (int) NO_REGS
326018334Speter		  && this_alternative_matches[i] < 0)
326118334Speter		bad = 1;
326218334Speter
326350605Sobrien#if 0
326450605Sobrien	      /* If this is a pseudo-register that is set in the previous
326550605Sobrien		 insns, there's a good chance that it will already be in a
326650605Sobrien		 spill register and we can use that spill register.  So
326750605Sobrien		 make this case cheaper.
326818334Speter
326950605Sobrien		 Disabled for egcs.  egcs has better inheritance code and
327050605Sobrien		 this change causes problems with the improved reload
327150605Sobrien		 inheritance code.  */
327250605Sobrien	      if (GET_CODE (operand) == REG
327350605Sobrien		  && REGNO (operand) >= FIRST_PSEUDO_REGISTER
327450605Sobrien		  && REGNO (operand) == last_output_reload_regno)
327550605Sobrien		reject--;
327650605Sobrien#endif
327750605Sobrien
327818334Speter	      /* If this is a constant that is reloaded into the desired
327918334Speter		 class by copying it to memory first, count that as another
328018334Speter		 reload.  This is consistent with other code and is
328118334Speter		 required to avoid choosing another alternative when
328218334Speter		 the constant is moved into memory by this function on
328318334Speter		 an early reload pass.  Note that the test here is
328418334Speter		 precisely the same as in the code below that calls
328518334Speter		 force_const_mem.  */
328618334Speter	      if (CONSTANT_P (operand)
328718334Speter		  /* force_const_mem does not accept HIGH.  */
328818334Speter		  && GET_CODE (operand) != HIGH
328950605Sobrien		  && ((PREFERRED_RELOAD_CLASS (operand,
329018334Speter					      (enum reg_class) this_alternative[i])
329150605Sobrien		       == NO_REGS)
329250605Sobrien		      || no_input_reloads)
329318334Speter		  && operand_mode[i] != VOIDmode)
329418334Speter		{
329518334Speter		  const_to_mem = 1;
329618334Speter		  if (this_alternative[i] != (int) NO_REGS)
329718334Speter		    losers++;
329818334Speter		}
329918334Speter
330018334Speter	      /* If we can't reload this value at all, reject this
330118334Speter		 alternative.  Note that we could also lose due to
330218334Speter		 LIMIT_RELOAD_RELOAD_CLASS, but we don't check that
330318334Speter		 here.  */
330418334Speter
330518334Speter	      if (! CONSTANT_P (operand)
330618334Speter		  && (enum reg_class) this_alternative[i] != NO_REGS
330718334Speter		  && (PREFERRED_RELOAD_CLASS (operand,
330818334Speter					      (enum reg_class) this_alternative[i])
330918334Speter		      == NO_REGS))
331018334Speter		bad = 1;
331118334Speter
331250605Sobrien	      /* Alternative loses if it requires a type of reload not
331350605Sobrien		 permitted for this insn.  We can always reload SCRATCH
331450605Sobrien		 and objects with a REG_UNUSED note.  */
331550605Sobrien	      else if (GET_CODE (operand) != SCRATCH
331650605Sobrien		  && modified[i] != RELOAD_READ && no_output_reloads
331750605Sobrien		  && ! find_reg_note (insn, REG_UNUSED, operand))
331850605Sobrien		bad = 1;
331950605Sobrien	      else if (modified[i] != RELOAD_WRITE && no_input_reloads
332050605Sobrien		       && ! const_to_mem)
332150605Sobrien		bad = 1;
332250605Sobrien
332350605Sobrien
332418334Speter	      /* We prefer to reload pseudos over reloading other things,
332518334Speter		 since such reloads may be able to be eliminated later.
332618334Speter		 If we are reloading a SCRATCH, we won't be generating any
332718334Speter		 insns, just using a register, so it is also preferred.
332818334Speter		 So bump REJECT in other cases.  Don't do this in the
332918334Speter		 case where we are forcing a constant into memory and
333018334Speter		 it will then win since we don't want to have a different
333118334Speter		 alternative match then.  */
333218334Speter	      if (! (GET_CODE (operand) == REG
333318334Speter		     && REGNO (operand) >= FIRST_PSEUDO_REGISTER)
333418334Speter		  && GET_CODE (operand) != SCRATCH
333518334Speter		  && ! (const_to_mem && constmemok))
333650605Sobrien		reject += 2;
333750605Sobrien
333850605Sobrien	      /* Input reloads can be inherited more often than output
333950605Sobrien		 reloads can be removed, so penalize output reloads.  */
334050605Sobrien	      if (operand_type[i] != RELOAD_FOR_INPUT
334150605Sobrien		  && GET_CODE (operand) != SCRATCH)
334218334Speter		reject++;
334318334Speter	    }
334418334Speter
334518334Speter	  /* If this operand is a pseudo register that didn't get a hard
334618334Speter	     reg and this alternative accepts some register, see if the
334718334Speter	     class that we want is a subset of the preferred class for this
334818334Speter	     register.  If not, but it intersects that class, use the
334918334Speter	     preferred class instead.  If it does not intersect the preferred
335018334Speter	     class, show that usage of this alternative should be discouraged;
335118334Speter	     it will be discouraged more still if the register is `preferred
335218334Speter	     or nothing'.  We do this because it increases the chance of
335318334Speter	     reusing our spill register in a later insn and avoiding a pair
335418334Speter	     of memory stores and loads.
335518334Speter
335618334Speter	     Don't bother with this if this alternative will accept this
335718334Speter	     operand.
335818334Speter
335918334Speter	     Don't do this for a multiword operand, since it is only a
336018334Speter	     small win and has the risk of requiring more spill registers,
336118334Speter	     which could cause a large loss.
336218334Speter
336318334Speter	     Don't do this if the preferred class has only one register
336418334Speter	     because we might otherwise exhaust the class.  */
336518334Speter
336618334Speter
336718334Speter	  if (! win && this_alternative[i] != (int) NO_REGS
336818334Speter	      && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
336918334Speter	      && reg_class_size[(int) preferred_class[i]] > 1)
337018334Speter	    {
337118334Speter	      if (! reg_class_subset_p (this_alternative[i],
337218334Speter					preferred_class[i]))
337318334Speter		{
337418334Speter		  /* Since we don't have a way of forming the intersection,
337518334Speter		     we just do something special if the preferred class
337618334Speter		     is a subset of the class we have; that's the most
337718334Speter		     common case anyway.  */
337818334Speter		  if (reg_class_subset_p (preferred_class[i],
337918334Speter					  this_alternative[i]))
338018334Speter		    this_alternative[i] = (int) preferred_class[i];
338118334Speter		  else
338250605Sobrien		    reject += (2 + 2 * pref_or_nothing[i]);
338318334Speter		}
338418334Speter	    }
338518334Speter	}
338618334Speter
338718334Speter      /* Now see if any output operands that are marked "earlyclobber"
338818334Speter	 in this alternative conflict with any input operands
338918334Speter	 or any memory addresses.  */
339018334Speter
339118334Speter      for (i = 0; i < noperands; i++)
339218334Speter	if (this_alternative_earlyclobber[i]
339318334Speter	    && this_alternative_win[i])
339418334Speter	  {
339518334Speter	    struct decomposition early_data;
339618334Speter
339718334Speter	    early_data = decompose (recog_operand[i]);
339818334Speter
339918334Speter	    if (modified[i] == RELOAD_READ)
340052557Sobrien	      abort ();
340118334Speter
340218334Speter	    if (this_alternative[i] == NO_REGS)
340318334Speter	      {
340418334Speter		this_alternative_earlyclobber[i] = 0;
340518334Speter		if (this_insn_is_asm)
340618334Speter		  error_for_asm (this_insn,
340718334Speter				 "`&' constraint used with no register class");
340818334Speter		else
340918334Speter		  abort ();
341018334Speter	      }
341118334Speter
341218334Speter	    for (j = 0; j < noperands; j++)
341318334Speter	      /* Is this an input operand or a memory ref?  */
341418334Speter	      if ((GET_CODE (recog_operand[j]) == MEM
341518334Speter		   || modified[j] != RELOAD_WRITE)
341618334Speter		  && j != i
341718334Speter		  /* Ignore things like match_operator operands.  */
341852557Sobrien		  && *recog_constraints[j] != 0
341918334Speter		  /* Don't count an input operand that is constrained to match
342018334Speter		     the early clobber operand.  */
342118334Speter		  && ! (this_alternative_matches[j] == i
342218334Speter			&& rtx_equal_p (recog_operand[i], recog_operand[j]))
342318334Speter		  /* Is it altered by storing the earlyclobber operand?  */
342418334Speter		  && !immune_p (recog_operand[j], recog_operand[i], early_data))
342518334Speter		{
342618334Speter		  /* If the output is in a single-reg class,
342718334Speter		     it's costly to reload it, so reload the input instead.  */
342818334Speter		  if (reg_class_size[this_alternative[i]] == 1
342918334Speter		      && (GET_CODE (recog_operand[j]) == REG
343018334Speter			  || GET_CODE (recog_operand[j]) == SUBREG))
343118334Speter		    {
343218334Speter		      losers++;
343318334Speter		      this_alternative_win[j] = 0;
343418334Speter		    }
343518334Speter		  else
343618334Speter		    break;
343718334Speter		}
343818334Speter	    /* If an earlyclobber operand conflicts with something,
343918334Speter	       it must be reloaded, so request this and count the cost.  */
344018334Speter	    if (j != noperands)
344118334Speter	      {
344218334Speter		losers++;
344318334Speter		this_alternative_win[i] = 0;
344418334Speter		for (j = 0; j < noperands; j++)
344518334Speter		  if (this_alternative_matches[j] == i
344618334Speter		      && this_alternative_win[j])
344718334Speter		    {
344818334Speter		      this_alternative_win[j] = 0;
344918334Speter		      losers++;
345018334Speter		    }
345118334Speter	      }
345218334Speter	  }
345318334Speter
345418334Speter      /* If one alternative accepts all the operands, no reload required,
345518334Speter	 choose that alternative; don't consider the remaining ones.  */
345618334Speter      if (losers == 0)
345718334Speter	{
345818334Speter	  /* Unswap these so that they are never swapped at `finish'.  */
345918334Speter	  if (commutative >= 0)
346018334Speter	    {
346118334Speter	      recog_operand[commutative] = substed_operand[commutative];
346218334Speter	      recog_operand[commutative + 1]
346318334Speter		= substed_operand[commutative + 1];
346418334Speter	    }
346518334Speter	  for (i = 0; i < noperands; i++)
346618334Speter	    {
346718334Speter	      goal_alternative_win[i] = 1;
346818334Speter	      goal_alternative[i] = this_alternative[i];
346918334Speter	      goal_alternative_offmemok[i] = this_alternative_offmemok[i];
347018334Speter	      goal_alternative_matches[i] = this_alternative_matches[i];
347118334Speter	      goal_alternative_earlyclobber[i]
347218334Speter		= this_alternative_earlyclobber[i];
347318334Speter	    }
347418334Speter	  goal_alternative_number = this_alternative_number;
347518334Speter	  goal_alternative_swapped = swapped;
347618334Speter	  goal_earlyclobber = this_earlyclobber;
347718334Speter	  goto finish;
347818334Speter	}
347918334Speter
348018334Speter      /* REJECT, set by the ! and ? constraint characters and when a register
348118334Speter	 would be reloaded into a non-preferred class, discourages the use of
348250605Sobrien	 this alternative for a reload goal.  REJECT is incremented by six
348350605Sobrien	 for each ? and two for each non-preferred class.  */
348450605Sobrien      losers = losers * 6 + reject;
348518334Speter
348618334Speter      /* If this alternative can be made to work by reloading,
348718334Speter	 and it needs less reloading than the others checked so far,
348818334Speter	 record it as the chosen goal for reloading.  */
348918334Speter      if (! bad && best > losers)
349018334Speter	{
349118334Speter	  for (i = 0; i < noperands; i++)
349218334Speter	    {
349318334Speter	      goal_alternative[i] = this_alternative[i];
349418334Speter	      goal_alternative_win[i] = this_alternative_win[i];
349518334Speter	      goal_alternative_offmemok[i] = this_alternative_offmemok[i];
349618334Speter	      goal_alternative_matches[i] = this_alternative_matches[i];
349718334Speter	      goal_alternative_earlyclobber[i]
349818334Speter		= this_alternative_earlyclobber[i];
349918334Speter	    }
350018334Speter	  goal_alternative_swapped = swapped;
350118334Speter	  best = losers;
350218334Speter	  goal_alternative_number = this_alternative_number;
350318334Speter	  goal_earlyclobber = this_earlyclobber;
350418334Speter	}
350518334Speter    }
350618334Speter
350718334Speter  /* If insn is commutative (it's safe to exchange a certain pair of operands)
350818334Speter     then we need to try each alternative twice,
350918334Speter     the second time matching those two operands
351018334Speter     as if we had exchanged them.
351118334Speter     To do this, really exchange them in operands.
351218334Speter
351318334Speter     If we have just tried the alternatives the second time,
351418334Speter     return operands to normal and drop through.  */
351518334Speter
351618334Speter  if (commutative >= 0)
351718334Speter    {
351818334Speter      swapped = !swapped;
351918334Speter      if (swapped)
352018334Speter	{
352118334Speter	  register enum reg_class tclass;
352218334Speter	  register int t;
352318334Speter
352418334Speter	  recog_operand[commutative] = substed_operand[commutative + 1];
352518334Speter	  recog_operand[commutative + 1] = substed_operand[commutative];
352618334Speter
352718334Speter	  tclass = preferred_class[commutative];
352818334Speter	  preferred_class[commutative] = preferred_class[commutative + 1];
352918334Speter	  preferred_class[commutative + 1] = tclass;
353018334Speter
353118334Speter	  t = pref_or_nothing[commutative];
353218334Speter	  pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
353318334Speter	  pref_or_nothing[commutative + 1] = t;
353418334Speter
353552557Sobrien	  bcopy ((char *) recog_constraints, (char *) constraints,
353618334Speter		 noperands * sizeof (char *));
353718334Speter	  goto try_swapped;
353818334Speter	}
353918334Speter      else
354018334Speter	{
354118334Speter	  recog_operand[commutative] = substed_operand[commutative];
354218334Speter	  recog_operand[commutative + 1] = substed_operand[commutative + 1];
354318334Speter	}
354418334Speter    }
354518334Speter
354618334Speter  /* The operands don't meet the constraints.
354718334Speter     goal_alternative describes the alternative
354818334Speter     that we could reach by reloading the fewest operands.
354918334Speter     Reload so as to fit it.  */
355018334Speter
355150605Sobrien  if (best == MAX_RECOG_OPERANDS * 2 + 600)
355218334Speter    {
355318334Speter      /* No alternative works with reloads??  */
355418334Speter      if (insn_code_number >= 0)
355552557Sobrien	fatal_insn ("Unable to generate reloads for:", insn);
355618334Speter      error_for_asm (insn, "inconsistent operand constraints in an `asm'");
355718334Speter      /* Avoid further trouble with this insn.  */
355850605Sobrien      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
355918334Speter      n_reloads = 0;
356052557Sobrien      return 0;
356118334Speter    }
356218334Speter
356318334Speter  /* Jump to `finish' from above if all operands are valid already.
356418334Speter     In that case, goal_alternative_win is all 1.  */
356518334Speter finish:
356618334Speter
356718334Speter  /* Right now, for any pair of operands I and J that are required to match,
356818334Speter     with I < J,
356918334Speter     goal_alternative_matches[J] is I.
357018334Speter     Set up goal_alternative_matched as the inverse function:
357118334Speter     goal_alternative_matched[I] = J.  */
357218334Speter
357318334Speter  for (i = 0; i < noperands; i++)
357418334Speter    goal_alternative_matched[i] = -1;
357518334Speter
357618334Speter  for (i = 0; i < noperands; i++)
357718334Speter    if (! goal_alternative_win[i]
357818334Speter	&& goal_alternative_matches[i] >= 0)
357918334Speter      goal_alternative_matched[goal_alternative_matches[i]] = i;
358018334Speter
358118334Speter  /* If the best alternative is with operands 1 and 2 swapped,
358218334Speter     consider them swapped before reporting the reloads.  Update the
358318334Speter     operand numbers of any reloads already pushed.  */
358418334Speter
358518334Speter  if (goal_alternative_swapped)
358618334Speter    {
358718334Speter      register rtx tem;
358818334Speter
358918334Speter      tem = substed_operand[commutative];
359018334Speter      substed_operand[commutative] = substed_operand[commutative + 1];
359118334Speter      substed_operand[commutative + 1] = tem;
359218334Speter      tem = recog_operand[commutative];
359318334Speter      recog_operand[commutative] = recog_operand[commutative + 1];
359418334Speter      recog_operand[commutative + 1] = tem;
359552557Sobrien      tem = *recog_operand_loc[commutative];
359652557Sobrien      *recog_operand_loc[commutative] = *recog_operand_loc[commutative+1];
359752557Sobrien      *recog_operand_loc[commutative+1] = tem;
359818334Speter
359918334Speter      for (i = 0; i < n_reloads; i++)
360018334Speter	{
360118334Speter	  if (reload_opnum[i] == commutative)
360218334Speter	    reload_opnum[i] = commutative + 1;
360318334Speter	  else if (reload_opnum[i] == commutative + 1)
360418334Speter	    reload_opnum[i] = commutative;
360518334Speter	}
360618334Speter    }
360718334Speter
360818334Speter  for (i = 0; i < noperands; i++)
360918334Speter    {
361018334Speter      operand_reloadnum[i] = -1;
361118334Speter
361218334Speter      /* If this is an earlyclobber operand, we need to widen the scope.
361318334Speter	 The reload must remain valid from the start of the insn being
361418334Speter	 reloaded until after the operand is stored into its destination.
361518334Speter	 We approximate this with RELOAD_OTHER even though we know that we
361618334Speter	 do not conflict with RELOAD_FOR_INPUT_ADDRESS reloads.
361718334Speter
361818334Speter	 One special case that is worth checking is when we have an
361918334Speter	 output that is earlyclobber but isn't used past the insn (typically
362018334Speter	 a SCRATCH).  In this case, we only need have the reload live
362118334Speter	 through the insn itself, but not for any of our input or output
362218334Speter	 reloads.
362350605Sobrien	 But we must not accidentally narrow the scope of an existing
362450605Sobrien	 RELOAD_OTHER reload - leave these alone.
362518334Speter
362618334Speter	 In any case, anything needed to address this operand can remain
362718334Speter	 however they were previously categorized.  */
362818334Speter
362950605Sobrien      if (goal_alternative_earlyclobber[i] && operand_type[i] != RELOAD_OTHER)
363018334Speter	operand_type[i]
363118334Speter	  = (find_reg_note (insn, REG_UNUSED, recog_operand[i])
363218334Speter	     ? RELOAD_FOR_INSN : RELOAD_OTHER);
363318334Speter    }
363418334Speter
363518334Speter  /* Any constants that aren't allowed and can't be reloaded
363618334Speter     into registers are here changed into memory references.  */
363718334Speter  for (i = 0; i < noperands; i++)
363818334Speter    if (! goal_alternative_win[i]
363918334Speter	&& CONSTANT_P (recog_operand[i])
364018334Speter	/* force_const_mem does not accept HIGH.  */
364118334Speter	&& GET_CODE (recog_operand[i]) != HIGH
364250605Sobrien	&& ((PREFERRED_RELOAD_CLASS (recog_operand[i],
364318334Speter				    (enum reg_class) goal_alternative[i])
364450605Sobrien	     == NO_REGS)
364550605Sobrien	    || no_input_reloads)
364618334Speter	&& operand_mode[i] != VOIDmode)
364718334Speter      {
364852557Sobrien	substed_operand[i] = recog_operand[i]
364918334Speter	  = find_reloads_toplev (force_const_mem (operand_mode[i],
365018334Speter						  recog_operand[i]),
365152557Sobrien				 i, address_type[i], ind_levels, 0, insn);
365252557Sobrien	if (alternative_allows_memconst (recog_constraints[i],
365318334Speter					 goal_alternative_number))
365418334Speter	  goal_alternative_win[i] = 1;
365518334Speter      }
365618334Speter
365718334Speter  /* Record the values of the earlyclobber operands for the caller.  */
365818334Speter  if (goal_earlyclobber)
365918334Speter    for (i = 0; i < noperands; i++)
366018334Speter      if (goal_alternative_earlyclobber[i])
366118334Speter	reload_earlyclobbers[n_earlyclobbers++] = recog_operand[i];
366218334Speter
366318334Speter  /* Now record reloads for all the operands that need them.  */
366450605Sobrien  last_output_reload_regno = -1;
366518334Speter  for (i = 0; i < noperands; i++)
366618334Speter    if (! goal_alternative_win[i])
366718334Speter      {
366818334Speter	/* Operands that match previous ones have already been handled.  */
366918334Speter	if (goal_alternative_matches[i] >= 0)
367018334Speter	  ;
367118334Speter	/* Handle an operand with a nonoffsettable address
367218334Speter	   appearing where an offsettable address will do
367318334Speter	   by reloading the address into a base register.
367418334Speter
367518334Speter	   ??? We can also do this when the operand is a register and
367618334Speter	   reg_equiv_mem is not offsettable, but this is a bit tricky,
367718334Speter	   so we don't bother with it.  It may not be worth doing.  */
367818334Speter	else if (goal_alternative_matched[i] == -1
367918334Speter		 && goal_alternative_offmemok[i]
368018334Speter		 && GET_CODE (recog_operand[i]) == MEM)
368118334Speter	  {
368218334Speter	    operand_reloadnum[i]
368318334Speter	      = push_reload (XEXP (recog_operand[i], 0), NULL_RTX,
368418334Speter			     &XEXP (recog_operand[i], 0), NULL_PTR,
368518334Speter			     BASE_REG_CLASS, GET_MODE (XEXP (recog_operand[i], 0)),
368618334Speter			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
368718334Speter	    reload_inc[operand_reloadnum[i]]
368818334Speter	      = GET_MODE_SIZE (GET_MODE (recog_operand[i]));
368918334Speter
369018334Speter	    /* If this operand is an output, we will have made any
369118334Speter	       reloads for its address as RELOAD_FOR_OUTPUT_ADDRESS, but
369218334Speter	       now we are treating part of the operand as an input, so
369318334Speter	       we must change these to RELOAD_FOR_INPUT_ADDRESS.  */
369418334Speter
369518334Speter	    if (modified[i] == RELOAD_WRITE)
369650605Sobrien	      {
369750605Sobrien		for (j = 0; j < n_reloads; j++)
369850605Sobrien		  {
369950605Sobrien		    if (reload_opnum[j] == i)
370050605Sobrien		      {
370150605Sobrien			if (reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS)
370250605Sobrien			  reload_when_needed[j] = RELOAD_FOR_INPUT_ADDRESS;
370350605Sobrien			else if (reload_when_needed[j]
370450605Sobrien				 == RELOAD_FOR_OUTADDR_ADDRESS)
370550605Sobrien			  reload_when_needed[j] = RELOAD_FOR_INPADDR_ADDRESS;
370650605Sobrien		      }
370750605Sobrien		  }
370850605Sobrien	      }
370918334Speter	  }
371018334Speter	else if (goal_alternative_matched[i] == -1)
371150605Sobrien	  {
371250605Sobrien	    operand_reloadnum[i]
371350605Sobrien	      = push_reload ((modified[i] != RELOAD_WRITE
371450605Sobrien			      ? recog_operand[i] : 0),
371550605Sobrien			     modified[i] != RELOAD_READ ? recog_operand[i] : 0,
371650605Sobrien			     (modified[i] != RELOAD_WRITE
371750605Sobrien			      ? recog_operand_loc[i] : 0),
371850605Sobrien			     (modified[i] != RELOAD_READ
371950605Sobrien			      ? recog_operand_loc[i] : 0),
372050605Sobrien			     (enum reg_class) goal_alternative[i],
372150605Sobrien			     (modified[i] == RELOAD_WRITE
372250605Sobrien			      ? VOIDmode : operand_mode[i]),
372350605Sobrien			     (modified[i] == RELOAD_READ
372450605Sobrien			      ? VOIDmode : operand_mode[i]),
372550605Sobrien			     (insn_code_number < 0 ? 0
372650605Sobrien			      : insn_operand_strict_low[insn_code_number][i]),
372750605Sobrien			     0, i, operand_type[i]);
372850605Sobrien	    if (modified[i] != RELOAD_READ
372950605Sobrien		&& GET_CODE (recog_operand[i]) == REG)
373050605Sobrien	      last_output_reload_regno = REGNO (recog_operand[i]);
373150605Sobrien	  }
373218334Speter	/* In a matching pair of operands, one must be input only
373318334Speter	   and the other must be output only.
373418334Speter	   Pass the input operand as IN and the other as OUT.  */
373518334Speter	else if (modified[i] == RELOAD_READ
373618334Speter		 && modified[goal_alternative_matched[i]] == RELOAD_WRITE)
373718334Speter	  {
373818334Speter	    operand_reloadnum[i]
373918334Speter	      = push_reload (recog_operand[i],
374018334Speter			     recog_operand[goal_alternative_matched[i]],
374118334Speter			     recog_operand_loc[i],
374218334Speter			     recog_operand_loc[goal_alternative_matched[i]],
374318334Speter			     (enum reg_class) goal_alternative[i],
374418334Speter			     operand_mode[i],
374518334Speter			     operand_mode[goal_alternative_matched[i]],
374618334Speter			     0, 0, i, RELOAD_OTHER);
374718334Speter	    operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
374850605Sobrien	    if (GET_CODE (recog_operand[goal_alternative_matched[i]]) == REG)
374950605Sobrien	      last_output_reload_regno
375050605Sobrien		= REGNO (recog_operand[goal_alternative_matched[i]]);
375118334Speter	  }
375218334Speter	else if (modified[i] == RELOAD_WRITE
375318334Speter		 && modified[goal_alternative_matched[i]] == RELOAD_READ)
375418334Speter	  {
375518334Speter	    operand_reloadnum[goal_alternative_matched[i]]
375618334Speter	      = push_reload (recog_operand[goal_alternative_matched[i]],
375718334Speter			     recog_operand[i],
375818334Speter			     recog_operand_loc[goal_alternative_matched[i]],
375918334Speter			     recog_operand_loc[i],
376018334Speter			     (enum reg_class) goal_alternative[i],
376118334Speter			     operand_mode[goal_alternative_matched[i]],
376218334Speter			     operand_mode[i],
376318334Speter			     0, 0, i, RELOAD_OTHER);
376418334Speter	    operand_reloadnum[i] = output_reloadnum;
376550605Sobrien	    if (GET_CODE (recog_operand[i]) == REG)
376650605Sobrien	      last_output_reload_regno = REGNO (recog_operand[i]);
376718334Speter	  }
376818334Speter	else if (insn_code_number >= 0)
376918334Speter	  abort ();
377018334Speter	else
377118334Speter	  {
377218334Speter	    error_for_asm (insn, "inconsistent operand constraints in an `asm'");
377318334Speter	    /* Avoid further trouble with this insn.  */
377450605Sobrien	    PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
377518334Speter	    n_reloads = 0;
377652557Sobrien	    return 0;
377718334Speter	  }
377818334Speter      }
377918334Speter    else if (goal_alternative_matched[i] < 0
378018334Speter	     && goal_alternative_matches[i] < 0
378118334Speter	     && optimize)
378218334Speter      {
378318334Speter	/* For each non-matching operand that's a MEM or a pseudo-register
378418334Speter	   that didn't get a hard register, make an optional reload.
378518334Speter	   This may get done even if the insn needs no reloads otherwise.  */
378618334Speter
378718334Speter	rtx operand = recog_operand[i];
378818334Speter
378918334Speter	while (GET_CODE (operand) == SUBREG)
379018334Speter	  operand = XEXP (operand, 0);
379118334Speter	if ((GET_CODE (operand) == MEM
379218334Speter	     || (GET_CODE (operand) == REG
379318334Speter		 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
379452557Sobrien	    /* If this is only for an output, the optional reload would not
379552557Sobrien	       actually cause us to use a register now, just note that
379652557Sobrien	       something is stored here.  */
379752557Sobrien	    && ((enum reg_class) goal_alternative[i] != NO_REGS
379852557Sobrien		|| modified[i] == RELOAD_WRITE)
379918334Speter	    && ! no_input_reloads
380052557Sobrien	    /* An optional output reload might allow to delete INSN later.
380152557Sobrien	       We mustn't make in-out reloads on insns that are not permitted
380252557Sobrien	       output reloads.
380352557Sobrien	       If this is an asm, we can't delete it; we must not even call
380452557Sobrien	       push_reload for an optional output reload in this case,
380552557Sobrien	       because we can't be sure that the constraint allows a register,
380652557Sobrien	       and push_reload verifies the constraints for asms.  */
380718334Speter	    && (modified[i] == RELOAD_READ
380852557Sobrien		|| (! no_output_reloads && ! this_insn_is_asm)))
380918334Speter	  operand_reloadnum[i]
381018334Speter	    = push_reload (modified[i] != RELOAD_WRITE ? recog_operand[i] : 0,
381118334Speter			   modified[i] != RELOAD_READ ? recog_operand[i] : 0,
381218334Speter			   (modified[i] != RELOAD_WRITE
381318334Speter			    ? recog_operand_loc[i] : 0),
381418334Speter			   (modified[i] != RELOAD_READ
381518334Speter			    ? recog_operand_loc[i] : 0),
381618334Speter			   (enum reg_class) goal_alternative[i],
381718334Speter			   (modified[i] == RELOAD_WRITE
381818334Speter			    ? VOIDmode : operand_mode[i]),
381918334Speter			   (modified[i] == RELOAD_READ
382018334Speter			    ? VOIDmode : operand_mode[i]),
382118334Speter			   (insn_code_number < 0 ? 0
382218334Speter			    : insn_operand_strict_low[insn_code_number][i]),
382318334Speter			   1, i, operand_type[i]);
382452557Sobrien	/* If a memory reference remains (either as a MEM or a pseudo that
382552557Sobrien	   did not get a hard register), yet we can't make an optional
382652557Sobrien	   reload, check if this is actually a pseudo register reference;
382752557Sobrien	   we then need to emit a USE and/or a CLOBBER so that reload
382852557Sobrien	   inheritance will do the right thing.  */
382952557Sobrien	else if (replace
383052557Sobrien		 && (GET_CODE (operand) == MEM
383152557Sobrien		     || (GET_CODE (operand) == REG
383252557Sobrien			 && REGNO (operand) >= FIRST_PSEUDO_REGISTER
383352557Sobrien			 && reg_renumber [REGNO (operand)] < 0)))
383452557Sobrien	  {
383552557Sobrien	    operand = *recog_operand_loc[i];
383652557Sobrien
383752557Sobrien	    while (GET_CODE (operand) == SUBREG)
383852557Sobrien	      operand = XEXP (operand, 0);
383952557Sobrien	    if (GET_CODE (operand) == REG)
384052557Sobrien	      {
384152557Sobrien		if (modified[i] != RELOAD_WRITE)
384252557Sobrien		  emit_insn_before (gen_rtx_USE (VOIDmode, operand), insn);
384352557Sobrien		if (modified[i] != RELOAD_READ)
384452557Sobrien		  emit_insn_after (gen_rtx_CLOBBER (VOIDmode, operand), insn);
384552557Sobrien	      }
384652557Sobrien	  }
384718334Speter      }
384818334Speter    else if (goal_alternative_matches[i] >= 0
384918334Speter	     && goal_alternative_win[goal_alternative_matches[i]]
385018334Speter	     && modified[i] == RELOAD_READ
385118334Speter	     && modified[goal_alternative_matches[i]] == RELOAD_WRITE
385218334Speter	     && ! no_input_reloads && ! no_output_reloads
385318334Speter	     && optimize)
385418334Speter      {
385518334Speter	/* Similarly, make an optional reload for a pair of matching
385618334Speter	   objects that are in MEM or a pseudo that didn't get a hard reg.  */
385718334Speter
385818334Speter	rtx operand = recog_operand[i];
385918334Speter
386018334Speter	while (GET_CODE (operand) == SUBREG)
386118334Speter	  operand = XEXP (operand, 0);
386218334Speter	if ((GET_CODE (operand) == MEM
386318334Speter	     || (GET_CODE (operand) == REG
386418334Speter		 && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
386518334Speter	    && ((enum reg_class) goal_alternative[goal_alternative_matches[i]]
386618334Speter		!= NO_REGS))
386718334Speter	  operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]]
386818334Speter	    = push_reload (recog_operand[goal_alternative_matches[i]],
386918334Speter			   recog_operand[i],
387018334Speter			   recog_operand_loc[goal_alternative_matches[i]],
387118334Speter			   recog_operand_loc[i],
387218334Speter			   (enum reg_class) goal_alternative[goal_alternative_matches[i]],
387318334Speter			   operand_mode[goal_alternative_matches[i]],
387418334Speter			   operand_mode[i],
387518334Speter			   0, 1, goal_alternative_matches[i], RELOAD_OTHER);
387618334Speter      }
387718334Speter
387852557Sobrien  /* Perform whatever substitutions on the operands we are supposed
387952557Sobrien     to make due to commutativity or replacement of registers
388052557Sobrien     with equivalent constants or memory slots.  */
388152557Sobrien
388252557Sobrien  for (i = 0; i < noperands; i++)
388352557Sobrien    {
388452557Sobrien      /* We only do this on the last pass through reload, because it is
388552557Sobrien       possible for some data (like reg_equiv_address) to be changed during
388652557Sobrien       later passes.  Moreover, we loose the opportunity to get a useful
388752557Sobrien       reload_{in,out}_reg when we do these replacements.  */
388852557Sobrien
388952557Sobrien      if (replace)
389052557Sobrien	{
389152557Sobrien	  rtx substitution = substed_operand[i];
389252557Sobrien
389352557Sobrien	  *recog_operand_loc[i] = substitution;
389452557Sobrien
389552557Sobrien	  /* If we're replacing an operand with a LABEL_REF, we need
389652557Sobrien	     to make sure that there's a REG_LABEL note attached to
389752557Sobrien	     this instruction.  */
389852557Sobrien	  if (GET_CODE (insn) != JUMP_INSN
389952557Sobrien	      && GET_CODE (substitution) == LABEL_REF
390052557Sobrien	      && !find_reg_note (insn, REG_LABEL, XEXP (substitution, 0)))
390152557Sobrien	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL,
390252557Sobrien						  XEXP (substitution, 0),
390352557Sobrien						  REG_NOTES (insn));
390452557Sobrien	}
390552557Sobrien      else
390652557Sobrien	retval |= (substed_operand[i] != *recog_operand_loc[i]);
390752557Sobrien    }
390852557Sobrien
390918334Speter  /* If this insn pattern contains any MATCH_DUP's, make sure that
391018334Speter     they will be substituted if the operands they match are substituted.
391118334Speter     Also do now any substitutions we already did on the operands.
391218334Speter
391318334Speter     Don't do this if we aren't making replacements because we might be
391418334Speter     propagating things allocated by frame pointer elimination into places
391518334Speter     it doesn't expect.  */
391618334Speter
391718334Speter  if (insn_code_number >= 0 && replace)
391818334Speter    for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
391918334Speter      {
392018334Speter	int opno = recog_dup_num[i];
392118334Speter	*recog_dup_loc[i] = *recog_operand_loc[opno];
392218334Speter	if (operand_reloadnum[opno] >= 0)
392318334Speter	  push_replacement (recog_dup_loc[i], operand_reloadnum[opno],
392418334Speter			    insn_operand_mode[insn_code_number][opno]);
392518334Speter      }
392618334Speter
392718334Speter#if 0
392818334Speter  /* This loses because reloading of prior insns can invalidate the equivalence
392918334Speter     (or at least find_equiv_reg isn't smart enough to find it any more),
393018334Speter     causing this insn to need more reload regs than it needed before.
393118334Speter     It may be too late to make the reload regs available.
393218334Speter     Now this optimization is done safely in choose_reload_regs.  */
393318334Speter
393418334Speter  /* For each reload of a reg into some other class of reg,
393518334Speter     search for an existing equivalent reg (same value now) in the right class.
393618334Speter     We can use it as long as we don't need to change its contents.  */
393718334Speter  for (i = 0; i < n_reloads; i++)
393818334Speter    if (reload_reg_rtx[i] == 0
393918334Speter	&& reload_in[i] != 0
394018334Speter	&& GET_CODE (reload_in[i]) == REG
394118334Speter	&& reload_out[i] == 0)
394218334Speter      {
394318334Speter	reload_reg_rtx[i]
394418334Speter	  = find_equiv_reg (reload_in[i], insn, reload_reg_class[i], -1,
394518334Speter			    static_reload_reg_p, 0, reload_inmode[i]);
394618334Speter	/* Prevent generation of insn to load the value
394718334Speter	   because the one we found already has the value.  */
394818334Speter	if (reload_reg_rtx[i])
394918334Speter	  reload_in[i] = reload_reg_rtx[i];
395018334Speter      }
395118334Speter#endif
395218334Speter
395318334Speter  /* Perhaps an output reload can be combined with another
395418334Speter     to reduce needs by one.  */
395518334Speter  if (!goal_earlyclobber)
395618334Speter    combine_reloads ();
395718334Speter
395818334Speter  /* If we have a pair of reloads for parts of an address, they are reloading
395918334Speter     the same object, the operands themselves were not reloaded, and they
396018334Speter     are for two operands that are supposed to match, merge the reloads and
396150605Sobrien     change the type of the surviving reload to RELOAD_FOR_OPERAND_ADDRESS.  */
396218334Speter
396318334Speter  for (i = 0; i < n_reloads; i++)
396418334Speter    {
396518334Speter      int k;
396618334Speter
396718334Speter      for (j = i + 1; j < n_reloads; j++)
396818334Speter	if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
396950605Sobrien	     || reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
397050605Sobrien	     || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
397150605Sobrien	     || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
397218334Speter	    && (reload_when_needed[j] == RELOAD_FOR_INPUT_ADDRESS
397350605Sobrien		|| reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS
397450605Sobrien		|| reload_when_needed[j] == RELOAD_FOR_INPADDR_ADDRESS
397550605Sobrien		|| reload_when_needed[j] == RELOAD_FOR_OUTADDR_ADDRESS)
397618334Speter	    && rtx_equal_p (reload_in[i], reload_in[j])
397718334Speter	    && (operand_reloadnum[reload_opnum[i]] < 0
397818334Speter		|| reload_optional[operand_reloadnum[reload_opnum[i]]])
397918334Speter	    && (operand_reloadnum[reload_opnum[j]] < 0
398018334Speter		|| reload_optional[operand_reloadnum[reload_opnum[j]]])
398118334Speter	    && (goal_alternative_matches[reload_opnum[i]] == reload_opnum[j]
398218334Speter		|| (goal_alternative_matches[reload_opnum[j]]
398318334Speter		    == reload_opnum[i])))
398418334Speter	  {
398518334Speter	    for (k = 0; k < n_replacements; k++)
398618334Speter	      if (replacements[k].what == j)
398718334Speter		replacements[k].what = i;
398818334Speter
398950605Sobrien	    if (reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
399050605Sobrien		|| reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
399150605Sobrien	      reload_when_needed[i] = RELOAD_FOR_OPADDR_ADDR;
399250605Sobrien	    else
399350605Sobrien	      reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
399418334Speter	    reload_in[j] = 0;
399518334Speter	  }
399618334Speter    }
399718334Speter
399818334Speter  /* Scan all the reloads and update their type.
399918334Speter     If a reload is for the address of an operand and we didn't reload
400018334Speter     that operand, change the type.  Similarly, change the operand number
400118334Speter     of a reload when two operands match.  If a reload is optional, treat it
400218334Speter     as though the operand isn't reloaded.
400318334Speter
400418334Speter     ??? This latter case is somewhat odd because if we do the optional
400518334Speter     reload, it means the object is hanging around.  Thus we need only
400618334Speter     do the address reload if the optional reload was NOT done.
400718334Speter
400818334Speter     Change secondary reloads to be the address type of their operand, not
400918334Speter     the normal type.
401018334Speter
401118334Speter     If an operand's reload is now RELOAD_OTHER, change any
401218334Speter     RELOAD_FOR_INPUT_ADDRESS reloads of that operand to
401318334Speter     RELOAD_FOR_OTHER_ADDRESS.  */
401418334Speter
401518334Speter  for (i = 0; i < n_reloads; i++)
401618334Speter    {
401718334Speter      if (reload_secondary_p[i]
401818334Speter	  && reload_when_needed[i] == operand_type[reload_opnum[i]])
401918334Speter	reload_when_needed[i] = address_type[reload_opnum[i]];
402018334Speter
402118334Speter      if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
402250605Sobrien	   || reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
402350605Sobrien	   || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
402450605Sobrien	   || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
402518334Speter	  && (operand_reloadnum[reload_opnum[i]] < 0
402618334Speter	      || reload_optional[operand_reloadnum[reload_opnum[i]]]))
402718334Speter	{
402818334Speter	  /* If we have a secondary reload to go along with this reload,
402950605Sobrien	     change its type to RELOAD_FOR_OPADDR_ADDR.  */
403018334Speter
403150605Sobrien	  if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
403250605Sobrien	       || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
403318334Speter	      && reload_secondary_in_reload[i] != -1)
403418334Speter	    {
403518334Speter	      int secondary_in_reload = reload_secondary_in_reload[i];
403618334Speter
403750605Sobrien	      reload_when_needed[secondary_in_reload]
403850605Sobrien		= RELOAD_FOR_OPADDR_ADDR;
403918334Speter
404050605Sobrien	      /* If there's a tertiary reload we have to change it also.  */
404118334Speter	      if (secondary_in_reload > 0
404218334Speter		  && reload_secondary_in_reload[secondary_in_reload] != -1)
404318334Speter		reload_when_needed[reload_secondary_in_reload[secondary_in_reload]]
404418334Speter		  = RELOAD_FOR_OPADDR_ADDR;
404518334Speter	    }
404618334Speter
404750605Sobrien	  if ((reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
404850605Sobrien	       || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
404918334Speter	      && reload_secondary_out_reload[i] != -1)
405018334Speter	    {
405118334Speter	      int secondary_out_reload = reload_secondary_out_reload[i];
405218334Speter
405350605Sobrien	      reload_when_needed[secondary_out_reload]
405450605Sobrien		= RELOAD_FOR_OPADDR_ADDR;
405518334Speter
405650605Sobrien	      /* If there's a tertiary reload we have to change it also.  */
405718334Speter	      if (secondary_out_reload
405818334Speter		  && reload_secondary_out_reload[secondary_out_reload] != -1)
405918334Speter		reload_when_needed[reload_secondary_out_reload[secondary_out_reload]]
406018334Speter		  = RELOAD_FOR_OPADDR_ADDR;
406118334Speter	    }
406250605Sobrien
406352557Sobrien	  if (reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
406452557Sobrien	      || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
406552557Sobrien	    reload_when_needed[i] = RELOAD_FOR_OPADDR_ADDR;
406652557Sobrien	  else
406752557Sobrien	    reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
406818334Speter	}
406918334Speter
407050605Sobrien      if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
407150605Sobrien	   || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
407218334Speter	  && operand_reloadnum[reload_opnum[i]] >= 0
407318334Speter	  && (reload_when_needed[operand_reloadnum[reload_opnum[i]]]
407418334Speter	      == RELOAD_OTHER))
407518334Speter	reload_when_needed[i] = RELOAD_FOR_OTHER_ADDRESS;
407618334Speter
407718334Speter      if (goal_alternative_matches[reload_opnum[i]] >= 0)
407818334Speter	reload_opnum[i] = goal_alternative_matches[reload_opnum[i]];
407918334Speter    }
408018334Speter
408150605Sobrien  /* Scan all the reloads, and check for RELOAD_FOR_OPERAND_ADDRESS reloads.
408250605Sobrien     If we have more than one, then convert all RELOAD_FOR_OPADDR_ADDR
408350605Sobrien     reloads to RELOAD_FOR_OPERAND_ADDRESS reloads.
408450605Sobrien
408550605Sobrien     choose_reload_regs assumes that RELOAD_FOR_OPADDR_ADDR reloads never
408650605Sobrien     conflict with RELOAD_FOR_OPERAND_ADDRESS reloads.  This is true for a
408750605Sobrien     single pair of RELOAD_FOR_OPADDR_ADDR/RELOAD_FOR_OPERAND_ADDRESS reloads.
408850605Sobrien     However, if there is more than one RELOAD_FOR_OPERAND_ADDRESS reload,
408950605Sobrien     then a RELOAD_FOR_OPADDR_ADDR reload conflicts with all
409050605Sobrien     RELOAD_FOR_OPERAND_ADDRESS reloads other than the one that uses it.
409150605Sobrien     This is complicated by the fact that a single operand can have more
409250605Sobrien     than one RELOAD_FOR_OPERAND_ADDRESS reload.  It is very difficult to fix
409350605Sobrien     choose_reload_regs without affecting code quality, and cases that
409450605Sobrien     actually fail are extremely rare, so it turns out to be better to fix
409550605Sobrien     the problem here by not generating cases that choose_reload_regs will
409650605Sobrien     fail for.  */
409752557Sobrien  /* There is a similar problem with RELOAD_FOR_INPUT_ADDRESS /
409850605Sobrien     RELOAD_FOR_OUTPUT_ADDRESS when there is more than one of a kind for
409950605Sobrien     a single operand.
410050605Sobrien     We can reduce the register pressure by exploiting that a
410150605Sobrien     RELOAD_FOR_X_ADDR_ADDR that precedes all RELOAD_FOR_X_ADDRESS reloads
410252557Sobrien     does not conflict with any of them, if it is only used for the first of
410352557Sobrien     the RELOAD_FOR_X_ADDRESS reloads.  */
410450605Sobrien  {
410550605Sobrien    int first_op_addr_num = -2;
410650605Sobrien    int first_inpaddr_num[MAX_RECOG_OPERANDS];
410750605Sobrien    int first_outpaddr_num[MAX_RECOG_OPERANDS];
410850605Sobrien    int need_change= 0;
410950605Sobrien    /* We use last_op_addr_reload and the contents of the above arrays
411050605Sobrien       first as flags - -2 means no instance encountered, -1 means exactly
411150605Sobrien       one instance encountered.
411250605Sobrien       If more than one instance has been encountered, we store the reload
411350605Sobrien       number of the first reload of the kind in question; reload numbers
411450605Sobrien       are known to be non-negative.  */
411550605Sobrien    for (i = 0; i < noperands; i++)
411650605Sobrien      first_inpaddr_num[i] = first_outpaddr_num[i] = -2;
411750605Sobrien    for (i = n_reloads - 1; i >= 0; i--)
411850605Sobrien      {
411950605Sobrien	switch (reload_when_needed[i])
412050605Sobrien	  {
412150605Sobrien	  case RELOAD_FOR_OPERAND_ADDRESS:
412252557Sobrien	    if (++first_op_addr_num >= 0)
412350605Sobrien	      {
412452557Sobrien		first_op_addr_num = i;
412550605Sobrien		need_change = 1;
412650605Sobrien	      }
412750605Sobrien	    break;
412850605Sobrien	  case RELOAD_FOR_INPUT_ADDRESS:
412952557Sobrien	    if (++first_inpaddr_num[reload_opnum[i]] >= 0)
413050605Sobrien	      {
413150605Sobrien		first_inpaddr_num[reload_opnum[i]] = i;
413250605Sobrien		need_change = 1;
413350605Sobrien	      }
413450605Sobrien	    break;
413550605Sobrien	  case RELOAD_FOR_OUTPUT_ADDRESS:
413652557Sobrien	    if (++first_outpaddr_num[reload_opnum[i]] >= 0)
413750605Sobrien	      {
413850605Sobrien		first_outpaddr_num[reload_opnum[i]] = i;
413950605Sobrien		need_change = 1;
414050605Sobrien	      }
414150605Sobrien	    break;
414250605Sobrien	  default:
414350605Sobrien	    break;
414450605Sobrien	  }
414550605Sobrien      }
414650605Sobrien
414750605Sobrien    if (need_change)
414850605Sobrien      {
414950605Sobrien	for (i = 0; i < n_reloads; i++)
415050605Sobrien	  {
415150605Sobrien	    int first_num, type;
415250605Sobrien
415350605Sobrien	    switch (reload_when_needed[i])
415450605Sobrien	      {
415550605Sobrien	      case RELOAD_FOR_OPADDR_ADDR:
415650605Sobrien		first_num = first_op_addr_num;
415750605Sobrien		type = RELOAD_FOR_OPERAND_ADDRESS;
415850605Sobrien		break;
415950605Sobrien	      case RELOAD_FOR_INPADDR_ADDRESS:
416050605Sobrien		first_num = first_inpaddr_num[reload_opnum[i]];
416150605Sobrien		type = RELOAD_FOR_INPUT_ADDRESS;
416250605Sobrien		break;
416350605Sobrien	      case RELOAD_FOR_OUTADDR_ADDRESS:
416450605Sobrien		first_num = first_outpaddr_num[reload_opnum[i]];
416550605Sobrien		type = RELOAD_FOR_OUTPUT_ADDRESS;
416650605Sobrien		break;
416750605Sobrien	      default:
416850605Sobrien		continue;
416950605Sobrien	      }
417052557Sobrien	    if (first_num < 0)
417152557Sobrien	      continue;
417252557Sobrien	    else if (i > first_num)
417350605Sobrien	      reload_when_needed[i] = type;
417452557Sobrien	    else
417552557Sobrien	      {
417652557Sobrien		/* Check if the only TYPE reload that uses reload I is
417752557Sobrien		   reload FIRST_NUM.  */
417852557Sobrien		for (j = n_reloads - 1; j > first_num; j--)
417952557Sobrien		  {
418052557Sobrien		    if (reload_when_needed[j] == type
418152557Sobrien			&& (reload_secondary_p[i]
418252557Sobrien			    ? reload_secondary_in_reload[j] == i
418352557Sobrien			    : reg_mentioned_p (reload_in[i], reload_in[j])))
418452557Sobrien		      {
418552557Sobrien			reload_when_needed[i] = type;
418652557Sobrien			break;
418752557Sobrien		      }
418852557Sobrien		  }
418952557Sobrien	      }
419050605Sobrien	  }
419150605Sobrien      }
419250605Sobrien  }
419350605Sobrien
419418334Speter  /* See if we have any reloads that are now allowed to be merged
419518334Speter     because we've changed when the reload is needed to
419618334Speter     RELOAD_FOR_OPERAND_ADDRESS or RELOAD_FOR_OTHER_ADDRESS.  Only
419718334Speter     check for the most common cases.  */
419818334Speter
419918334Speter  for (i = 0; i < n_reloads; i++)
420018334Speter    if (reload_in[i] != 0 && reload_out[i] == 0
420118334Speter	&& (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS
420250605Sobrien	    || reload_when_needed[i] == RELOAD_FOR_OPADDR_ADDR
420318334Speter	    || reload_when_needed[i] == RELOAD_FOR_OTHER_ADDRESS))
420418334Speter      for (j = 0; j < n_reloads; j++)
420518334Speter	if (i != j && reload_in[j] != 0 && reload_out[j] == 0
420618334Speter	    && reload_when_needed[j] == reload_when_needed[i]
420718334Speter	    && MATCHES (reload_in[i], reload_in[j])
420818334Speter	    && reload_reg_class[i] == reload_reg_class[j]
420918334Speter	    && !reload_nocombine[i] && !reload_nocombine[j]
421018334Speter	    && reload_reg_rtx[i] == reload_reg_rtx[j])
421118334Speter	  {
421218334Speter	    reload_opnum[i] = MIN (reload_opnum[i], reload_opnum[j]);
421318334Speter	    transfer_replacements (i, j);
421418334Speter	    reload_in[j] = 0;
421518334Speter	  }
421618334Speter
421750605Sobrien  /* Set which reloads must use registers not used in any group.  Start
421850605Sobrien     with those that conflict with a group and then include ones that
421950605Sobrien     conflict with ones that are already known to conflict with a group.  */
422050605Sobrien
422150605Sobrien  changed = 0;
422250605Sobrien  for (i = 0; i < n_reloads; i++)
422350605Sobrien    {
422450605Sobrien      enum machine_mode mode = reload_inmode[i];
422550605Sobrien      enum reg_class class = reload_reg_class[i];
422650605Sobrien      int size;
422750605Sobrien
422850605Sobrien      if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))
422950605Sobrien	mode = reload_outmode[i];
423050605Sobrien      size = CLASS_MAX_NREGS (class, mode);
423150605Sobrien
423250605Sobrien      if (size == 1)
423350605Sobrien	for (j = 0; j < n_reloads; j++)
423450605Sobrien	  if ((CLASS_MAX_NREGS (reload_reg_class[j],
423550605Sobrien				(GET_MODE_SIZE (reload_outmode[j])
423650605Sobrien				 > GET_MODE_SIZE (reload_inmode[j]))
423750605Sobrien				? reload_outmode[j] : reload_inmode[j])
423850605Sobrien	       > 1)
423950605Sobrien	      && !reload_optional[j]
424050605Sobrien	      && (reload_in[j] != 0 || reload_out[j] != 0
424150605Sobrien		  || reload_secondary_p[j])
424250605Sobrien	      && reloads_conflict (i, j)
424350605Sobrien	      && reg_classes_intersect_p (class, reload_reg_class[j]))
424450605Sobrien	    {
424550605Sobrien	      reload_nongroup[i] = 1;
424650605Sobrien	      changed = 1;
424750605Sobrien	      break;
424850605Sobrien	    }
424950605Sobrien    }
425050605Sobrien
425150605Sobrien  while (changed)
425250605Sobrien    {
425350605Sobrien      changed = 0;
425450605Sobrien
425550605Sobrien      for (i = 0; i < n_reloads; i++)
425650605Sobrien	{
425750605Sobrien	  enum machine_mode mode = reload_inmode[i];
425850605Sobrien	  enum reg_class class = reload_reg_class[i];
425950605Sobrien	  int size;
426050605Sobrien
426150605Sobrien	  if (GET_MODE_SIZE (reload_outmode[i]) > GET_MODE_SIZE (mode))
426250605Sobrien	    mode = reload_outmode[i];
426350605Sobrien	  size = CLASS_MAX_NREGS (class, mode);
426450605Sobrien
426550605Sobrien	  if (! reload_nongroup[i] && size == 1)
426650605Sobrien	    for (j = 0; j < n_reloads; j++)
426750605Sobrien	      if (reload_nongroup[j]
426850605Sobrien		  && reloads_conflict (i, j)
426950605Sobrien		  && reg_classes_intersect_p (class, reload_reg_class[j]))
427050605Sobrien		{
427150605Sobrien		  reload_nongroup[i] = 1;
427250605Sobrien		  changed = 1;
427350605Sobrien		  break;
427450605Sobrien		}
427550605Sobrien	}
427650605Sobrien    }
427750605Sobrien
427818334Speter#else /* no REGISTER_CONSTRAINTS */
427918334Speter  int noperands;
428018334Speter  int insn_code_number;
428118334Speter  int goal_earlyclobber = 0; /* Always 0, to make combine_reloads happen.  */
428218334Speter  register int i;
428318334Speter  rtx body = PATTERN (insn);
428452557Sobrien  int retval = 0;
428518334Speter
428618334Speter  n_reloads = 0;
428718334Speter  n_replacements = 0;
428818334Speter  n_earlyclobbers = 0;
428918334Speter  replace_reloads = replace;
429018334Speter  this_insn = insn;
429118334Speter
429252557Sobrien  extract_insn (insn);
429318334Speter
429452557Sobrien  noperands = reload_n_operands = recog_n_operands;
429518334Speter
429652557Sobrien  /* Return if the insn needs no reload processing.  */
429718334Speter  if (noperands == 0)
429818334Speter    return;
429918334Speter
430018334Speter  for (i = 0; i < noperands; i++)
430118334Speter    {
430218334Speter      register RTX_CODE code = GET_CODE (recog_operand[i]);
430318334Speter      int is_set_dest = GET_CODE (body) == SET && (i == 0);
430418334Speter
430518334Speter      if (insn_code_number >= 0)
430618334Speter	if (insn_operand_address_p[insn_code_number][i])
430718334Speter	  find_reloads_address (VOIDmode, NULL_PTR,
430818334Speter				recog_operand[i], recog_operand_loc[i],
430950605Sobrien				i, RELOAD_FOR_INPUT, ind_levels, insn);
431018334Speter
431118334Speter      /* In these cases, we can't tell if the operand is an input
431218334Speter	 or an output, so be conservative.  In practice it won't be
431318334Speter	 problem.  */
431418334Speter
431518334Speter      if (code == MEM)
431618334Speter	find_reloads_address (GET_MODE (recog_operand[i]),
431718334Speter			      recog_operand_loc[i],
431818334Speter			      XEXP (recog_operand[i], 0),
431918334Speter			      &XEXP (recog_operand[i], 0),
432050605Sobrien			      i, RELOAD_OTHER, ind_levels, insn);
432118334Speter      if (code == SUBREG)
432218334Speter	recog_operand[i] = *recog_operand_loc[i]
432318334Speter	  = find_reloads_toplev (recog_operand[i], i, RELOAD_OTHER,
432418334Speter				 ind_levels, is_set_dest);
432518334Speter      if (code == REG)
432618334Speter	{
432718334Speter	  register int regno = REGNO (recog_operand[i]);
432818334Speter	  if (reg_equiv_constant[regno] != 0 && !is_set_dest)
432918334Speter	    recog_operand[i] = *recog_operand_loc[i]
433018334Speter	      = reg_equiv_constant[regno];
433118334Speter#if 0 /* This might screw code in reload1.c to delete prior output-reload
433218334Speter	 that feeds this insn.  */
433318334Speter	  if (reg_equiv_mem[regno] != 0)
433418334Speter	    recog_operand[i] = *recog_operand_loc[i]
433518334Speter	      = reg_equiv_mem[regno];
433618334Speter#endif
433718334Speter	}
433818334Speter    }
433918334Speter
434018334Speter  /* Perhaps an output reload can be combined with another
434118334Speter     to reduce needs by one.  */
434218334Speter  if (!goal_earlyclobber)
434318334Speter    combine_reloads ();
434418334Speter#endif /* no REGISTER_CONSTRAINTS */
434552557Sobrien  return retval;
434618334Speter}
434718334Speter
434818334Speter/* Return 1 if alternative number ALTNUM in constraint-string CONSTRAINT
434918334Speter   accepts a memory operand with constant address.  */
435018334Speter
435118334Speterstatic int
435218334Speteralternative_allows_memconst (constraint, altnum)
435352557Sobrien     const char *constraint;
435418334Speter     int altnum;
435518334Speter{
435618334Speter  register int c;
435718334Speter  /* Skip alternatives before the one requested.  */
435818334Speter  while (altnum > 0)
435918334Speter    {
436018334Speter      while (*constraint++ != ',');
436118334Speter      altnum--;
436218334Speter    }
436318334Speter  /* Scan the requested alternative for 'm' or 'o'.
436418334Speter     If one of them is present, this alternative accepts memory constants.  */
436518334Speter  while ((c = *constraint++) && c != ',' && c != '#')
436618334Speter    if (c == 'm' || c == 'o')
436718334Speter      return 1;
436818334Speter  return 0;
436918334Speter}
437018334Speter
437118334Speter/* Scan X for memory references and scan the addresses for reloading.
437218334Speter   Also checks for references to "constant" regs that we want to eliminate
437318334Speter   and replaces them with the values they stand for.
437418334Speter   We may alter X destructively if it contains a reference to such.
437518334Speter   If X is just a constant reg, we return the equivalent value
437618334Speter   instead of X.
437718334Speter
437818334Speter   IND_LEVELS says how many levels of indirect addressing this machine
437918334Speter   supports.
438018334Speter
438118334Speter   OPNUM and TYPE identify the purpose of the reload.
438218334Speter
438318334Speter   IS_SET_DEST is true if X is the destination of a SET, which is not
438452557Sobrien   appropriate to be replaced by a constant.
438518334Speter
438652557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
438752557Sobrien   to determine if we may generate output reloads, and where to put USEs
438852557Sobrien   for pseudos that we have to replace with stack slots.  */
438952557Sobrien
439018334Speterstatic rtx
439152557Sobrienfind_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn)
439218334Speter     rtx x;
439318334Speter     int opnum;
439418334Speter     enum reload_type type;
439518334Speter     int ind_levels;
439618334Speter     int is_set_dest;
439752557Sobrien     rtx insn;
439818334Speter{
439918334Speter  register RTX_CODE code = GET_CODE (x);
440018334Speter
440118334Speter  register char *fmt = GET_RTX_FORMAT (code);
440218334Speter  register int i;
440352557Sobrien  int copied;
440418334Speter
440518334Speter  if (code == REG)
440618334Speter    {
440718334Speter      /* This code is duplicated for speed in find_reloads.  */
440818334Speter      register int regno = REGNO (x);
440918334Speter      if (reg_equiv_constant[regno] != 0 && !is_set_dest)
441018334Speter	x = reg_equiv_constant[regno];
441118334Speter#if 0
441218334Speter/*  This creates (subreg (mem...)) which would cause an unnecessary
441318334Speter    reload of the mem.  */
441418334Speter      else if (reg_equiv_mem[regno] != 0)
441518334Speter	x = reg_equiv_mem[regno];
441618334Speter#endif
441752557Sobrien      else if (reg_equiv_memory_loc[regno]
441852557Sobrien	       && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
441918334Speter	{
442052557Sobrien	  rtx mem = make_memloc (x, regno);
442152557Sobrien	  if (reg_equiv_address[regno]
442252557Sobrien	      || ! rtx_equal_p (mem, reg_equiv_mem[regno]))
442352557Sobrien	    {
442452557Sobrien	      /* If this is not a toplevel operand, find_reloads doesn't see
442552557Sobrien		 this substitution.  We have to emit a USE of the pseudo so
442652557Sobrien		 that delete_output_reload can see it.  */
442752557Sobrien	      if (replace_reloads && recog_operand[opnum] != x)
442852557Sobrien		emit_insn_before (gen_rtx_USE (VOIDmode, x), insn);
442952557Sobrien	      x = mem;
443052557Sobrien	      find_reloads_address (GET_MODE (x), &x, XEXP (x, 0), &XEXP (x, 0),
443152557Sobrien				    opnum, type, ind_levels, insn);
443252557Sobrien	    }
443318334Speter	}
443418334Speter      return x;
443518334Speter    }
443618334Speter  if (code == MEM)
443718334Speter    {
443818334Speter      rtx tem = x;
443918334Speter      find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0),
444052557Sobrien			    opnum, type, ind_levels, insn);
444118334Speter      return tem;
444218334Speter    }
444318334Speter
444418334Speter  if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)
444518334Speter    {
444618334Speter      /* Check for SUBREG containing a REG that's equivalent to a constant.
444718334Speter	 If the constant has a known value, truncate it right now.
444818334Speter	 Similarly if we are extracting a single-word of a multi-word
444918334Speter	 constant.  If the constant is symbolic, allow it to be substituted
445018334Speter	 normally.  push_reload will strip the subreg later.  If the
445118334Speter	 constant is VOIDmode, abort because we will lose the mode of
445218334Speter	 the register (this should never happen because one of the cases
445318334Speter	 above should handle it).  */
445418334Speter
445518334Speter      register int regno = REGNO (SUBREG_REG (x));
445618334Speter      rtx tem;
445718334Speter
445818334Speter      if (subreg_lowpart_p (x)
445918334Speter	  && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
446018334Speter	  && reg_equiv_constant[regno] != 0
446118334Speter	  && (tem = gen_lowpart_common (GET_MODE (x),
446218334Speter					reg_equiv_constant[regno])) != 0)
446318334Speter	return tem;
446418334Speter
446518334Speter      if (GET_MODE_BITSIZE (GET_MODE (x)) == BITS_PER_WORD
446618334Speter	  && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
446718334Speter	  && reg_equiv_constant[regno] != 0
446818334Speter	  && (tem = operand_subword (reg_equiv_constant[regno],
446918334Speter				     SUBREG_WORD (x), 0,
447018334Speter				     GET_MODE (SUBREG_REG (x)))) != 0)
447150605Sobrien	{
447250605Sobrien	  /* TEM is now a word sized constant for the bits from X that
447350605Sobrien	     we wanted.  However, TEM may be the wrong representation.
447418334Speter
447550605Sobrien	     Use gen_lowpart_common to convert a CONST_INT into a
447650605Sobrien	     CONST_DOUBLE and vice versa as needed according to by the mode
447750605Sobrien	     of the SUBREG.  */
447850605Sobrien	  tem = gen_lowpart_common (GET_MODE (x), tem);
447950605Sobrien	  if (!tem)
448050605Sobrien	    abort ();
448150605Sobrien	  return tem;
448250605Sobrien	}
448350605Sobrien
448450605Sobrien      /* If the SUBREG is wider than a word, the above test will fail.
448550605Sobrien	 For example, we might have a SImode SUBREG of a DImode SUBREG_REG
448650605Sobrien	 for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
448750605Sobrien	 a 32 bit target.  We still can - and have to - handle this
448850605Sobrien	 for non-paradoxical subregs of CONST_INTs.  */
448918334Speter      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
449018334Speter	  && reg_equiv_constant[regno] != 0
449150605Sobrien	  && GET_CODE (reg_equiv_constant[regno]) == CONST_INT
449250605Sobrien	  && (GET_MODE_SIZE (GET_MODE (x))
449350605Sobrien	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
449450605Sobrien	  {
449550605Sobrien	    int shift = SUBREG_WORD (x) * BITS_PER_WORD;
449650605Sobrien	    if (WORDS_BIG_ENDIAN)
449750605Sobrien	      shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
449850605Sobrien		       - GET_MODE_BITSIZE (GET_MODE (x))
449950605Sobrien		       - shift);
450050605Sobrien	    /* Here we use the knowledge that CONST_INTs have a
450150605Sobrien	       HOST_WIDE_INT field.  */
450250605Sobrien	    if (shift >= HOST_BITS_PER_WIDE_INT)
450350605Sobrien	      shift = HOST_BITS_PER_WIDE_INT - 1;
450450605Sobrien	    return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
450550605Sobrien	  }
450650605Sobrien
450750605Sobrien      if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
450850605Sobrien	  && reg_equiv_constant[regno] != 0
450918334Speter	  && GET_MODE (reg_equiv_constant[regno]) == VOIDmode)
451018334Speter	abort ();
451118334Speter
451218334Speter      /* If the subreg contains a reg that will be converted to a mem,
451318334Speter	 convert the subreg to a narrower memref now.
451418334Speter	 Otherwise, we would get (subreg (mem ...) ...),
451518334Speter	 which would force reload of the mem.
451618334Speter
451718334Speter	 We also need to do this if there is an equivalent MEM that is
451818334Speter	 not offsettable.  In that case, alter_subreg would produce an
451918334Speter	 invalid address on big-endian machines.
452018334Speter
452118334Speter	 For machines that extend byte loads, we must not reload using
452218334Speter	 a wider mode if we have a paradoxical SUBREG.  find_reloads will
452318334Speter	 force a reload in that case.  So we should not do anything here.  */
452418334Speter
452518334Speter      else if (regno >= FIRST_PSEUDO_REGISTER
452618334Speter#ifdef LOAD_EXTEND_OP
452718334Speter	       && (GET_MODE_SIZE (GET_MODE (x))
452818334Speter		   <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
452918334Speter#endif
453018334Speter	       && (reg_equiv_address[regno] != 0
453118334Speter		   || (reg_equiv_mem[regno] != 0
453218334Speter		       && (! strict_memory_address_p (GET_MODE (x),
453318334Speter						      XEXP (reg_equiv_mem[regno], 0))
453452557Sobrien			   || ! offsettable_memref_p (reg_equiv_mem[regno])
453552557Sobrien			   || num_not_at_initial_offset))))
453652557Sobrien	x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
453752557Sobrien					 insn);
453852557Sobrien    }
453952557Sobrien
454052557Sobrien  for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
454152557Sobrien    {
454252557Sobrien      if (fmt[i] == 'e')
454318334Speter	{
454452557Sobrien	  rtx new_part = find_reloads_toplev (XEXP (x, i), opnum, type,
454552557Sobrien					      ind_levels, is_set_dest, insn);
454652557Sobrien	  /* If we have replaced a reg with it's equivalent memory loc -
454752557Sobrien	     that can still be handled here e.g. if it's in a paradoxical
454852557Sobrien	     subreg - we must make the change in a copy, rather than using
454952557Sobrien	     a destructive change.  This way, find_reloads can still elect
455052557Sobrien	     not to do the change.  */
455152557Sobrien	  if (new_part != XEXP (x, i) && ! CONSTANT_P (new_part) && ! copied)
455218334Speter	    {
455352557Sobrien	      x = shallow_copy_rtx (x);
455452557Sobrien	      copied = 1;
455518334Speter	    }
455652557Sobrien	  XEXP (x, i) = new_part;
455718334Speter	}
455818334Speter    }
455918334Speter  return x;
456018334Speter}
456118334Speter
456218334Speter/* Return a mem ref for the memory equivalent of reg REGNO.
456318334Speter   This mem ref is not shared with anything.  */
456418334Speter
456518334Speterstatic rtx
456618334Spetermake_memloc (ad, regno)
456718334Speter     rtx ad;
456818334Speter     int regno;
456918334Speter{
457018334Speter  /* We must rerun eliminate_regs, in case the elimination
457118334Speter     offsets have changed.  */
457252557Sobrien  rtx tem
457352557Sobrien    = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0, NULL_RTX), 0);
457418334Speter
457518334Speter  /* If TEM might contain a pseudo, we must copy it to avoid
457618334Speter     modifying it when we do the substitution for the reload.  */
457718334Speter  if (rtx_varies_p (tem))
457818334Speter    tem = copy_rtx (tem);
457918334Speter
458050605Sobrien  tem = gen_rtx_MEM (GET_MODE (ad), tem);
458118334Speter  RTX_UNCHANGING_P (tem) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
458218334Speter  return tem;
458318334Speter}
458418334Speter
458518334Speter/* Record all reloads needed for handling memory address AD
458618334Speter   which appears in *LOC in a memory reference to mode MODE
458718334Speter   which itself is found in location  *MEMREFLOC.
458818334Speter   Note that we take shortcuts assuming that no multi-reg machine mode
458918334Speter   occurs as part of an address.
459018334Speter
459118334Speter   OPNUM and TYPE specify the purpose of this reload.
459218334Speter
459318334Speter   IND_LEVELS says how many levels of indirect addressing this machine
459418334Speter   supports.
459518334Speter
459650605Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
459752557Sobrien   to determine if we may generate output reloads, and where to put USEs
459852557Sobrien   for pseudos that we have to replace with stack slots.
459950605Sobrien
460018334Speter   Value is nonzero if this address is reloaded or replaced as a whole.
460118334Speter   This is interesting to the caller if the address is an autoincrement.
460218334Speter
460318334Speter   Note that there is no verification that the address will be valid after
460418334Speter   this routine does its work.  Instead, we rely on the fact that the address
460518334Speter   was valid when reload started.  So we need only undo things that reload
460618334Speter   could have broken.  These are wrong register types, pseudos not allocated
460718334Speter   to a hard register, and frame pointer elimination.  */
460818334Speter
460918334Speterstatic int
461050605Sobrienfind_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
461118334Speter     enum machine_mode mode;
461218334Speter     rtx *memrefloc;
461318334Speter     rtx ad;
461418334Speter     rtx *loc;
461518334Speter     int opnum;
461618334Speter     enum reload_type type;
461718334Speter     int ind_levels;
461850605Sobrien     rtx insn;
461918334Speter{
462018334Speter  register int regno;
462152557Sobrien  int removed_and = 0;
462218334Speter  rtx tem;
462318334Speter
462418334Speter  /* If the address is a register, see if it is a legitimate address and
462518334Speter     reload if not.  We first handle the cases where we need not reload
462618334Speter     or where we must reload in a non-standard way.  */
462718334Speter
462818334Speter  if (GET_CODE (ad) == REG)
462918334Speter    {
463018334Speter      regno = REGNO (ad);
463118334Speter
463218334Speter      if (reg_equiv_constant[regno] != 0
463318334Speter	  && strict_memory_address_p (mode, reg_equiv_constant[regno]))
463418334Speter	{
463518334Speter	  *loc = ad = reg_equiv_constant[regno];
463652557Sobrien	  return 0;
463718334Speter	}
463818334Speter
463952557Sobrien      tem = reg_equiv_memory_loc[regno];
464052557Sobrien      if (tem != 0)
464118334Speter	{
464252557Sobrien	  if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
464352557Sobrien	    {
464452557Sobrien	      tem = make_memloc (ad, regno);
464552557Sobrien	      if (! strict_memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
464652557Sobrien		{
464752557Sobrien		  find_reloads_address (GET_MODE (tem), NULL_PTR, XEXP (tem, 0),
464852557Sobrien					&XEXP (tem, 0), opnum, ADDR_TYPE (type),
464952557Sobrien					ind_levels, insn);
465052557Sobrien		}
465152557Sobrien	      /* We can avoid a reload if the register's equivalent memory
465252557Sobrien		 expression is valid as an indirect memory address.
465352557Sobrien		 But not all addresses are valid in a mem used as an indirect
465452557Sobrien		 address: only reg or reg+constant.  */
465552557Sobrien
465652557Sobrien	      if (ind_levels > 0
465752557Sobrien		  && strict_memory_address_p (mode, tem)
465852557Sobrien		  && (GET_CODE (XEXP (tem, 0)) == REG
465952557Sobrien		      || (GET_CODE (XEXP (tem, 0)) == PLUS
466052557Sobrien			  && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
466152557Sobrien			  && CONSTANT_P (XEXP (XEXP (tem, 0), 1)))))
466252557Sobrien		{
466352557Sobrien		  /* TEM is not the same as what we'll be replacing the
466452557Sobrien		     pseudo with after reload, put a USE in front of INSN
466552557Sobrien		     in the final reload pass.  */
466652557Sobrien		  if (replace_reloads
466752557Sobrien		      && num_not_at_initial_offset
466852557Sobrien		      && ! rtx_equal_p (tem, reg_equiv_mem[regno]))
466952557Sobrien		    {
467052557Sobrien		      *loc = tem;
467152557Sobrien		      emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn);
467252557Sobrien		      /* This doesn't really count as replacing the address
467352557Sobrien			 as a whole, since it is still a memory access.  */
467452557Sobrien		    }
467552557Sobrien		  return 0;
467652557Sobrien		}
467752557Sobrien	      ad = tem;
467852557Sobrien	    }
467918334Speter	}
468018334Speter
468118334Speter      /* The only remaining case where we can avoid a reload is if this is a
468218334Speter	 hard register that is valid as a base register and which is not the
468318334Speter	 subject of a CLOBBER in this insn.  */
468418334Speter
468550605Sobrien      else if (regno < FIRST_PSEUDO_REGISTER
468650605Sobrien	       && REGNO_MODE_OK_FOR_BASE_P (regno, mode)
468770639Sobrien	       && ! regno_clobbered_p (regno, this_insn, GET_MODE (ad), 0))
468818334Speter	return 0;
468918334Speter
469018334Speter      /* If we do not have one of the cases above, we must do the reload.  */
469152557Sobrien      push_reload (ad, NULL_RTX, loc, NULL_PTR, BASE_REG_CLASS,
469218334Speter		   GET_MODE (ad), VOIDmode, 0, 0, opnum, type);
469318334Speter      return 1;
469418334Speter    }
469518334Speter
469618334Speter  if (strict_memory_address_p (mode, ad))
469718334Speter    {
469818334Speter      /* The address appears valid, so reloads are not needed.
469918334Speter	 But the address may contain an eliminable register.
470018334Speter	 This can happen because a machine with indirect addressing
470118334Speter	 may consider a pseudo register by itself a valid address even when
470218334Speter	 it has failed to get a hard reg.
470318334Speter	 So do a tree-walk to find and eliminate all such regs.  */
470418334Speter
470518334Speter      /* But first quickly dispose of a common case.  */
470618334Speter      if (GET_CODE (ad) == PLUS
470718334Speter	  && GET_CODE (XEXP (ad, 1)) == CONST_INT
470818334Speter	  && GET_CODE (XEXP (ad, 0)) == REG
470918334Speter	  && reg_equiv_constant[REGNO (XEXP (ad, 0))] == 0)
471018334Speter	return 0;
471118334Speter
471218334Speter      subst_reg_equivs_changed = 0;
471352557Sobrien      *loc = subst_reg_equivs (ad, insn);
471418334Speter
471518334Speter      if (! subst_reg_equivs_changed)
471618334Speter	return 0;
471718334Speter
471818334Speter      /* Check result for validity after substitution.  */
471918334Speter      if (strict_memory_address_p (mode, ad))
472018334Speter	return 0;
472118334Speter    }
472218334Speter
472350605Sobrien#ifdef LEGITIMIZE_RELOAD_ADDRESS
472450605Sobrien  do
472550605Sobrien    {
472650605Sobrien      if (memrefloc)
472750605Sobrien	{
472850605Sobrien	  LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
472950605Sobrien				     ind_levels, win);
473050605Sobrien	}
473150605Sobrien      break;
473250605Sobrien    win:
473350605Sobrien      *memrefloc = copy_rtx (*memrefloc);
473450605Sobrien      XEXP (*memrefloc, 0) = ad;
473550605Sobrien      move_replacements (&ad, &XEXP (*memrefloc, 0));
473650605Sobrien      return 1;
473750605Sobrien    }
473850605Sobrien  while (0);
473950605Sobrien#endif
474050605Sobrien
474152557Sobrien  /* The address is not valid.  We have to figure out why.  First see if
474252557Sobrien     we have an outer AND and remove it if so.  Then analyze what's inside.  */
474352557Sobrien
474452557Sobrien  if (GET_CODE (ad) == AND)
474552557Sobrien    {
474652557Sobrien      removed_and = 1;
474752557Sobrien      loc = &XEXP (ad, 0);
474852557Sobrien      ad = *loc;
474952557Sobrien    }
475052557Sobrien
475152557Sobrien  /* One possibility for why the address is invalid is that it is itself
475252557Sobrien     a MEM.  This can happen when the frame pointer is being eliminated, a
475352557Sobrien     pseudo is not allocated to a hard register, and the offset between the
475452557Sobrien     frame and stack pointers is not its initial value.  In that case the
475552557Sobrien     pseudo will have been replaced by a MEM referring to the
475652557Sobrien     stack pointer.  */
475718334Speter  if (GET_CODE (ad) == MEM)
475818334Speter    {
475918334Speter      /* First ensure that the address in this MEM is valid.  Then, unless
476018334Speter	 indirect addresses are valid, reload the MEM into a register.  */
476118334Speter      tem = ad;
476218334Speter      find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0),
476350605Sobrien			    opnum, ADDR_TYPE (type),
476450605Sobrien			    ind_levels == 0 ? 0 : ind_levels - 1, insn);
476518334Speter
476618334Speter      /* If tem was changed, then we must create a new memory reference to
476718334Speter	 hold it and store it back into memrefloc.  */
476818334Speter      if (tem != ad && memrefloc)
476918334Speter	{
477018334Speter	  *memrefloc = copy_rtx (*memrefloc);
477118334Speter	  copy_replacements (tem, XEXP (*memrefloc, 0));
477218334Speter	  loc = &XEXP (*memrefloc, 0);
477352557Sobrien	  if (removed_and)
477452557Sobrien	    loc = &XEXP (*loc, 0);
477518334Speter	}
477618334Speter
477718334Speter      /* Check similar cases as for indirect addresses as above except
477818334Speter	 that we can allow pseudos and a MEM since they should have been
477918334Speter	 taken care of above.  */
478018334Speter
478118334Speter      if (ind_levels == 0
478218334Speter	  || (GET_CODE (XEXP (tem, 0)) == SYMBOL_REF && ! indirect_symref_ok)
478318334Speter	  || GET_CODE (XEXP (tem, 0)) == MEM
478418334Speter	  || ! (GET_CODE (XEXP (tem, 0)) == REG
478518334Speter		|| (GET_CODE (XEXP (tem, 0)) == PLUS
478618334Speter		    && GET_CODE (XEXP (XEXP (tem, 0), 0)) == REG
478718334Speter		    && GET_CODE (XEXP (XEXP (tem, 0), 1)) == CONST_INT)))
478818334Speter	{
478918334Speter	  /* Must use TEM here, not AD, since it is the one that will
479018334Speter	     have any subexpressions reloaded, if needed.  */
479118334Speter	  push_reload (tem, NULL_RTX, loc, NULL_PTR,
479252557Sobrien		       BASE_REG_CLASS, GET_MODE (tem),
479350605Sobrien		       VOIDmode, 0,
479418334Speter		       0, opnum, type);
479552557Sobrien	  return ! removed_and;
479618334Speter	}
479718334Speter      else
479818334Speter	return 0;
479918334Speter    }
480018334Speter
480118334Speter  /* If we have address of a stack slot but it's not valid because the
480218334Speter     displacement is too large, compute the sum in a register.
480318334Speter     Handle all base registers here, not just fp/ap/sp, because on some
480418334Speter     targets (namely SH) we can also get too large displacements from
480518334Speter     big-endian corrections.  */
480618334Speter  else if (GET_CODE (ad) == PLUS
480718334Speter	   && GET_CODE (XEXP (ad, 0)) == REG
480818334Speter	   && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
480950605Sobrien	   && REG_MODE_OK_FOR_BASE_P (XEXP (ad, 0), mode)
481018334Speter	   && GET_CODE (XEXP (ad, 1)) == CONST_INT)
481118334Speter    {
481218334Speter      /* Unshare the MEM rtx so we can safely alter it.  */
481318334Speter      if (memrefloc)
481418334Speter	{
481518334Speter	  *memrefloc = copy_rtx (*memrefloc);
481618334Speter	  loc = &XEXP (*memrefloc, 0);
481752557Sobrien	  if (removed_and)
481852557Sobrien	    loc = &XEXP (*loc, 0);
481918334Speter	}
482052557Sobrien
482118334Speter      if (double_reg_address_ok)
482218334Speter	{
482318334Speter	  /* Unshare the sum as well.  */
482418334Speter	  *loc = ad = copy_rtx (ad);
482552557Sobrien
482618334Speter	  /* Reload the displacement into an index reg.
482718334Speter	     We assume the frame pointer or arg pointer is a base reg.  */
482818334Speter	  find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1),
482952557Sobrien				     INDEX_REG_CLASS, GET_MODE (ad), opnum,
483052557Sobrien				     type, ind_levels);
483152557Sobrien	  return 0;
483218334Speter	}
483318334Speter      else
483418334Speter	{
483518334Speter	  /* If the sum of two regs is not necessarily valid,
483618334Speter	     reload the sum into a base reg.
483718334Speter	     That will at least work.  */
483852557Sobrien	  find_reloads_address_part (ad, loc, BASE_REG_CLASS,
483950605Sobrien				     Pmode, opnum, type, ind_levels);
484018334Speter	}
484152557Sobrien      return ! removed_and;
484218334Speter    }
484318334Speter
484418334Speter  /* If we have an indexed stack slot, there are three possible reasons why
484518334Speter     it might be invalid: The index might need to be reloaded, the address
484618334Speter     might have been made by frame pointer elimination and hence have a
484718334Speter     constant out of range, or both reasons might apply.
484818334Speter
484918334Speter     We can easily check for an index needing reload, but even if that is the
485018334Speter     case, we might also have an invalid constant.  To avoid making the
485118334Speter     conservative assumption and requiring two reloads, we see if this address
485218334Speter     is valid when not interpreted strictly.  If it is, the only problem is
485318334Speter     that the index needs a reload and find_reloads_address_1 will take care
485418334Speter     of it.
485518334Speter
485618334Speter     There is still a case when we might generate an extra reload,
485718334Speter     however.  In certain cases eliminate_regs will return a MEM for a REG
485818334Speter     (see the code there for details).  In those cases, memory_address_p
485918334Speter     applied to our address will return 0 so we will think that our offset
486018334Speter     must be too large.  But it might indeed be valid and the only problem
486118334Speter     is that a MEM is present where a REG should be.  This case should be
486218334Speter     very rare and there doesn't seem to be any way to avoid it.
486318334Speter
486418334Speter     If we decide to do something here, it must be that
486518334Speter     `double_reg_address_ok' is true and that this address rtl was made by
486618334Speter     eliminate_regs.  We generate a reload of the fp/sp/ap + constant and
486718334Speter     rework the sum so that the reload register will be added to the index.
486818334Speter     This is safe because we know the address isn't shared.
486918334Speter
487018334Speter     We check for fp/ap/sp as both the first and second operand of the
487118334Speter     innermost PLUS.  */
487218334Speter
487318334Speter  else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
487418334Speter	   && GET_CODE (XEXP (ad, 0)) == PLUS
487518334Speter	   && (XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
487618334Speter#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
487718334Speter	       || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
487818334Speter#endif
487918334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
488018334Speter	       || XEXP (XEXP (ad, 0), 0) == arg_pointer_rtx
488118334Speter#endif
488218334Speter	       || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
488318334Speter	   && ! memory_address_p (mode, ad))
488418334Speter    {
488550605Sobrien      *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
488650605Sobrien				plus_constant (XEXP (XEXP (ad, 0), 0),
488750605Sobrien					       INTVAL (XEXP (ad, 1))),
488818334Speter			   XEXP (XEXP (ad, 0), 1));
488952557Sobrien      find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0), BASE_REG_CLASS,
489018334Speter				 GET_MODE (ad), opnum, type, ind_levels);
489150605Sobrien      find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
489250605Sobrien			      type, 0, insn);
489318334Speter
489452557Sobrien      return 0;
489518334Speter    }
489618334Speter
489718334Speter  else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT
489818334Speter	   && GET_CODE (XEXP (ad, 0)) == PLUS
489918334Speter	   && (XEXP (XEXP (ad, 0), 1) == frame_pointer_rtx
490018334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
490118334Speter	       || XEXP (XEXP (ad, 0), 1) == hard_frame_pointer_rtx
490218334Speter#endif
490318334Speter#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
490418334Speter	       || XEXP (XEXP (ad, 0), 1) == arg_pointer_rtx
490518334Speter#endif
490618334Speter	       || XEXP (XEXP (ad, 0), 1) == stack_pointer_rtx)
490718334Speter	   && ! memory_address_p (mode, ad))
490818334Speter    {
490950605Sobrien      *loc = ad = gen_rtx_PLUS (GET_MODE (ad),
491050605Sobrien				XEXP (XEXP (ad, 0), 0),
491150605Sobrien				plus_constant (XEXP (XEXP (ad, 0), 1),
491250605Sobrien					       INTVAL (XEXP (ad, 1))));
491352557Sobrien      find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1), BASE_REG_CLASS,
491418334Speter				 GET_MODE (ad), opnum, type, ind_levels);
491550605Sobrien      find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
491650605Sobrien			      type, 0, insn);
491718334Speter
491852557Sobrien      return 0;
491918334Speter    }
492018334Speter
492118334Speter  /* See if address becomes valid when an eliminable register
492218334Speter     in a sum is replaced.  */
492318334Speter
492418334Speter  tem = ad;
492518334Speter  if (GET_CODE (ad) == PLUS)
492618334Speter    tem = subst_indexed_address (ad);
492718334Speter  if (tem != ad && strict_memory_address_p (mode, tem))
492818334Speter    {
492918334Speter      /* Ok, we win that way.  Replace any additional eliminable
493018334Speter	 registers.  */
493118334Speter
493218334Speter      subst_reg_equivs_changed = 0;
493352557Sobrien      tem = subst_reg_equivs (tem, insn);
493418334Speter
493518334Speter      /* Make sure that didn't make the address invalid again.  */
493618334Speter
493718334Speter      if (! subst_reg_equivs_changed || strict_memory_address_p (mode, tem))
493818334Speter	{
493918334Speter	  *loc = tem;
494018334Speter	  return 0;
494118334Speter	}
494218334Speter    }
494318334Speter
494418334Speter  /* If constants aren't valid addresses, reload the constant address
494518334Speter     into a register.  */
494618334Speter  if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
494718334Speter    {
494818334Speter      /* If AD is in address in the constant pool, the MEM rtx may be shared.
494918334Speter	 Unshare it so we can safely alter it.  */
495018334Speter      if (memrefloc && GET_CODE (ad) == SYMBOL_REF
495118334Speter	  && CONSTANT_POOL_ADDRESS_P (ad))
495218334Speter	{
495318334Speter	  *memrefloc = copy_rtx (*memrefloc);
495418334Speter	  loc = &XEXP (*memrefloc, 0);
495552557Sobrien	  if (removed_and)
495652557Sobrien	    loc = &XEXP (*loc, 0);
495718334Speter	}
495818334Speter
495952557Sobrien      find_reloads_address_part (ad, loc, BASE_REG_CLASS, Pmode, opnum, type,
496018334Speter				 ind_levels);
496152557Sobrien      return ! removed_and;
496218334Speter    }
496318334Speter
496450605Sobrien  return find_reloads_address_1 (mode, ad, 0, loc, opnum, type, ind_levels,
496550605Sobrien				 insn);
496618334Speter}
496718334Speter
496818334Speter/* Find all pseudo regs appearing in AD
496918334Speter   that are eliminable in favor of equivalent values
497052557Sobrien   and do not have hard regs; replace them by their equivalents.
497152557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  We put USEs in
497252557Sobrien   front of it for pseudos that we have to replace with stack slots.  */
497318334Speter
497418334Speterstatic rtx
497552557Sobriensubst_reg_equivs (ad, insn)
497618334Speter     rtx ad;
497752557Sobrien     rtx insn;
497818334Speter{
497918334Speter  register RTX_CODE code = GET_CODE (ad);
498018334Speter  register int i;
498118334Speter  register char *fmt;
498218334Speter
498318334Speter  switch (code)
498418334Speter    {
498518334Speter    case HIGH:
498618334Speter    case CONST_INT:
498718334Speter    case CONST:
498818334Speter    case CONST_DOUBLE:
498918334Speter    case SYMBOL_REF:
499018334Speter    case LABEL_REF:
499118334Speter    case PC:
499218334Speter    case CC0:
499318334Speter      return ad;
499418334Speter
499518334Speter    case REG:
499618334Speter      {
499718334Speter	register int regno = REGNO (ad);
499818334Speter
499918334Speter	if (reg_equiv_constant[regno] != 0)
500018334Speter	  {
500118334Speter	    subst_reg_equivs_changed = 1;
500218334Speter	    return reg_equiv_constant[regno];
500318334Speter	  }
500452557Sobrien	if (reg_equiv_memory_loc[regno] && num_not_at_initial_offset)
500552557Sobrien	  {
500652557Sobrien	    rtx mem = make_memloc (ad, regno);
500752557Sobrien	    if (! rtx_equal_p (mem, reg_equiv_mem[regno]))
500852557Sobrien	      {
500952557Sobrien		subst_reg_equivs_changed = 1;
501052557Sobrien		emit_insn_before (gen_rtx_USE (VOIDmode, ad), insn);
501152557Sobrien		return mem;
501252557Sobrien	      }
501352557Sobrien	  }
501418334Speter      }
501518334Speter      return ad;
501618334Speter
501718334Speter    case PLUS:
501818334Speter      /* Quickly dispose of a common case.  */
501918334Speter      if (XEXP (ad, 0) == frame_pointer_rtx
502018334Speter	  && GET_CODE (XEXP (ad, 1)) == CONST_INT)
502118334Speter	return ad;
502250605Sobrien      break;
502350605Sobrien
502450605Sobrien    default:
502550605Sobrien      break;
502618334Speter    }
502718334Speter
502818334Speter  fmt = GET_RTX_FORMAT (code);
502918334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
503018334Speter    if (fmt[i] == 'e')
503152557Sobrien      XEXP (ad, i) = subst_reg_equivs (XEXP (ad, i), insn);
503218334Speter  return ad;
503318334Speter}
503418334Speter
503518334Speter/* Compute the sum of X and Y, making canonicalizations assumed in an
503618334Speter   address, namely: sum constant integers, surround the sum of two
503718334Speter   constants with a CONST, put the constant as the second operand, and
503818334Speter   group the constant on the outermost sum.
503918334Speter
504018334Speter   This routine assumes both inputs are already in canonical form.  */
504118334Speter
504218334Speterrtx
504318334Speterform_sum (x, y)
504418334Speter     rtx x, y;
504518334Speter{
504618334Speter  rtx tem;
504718334Speter  enum machine_mode mode = GET_MODE (x);
504818334Speter
504918334Speter  if (mode == VOIDmode)
505018334Speter    mode = GET_MODE (y);
505118334Speter
505218334Speter  if (mode == VOIDmode)
505318334Speter    mode = Pmode;
505418334Speter
505518334Speter  if (GET_CODE (x) == CONST_INT)
505618334Speter    return plus_constant (y, INTVAL (x));
505718334Speter  else if (GET_CODE (y) == CONST_INT)
505818334Speter    return plus_constant (x, INTVAL (y));
505918334Speter  else if (CONSTANT_P (x))
506018334Speter    tem = x, x = y, y = tem;
506118334Speter
506218334Speter  if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
506318334Speter    return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
506418334Speter
506518334Speter  /* Note that if the operands of Y are specified in the opposite
506618334Speter     order in the recursive calls below, infinite recursion will occur.  */
506718334Speter  if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
506818334Speter    return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
506918334Speter
507018334Speter  /* If both constant, encapsulate sum.  Otherwise, just form sum.  A
507118334Speter     constant will have been placed second.  */
507218334Speter  if (CONSTANT_P (x) && CONSTANT_P (y))
507318334Speter    {
507418334Speter      if (GET_CODE (x) == CONST)
507518334Speter	x = XEXP (x, 0);
507618334Speter      if (GET_CODE (y) == CONST)
507718334Speter	y = XEXP (y, 0);
507818334Speter
507950605Sobrien      return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y));
508018334Speter    }
508118334Speter
508250605Sobrien  return gen_rtx_PLUS (mode, x, y);
508318334Speter}
508418334Speter
508518334Speter/* If ADDR is a sum containing a pseudo register that should be
508618334Speter   replaced with a constant (from reg_equiv_constant),
508718334Speter   return the result of doing so, and also apply the associative
508818334Speter   law so that the result is more likely to be a valid address.
508918334Speter   (But it is not guaranteed to be one.)
509018334Speter
509118334Speter   Note that at most one register is replaced, even if more are
509218334Speter   replaceable.  Also, we try to put the result into a canonical form
509318334Speter   so it is more likely to be a valid address.
509418334Speter
509518334Speter   In all other cases, return ADDR.  */
509618334Speter
509718334Speterstatic rtx
509818334Spetersubst_indexed_address (addr)
509918334Speter     rtx addr;
510018334Speter{
510118334Speter  rtx op0 = 0, op1 = 0, op2 = 0;
510218334Speter  rtx tem;
510318334Speter  int regno;
510418334Speter
510518334Speter  if (GET_CODE (addr) == PLUS)
510618334Speter    {
510718334Speter      /* Try to find a register to replace.  */
510818334Speter      op0 = XEXP (addr, 0), op1 = XEXP (addr, 1), op2 = 0;
510918334Speter      if (GET_CODE (op0) == REG
511018334Speter	  && (regno = REGNO (op0)) >= FIRST_PSEUDO_REGISTER
511118334Speter	  && reg_renumber[regno] < 0
511218334Speter	  && reg_equiv_constant[regno] != 0)
511318334Speter	op0 = reg_equiv_constant[regno];
511418334Speter      else if (GET_CODE (op1) == REG
511518334Speter	  && (regno = REGNO (op1)) >= FIRST_PSEUDO_REGISTER
511618334Speter	  && reg_renumber[regno] < 0
511718334Speter	  && reg_equiv_constant[regno] != 0)
511818334Speter	op1 = reg_equiv_constant[regno];
511918334Speter      else if (GET_CODE (op0) == PLUS
512018334Speter	       && (tem = subst_indexed_address (op0)) != op0)
512118334Speter	op0 = tem;
512218334Speter      else if (GET_CODE (op1) == PLUS
512318334Speter	       && (tem = subst_indexed_address (op1)) != op1)
512418334Speter	op1 = tem;
512518334Speter      else
512618334Speter	return addr;
512718334Speter
512818334Speter      /* Pick out up to three things to add.  */
512918334Speter      if (GET_CODE (op1) == PLUS)
513018334Speter	op2 = XEXP (op1, 1), op1 = XEXP (op1, 0);
513118334Speter      else if (GET_CODE (op0) == PLUS)
513218334Speter	op2 = op1, op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
513318334Speter
513418334Speter      /* Compute the sum.  */
513518334Speter      if (op2 != 0)
513618334Speter	op1 = form_sum (op1, op2);
513718334Speter      if (op1 != 0)
513818334Speter	op0 = form_sum (op0, op1);
513918334Speter
514018334Speter      return op0;
514118334Speter    }
514218334Speter  return addr;
514318334Speter}
514418334Speter
514550605Sobrien/* Record the pseudo registers we must reload into hard registers in a
514650605Sobrien   subexpression of a would-be memory address, X referring to a value
514750605Sobrien   in mode MODE.  (This function is not called if the address we find
514850605Sobrien   is strictly valid.)
514950605Sobrien
515018334Speter   CONTEXT = 1 means we are considering regs as index regs,
515118334Speter   = 0 means we are considering them as base regs.
515218334Speter
515318334Speter   OPNUM and TYPE specify the purpose of any reloads made.
515418334Speter
515518334Speter   IND_LEVELS says how many levels of indirect addressing are
515618334Speter   supported at this point in the address.
515718334Speter
515850605Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
515950605Sobrien   to determine if we may generate output reloads.
516050605Sobrien
516118334Speter   We return nonzero if X, as a whole, is reloaded or replaced.  */
516218334Speter
516318334Speter/* Note that we take shortcuts assuming that no multi-reg machine mode
516418334Speter   occurs as part of an address.
516518334Speter   Also, this is not fully machine-customizable; it works for machines
516618334Speter   such as vaxes and 68000's and 32000's, but other possible machines
516718334Speter   could have addressing modes that this does not handle right.  */
516818334Speter
516918334Speterstatic int
517050605Sobrienfind_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
517150605Sobrien     enum machine_mode mode;
517218334Speter     rtx x;
517318334Speter     int context;
517418334Speter     rtx *loc;
517518334Speter     int opnum;
517618334Speter     enum reload_type type;
517718334Speter     int ind_levels;
517850605Sobrien     rtx insn;
517918334Speter{
518018334Speter  register RTX_CODE code = GET_CODE (x);
518118334Speter
518218334Speter  switch (code)
518318334Speter    {
518418334Speter    case PLUS:
518518334Speter      {
518618334Speter	register rtx orig_op0 = XEXP (x, 0);
518718334Speter	register rtx orig_op1 = XEXP (x, 1);
518818334Speter	register RTX_CODE code0 = GET_CODE (orig_op0);
518918334Speter	register RTX_CODE code1 = GET_CODE (orig_op1);
519018334Speter	register rtx op0 = orig_op0;
519118334Speter	register rtx op1 = orig_op1;
519218334Speter
519318334Speter	if (GET_CODE (op0) == SUBREG)
519418334Speter	  {
519518334Speter	    op0 = SUBREG_REG (op0);
519618334Speter	    code0 = GET_CODE (op0);
519718334Speter	    if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
519850605Sobrien	      op0 = gen_rtx_REG (word_mode,
519950605Sobrien				 REGNO (op0) + SUBREG_WORD (orig_op0));
520018334Speter	  }
520118334Speter
520218334Speter	if (GET_CODE (op1) == SUBREG)
520318334Speter	  {
520418334Speter	    op1 = SUBREG_REG (op1);
520518334Speter	    code1 = GET_CODE (op1);
520618334Speter	    if (code1 == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER)
520750605Sobrien	      op1 = gen_rtx_REG (GET_MODE (op1),
520850605Sobrien				 REGNO (op1) + SUBREG_WORD (orig_op1));
520918334Speter	  }
521018334Speter
521118334Speter	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
521218334Speter	    || code0 == ZERO_EXTEND || code1 == MEM)
521318334Speter	  {
521450605Sobrien	    find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
521550605Sobrien				    type, ind_levels, insn);
521650605Sobrien	    find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
521750605Sobrien				    type, ind_levels, insn);
521818334Speter	  }
521918334Speter
522018334Speter	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
522118334Speter		 || code1 == ZERO_EXTEND || code0 == MEM)
522218334Speter	  {
522350605Sobrien	    find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
522450605Sobrien				    type, ind_levels, insn);
522550605Sobrien	    find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
522650605Sobrien				    type, ind_levels, insn);
522718334Speter	  }
522818334Speter
522918334Speter	else if (code0 == CONST_INT || code0 == CONST
523018334Speter		 || code0 == SYMBOL_REF || code0 == LABEL_REF)
523150605Sobrien	  find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
523250605Sobrien				  type, ind_levels, insn);
523318334Speter
523418334Speter	else if (code1 == CONST_INT || code1 == CONST
523518334Speter		 || code1 == SYMBOL_REF || code1 == LABEL_REF)
523650605Sobrien	  find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
523750605Sobrien				  type, ind_levels, insn);
523818334Speter
523918334Speter	else if (code0 == REG && code1 == REG)
524018334Speter	  {
524118334Speter	    if (REG_OK_FOR_INDEX_P (op0)
524250605Sobrien		&& REG_MODE_OK_FOR_BASE_P (op1, mode))
524318334Speter	      return 0;
524418334Speter	    else if (REG_OK_FOR_INDEX_P (op1)
524550605Sobrien		     && REG_MODE_OK_FOR_BASE_P (op0, mode))
524618334Speter	      return 0;
524750605Sobrien	    else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
524850605Sobrien	      find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
524950605Sobrien				      type, ind_levels, insn);
525050605Sobrien	    else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
525150605Sobrien	      find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
525250605Sobrien				      type, ind_levels, insn);
525318334Speter	    else if (REG_OK_FOR_INDEX_P (op1))
525450605Sobrien	      find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
525550605Sobrien				      type, ind_levels, insn);
525618334Speter	    else if (REG_OK_FOR_INDEX_P (op0))
525750605Sobrien	      find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
525850605Sobrien				      type, ind_levels, insn);
525918334Speter	    else
526018334Speter	      {
526150605Sobrien		find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
526250605Sobrien					type, ind_levels, insn);
526350605Sobrien		find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
526450605Sobrien					type, ind_levels, insn);
526518334Speter	      }
526618334Speter	  }
526718334Speter
526818334Speter	else if (code0 == REG)
526918334Speter	  {
527050605Sobrien	    find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
527150605Sobrien				    type, ind_levels, insn);
527250605Sobrien	    find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
527350605Sobrien				    type, ind_levels, insn);
527418334Speter	  }
527518334Speter
527618334Speter	else if (code1 == REG)
527718334Speter	  {
527850605Sobrien	    find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
527950605Sobrien				    type, ind_levels, insn);
528050605Sobrien	    find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
528150605Sobrien				    type, ind_levels, insn);
528218334Speter	  }
528318334Speter      }
528418334Speter
528518334Speter      return 0;
528618334Speter
528718334Speter    case POST_INC:
528818334Speter    case POST_DEC:
528918334Speter    case PRE_INC:
529018334Speter    case PRE_DEC:
529118334Speter      if (GET_CODE (XEXP (x, 0)) == REG)
529218334Speter	{
529318334Speter	  register int regno = REGNO (XEXP (x, 0));
529418334Speter	  int value = 0;
529518334Speter	  rtx x_orig = x;
529618334Speter
529718334Speter	  /* A register that is incremented cannot be constant!  */
529818334Speter	  if (regno >= FIRST_PSEUDO_REGISTER
529918334Speter	      && reg_equiv_constant[regno] != 0)
530018334Speter	    abort ();
530118334Speter
530218334Speter	  /* Handle a register that is equivalent to a memory location
530318334Speter	     which cannot be addressed directly.  */
530452557Sobrien	  if (reg_equiv_memory_loc[regno] != 0
530552557Sobrien	      && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
530618334Speter	    {
530718334Speter	      rtx tem = make_memloc (XEXP (x, 0), regno);
530852557Sobrien	      if (reg_equiv_address[regno]
530952557Sobrien		  || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
531052557Sobrien		{
531152557Sobrien		  /* First reload the memory location's address.
531252557Sobrien		     We can't use ADDR_TYPE (type) here, because we need to
531352557Sobrien		     write back the value after reading it, hence we actually
531452557Sobrien		     need two registers.  */
531552557Sobrien		  find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
531652557Sobrien					&XEXP (tem, 0), opnum, type,
531752557Sobrien					ind_levels, insn);
531852557Sobrien		  /* Put this inside a new increment-expression.  */
531952557Sobrien		  x = gen_rtx_fmt_e (GET_CODE (x), GET_MODE (x), tem);
532052557Sobrien		  /* Proceed to reload that, as if it contained a register.  */
532152557Sobrien		}
532218334Speter	    }
532318334Speter
532418334Speter	  /* If we have a hard register that is ok as an index,
532518334Speter	     don't make a reload.  If an autoincrement of a nice register
532618334Speter	     isn't "valid", it must be that no autoincrement is "valid".
532718334Speter	     If that is true and something made an autoincrement anyway,
532818334Speter	     this must be a special context where one is allowed.
532918334Speter	     (For example, a "push" instruction.)
533018334Speter	     We can't improve this address, so leave it alone.  */
533118334Speter
533218334Speter	  /* Otherwise, reload the autoincrement into a suitable hard reg
533318334Speter	     and record how much to increment by.  */
533418334Speter
533518334Speter	  if (reg_renumber[regno] >= 0)
533618334Speter	    regno = reg_renumber[regno];
533718334Speter	  if ((regno >= FIRST_PSEUDO_REGISTER
533818334Speter	       || !(context ? REGNO_OK_FOR_INDEX_P (regno)
533950605Sobrien		    : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
534018334Speter	    {
534150605Sobrien#ifdef AUTO_INC_DEC
534218334Speter	      register rtx link;
534350605Sobrien#endif
534450605Sobrien	      int reloadnum;
534518334Speter
534650605Sobrien	      /* If we can output the register afterwards, do so, this
534750605Sobrien		 saves the extra update.
534850605Sobrien		 We can do so if we have an INSN - i.e. no JUMP_INSN nor
534950605Sobrien		 CALL_INSN - and it does not set CC0.
535050605Sobrien		 But don't do this if we cannot directly address the
535150605Sobrien		 memory location, since this will make it harder to
535250605Sobrien		 reuse address reloads, and increases register pressure.
535350605Sobrien		 Also don't do this if we can probably update x directly.  */
535452557Sobrien	      rtx equiv = (GET_CODE (XEXP (x, 0)) == MEM
535552557Sobrien			   ? XEXP (x, 0)
535652557Sobrien			   : reg_equiv_mem[regno]);
535750605Sobrien	      int icode = (int) add_optab->handlers[(int) Pmode].insn_code;
535850605Sobrien	      if (insn && GET_CODE (insn) == INSN && equiv
535952557Sobrien		  && memory_operand (equiv, GET_MODE (equiv))
536050605Sobrien#ifdef HAVE_cc0
536150605Sobrien		  && ! sets_cc0_p (PATTERN (insn))
536250605Sobrien#endif
536350605Sobrien		  && ! (icode != CODE_FOR_nothing
536450605Sobrien			&& (*insn_operand_predicate[icode][0]) (equiv, Pmode)
536550605Sobrien			&& (*insn_operand_predicate[icode][1]) (equiv, Pmode)))
536650605Sobrien		{
536770639Sobrien		  /* We use the original pseudo for loc, so that
536870639Sobrien		     emit_reload_insns() knows which pseudo this
536970639Sobrien		     reload refers to and updates the pseudo rtx, not
537070639Sobrien		     its equivalent memory location, as well as the
537170639Sobrien		     corresponding entry in reg_last_reload_reg.  */
537270639Sobrien		  loc = &XEXP (x_orig, 0);
537350605Sobrien		  x = XEXP (x, 0);
537450605Sobrien		  reloadnum
537550605Sobrien		    = push_reload (x, x, loc, loc,
537652557Sobrien				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
537750605Sobrien				    GET_MODE (x), GET_MODE (x), 0, 0,
537850605Sobrien				    opnum, RELOAD_OTHER);
537952557Sobrien
538050605Sobrien		}
538150605Sobrien	      else
538250605Sobrien		{
538350605Sobrien		  reloadnum
538450605Sobrien		    = push_reload (x, NULL_RTX, loc, NULL_PTR,
538552557Sobrien				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
538650605Sobrien				   GET_MODE (x), GET_MODE (x), 0, 0,
538750605Sobrien				   opnum, type);
538850605Sobrien		  reload_inc[reloadnum]
538950605Sobrien		    = find_inc_amount (PATTERN (this_insn), XEXP (x_orig, 0));
539050605Sobrien
539150605Sobrien		  value = 1;
539250605Sobrien		}
539318334Speter
539418334Speter#ifdef AUTO_INC_DEC
539518334Speter	      /* Update the REG_INC notes.  */
539618334Speter
539718334Speter	      for (link = REG_NOTES (this_insn);
539818334Speter		   link; link = XEXP (link, 1))
539918334Speter		if (REG_NOTE_KIND (link) == REG_INC
540018334Speter		    && REGNO (XEXP (link, 0)) == REGNO (XEXP (x_orig, 0)))
540118334Speter		  push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
540218334Speter#endif
540318334Speter	    }
540418334Speter	  return value;
540518334Speter	}
540618334Speter
540718334Speter      else if (GET_CODE (XEXP (x, 0)) == MEM)
540818334Speter	{
540918334Speter	  /* This is probably the result of a substitution, by eliminate_regs,
541018334Speter	     of an equivalent address for a pseudo that was not allocated to a
541118334Speter	     hard register.  Verify that the specified address is valid and
541218334Speter	     reload it into a register.  */
541352557Sobrien	  /* Variable `tem' might or might not be used in FIND_REG_INC_NOTE. */
541452557Sobrien	  rtx tem ATTRIBUTE_UNUSED = XEXP (x, 0);
541518334Speter	  register rtx link;
541618334Speter	  int reloadnum;
541718334Speter
541818334Speter	  /* Since we know we are going to reload this item, don't decrement
541918334Speter	     for the indirection level.
542018334Speter
542118334Speter	     Note that this is actually conservative:  it would be slightly
542218334Speter	     more efficient to use the value of SPILL_INDIRECT_LEVELS from
542318334Speter	     reload1.c here.  */
542450605Sobrien	  /* We can't use ADDR_TYPE (type) here, because we need to
542550605Sobrien	     write back the value after reading it, hence we actually
542650605Sobrien	     need two registers.  */
542718334Speter	  find_reloads_address (GET_MODE (x), &XEXP (x, 0),
542818334Speter				XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 0),
542950605Sobrien				opnum, type, ind_levels, insn);
543018334Speter
543118334Speter	  reloadnum = push_reload (x, NULL_RTX, loc, NULL_PTR,
543252557Sobrien				   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
543318334Speter				   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
543418334Speter	  reload_inc[reloadnum]
543518334Speter	    = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
543618334Speter
543718334Speter	  link = FIND_REG_INC_NOTE (this_insn, tem);
543818334Speter	  if (link != 0)
543918334Speter	    push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
544018334Speter
544118334Speter	  return 1;
544218334Speter	}
544318334Speter      return 0;
544418334Speter
544518334Speter    case MEM:
544618334Speter      /* This is probably the result of a substitution, by eliminate_regs, of
544718334Speter	 an equivalent address for a pseudo that was not allocated to a hard
544818334Speter	 register.  Verify that the specified address is valid and reload it
544918334Speter	 into a register.
545018334Speter
545118334Speter	 Since we know we are going to reload this item, don't decrement for
545218334Speter	 the indirection level.
545318334Speter
545418334Speter	 Note that this is actually conservative:  it would be slightly more
545518334Speter	 efficient to use the value of SPILL_INDIRECT_LEVELS from
545618334Speter	 reload1.c here.  */
545718334Speter
545818334Speter      find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
545950605Sobrien			    opnum, ADDR_TYPE (type), ind_levels, insn);
546018334Speter      push_reload (*loc, NULL_RTX, loc, NULL_PTR,
546152557Sobrien		   (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
546218334Speter		   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
546318334Speter      return 1;
546418334Speter
546518334Speter    case REG:
546618334Speter      {
546718334Speter	register int regno = REGNO (x);
546818334Speter
546918334Speter	if (reg_equiv_constant[regno] != 0)
547018334Speter	  {
547152557Sobrien	    find_reloads_address_part (reg_equiv_constant[regno], loc,
547252557Sobrien				       (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
547318334Speter				       GET_MODE (x), opnum, type, ind_levels);
547418334Speter	    return 1;
547518334Speter	  }
547618334Speter
547718334Speter#if 0 /* This might screw code in reload1.c to delete prior output-reload
547818334Speter	 that feeds this insn.  */
547918334Speter	if (reg_equiv_mem[regno] != 0)
548018334Speter	  {
548118334Speter	    push_reload (reg_equiv_mem[regno], NULL_RTX, loc, NULL_PTR,
548252557Sobrien			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
548318334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
548418334Speter	    return 1;
548518334Speter	  }
548618334Speter#endif
548718334Speter
548852557Sobrien	if (reg_equiv_memory_loc[regno]
548952557Sobrien	    && (reg_equiv_address[regno] != 0 || num_not_at_initial_offset))
549018334Speter	  {
549152557Sobrien	    rtx tem = make_memloc (x, regno);
549252557Sobrien	    if (reg_equiv_address[regno] != 0
549352557Sobrien		|| ! rtx_equal_p (tem, reg_equiv_mem[regno]))
549452557Sobrien	      {
549552557Sobrien		x = tem;
549652557Sobrien		find_reloads_address (GET_MODE (x), &x, XEXP (x, 0),
549752557Sobrien				      &XEXP (x, 0), opnum, ADDR_TYPE (type),
549852557Sobrien				      ind_levels, insn);
549952557Sobrien	      }
550018334Speter	  }
550118334Speter
550218334Speter	if (reg_renumber[regno] >= 0)
550318334Speter	  regno = reg_renumber[regno];
550418334Speter
550518334Speter	if ((regno >= FIRST_PSEUDO_REGISTER
550618334Speter	     || !(context ? REGNO_OK_FOR_INDEX_P (regno)
550750605Sobrien		  : REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
550818334Speter	  {
550918334Speter	    push_reload (x, NULL_RTX, loc, NULL_PTR,
551052557Sobrien			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
551118334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
551218334Speter	    return 1;
551318334Speter	  }
551418334Speter
551518334Speter	/* If a register appearing in an address is the subject of a CLOBBER
551618334Speter	   in this insn, reload it into some other register to be safe.
551718334Speter	   The CLOBBER is supposed to make the register unavailable
551818334Speter	   from before this insn to after it.  */
551970639Sobrien	if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
552018334Speter	  {
552118334Speter	    push_reload (x, NULL_RTX, loc, NULL_PTR,
552252557Sobrien			 (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
552318334Speter			 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
552418334Speter	    return 1;
552518334Speter	  }
552618334Speter      }
552718334Speter      return 0;
552818334Speter
552918334Speter    case SUBREG:
553018334Speter      if (GET_CODE (SUBREG_REG (x)) == REG)
553118334Speter	{
553218334Speter	  /* If this is a SUBREG of a hard register and the resulting register
553318334Speter	     is of the wrong class, reload the whole SUBREG.  This avoids
553418334Speter	     needless copies if SUBREG_REG is multi-word.  */
553518334Speter	  if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
553618334Speter	    {
553718334Speter	      int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
553818334Speter
553918334Speter	      if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
554050605Sobrien		     : REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
554118334Speter		{
554218334Speter		  push_reload (x, NULL_RTX, loc, NULL_PTR,
554352557Sobrien			       (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
554418334Speter			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
554518334Speter		  return 1;
554618334Speter		}
554718334Speter	    }
554818334Speter	  /* If this is a SUBREG of a pseudo-register, and the pseudo-register
554918334Speter	     is larger than the class size, then reload the whole SUBREG.  */
555018334Speter	  else
555118334Speter	    {
555252557Sobrien	      enum reg_class class = (context ? INDEX_REG_CLASS
555352557Sobrien				      : BASE_REG_CLASS);
555418334Speter	      if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
555518334Speter		  > reg_class_size[class])
555618334Speter		{
555752557Sobrien		  x = find_reloads_subreg_address (x, 0, opnum, type,
555852557Sobrien						   ind_levels, insn);
555918334Speter		  push_reload (x, NULL_RTX, loc, NULL_PTR, class,
556018334Speter			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
556118334Speter		  return 1;
556218334Speter		}
556318334Speter	    }
556418334Speter	}
556518334Speter      break;
556650605Sobrien
556750605Sobrien    default:
556850605Sobrien      break;
556918334Speter    }
557018334Speter
557118334Speter  {
557218334Speter    register char *fmt = GET_RTX_FORMAT (code);
557318334Speter    register int i;
557418334Speter
557518334Speter    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
557618334Speter      {
557718334Speter	if (fmt[i] == 'e')
557850605Sobrien	  find_reloads_address_1 (mode, XEXP (x, i), context, &XEXP (x, i),
557950605Sobrien				  opnum, type, ind_levels, insn);
558018334Speter      }
558118334Speter  }
558218334Speter
558318334Speter  return 0;
558418334Speter}
558518334Speter
558618334Speter/* X, which is found at *LOC, is a part of an address that needs to be
558718334Speter   reloaded into a register of class CLASS.  If X is a constant, or if
558818334Speter   X is a PLUS that contains a constant, check that the constant is a
558918334Speter   legitimate operand and that we are supposed to be able to load
559018334Speter   it into the register.
559118334Speter
559218334Speter   If not, force the constant into memory and reload the MEM instead.
559318334Speter
559418334Speter   MODE is the mode to use, in case X is an integer constant.
559518334Speter
559618334Speter   OPNUM and TYPE describe the purpose of any reloads made.
559718334Speter
559818334Speter   IND_LEVELS says how many levels of indirect addressing this machine
559918334Speter   supports.  */
560018334Speter
560118334Speterstatic void
560218334Speterfind_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
560318334Speter     rtx x;
560418334Speter     rtx *loc;
560518334Speter     enum reg_class class;
560618334Speter     enum machine_mode mode;
560718334Speter     int opnum;
560818334Speter     enum reload_type type;
560918334Speter     int ind_levels;
561018334Speter{
561118334Speter  if (CONSTANT_P (x)
561218334Speter      && (! LEGITIMATE_CONSTANT_P (x)
561318334Speter	  || PREFERRED_RELOAD_CLASS (x, class) == NO_REGS))
561418334Speter    {
561552557Sobrien      rtx tem;
561652557Sobrien
561752557Sobrien      /* If this is a CONST_INT, it could have been created by a
561852557Sobrien	 plus_constant call in eliminate_regs, which means it may be
561952557Sobrien	 on the reload_obstack.  reload_obstack will be freed later, so
562052557Sobrien	 we can't allow such RTL to be put in the constant pool.  There
562152557Sobrien	 is code in force_const_mem to check for this case, but it doesn't
562252557Sobrien	 work because we have already popped off the reload_obstack, so
562352557Sobrien	 rtl_obstack == saveable_obstack is true at this point.  */
562452557Sobrien      if (GET_CODE (x) == CONST_INT)
562552557Sobrien	tem = x = force_const_mem (mode, GEN_INT (INTVAL (x)));
562652557Sobrien      else
562752557Sobrien	tem = x = force_const_mem (mode, x);
562852557Sobrien
562918334Speter      find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
563050605Sobrien			    opnum, type, ind_levels, 0);
563118334Speter    }
563218334Speter
563318334Speter  else if (GET_CODE (x) == PLUS
563418334Speter	   && CONSTANT_P (XEXP (x, 1))
563518334Speter	   && (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
563618334Speter	       || PREFERRED_RELOAD_CLASS (XEXP (x, 1), class) == NO_REGS))
563718334Speter    {
563852557Sobrien      rtx tem;
563918334Speter
564052557Sobrien      /* See comment above.  */
564152557Sobrien      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
564252557Sobrien	tem = force_const_mem (GET_MODE (x), GEN_INT (INTVAL (XEXP (x, 1))));
564352557Sobrien      else
564452557Sobrien	tem = force_const_mem (GET_MODE (x), XEXP (x, 1));
564552557Sobrien
564650605Sobrien      x = gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), tem);
564718334Speter      find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
564850605Sobrien			    opnum, type, ind_levels, 0);
564918334Speter    }
565018334Speter
565118334Speter  push_reload (x, NULL_RTX, loc, NULL_PTR, class,
565218334Speter	       mode, VOIDmode, 0, 0, opnum, type);
565318334Speter}
565418334Speter
565552557Sobrien/* X, a subreg of a pseudo, is a part of an address that needs to be
565652557Sobrien   reloaded.
565752557Sobrien
565852557Sobrien   If the pseudo is equivalent to a memory location that cannot be directly
565952557Sobrien   addressed, make the necessary address reloads.
566052557Sobrien
566152557Sobrien   If address reloads have been necessary, or if the address is changed
566252557Sobrien   by register elimination, return the rtx of the memory location;
566352557Sobrien   otherwise, return X.
566452557Sobrien
566552557Sobrien   If FORCE_REPLACE is nonzero, unconditionally replace the subreg with the
566652557Sobrien   memory location.
566752557Sobrien
566852557Sobrien   OPNUM and TYPE identify the purpose of the reload.
566952557Sobrien
567052557Sobrien   IND_LEVELS says how many levels of indirect addressing are
567152557Sobrien   supported at this point in the address.
567252557Sobrien
567352557Sobrien   INSN, if nonzero, is the insn in which we do the reload.  It is used
567452557Sobrien   to determine where to put USEs for pseudos that we have to replace with
567552557Sobrien   stack slots.  */
567652557Sobrien
567752557Sobrienstatic rtx
567852557Sobrienfind_reloads_subreg_address (x, force_replace, opnum, type,
567952557Sobrien			     ind_levels, insn)
568052557Sobrien     rtx x;
568152557Sobrien     int force_replace;
568252557Sobrien     int opnum;
568352557Sobrien     enum reload_type type;
568452557Sobrien     int ind_levels;
568552557Sobrien     rtx insn;
568652557Sobrien{
568752557Sobrien  int regno = REGNO (SUBREG_REG (x));
568852557Sobrien
568952557Sobrien  if (reg_equiv_memory_loc[regno])
569052557Sobrien    {
569152557Sobrien      /* If the address is not directly addressable, or if the address is not
569252557Sobrien	 offsettable, then it must be replaced.  */
569352557Sobrien      if (! force_replace
569452557Sobrien	  && (reg_equiv_address[regno]
569552557Sobrien	      || ! offsettable_memref_p (reg_equiv_mem[regno])))
569652557Sobrien	force_replace = 1;
569752557Sobrien
569852557Sobrien      if (force_replace || num_not_at_initial_offset)
569952557Sobrien	{
570052557Sobrien	  rtx tem = make_memloc (SUBREG_REG (x), regno);
570152557Sobrien
570252557Sobrien	  /* If the address changes because of register elimination, then
570352557Sobrien	     it must be replaced.  */
570452557Sobrien	  if (force_replace
570552557Sobrien	      || ! rtx_equal_p (tem, reg_equiv_mem[regno]))
570652557Sobrien	    {
570752557Sobrien	      int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
570852557Sobrien
570952557Sobrien	      if (BYTES_BIG_ENDIAN)
571052557Sobrien		{
571152557Sobrien		  int size;
571252557Sobrien
571352557Sobrien		  size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
571452557Sobrien		  offset += MIN (size, UNITS_PER_WORD);
571552557Sobrien		  size = GET_MODE_SIZE (GET_MODE (x));
571652557Sobrien		  offset -= MIN (size, UNITS_PER_WORD);
571752557Sobrien		}
571852557Sobrien	      XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
571952557Sobrien	      PUT_MODE (tem, GET_MODE (x));
572052557Sobrien	      find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
572152557Sobrien				    &XEXP (tem, 0), opnum, ADDR_TYPE (type),
572252557Sobrien				    ind_levels, insn);
572352557Sobrien	      /* If this is not a toplevel operand, find_reloads doesn't see
572452557Sobrien		 this substitution.  We have to emit a USE of the pseudo so
572552557Sobrien		 that delete_output_reload can see it.  */
572652557Sobrien	      if (replace_reloads && recog_operand[opnum] != x)
572752557Sobrien		emit_insn_before (gen_rtx_USE (VOIDmode, SUBREG_REG (x)), insn);
572852557Sobrien	      x = tem;
572952557Sobrien	    }
573052557Sobrien	}
573152557Sobrien    }
573252557Sobrien  return x;
573352557Sobrien}
573452557Sobrien
573518334Speter/* Substitute into the current INSN the registers into which we have reloaded
573618334Speter   the things that need reloading.  The array `replacements'
573718334Speter   says contains the locations of all pointers that must be changed
573818334Speter   and says what to replace them with.
573918334Speter
574018334Speter   Return the rtx that X translates into; usually X, but modified.  */
574118334Speter
574218334Spetervoid
574318334Spetersubst_reloads ()
574418334Speter{
574518334Speter  register int i;
574618334Speter
574718334Speter  for (i = 0; i < n_replacements; i++)
574818334Speter    {
574918334Speter      register struct replacement *r = &replacements[i];
575018334Speter      register rtx reloadreg = reload_reg_rtx[r->what];
575118334Speter      if (reloadreg)
575218334Speter	{
575318334Speter	  /* Encapsulate RELOADREG so its machine mode matches what
575418334Speter	     used to be there.  Note that gen_lowpart_common will
575518334Speter	     do the wrong thing if RELOADREG is multi-word.  RELOADREG
575618334Speter	     will always be a REG here.  */
575718334Speter	  if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
575850605Sobrien	    reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
575918334Speter
576018334Speter	  /* If we are putting this into a SUBREG and RELOADREG is a
576118334Speter	     SUBREG, we would be making nested SUBREGs, so we have to fix
576218334Speter	     this up.  Note that r->where == &SUBREG_REG (*r->subreg_loc).  */
576318334Speter
576418334Speter	  if (r->subreg_loc != 0 && GET_CODE (reloadreg) == SUBREG)
576518334Speter	    {
576618334Speter	      if (GET_MODE (*r->subreg_loc)
576718334Speter		  == GET_MODE (SUBREG_REG (reloadreg)))
576818334Speter		*r->subreg_loc = SUBREG_REG (reloadreg);
576918334Speter	      else
577018334Speter		{
577118334Speter		  *r->where = SUBREG_REG (reloadreg);
577218334Speter		  SUBREG_WORD (*r->subreg_loc) += SUBREG_WORD (reloadreg);
577318334Speter		}
577418334Speter	    }
577518334Speter	  else
577618334Speter	    *r->where = reloadreg;
577718334Speter	}
577818334Speter      /* If reload got no reg and isn't optional, something's wrong.  */
577918334Speter      else if (! reload_optional[r->what])
578018334Speter	abort ();
578118334Speter    }
578218334Speter}
578318334Speter
578418334Speter/* Make a copy of any replacements being done into X and move those copies
578518334Speter   to locations in Y, a copy of X.  We only look at the highest level of
578618334Speter   the RTL.  */
578718334Speter
578818334Spetervoid
578918334Spetercopy_replacements (x, y)
579018334Speter     rtx x;
579118334Speter     rtx y;
579218334Speter{
579318334Speter  int i, j;
579418334Speter  enum rtx_code code = GET_CODE (x);
579518334Speter  char *fmt = GET_RTX_FORMAT (code);
579618334Speter  struct replacement *r;
579718334Speter
579818334Speter  /* We can't support X being a SUBREG because we might then need to know its
579918334Speter     location if something inside it was replaced.  */
580018334Speter  if (code == SUBREG)
580118334Speter    abort ();
580218334Speter
580318334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
580418334Speter    if (fmt[i] == 'e')
580518334Speter      for (j = 0; j < n_replacements; j++)
580618334Speter	{
580718334Speter	  if (replacements[j].subreg_loc == &XEXP (x, i))
580818334Speter	    {
580918334Speter	      r = &replacements[n_replacements++];
581018334Speter	      r->where = replacements[j].where;
581118334Speter	      r->subreg_loc = &XEXP (y, i);
581218334Speter	      r->what = replacements[j].what;
581318334Speter	      r->mode = replacements[j].mode;
581418334Speter	    }
581518334Speter	  else if (replacements[j].where == &XEXP (x, i))
581618334Speter	    {
581718334Speter	      r = &replacements[n_replacements++];
581818334Speter	      r->where = &XEXP (y, i);
581918334Speter	      r->subreg_loc = 0;
582018334Speter	      r->what = replacements[j].what;
582118334Speter	      r->mode = replacements[j].mode;
582218334Speter	    }
582318334Speter	}
582418334Speter}
582550605Sobrien
582650605Sobrien/* Change any replacements being done to *X to be done to *Y */
582750605Sobrien
582850605Sobrienvoid
582950605Sobrienmove_replacements (x, y)
583050605Sobrien     rtx *x;
583150605Sobrien     rtx *y;
583250605Sobrien{
583350605Sobrien  int i;
583450605Sobrien
583550605Sobrien  for (i = 0; i < n_replacements; i++)
583650605Sobrien    if (replacements[i].subreg_loc == x)
583750605Sobrien      replacements[i].subreg_loc = y;
583850605Sobrien    else if (replacements[i].where == x)
583950605Sobrien      {
584050605Sobrien	replacements[i].where = y;
584150605Sobrien	replacements[i].subreg_loc = 0;
584250605Sobrien      }
584350605Sobrien}
584418334Speter
584518334Speter/* If LOC was scheduled to be replaced by something, return the replacement.
584618334Speter   Otherwise, return *LOC.  */
584718334Speter
584818334Speterrtx
584918334Speterfind_replacement (loc)
585018334Speter     rtx *loc;
585118334Speter{
585218334Speter  struct replacement *r;
585318334Speter
585418334Speter  for (r = &replacements[0]; r < &replacements[n_replacements]; r++)
585518334Speter    {
585618334Speter      rtx reloadreg = reload_reg_rtx[r->what];
585718334Speter
585818334Speter      if (reloadreg && r->where == loc)
585918334Speter	{
586018334Speter	  if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
586150605Sobrien	    reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
586218334Speter
586318334Speter	  return reloadreg;
586418334Speter	}
586518334Speter      else if (reloadreg && r->subreg_loc == loc)
586618334Speter	{
586718334Speter	  /* RELOADREG must be either a REG or a SUBREG.
586818334Speter
586918334Speter	     ??? Is it actually still ever a SUBREG?  If so, why?  */
587018334Speter
587118334Speter	  if (GET_CODE (reloadreg) == REG)
587250605Sobrien	    return gen_rtx_REG (GET_MODE (*loc),
587350605Sobrien				REGNO (reloadreg) + SUBREG_WORD (*loc));
587418334Speter	  else if (GET_MODE (reloadreg) == GET_MODE (*loc))
587518334Speter	    return reloadreg;
587618334Speter	  else
587750605Sobrien	    return gen_rtx_SUBREG (GET_MODE (*loc), SUBREG_REG (reloadreg),
587850605Sobrien				   SUBREG_WORD (reloadreg) + SUBREG_WORD (*loc));
587918334Speter	}
588018334Speter    }
588118334Speter
588250605Sobrien  /* If *LOC is a PLUS, MINUS, or MULT, see if a replacement is scheduled for
588350605Sobrien     what's inside and make a new rtl if so.  */
588450605Sobrien  if (GET_CODE (*loc) == PLUS || GET_CODE (*loc) == MINUS
588550605Sobrien      || GET_CODE (*loc) == MULT)
588650605Sobrien    {
588750605Sobrien      rtx x = find_replacement (&XEXP (*loc, 0));
588850605Sobrien      rtx y = find_replacement (&XEXP (*loc, 1));
588950605Sobrien
589050605Sobrien      if (x != XEXP (*loc, 0) || y != XEXP (*loc, 1))
589150605Sobrien	return gen_rtx_fmt_ee (GET_CODE (*loc), GET_MODE (*loc), x, y);
589250605Sobrien    }
589350605Sobrien
589418334Speter  return *loc;
589518334Speter}
589618334Speter
589718334Speter/* Return nonzero if register in range [REGNO, ENDREGNO)
589818334Speter   appears either explicitly or implicitly in X
589918334Speter   other than being stored into (except for earlyclobber operands).
590018334Speter
590118334Speter   References contained within the substructure at LOC do not count.
590218334Speter   LOC may be zero, meaning don't ignore anything.
590318334Speter
590418334Speter   This is similar to refers_to_regno_p in rtlanal.c except that we
590518334Speter   look at equivalences for pseudos that didn't get hard registers.  */
590618334Speter
590718334Speterint
590818334Speterrefers_to_regno_for_reload_p (regno, endregno, x, loc)
590918334Speter     int regno, endregno;
591018334Speter     rtx x;
591118334Speter     rtx *loc;
591218334Speter{
591318334Speter  register int i;
591418334Speter  register RTX_CODE code;
591518334Speter  register char *fmt;
591618334Speter
591718334Speter  if (x == 0)
591818334Speter    return 0;
591918334Speter
592018334Speter repeat:
592118334Speter  code = GET_CODE (x);
592218334Speter
592318334Speter  switch (code)
592418334Speter    {
592518334Speter    case REG:
592618334Speter      i = REGNO (x);
592718334Speter
592818334Speter      /* If this is a pseudo, a hard register must not have been allocated.
592918334Speter	 X must therefore either be a constant or be in memory.  */
593018334Speter      if (i >= FIRST_PSEUDO_REGISTER)
593118334Speter	{
593218334Speter	  if (reg_equiv_memory_loc[i])
593318334Speter	    return refers_to_regno_for_reload_p (regno, endregno,
593418334Speter						 reg_equiv_memory_loc[i],
593518334Speter						 NULL_PTR);
593618334Speter
593718334Speter	  if (reg_equiv_constant[i])
593818334Speter	    return 0;
593918334Speter
594018334Speter	  abort ();
594118334Speter	}
594218334Speter
594318334Speter      return (endregno > i
594418334Speter	      && regno < i + (i < FIRST_PSEUDO_REGISTER
594518334Speter			      ? HARD_REGNO_NREGS (i, GET_MODE (x))
594618334Speter			      : 1));
594718334Speter
594818334Speter    case SUBREG:
594918334Speter      /* If this is a SUBREG of a hard reg, we can see exactly which
595018334Speter	 registers are being modified.  Otherwise, handle normally.  */
595118334Speter      if (GET_CODE (SUBREG_REG (x)) == REG
595218334Speter	  && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
595318334Speter	{
595418334Speter	  int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
595518334Speter	  int inner_endregno
595618334Speter	    = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
595718334Speter			     ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
595818334Speter
595918334Speter	  return endregno > inner_regno && regno < inner_endregno;
596018334Speter	}
596118334Speter      break;
596218334Speter
596318334Speter    case CLOBBER:
596418334Speter    case SET:
596518334Speter      if (&SET_DEST (x) != loc
596618334Speter	  /* Note setting a SUBREG counts as referring to the REG it is in for
596718334Speter	     a pseudo but not for hard registers since we can
596818334Speter	     treat each word individually.  */
596918334Speter	  && ((GET_CODE (SET_DEST (x)) == SUBREG
597018334Speter	       && loc != &SUBREG_REG (SET_DEST (x))
597118334Speter	       && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
597218334Speter	       && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
597318334Speter	       && refers_to_regno_for_reload_p (regno, endregno,
597418334Speter						SUBREG_REG (SET_DEST (x)),
597518334Speter						loc))
597618334Speter	      /* If the output is an earlyclobber operand, this is
597718334Speter		 a conflict.  */
597818334Speter	      || ((GET_CODE (SET_DEST (x)) != REG
597918334Speter		   || earlyclobber_operand_p (SET_DEST (x)))
598018334Speter		  && refers_to_regno_for_reload_p (regno, endregno,
598118334Speter						   SET_DEST (x), loc))))
598218334Speter	return 1;
598318334Speter
598418334Speter      if (code == CLOBBER || loc == &SET_SRC (x))
598518334Speter	return 0;
598618334Speter      x = SET_SRC (x);
598718334Speter      goto repeat;
598850605Sobrien
598950605Sobrien    default:
599050605Sobrien      break;
599118334Speter    }
599218334Speter
599318334Speter  /* X does not match, so try its subexpressions.  */
599418334Speter
599518334Speter  fmt = GET_RTX_FORMAT (code);
599618334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
599718334Speter    {
599818334Speter      if (fmt[i] == 'e' && loc != &XEXP (x, i))
599918334Speter	{
600018334Speter	  if (i == 0)
600118334Speter	    {
600218334Speter	      x = XEXP (x, 0);
600318334Speter	      goto repeat;
600418334Speter	    }
600518334Speter	  else
600618334Speter	    if (refers_to_regno_for_reload_p (regno, endregno,
600718334Speter					      XEXP (x, i), loc))
600818334Speter	      return 1;
600918334Speter	}
601018334Speter      else if (fmt[i] == 'E')
601118334Speter	{
601218334Speter	  register int j;
601318334Speter	  for (j = XVECLEN (x, i) - 1; j >=0; j--)
601418334Speter	    if (loc != &XVECEXP (x, i, j)
601518334Speter		&& refers_to_regno_for_reload_p (regno, endregno,
601618334Speter						 XVECEXP (x, i, j), loc))
601718334Speter	      return 1;
601818334Speter	}
601918334Speter    }
602018334Speter  return 0;
602118334Speter}
602218334Speter
602318334Speter/* Nonzero if modifying X will affect IN.  If X is a register or a SUBREG,
602418334Speter   we check if any register number in X conflicts with the relevant register
602518334Speter   numbers.  If X is a constant, return 0.  If X is a MEM, return 1 iff IN
602618334Speter   contains a MEM (we don't bother checking for memory addresses that can't
602718334Speter   conflict because we expect this to be a rare case.
602818334Speter
602918334Speter   This function is similar to reg_overlap_mention_p in rtlanal.c except
603018334Speter   that we look at equivalences for pseudos that didn't get hard registers.  */
603118334Speter
603218334Speterint
603318334Speterreg_overlap_mentioned_for_reload_p (x, in)
603418334Speter     rtx x, in;
603518334Speter{
603618334Speter  int regno, endregno;
603718334Speter
603850605Sobrien  /* Overly conservative.  */
603950605Sobrien  if (GET_CODE (x) == STRICT_LOW_PART)
604050605Sobrien    x = XEXP (x, 0);
604150605Sobrien
604250605Sobrien  /* If either argument is a constant, then modifying X can not affect IN.  */
604350605Sobrien  if (CONSTANT_P (x) || CONSTANT_P (in))
604450605Sobrien    return 0;
604550605Sobrien  else if (GET_CODE (x) == SUBREG)
604618334Speter    {
604718334Speter      regno = REGNO (SUBREG_REG (x));
604818334Speter      if (regno < FIRST_PSEUDO_REGISTER)
604918334Speter	regno += SUBREG_WORD (x);
605018334Speter    }
605118334Speter  else if (GET_CODE (x) == REG)
605218334Speter    {
605318334Speter      regno = REGNO (x);
605418334Speter
605518334Speter      /* If this is a pseudo, it must not have been assigned a hard register.
605618334Speter	 Therefore, it must either be in memory or be a constant.  */
605718334Speter
605818334Speter      if (regno >= FIRST_PSEUDO_REGISTER)
605918334Speter	{
606018334Speter	  if (reg_equiv_memory_loc[regno])
606118334Speter	    return refers_to_mem_for_reload_p (in);
606218334Speter	  else if (reg_equiv_constant[regno])
606318334Speter	    return 0;
606418334Speter	  abort ();
606518334Speter	}
606618334Speter    }
606718334Speter  else if (GET_CODE (x) == MEM)
606818334Speter    return refers_to_mem_for_reload_p (in);
606918334Speter  else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
607018334Speter	   || GET_CODE (x) == CC0)
607118334Speter    return reg_mentioned_p (x, in);
607218334Speter  else
607318334Speter    abort ();
607418334Speter
607518334Speter  endregno = regno + (regno < FIRST_PSEUDO_REGISTER
607618334Speter		      ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
607718334Speter
607818334Speter  return refers_to_regno_for_reload_p (regno, endregno, in, NULL_PTR);
607918334Speter}
608018334Speter
608118334Speter/* Return nonzero if anything in X contains a MEM.  Look also for pseudo
608218334Speter   registers.  */
608318334Speter
608418334Speterint
608518334Speterrefers_to_mem_for_reload_p (x)
608618334Speter     rtx x;
608718334Speter{
608818334Speter  char *fmt;
608918334Speter  int i;
609018334Speter
609118334Speter  if (GET_CODE (x) == MEM)
609218334Speter    return 1;
609318334Speter
609418334Speter  if (GET_CODE (x) == REG)
609518334Speter    return (REGNO (x) >= FIRST_PSEUDO_REGISTER
609618334Speter	    && reg_equiv_memory_loc[REGNO (x)]);
609718334Speter
609818334Speter  fmt = GET_RTX_FORMAT (GET_CODE (x));
609918334Speter  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
610018334Speter    if (fmt[i] == 'e'
610118334Speter	&& (GET_CODE (XEXP (x, i)) == MEM
610218334Speter	    || refers_to_mem_for_reload_p (XEXP (x, i))))
610318334Speter      return 1;
610418334Speter
610518334Speter  return 0;
610618334Speter}
610718334Speter
610818334Speter/* Check the insns before INSN to see if there is a suitable register
610918334Speter   containing the same value as GOAL.
611018334Speter   If OTHER is -1, look for a register in class CLASS.
611118334Speter   Otherwise, just see if register number OTHER shares GOAL's value.
611218334Speter
611318334Speter   Return an rtx for the register found, or zero if none is found.
611418334Speter
611518334Speter   If RELOAD_REG_P is (short *)1,
611618334Speter   we reject any hard reg that appears in reload_reg_rtx
611718334Speter   because such a hard reg is also needed coming into this insn.
611818334Speter
611918334Speter   If RELOAD_REG_P is any other nonzero value,
612018334Speter   it is a vector indexed by hard reg number
612118334Speter   and we reject any hard reg whose element in the vector is nonnegative
612218334Speter   as well as any that appears in reload_reg_rtx.
612318334Speter
612418334Speter   If GOAL is zero, then GOALREG is a register number; we look
612518334Speter   for an equivalent for that register.
612618334Speter
612718334Speter   MODE is the machine mode of the value we want an equivalence for.
612818334Speter   If GOAL is nonzero and not VOIDmode, then it must have mode MODE.
612918334Speter
613018334Speter   This function is used by jump.c as well as in the reload pass.
613118334Speter
613218334Speter   If GOAL is the sum of the stack pointer and a constant, we treat it
613318334Speter   as if it were a constant except that sp is required to be unchanging.  */
613418334Speter
613518334Speterrtx
613618334Speterfind_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
613718334Speter     register rtx goal;
613818334Speter     rtx insn;
613918334Speter     enum reg_class class;
614018334Speter     register int other;
614118334Speter     short *reload_reg_p;
614218334Speter     int goalreg;
614318334Speter     enum machine_mode mode;
614418334Speter{
614518334Speter  register rtx p = insn;
614618334Speter  rtx goaltry, valtry, value, where;
614718334Speter  register rtx pat;
614818334Speter  register int regno = -1;
614918334Speter  int valueno;
615018334Speter  int goal_mem = 0;
615118334Speter  int goal_const = 0;
615218334Speter  int goal_mem_addr_varies = 0;
615318334Speter  int need_stable_sp = 0;
615418334Speter  int nregs;
615518334Speter  int valuenregs;
615618334Speter
615718334Speter  if (goal == 0)
615818334Speter    regno = goalreg;
615918334Speter  else if (GET_CODE (goal) == REG)
616018334Speter    regno = REGNO (goal);
616118334Speter  else if (GET_CODE (goal) == MEM)
616218334Speter    {
616318334Speter      enum rtx_code code = GET_CODE (XEXP (goal, 0));
616418334Speter      if (MEM_VOLATILE_P (goal))
616518334Speter	return 0;
616618334Speter      if (flag_float_store && GET_MODE_CLASS (GET_MODE (goal)) == MODE_FLOAT)
616718334Speter	return 0;
616818334Speter      /* An address with side effects must be reexecuted.  */
616918334Speter      switch (code)
617018334Speter	{
617118334Speter	case POST_INC:
617218334Speter	case PRE_INC:
617318334Speter	case POST_DEC:
617418334Speter	case PRE_DEC:
617518334Speter	  return 0;
617650605Sobrien	default:
617750605Sobrien	  break;
617818334Speter	}
617918334Speter      goal_mem = 1;
618018334Speter    }
618118334Speter  else if (CONSTANT_P (goal))
618218334Speter    goal_const = 1;
618318334Speter  else if (GET_CODE (goal) == PLUS
618418334Speter	   && XEXP (goal, 0) == stack_pointer_rtx
618518334Speter	   && CONSTANT_P (XEXP (goal, 1)))
618618334Speter    goal_const = need_stable_sp = 1;
618750605Sobrien  else if (GET_CODE (goal) == PLUS
618850605Sobrien	   && XEXP (goal, 0) == frame_pointer_rtx
618950605Sobrien	   && CONSTANT_P (XEXP (goal, 1)))
619050605Sobrien    goal_const = 1;
619118334Speter  else
619218334Speter    return 0;
619318334Speter
619418334Speter  /* On some machines, certain regs must always be rejected
619518334Speter     because they don't behave the way ordinary registers do.  */
619618334Speter
619718334Speter#ifdef OVERLAPPING_REGNO_P
619818334Speter   if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
619918334Speter       && OVERLAPPING_REGNO_P (regno))
620018334Speter     return 0;
620118334Speter#endif
620218334Speter
620318334Speter  /* Scan insns back from INSN, looking for one that copies
620418334Speter     a value into or out of GOAL.
620518334Speter     Stop and give up if we reach a label.  */
620618334Speter
620718334Speter  while (1)
620818334Speter    {
620918334Speter      p = PREV_INSN (p);
621018334Speter      if (p == 0 || GET_CODE (p) == CODE_LABEL)
621118334Speter	return 0;
621218334Speter      if (GET_CODE (p) == INSN
621350605Sobrien	  /* If we don't want spill regs ...  */
621418334Speter	  && (! (reload_reg_p != 0
621518334Speter		 && reload_reg_p != (short *) (HOST_WIDE_INT) 1)
621618334Speter	  /* ... then ignore insns introduced by reload; they aren't useful
621718334Speter	     and can cause results in reload_as_needed to be different
621818334Speter	     from what they were when calculating the need for spills.
621918334Speter	     If we notice an input-reload insn here, we will reject it below,
622018334Speter	     but it might hide a usable equivalent.  That makes bad code.
622118334Speter	     It may even abort: perhaps no reg was spilled for this insn
622218334Speter	     because it was assumed we would find that equivalent.  */
622318334Speter	      || INSN_UID (p) < reload_first_uid))
622418334Speter	{
622518334Speter	  rtx tem;
622618334Speter	  pat = single_set (p);
622718334Speter	  /* First check for something that sets some reg equal to GOAL.  */
622818334Speter	  if (pat != 0
622918334Speter	      && ((regno >= 0
623018334Speter		   && true_regnum (SET_SRC (pat)) == regno
623118334Speter		   && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
623218334Speter		  ||
623318334Speter		  (regno >= 0
623418334Speter		   && true_regnum (SET_DEST (pat)) == regno
623518334Speter		   && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0)
623618334Speter		  ||
623718334Speter		  (goal_const && rtx_equal_p (SET_SRC (pat), goal)
623850605Sobrien		   /* When looking for stack pointer + const,
623950605Sobrien		      make sure we don't use a stack adjust.  */
624050605Sobrien		   && !reg_overlap_mentioned_for_reload_p (SET_DEST (pat), goal)
624118334Speter		   && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
624218334Speter		  || (goal_mem
624318334Speter		      && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0
624418334Speter		      && rtx_renumbered_equal_p (goal, SET_SRC (pat)))
624518334Speter		  || (goal_mem
624618334Speter		      && (valueno = true_regnum (valtry = SET_SRC (pat))) >= 0
624718334Speter		      && rtx_renumbered_equal_p (goal, SET_DEST (pat)))
624818334Speter		  /* If we are looking for a constant,
624918334Speter		     and something equivalent to that constant was copied
625018334Speter		     into a reg, we can use that reg.  */
625118334Speter		  || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
625218334Speter							  NULL_RTX))
625318334Speter		      && rtx_equal_p (XEXP (tem, 0), goal)
625418334Speter		      && (valueno = true_regnum (valtry = SET_DEST (pat))) >= 0)
625518334Speter		  || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
625618334Speter							  NULL_RTX))
625718334Speter		      && GET_CODE (SET_DEST (pat)) == REG
625818334Speter		      && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
625918334Speter		      && GET_MODE_CLASS (GET_MODE (XEXP (tem, 0))) == MODE_FLOAT
626018334Speter		      && GET_CODE (goal) == CONST_INT
626118334Speter		      && 0 != (goaltry = operand_subword (XEXP (tem, 0), 0, 0,
626218334Speter							  VOIDmode))
626318334Speter		      && rtx_equal_p (goal, goaltry)
626418334Speter		      && (valtry = operand_subword (SET_DEST (pat), 0, 0,
626518334Speter						    VOIDmode))
626618334Speter		      && (valueno = true_regnum (valtry)) >= 0)
626718334Speter		  || (goal_const && (tem = find_reg_note (p, REG_EQUIV,
626818334Speter							  NULL_RTX))
626918334Speter		      && GET_CODE (SET_DEST (pat)) == REG
627018334Speter		      && GET_CODE (XEXP (tem, 0)) == CONST_DOUBLE
627118334Speter		      && GET_MODE_CLASS (GET_MODE (XEXP (tem, 0))) == MODE_FLOAT
627218334Speter		      && GET_CODE (goal) == CONST_INT
627318334Speter		      && 0 != (goaltry = operand_subword (XEXP (tem, 0), 1, 0,
627418334Speter							  VOIDmode))
627518334Speter		      && rtx_equal_p (goal, goaltry)
627618334Speter		      && (valtry
627718334Speter			  = operand_subword (SET_DEST (pat), 1, 0, VOIDmode))
627818334Speter		      && (valueno = true_regnum (valtry)) >= 0)))
627970639Sobrien	    {
628070639Sobrien	      if (other >= 0)
628170639Sobrien		{
628270639Sobrien		  if (valueno != other)
628370639Sobrien		    continue;
628470639Sobrien		}
628570639Sobrien	      else if ((unsigned) valueno >= FIRST_PSEUDO_REGISTER)
628670639Sobrien		continue;
628770639Sobrien	      else
628870639Sobrien		{
628970639Sobrien		  int i;
629070639Sobrien
629170639Sobrien		  for (i = HARD_REGNO_NREGS (valueno, mode) - 1; i >= 0; i--)
629270639Sobrien		    if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
629370639Sobrien					     valueno + i))
629470639Sobrien		      break;
629570639Sobrien		  if (i >= 0)
629670639Sobrien		    continue;
629770639Sobrien		}
629870639Sobrien	      value = valtry;
629970639Sobrien	      where = p;
630070639Sobrien	      break;
630170639Sobrien	    }
630218334Speter	}
630318334Speter    }
630418334Speter
630518334Speter  /* We found a previous insn copying GOAL into a suitable other reg VALUE
630618334Speter     (or copying VALUE into GOAL, if GOAL is also a register).
630718334Speter     Now verify that VALUE is really valid.  */
630818334Speter
630918334Speter  /* VALUENO is the register number of VALUE; a hard register.  */
631018334Speter
631118334Speter  /* Don't try to re-use something that is killed in this insn.  We want
631218334Speter     to be able to trust REG_UNUSED notes.  */
631318334Speter  if (find_reg_note (where, REG_UNUSED, value))
631418334Speter    return 0;
631518334Speter
631618334Speter  /* If we propose to get the value from the stack pointer or if GOAL is
631718334Speter     a MEM based on the stack pointer, we need a stable SP.  */
631850605Sobrien  if (valueno == STACK_POINTER_REGNUM || regno == STACK_POINTER_REGNUM
631918334Speter      || (goal_mem && reg_overlap_mentioned_for_reload_p (stack_pointer_rtx,
632018334Speter							  goal)))
632118334Speter    need_stable_sp = 1;
632218334Speter
632318334Speter  /* Reject VALUE if the copy-insn moved the wrong sort of datum.  */
632418334Speter  if (GET_MODE (value) != mode)
632518334Speter    return 0;
632618334Speter
632718334Speter  /* Reject VALUE if it was loaded from GOAL
632818334Speter     and is also a register that appears in the address of GOAL.  */
632918334Speter
633050605Sobrien  if (goal_mem && value == SET_DEST (single_set (where))
633118334Speter      && refers_to_regno_for_reload_p (valueno,
633218334Speter				       (valueno
633318334Speter					+ HARD_REGNO_NREGS (valueno, mode)),
633418334Speter				       goal, NULL_PTR))
633518334Speter    return 0;
633618334Speter
633718334Speter  /* Reject registers that overlap GOAL.  */
633818334Speter
633918334Speter  if (!goal_mem && !goal_const
634018334Speter      && regno + HARD_REGNO_NREGS (regno, mode) > valueno
634118334Speter      && regno < valueno + HARD_REGNO_NREGS (valueno, mode))
634218334Speter    return 0;
634318334Speter
634470639Sobrien  nregs = HARD_REGNO_NREGS (regno, mode);
634570639Sobrien  valuenregs = HARD_REGNO_NREGS (valueno, mode);
634670639Sobrien
634718334Speter  /* Reject VALUE if it is one of the regs reserved for reloads.
634818334Speter     Reload1 knows how to reuse them anyway, and it would get
634918334Speter     confused if we allocated one without its knowledge.
635018334Speter     (Now that insns introduced by reload are ignored above,
635118334Speter     this case shouldn't happen, but I'm not positive.)  */
635218334Speter
635370639Sobrien  if (reload_reg_p != 0 && reload_reg_p != (short *) (HOST_WIDE_INT) 1)
635470639Sobrien    {
635570639Sobrien      int i;
635670639Sobrien      for (i = 0; i < valuenregs; ++i)
635770639Sobrien	if (reload_reg_p[valueno + i] >= 0)
635870639Sobrien	  return 0;
635970639Sobrien    }
636018334Speter
636118334Speter  /* On some machines, certain regs must always be rejected
636218334Speter     because they don't behave the way ordinary registers do.  */
636318334Speter
636418334Speter#ifdef OVERLAPPING_REGNO_P
636518334Speter  if (OVERLAPPING_REGNO_P (valueno))
636618334Speter    return 0;
636718334Speter#endif
636818334Speter
636918334Speter  /* Reject VALUE if it is a register being used for an input reload
637018334Speter     even if it is not one of those reserved.  */
637118334Speter
637218334Speter  if (reload_reg_p != 0)
637318334Speter    {
637418334Speter      int i;
637518334Speter      for (i = 0; i < n_reloads; i++)
637618334Speter	if (reload_reg_rtx[i] != 0 && reload_in[i])
637718334Speter	  {
637818334Speter	    int regno1 = REGNO (reload_reg_rtx[i]);
637918334Speter	    int nregs1 = HARD_REGNO_NREGS (regno1,
638018334Speter					   GET_MODE (reload_reg_rtx[i]));
638118334Speter	    if (regno1 < valueno + valuenregs
638218334Speter		&& regno1 + nregs1 > valueno)
638318334Speter	      return 0;
638418334Speter	  }
638518334Speter    }
638618334Speter
638718334Speter  if (goal_mem)
638818334Speter    /* We must treat frame pointer as varying here,
638918334Speter       since it can vary--in a nonlocal goto as generated by expand_goto.  */
639018334Speter    goal_mem_addr_varies = !CONSTANT_ADDRESS_P (XEXP (goal, 0));
639118334Speter
639218334Speter  /* Now verify that the values of GOAL and VALUE remain unaltered
639318334Speter     until INSN is reached.  */
639418334Speter
639518334Speter  p = insn;
639618334Speter  while (1)
639718334Speter    {
639818334Speter      p = PREV_INSN (p);
639918334Speter      if (p == where)
640018334Speter	return value;
640118334Speter
640218334Speter      /* Don't trust the conversion past a function call
640318334Speter	 if either of the two is in a call-clobbered register, or memory.  */
640470639Sobrien      if (GET_CODE (p) == CALL_INSN)
640570639Sobrien	{
640670639Sobrien	  int i;
640718334Speter
640870639Sobrien	  if (goal_mem || need_stable_sp)
640970639Sobrien	    return 0;
641070639Sobrien
641170639Sobrien	  if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
641270639Sobrien	    for (i = 0; i < nregs; ++i)
641370639Sobrien	      if (call_used_regs[regno + i])
641470639Sobrien		return 0;
641570639Sobrien
641670639Sobrien	  if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER)
641770639Sobrien	    for (i = 0; i < valuenregs; ++i)
641870639Sobrien	      if (call_used_regs[valueno + i])
641970639Sobrien		return 0;
642070639Sobrien	}
642170639Sobrien
642218334Speter#ifdef NON_SAVING_SETJMP
642318334Speter      if (NON_SAVING_SETJMP && GET_CODE (p) == NOTE
642418334Speter	  && NOTE_LINE_NUMBER (p) == NOTE_INSN_SETJMP)
642518334Speter	return 0;
642618334Speter#endif
642718334Speter
642818334Speter#ifdef INSN_CLOBBERS_REGNO_P
642918334Speter      if ((valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER
643018334Speter	  && INSN_CLOBBERS_REGNO_P (p, valueno))
643118334Speter	  || (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
643218334Speter	  && INSN_CLOBBERS_REGNO_P (p, regno)))
643318334Speter	return 0;
643418334Speter#endif
643518334Speter
643618334Speter      if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
643718334Speter	{
643850605Sobrien	  pat = PATTERN (p);
643950605Sobrien
644050605Sobrien          /* Watch out for unspec_volatile, and volatile asms.  */
644150605Sobrien          if (volatile_insn_p (pat))
644250605Sobrien	    return 0;
644350605Sobrien
644418334Speter	  /* If this insn P stores in either GOAL or VALUE, return 0.
644518334Speter	     If GOAL is a memory ref and this insn writes memory, return 0.
644618334Speter	     If GOAL is a memory ref and its address is not constant,
644718334Speter	     and this insn P changes a register used in GOAL, return 0.  */
644818334Speter
644918334Speter	  if (GET_CODE (pat) == SET || GET_CODE (pat) == CLOBBER)
645018334Speter	    {
645118334Speter	      register rtx dest = SET_DEST (pat);
645218334Speter	      while (GET_CODE (dest) == SUBREG
645318334Speter		     || GET_CODE (dest) == ZERO_EXTRACT
645418334Speter		     || GET_CODE (dest) == SIGN_EXTRACT
645518334Speter		     || GET_CODE (dest) == STRICT_LOW_PART)
645618334Speter		dest = XEXP (dest, 0);
645718334Speter	      if (GET_CODE (dest) == REG)
645818334Speter		{
645918334Speter		  register int xregno = REGNO (dest);
646018334Speter		  int xnregs;
646118334Speter		  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
646218334Speter		    xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
646318334Speter		  else
646418334Speter		    xnregs = 1;
646518334Speter		  if (xregno < regno + nregs && xregno + xnregs > regno)
646618334Speter		    return 0;
646718334Speter		  if (xregno < valueno + valuenregs
646818334Speter		      && xregno + xnregs > valueno)
646918334Speter		    return 0;
647018334Speter		  if (goal_mem_addr_varies
647118334Speter		      && reg_overlap_mentioned_for_reload_p (dest, goal))
647218334Speter		    return 0;
647350605Sobrien		  if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
647450605Sobrien		    return 0;
647518334Speter		}
647618334Speter	      else if (goal_mem && GET_CODE (dest) == MEM
647718334Speter		       && ! push_operand (dest, GET_MODE (dest)))
647818334Speter		return 0;
647918334Speter	      else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
648018334Speter		       && reg_equiv_memory_loc[regno] != 0)
648118334Speter		return 0;
648218334Speter	      else if (need_stable_sp && push_operand (dest, GET_MODE (dest)))
648318334Speter		return 0;
648418334Speter	    }
648518334Speter	  else if (GET_CODE (pat) == PARALLEL)
648618334Speter	    {
648718334Speter	      register int i;
648818334Speter	      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
648918334Speter		{
649018334Speter		  register rtx v1 = XVECEXP (pat, 0, i);
649118334Speter		  if (GET_CODE (v1) == SET || GET_CODE (v1) == CLOBBER)
649218334Speter		    {
649318334Speter		      register rtx dest = SET_DEST (v1);
649418334Speter		      while (GET_CODE (dest) == SUBREG
649518334Speter			     || GET_CODE (dest) == ZERO_EXTRACT
649618334Speter			     || GET_CODE (dest) == SIGN_EXTRACT
649718334Speter			     || GET_CODE (dest) == STRICT_LOW_PART)
649818334Speter			dest = XEXP (dest, 0);
649918334Speter		      if (GET_CODE (dest) == REG)
650018334Speter			{
650118334Speter			  register int xregno = REGNO (dest);
650218334Speter			  int xnregs;
650318334Speter			  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
650418334Speter			    xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
650518334Speter			  else
650618334Speter			    xnregs = 1;
650718334Speter			  if (xregno < regno + nregs
650818334Speter			      && xregno + xnregs > regno)
650918334Speter			    return 0;
651018334Speter			  if (xregno < valueno + valuenregs
651118334Speter			      && xregno + xnregs > valueno)
651218334Speter			    return 0;
651318334Speter			  if (goal_mem_addr_varies
651418334Speter			      && reg_overlap_mentioned_for_reload_p (dest,
651518334Speter								     goal))
651618334Speter			    return 0;
651750605Sobrien			  if (xregno == STACK_POINTER_REGNUM && need_stable_sp)
651850605Sobrien			    return 0;
651918334Speter			}
652018334Speter		      else if (goal_mem && GET_CODE (dest) == MEM
652118334Speter			       && ! push_operand (dest, GET_MODE (dest)))
652218334Speter			return 0;
652350605Sobrien		      else if (GET_CODE (dest) == MEM && regno >= FIRST_PSEUDO_REGISTER
652450605Sobrien			       && reg_equiv_memory_loc[regno] != 0)
652550605Sobrien			return 0;
652618334Speter		      else if (need_stable_sp
652718334Speter			       && push_operand (dest, GET_MODE (dest)))
652818334Speter			return 0;
652918334Speter		    }
653018334Speter		}
653118334Speter	    }
653218334Speter
653318334Speter	  if (GET_CODE (p) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (p))
653418334Speter	    {
653518334Speter	      rtx link;
653618334Speter
653718334Speter	      for (link = CALL_INSN_FUNCTION_USAGE (p); XEXP (link, 1) != 0;
653818334Speter		   link = XEXP (link, 1))
653918334Speter		{
654018334Speter		  pat = XEXP (link, 0);
654118334Speter		  if (GET_CODE (pat) == CLOBBER)
654218334Speter		    {
654318334Speter		      register rtx dest = SET_DEST (pat);
654418334Speter		      while (GET_CODE (dest) == SUBREG
654518334Speter			     || GET_CODE (dest) == ZERO_EXTRACT
654618334Speter			     || GET_CODE (dest) == SIGN_EXTRACT
654718334Speter			     || GET_CODE (dest) == STRICT_LOW_PART)
654818334Speter			dest = XEXP (dest, 0);
654918334Speter		      if (GET_CODE (dest) == REG)
655018334Speter			{
655118334Speter			  register int xregno = REGNO (dest);
655218334Speter			  int xnregs;
655318334Speter			  if (REGNO (dest) < FIRST_PSEUDO_REGISTER)
655418334Speter			    xnregs = HARD_REGNO_NREGS (xregno, GET_MODE (dest));
655518334Speter			  else
655618334Speter			    xnregs = 1;
655718334Speter			  if (xregno < regno + nregs
655818334Speter			      && xregno + xnregs > regno)
655918334Speter			    return 0;
656018334Speter			  if (xregno < valueno + valuenregs
656118334Speter			      && xregno + xnregs > valueno)
656218334Speter			    return 0;
656318334Speter			  if (goal_mem_addr_varies
656418334Speter			      && reg_overlap_mentioned_for_reload_p (dest,
656518334Speter								     goal))
656618334Speter			    return 0;
656718334Speter			}
656818334Speter		      else if (goal_mem && GET_CODE (dest) == MEM
656918334Speter			       && ! push_operand (dest, GET_MODE (dest)))
657018334Speter			return 0;
657118334Speter		      else if (need_stable_sp
657218334Speter			       && push_operand (dest, GET_MODE (dest)))
657318334Speter			return 0;
657418334Speter		    }
657518334Speter		}
657618334Speter	    }
657718334Speter
657818334Speter#ifdef AUTO_INC_DEC
657918334Speter	  /* If this insn auto-increments or auto-decrements
658018334Speter	     either regno or valueno, return 0 now.
658118334Speter	     If GOAL is a memory ref and its address is not constant,
658218334Speter	     and this insn P increments a register used in GOAL, return 0.  */
658318334Speter	  {
658418334Speter	    register rtx link;
658518334Speter
658618334Speter	    for (link = REG_NOTES (p); link; link = XEXP (link, 1))
658718334Speter	      if (REG_NOTE_KIND (link) == REG_INC
658818334Speter		  && GET_CODE (XEXP (link, 0)) == REG)
658918334Speter		{
659018334Speter		  register int incno = REGNO (XEXP (link, 0));
659118334Speter		  if (incno < regno + nregs && incno >= regno)
659218334Speter		    return 0;
659318334Speter		  if (incno < valueno + valuenregs && incno >= valueno)
659418334Speter		    return 0;
659518334Speter		  if (goal_mem_addr_varies
659618334Speter		      && reg_overlap_mentioned_for_reload_p (XEXP (link, 0),
659718334Speter							     goal))
659818334Speter		    return 0;
659918334Speter		}
660018334Speter	  }
660118334Speter#endif
660218334Speter	}
660318334Speter    }
660418334Speter}
660518334Speter
660618334Speter/* Find a place where INCED appears in an increment or decrement operator
660718334Speter   within X, and return the amount INCED is incremented or decremented by.
660818334Speter   The value is always positive.  */
660918334Speter
661018334Speterstatic int
661118334Speterfind_inc_amount (x, inced)
661218334Speter     rtx x, inced;
661318334Speter{
661418334Speter  register enum rtx_code code = GET_CODE (x);
661518334Speter  register char *fmt;
661618334Speter  register int i;
661718334Speter
661818334Speter  if (code == MEM)
661918334Speter    {
662018334Speter      register rtx addr = XEXP (x, 0);
662118334Speter      if ((GET_CODE (addr) == PRE_DEC
662218334Speter	   || GET_CODE (addr) == POST_DEC
662318334Speter	   || GET_CODE (addr) == PRE_INC
662418334Speter	   || GET_CODE (addr) == POST_INC)
662518334Speter	  && XEXP (addr, 0) == inced)
662618334Speter	return GET_MODE_SIZE (GET_MODE (x));
662718334Speter    }
662818334Speter
662918334Speter  fmt = GET_RTX_FORMAT (code);
663018334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
663118334Speter    {
663218334Speter      if (fmt[i] == 'e')
663318334Speter	{
663418334Speter	  register int tem = find_inc_amount (XEXP (x, i), inced);
663518334Speter	  if (tem != 0)
663618334Speter	    return tem;
663718334Speter	}
663818334Speter      if (fmt[i] == 'E')
663918334Speter	{
664018334Speter	  register int j;
664118334Speter	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
664218334Speter	    {
664318334Speter	      register int tem = find_inc_amount (XVECEXP (x, i, j), inced);
664418334Speter	      if (tem != 0)
664518334Speter		return tem;
664618334Speter	    }
664718334Speter	}
664818334Speter    }
664918334Speter
665018334Speter  return 0;
665118334Speter}
665218334Speter
665318334Speter/* Return 1 if register REGNO is the subject of a clobber in insn INSN.  */
665418334Speter
665518334Speterint
665670639Sobrienregno_clobbered_p (regno, insn, mode, sets)
665718334Speter     int regno;
665818334Speter     rtx insn;
665970639Sobrien     enum machine_mode mode;
666070639Sobrien     int sets;
666118334Speter{
666270639Sobrien  int nregs = HARD_REGNO_NREGS (regno, mode);
666370639Sobrien  int endregno = regno + nregs;
666470639Sobrien
666570639Sobrien  if ((GET_CODE (PATTERN (insn)) == CLOBBER
666670639Sobrien       || (sets && GET_CODE (PATTERN (insn)) == SET))
666718334Speter      && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
666870639Sobrien    {
666970639Sobrien      int test = REGNO (XEXP (PATTERN (insn), 0));
667018334Speter
667170639Sobrien      return test >= regno && test < endregno;
667270639Sobrien    }
667370639Sobrien
667418334Speter  if (GET_CODE (PATTERN (insn)) == PARALLEL)
667518334Speter    {
667618334Speter      int i = XVECLEN (PATTERN (insn), 0) - 1;
667718334Speter
667818334Speter      for (; i >= 0; i--)
667918334Speter	{
668018334Speter	  rtx elt = XVECEXP (PATTERN (insn), 0, i);
668170639Sobrien	  if ((GET_CODE (elt) == CLOBBER
668270639Sobrien	       || (sets && GET_CODE (PATTERN (insn)) == SET))
668370639Sobrien	      && GET_CODE (XEXP (elt, 0)) == REG)
668470639Sobrien	    {
668570639Sobrien	      int test = REGNO (XEXP (elt, 0));
668670639Sobrien
668770639Sobrien	      if (test >= regno && test < endregno)
668870639Sobrien		return 1;
668970639Sobrien	    }
669018334Speter	}
669118334Speter    }
669218334Speter
669318334Speter  return 0;
669418334Speter}
669518334Speter
669618334Speterstatic char *reload_when_needed_name[] =
669718334Speter{
669818334Speter  "RELOAD_FOR_INPUT",
669918334Speter  "RELOAD_FOR_OUTPUT",
670018334Speter  "RELOAD_FOR_INSN",
670150605Sobrien  "RELOAD_FOR_INPUT_ADDRESS",
670250605Sobrien  "RELOAD_FOR_INPADDR_ADDRESS",
670318334Speter  "RELOAD_FOR_OUTPUT_ADDRESS",
670450605Sobrien  "RELOAD_FOR_OUTADDR_ADDRESS",
670518334Speter  "RELOAD_FOR_OPERAND_ADDRESS",
670618334Speter  "RELOAD_FOR_OPADDR_ADDR",
670718334Speter  "RELOAD_OTHER",
670818334Speter  "RELOAD_FOR_OTHER_ADDRESS"
670918334Speter};
671018334Speter
671118334Speterstatic char *reg_class_names[] = REG_CLASS_NAMES;
671218334Speter
671350605Sobrien/* These functions are used to print the variables set by 'find_reloads' */
671418334Speter
671518334Spetervoid
671650605Sobriendebug_reload_to_stream (f)
671750605Sobrien     FILE *f;
671818334Speter{
671918334Speter  int r;
672050605Sobrien  char *prefix;
672118334Speter
672250605Sobrien  if (! f)
672350605Sobrien    f = stderr;
672418334Speter  for (r = 0; r < n_reloads; r++)
672518334Speter    {
672650605Sobrien      fprintf (f, "Reload %d: ", r);
672718334Speter
672850605Sobrien      if (reload_in[r] != 0)
672918334Speter	{
673050605Sobrien	  fprintf (f, "reload_in (%s) = ",
673118334Speter		   GET_MODE_NAME (reload_inmode[r]));
673250605Sobrien	  print_inline_rtx (f, reload_in[r], 24);
673350605Sobrien	  fprintf (f, "\n\t");
673418334Speter	}
673518334Speter
673650605Sobrien      if (reload_out[r] != 0)
673718334Speter	{
673850605Sobrien	  fprintf (f, "reload_out (%s) = ",
673918334Speter		   GET_MODE_NAME (reload_outmode[r]));
674050605Sobrien	  print_inline_rtx (f, reload_out[r], 24);
674150605Sobrien	  fprintf (f, "\n\t");
674218334Speter	}
674318334Speter
674450605Sobrien      fprintf (f, "%s, ", reg_class_names[(int) reload_reg_class[r]]);
674518334Speter
674650605Sobrien      fprintf (f, "%s (opnum = %d)",
674750605Sobrien	       reload_when_needed_name[(int) reload_when_needed[r]],
674818334Speter	       reload_opnum[r]);
674918334Speter
675018334Speter      if (reload_optional[r])
675150605Sobrien	fprintf (f, ", optional");
675218334Speter
675350605Sobrien      if (reload_nongroup[r])
675450605Sobrien	fprintf (stderr, ", nongroup");
675518334Speter
675650605Sobrien      if (reload_inc[r] != 0)
675750605Sobrien	fprintf (f, ", inc by %d", reload_inc[r]);
675850605Sobrien
675918334Speter      if (reload_nocombine[r])
676050605Sobrien	fprintf (f, ", can't combine");
676118334Speter
676218334Speter      if (reload_secondary_p[r])
676350605Sobrien	fprintf (f, ", secondary_reload_p");
676418334Speter
676550605Sobrien      if (reload_in_reg[r] != 0)
676618334Speter	{
676750605Sobrien	  fprintf (f, "\n\treload_in_reg: ");
676850605Sobrien	  print_inline_rtx (f, reload_in_reg[r], 24);
676918334Speter	}
677018334Speter
677152557Sobrien      if (reload_out_reg[r] != 0)
677252557Sobrien	{
677352557Sobrien	  fprintf (f, "\n\treload_out_reg: ");
677452557Sobrien	  print_inline_rtx (f, reload_out_reg[r], 24);
677552557Sobrien	}
677652557Sobrien
677750605Sobrien      if (reload_reg_rtx[r] != 0)
677818334Speter	{
677950605Sobrien	  fprintf (f, "\n\treload_reg_rtx: ");
678050605Sobrien	  print_inline_rtx (f, reload_reg_rtx[r], 24);
678118334Speter	}
678218334Speter
678350605Sobrien      prefix = "\n\t";
678418334Speter      if (reload_secondary_in_reload[r] != -1)
678518334Speter	{
678650605Sobrien	  fprintf (f, "%ssecondary_in_reload = %d",
678750605Sobrien		   prefix, reload_secondary_in_reload[r]);
678850605Sobrien	  prefix = ", ";
678918334Speter	}
679018334Speter
679118334Speter      if (reload_secondary_out_reload[r] != -1)
679250605Sobrien	fprintf (f, "%ssecondary_out_reload = %d\n",
679350605Sobrien		 prefix, reload_secondary_out_reload[r]);
679418334Speter
679550605Sobrien      prefix = "\n\t";
679618334Speter      if (reload_secondary_in_icode[r] != CODE_FOR_nothing)
679718334Speter	{
679850605Sobrien	  fprintf (stderr, "%ssecondary_in_icode = %s", prefix,
679950605Sobrien		   insn_name[reload_secondary_in_icode[r]]);
680050605Sobrien	  prefix = ", ";
680118334Speter	}
680218334Speter
680318334Speter      if (reload_secondary_out_icode[r] != CODE_FOR_nothing)
680450605Sobrien	fprintf (stderr, "%ssecondary_out_icode = %s", prefix,
680550605Sobrien		 insn_name[reload_secondary_out_icode[r]]);
680618334Speter
680750605Sobrien      fprintf (f, "\n");
680818334Speter    }
680950605Sobrien}
681018334Speter
681150605Sobrienvoid
681250605Sobriendebug_reload ()
681350605Sobrien{
681450605Sobrien  debug_reload_to_stream (stderr);
681518334Speter}
6816