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