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