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