118334Speter/* Save and restore call-clobbered registers which are live across a call. 290075Sobrien Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 3169689Skan 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC. 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 2118334Speter 2218334Speter#include "config.h" 2350397Sobrien#include "system.h" 24132718Skan#include "coretypes.h" 25132718Skan#include "tm.h" 2618334Speter#include "rtl.h" 27169689Skan#include "regs.h" 2818334Speter#include "insn-config.h" 2918334Speter#include "flags.h" 3018334Speter#include "hard-reg-set.h" 3118334Speter#include "recog.h" 3218334Speter#include "basic-block.h" 3318334Speter#include "reload.h" 3490075Sobrien#include "function.h" 3518334Speter#include "expr.h" 3650397Sobrien#include "toplev.h" 3790075Sobrien#include "tm_p.h" 38169689Skan#include "addresses.h" 3918334Speter 4018334Speter#ifndef MAX_MOVE_MAX 4118334Speter#define MAX_MOVE_MAX MOVE_MAX 4218334Speter#endif 4318334Speter 4418334Speter#ifndef MIN_UNITS_PER_WORD 4518334Speter#define MIN_UNITS_PER_WORD UNITS_PER_WORD 4618334Speter#endif 4718334Speter 4852284Sobrien#define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD) 4952284Sobrien 5018334Speter/* Modes for each hard register that we can save. The smallest mode is wide 5118334Speter enough to save the entire contents of the register. When saving the 5218334Speter register because it is live we first try to save in multi-register modes. 5318334Speter If that is not possible the save is done one register at a time. */ 5418334Speter 55132718Skanstatic enum machine_mode 5618334Speter regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1]; 5718334Speter 5818334Speter/* For each hard register, a place on the stack where it can be saved, 5918334Speter if needed. */ 6018334Speter 61132718Skanstatic rtx 6218334Speter regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1]; 6318334Speter 6418334Speter/* We will only make a register eligible for caller-save if it can be 6518334Speter saved in its widest mode with a simple SET insn as long as the memory 6618334Speter address is valid. We record the INSN_CODE is those insns here since 6718334Speter when we emit them, the addresses might not be valid, so they might not 6818334Speter be recognized. */ 6918334Speter 7090075Sobrienstatic int 7190075Sobrien reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE]; 72132718Skanstatic int 7390075Sobrien reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE]; 7418334Speter 7518334Speter/* Set of hard regs currently residing in save area (during insn scan). */ 7618334Speter 7718334Speterstatic HARD_REG_SET hard_regs_saved; 7818334Speter 7952284Sobrien/* Number of registers currently in hard_regs_saved. */ 8018334Speter 8152284Sobrienstatic int n_regs_saved; 8218334Speter 8352284Sobrien/* Computed by mark_referenced_regs, all regs referenced in a given 8452284Sobrien insn. */ 8552284Sobrienstatic HARD_REG_SET referenced_regs; 8618334Speter 8718334Speter 88132718Skanstatic void mark_set_regs (rtx, rtx, void *); 89132718Skanstatic void mark_referenced_regs (rtx); 90132718Skanstatic int insert_save (struct insn_chain *, int, int, HARD_REG_SET *, 91132718Skan enum machine_mode *); 92132718Skanstatic int insert_restore (struct insn_chain *, int, int, int, 93132718Skan enum machine_mode *); 94132718Skanstatic struct insn_chain *insert_one_insn (struct insn_chain *, int, int, 95132718Skan rtx); 96132718Skanstatic void add_stored_regs (rtx, rtx, void *); 9718334Speter 9818334Speter/* Initialize for caller-save. 9918334Speter 10018334Speter Look at all the hard registers that are used by a call and for which 10118334Speter regclass.c has not already excluded from being used across a call. 10218334Speter 103132718Skan Ensure that we can find a mode to save the register and that there is a 10418334Speter simple insn to save and restore the register. This latter check avoids 10518334Speter problems that would occur if we tried to save the MQ register of some 10618334Speter machines directly into memory. */ 10718334Speter 10818334Spetervoid 109132718Skaninit_caller_save (void) 11018334Speter{ 11118334Speter rtx addr_reg; 11218334Speter int offset; 11318334Speter rtx address; 11418334Speter int i, j; 11590075Sobrien enum machine_mode mode; 116117395Skan rtx savepat, restpat; 117117395Skan rtx test_reg, test_mem; 118117395Skan rtx saveinsn, restinsn; 11918334Speter 12018334Speter /* First find all the registers that we need to deal with and all 12118334Speter the modes that they can have. If we can't find a mode to use, 12218334Speter we can't have the register live over calls. */ 12318334Speter 12418334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 12518334Speter { 12618334Speter if (call_used_regs[i] && ! call_fixed_regs[i]) 12718334Speter { 12852284Sobrien for (j = 1; j <= MOVE_MAX_WORDS; j++) 12918334Speter { 13090075Sobrien regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, 13190075Sobrien VOIDmode); 13218334Speter if (regno_save_mode[i][j] == VOIDmode && j == 1) 13318334Speter { 13418334Speter call_fixed_regs[i] = 1; 13518334Speter SET_HARD_REG_BIT (call_fixed_reg_set, i); 13618334Speter } 13718334Speter } 13818334Speter } 13918334Speter else 14018334Speter regno_save_mode[i][1] = VOIDmode; 14118334Speter } 14218334Speter 14318334Speter /* The following code tries to approximate the conditions under which 14418334Speter we can easily save and restore a register without scratch registers or 14518334Speter other complexities. It will usually work, except under conditions where 14618334Speter the validity of an insn operand is dependent on the address offset. 14718334Speter No such cases are currently known. 14818334Speter 14918334Speter We first find a typical offset from some BASE_REG_CLASS register. 15018334Speter This address is chosen by finding the first register in the class 15118334Speter and by finding the smallest power of two that is a valid offset from 15218334Speter that register in every mode we will use to save registers. */ 15318334Speter 15418334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 15590075Sobrien if (TEST_HARD_REG_BIT 15690075Sobrien (reg_class_contents 157169689Skan [(int) base_reg_class (regno_save_mode [i][1], PLUS, CONST_INT)], i)) 15818334Speter break; 15918334Speter 160169689Skan gcc_assert (i < FIRST_PSEUDO_REGISTER); 16118334Speter 16250397Sobrien addr_reg = gen_rtx_REG (Pmode, i); 16318334Speter 16418334Speter for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1) 16518334Speter { 16650397Sobrien address = gen_rtx_PLUS (Pmode, addr_reg, GEN_INT (offset)); 16718334Speter 16818334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 16918334Speter if (regno_save_mode[i][1] != VOIDmode 17018334Speter && ! strict_memory_address_p (regno_save_mode[i][1], address)) 17118334Speter break; 17218334Speter 17318334Speter if (i == FIRST_PSEUDO_REGISTER) 17418334Speter break; 17518334Speter } 17618334Speter 17718334Speter /* If we didn't find a valid address, we must use register indirect. */ 17818334Speter if (offset == 0) 17918334Speter address = addr_reg; 18018334Speter 18118334Speter /* Next we try to form an insn to save and restore the register. We 182132718Skan see if such an insn is recognized and meets its constraints. 18318334Speter 184117395Skan To avoid lots of unnecessary RTL allocation, we construct all the RTL 185117395Skan once, then modify the memory and register operands in-place. */ 18618334Speter 187117395Skan test_reg = gen_rtx_REG (VOIDmode, 0); 188117395Skan test_mem = gen_rtx_MEM (VOIDmode, address); 189117395Skan savepat = gen_rtx_SET (VOIDmode, test_mem, test_reg); 190117395Skan restpat = gen_rtx_SET (VOIDmode, test_reg, test_mem); 191117395Skan 192117395Skan saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, savepat, -1, 0, 0); 193117395Skan restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, restpat, -1, 0, 0); 194117395Skan 19518334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 19690075Sobrien for (mode = 0 ; mode < MAX_MACHINE_MODE; mode++) 19790075Sobrien if (HARD_REGNO_MODE_OK (i, mode)) 198169689Skan { 19918334Speter int ok; 20018334Speter 201117395Skan /* Update the register number and modes of the register 202117395Skan and memory operand. */ 203117395Skan REGNO (test_reg) = i; 204117395Skan PUT_MODE (test_reg, mode); 205117395Skan PUT_MODE (test_mem, mode); 206117395Skan 207117395Skan /* Force re-recognition of the modified insns. */ 208117395Skan INSN_CODE (saveinsn) = -1; 209117395Skan INSN_CODE (restinsn) = -1; 210117395Skan 21190075Sobrien reg_save_code[i][mode] = recog_memoized (saveinsn); 21290075Sobrien reg_restore_code[i][mode] = recog_memoized (restinsn); 21318334Speter 21450397Sobrien /* Now extract both insns and see if we can meet their 215169689Skan constraints. */ 21690075Sobrien ok = (reg_save_code[i][mode] != -1 21790075Sobrien && reg_restore_code[i][mode] != -1); 21818334Speter if (ok) 21918334Speter { 22052284Sobrien extract_insn (saveinsn); 22152284Sobrien ok = constrain_operands (1); 22252284Sobrien extract_insn (restinsn); 22352284Sobrien ok &= constrain_operands (1); 22418334Speter } 22518334Speter 22618334Speter if (! ok) 22718334Speter { 22890075Sobrien reg_save_code[i][mode] = -1; 22990075Sobrien reg_restore_code[i][mode] = -1; 23018334Speter } 231169689Skan } 23290075Sobrien else 23390075Sobrien { 23490075Sobrien reg_save_code[i][mode] = -1; 23590075Sobrien reg_restore_code[i][mode] = -1; 23690075Sobrien } 237117395Skan 23890075Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 23990075Sobrien for (j = 1; j <= MOVE_MAX_WORDS; j++) 24090075Sobrien if (reg_save_code [i][regno_save_mode[i][j]] == -1) 24190075Sobrien { 24290075Sobrien regno_save_mode[i][j] = VOIDmode; 24390075Sobrien if (j == 1) 24490075Sobrien { 24590075Sobrien call_fixed_regs[i] = 1; 24690075Sobrien SET_HARD_REG_BIT (call_fixed_reg_set, i); 24790075Sobrien } 24890075Sobrien } 24918334Speter} 25018334Speter 25118334Speter/* Initialize save areas by showing that we haven't allocated any yet. */ 25218334Speter 25318334Spetervoid 254132718Skaninit_save_areas (void) 25518334Speter{ 25618334Speter int i, j; 25718334Speter 25818334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 25952284Sobrien for (j = 1; j <= MOVE_MAX_WORDS; j++) 26018334Speter regno_save_mem[i][j] = 0; 26118334Speter} 26218334Speter 26318334Speter/* Allocate save areas for any hard registers that might need saving. 26418334Speter We take a conservative approach here and look for call-clobbered hard 26518334Speter registers that are assigned to pseudos that cross calls. This may 26618334Speter overestimate slightly (especially if some of these registers are later 26718334Speter used as spill registers), but it should not be significant. 26818334Speter 26918334Speter Future work: 27018334Speter 27118334Speter In the fallback case we should iterate backwards across all possible 272132718Skan modes for the save, choosing the largest available one instead of 27318334Speter falling back to the smallest mode immediately. (eg TF -> DF -> SF). 27418334Speter 27518334Speter We do not try to use "move multiple" instructions that exist 276132718Skan on some machines (such as the 68k moveml). It could be a win to try 27718334Speter and use them when possible. The hard part is doing it in a way that is 278132718Skan machine independent since they might be saving non-consecutive 27918334Speter registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */ 28018334Speter 28152284Sobrienvoid 282132718Skansetup_save_areas (void) 28318334Speter{ 28418334Speter int i, j, k; 28590075Sobrien unsigned int r; 28618334Speter HARD_REG_SET hard_regs_used; 28718334Speter 28818334Speter /* Allocate space in the save area for the largest multi-register 28918334Speter pseudos first, then work backwards to single register 29018334Speter pseudos. */ 29118334Speter 29218334Speter /* Find and record all call-used hard-registers in this function. */ 29318334Speter CLEAR_HARD_REG_SET (hard_regs_used); 29418334Speter for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 29550397Sobrien if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0) 29618334Speter { 29790075Sobrien unsigned int regno = reg_renumber[i]; 298132718Skan unsigned int endregno 299169689Skan = regno + hard_regno_nregs[regno][GET_MODE (regno_reg_rtx[i])]; 30018334Speter 30190075Sobrien for (r = regno; r < endregno; r++) 30290075Sobrien if (call_used_regs[r]) 30390075Sobrien SET_HARD_REG_BIT (hard_regs_used, r); 30418334Speter } 30518334Speter 30618334Speter /* Now run through all the call-used hard-registers and allocate 30718334Speter space for them in the caller-save area. Try to allocate space 30818334Speter in a manner which allows multi-register saves/restores to be done. */ 30918334Speter 31018334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 31152284Sobrien for (j = MOVE_MAX_WORDS; j > 0; j--) 31218334Speter { 31352284Sobrien int do_save = 1; 31418334Speter 31518334Speter /* If no mode exists for this size, try another. Also break out 31618334Speter if we have already saved this hard register. */ 31718334Speter if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0) 31818334Speter continue; 31918334Speter 32018334Speter /* See if any register in this group has been saved. */ 32118334Speter for (k = 0; k < j; k++) 32218334Speter if (regno_save_mem[i + k][1]) 32318334Speter { 32418334Speter do_save = 0; 32518334Speter break; 32618334Speter } 32718334Speter if (! do_save) 32818334Speter continue; 32918334Speter 33018334Speter for (k = 0; k < j; k++) 33152284Sobrien if (! TEST_HARD_REG_BIT (hard_regs_used, i + k)) 33218334Speter { 33352284Sobrien do_save = 0; 33452284Sobrien break; 33518334Speter } 33652284Sobrien if (! do_save) 33752284Sobrien continue; 33818334Speter 33950397Sobrien /* We have found an acceptable mode to store in. */ 34052284Sobrien regno_save_mem[i][j] 34152284Sobrien = assign_stack_local (regno_save_mode[i][j], 34252284Sobrien GET_MODE_SIZE (regno_save_mode[i][j]), 0); 34352284Sobrien 34452284Sobrien /* Setup single word save area just in case... */ 34552284Sobrien for (k = 0; k < j; k++) 34690075Sobrien /* This should not depend on WORDS_BIG_ENDIAN. 34790075Sobrien The order of words in regs is the same as in memory. */ 34890075Sobrien regno_save_mem[i + k][1] 34990075Sobrien = adjust_address_nv (regno_save_mem[i][j], 35090075Sobrien regno_save_mode[i + k][1], 35190075Sobrien k * UNITS_PER_WORD); 35290075Sobrien } 35318334Speter 35490075Sobrien /* Now loop again and set the alias set of any save areas we made to 35590075Sobrien the alias set used to represent frame objects. */ 35690075Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 35790075Sobrien for (j = MOVE_MAX_WORDS; j > 0; j--) 35890075Sobrien if (regno_save_mem[i][j] != 0) 35990075Sobrien set_mem_alias_set (regno_save_mem[i][j], get_frame_alias_set ()); 36018334Speter} 36118334Speter 36252284Sobrien/* Find the places where hard regs are live across calls and save them. */ 36390075Sobrien 36418334Spetervoid 365132718Skansave_call_clobbered_regs (void) 36618334Speter{ 36752284Sobrien struct insn_chain *chain, *next; 36890075Sobrien enum machine_mode save_mode [FIRST_PSEUDO_REGISTER]; 36918334Speter 370169689Skan /* Computed in mark_set_regs, holds all registers set by the current 371169689Skan instruction. */ 372169689Skan HARD_REG_SET this_insn_sets; 373169689Skan 37452284Sobrien CLEAR_HARD_REG_SET (hard_regs_saved); 37552284Sobrien n_regs_saved = 0; 37652284Sobrien 37752284Sobrien for (chain = reload_insn_chain; chain != 0; chain = next) 37818334Speter { 37952284Sobrien rtx insn = chain->insn; 38052284Sobrien enum rtx_code code = GET_CODE (insn); 38118334Speter 38252284Sobrien next = chain->next; 38318334Speter 384169689Skan gcc_assert (!chain->is_caller_save_insn); 38518334Speter 386169689Skan if (INSN_P (insn)) 38718334Speter { 38852284Sobrien /* If some registers have been saved, see if INSN references 38952284Sobrien any of them. We must restore them before the insn if so. */ 39018334Speter 39152284Sobrien if (n_regs_saved) 39218334Speter { 39352284Sobrien int regno; 39418334Speter 39552284Sobrien if (code == JUMP_INSN) 39652284Sobrien /* Restore all registers if this is a JUMP_INSN. */ 39752284Sobrien COPY_HARD_REG_SET (referenced_regs, hard_regs_saved); 39852284Sobrien else 39952284Sobrien { 40052284Sobrien CLEAR_HARD_REG_SET (referenced_regs); 40152284Sobrien mark_referenced_regs (PATTERN (insn)); 40252284Sobrien AND_HARD_REG_SET (referenced_regs, hard_regs_saved); 40352284Sobrien } 40418334Speter 40552284Sobrien for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 40652284Sobrien if (TEST_HARD_REG_BIT (referenced_regs, regno)) 40790075Sobrien regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode); 40852284Sobrien } 40918334Speter 410132718Skan if (code == CALL_INSN && ! find_reg_note (insn, REG_NORETURN, NULL)) 41152284Sobrien { 412169689Skan unsigned regno; 41352284Sobrien HARD_REG_SET hard_regs_to_save; 414169689Skan reg_set_iterator rsi; 41518334Speter 41652284Sobrien /* Use the register life information in CHAIN to compute which 41790075Sobrien regs are live during the call. */ 41890075Sobrien REG_SET_TO_HARD_REG_SET (hard_regs_to_save, 41990075Sobrien &chain->live_throughout); 42090075Sobrien /* Save hard registers always in the widest mode available. */ 42190075Sobrien for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 42290075Sobrien if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) 42390075Sobrien save_mode [regno] = regno_save_mode [regno][1]; 42490075Sobrien else 42590075Sobrien save_mode [regno] = VOIDmode; 42618334Speter 42790075Sobrien /* Look through all live pseudos, mark their hard registers 42890075Sobrien and choose proper mode for saving. */ 42990075Sobrien EXECUTE_IF_SET_IN_REG_SET 430169689Skan (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi) 431169689Skan { 432169689Skan int r = reg_renumber[regno]; 433169689Skan int nregs; 434169689Skan enum machine_mode mode; 43590075Sobrien 436169689Skan gcc_assert (r >= 0); 437169689Skan nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)]; 438169689Skan mode = HARD_REGNO_CALLER_SAVE_MODE 439169689Skan (r, nregs, PSEUDO_REGNO_MODE (regno)); 440169689Skan if (GET_MODE_BITSIZE (mode) 441169689Skan > GET_MODE_BITSIZE (save_mode[r])) 442169689Skan save_mode[r] = mode; 443169689Skan while (nregs-- > 0) 444169689Skan SET_HARD_REG_BIT (hard_regs_to_save, r + nregs); 445169689Skan } 44690075Sobrien 44752284Sobrien /* Record all registers set in this call insn. These don't need 44890075Sobrien to be saved. N.B. the call insn might set a subreg of a 44990075Sobrien multi-hard-reg pseudo; then the pseudo is considered live 45090075Sobrien during the call, but the subreg that is set isn't. */ 45152284Sobrien CLEAR_HARD_REG_SET (this_insn_sets); 452169689Skan note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets); 453169689Skan /* Sibcalls are considered to set the return value, 454169689Skan compare flow.c:propagate_one_insn. */ 455169689Skan if (SIBLING_CALL_P (insn) && current_function_return_rtx) 456169689Skan mark_set_regs (current_function_return_rtx, NULL_RTX, 457169689Skan &this_insn_sets); 45818334Speter 45952284Sobrien /* Compute which hard regs must be saved before this call. */ 46052284Sobrien AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); 46152284Sobrien AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets); 46252284Sobrien AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); 46352284Sobrien AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set); 46452284Sobrien 46552284Sobrien for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 46652284Sobrien if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) 46790075Sobrien regno += insert_save (chain, 1, regno, &hard_regs_to_save, save_mode); 46818334Speter 46952284Sobrien /* Must recompute n_regs_saved. */ 47052284Sobrien n_regs_saved = 0; 47152284Sobrien for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 47252284Sobrien if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) 47352284Sobrien n_regs_saved++; 47418334Speter } 47518334Speter } 47618334Speter 47752284Sobrien if (chain->next == 0 || chain->next->block > chain->block) 47852284Sobrien { 47952284Sobrien int regno; 48052284Sobrien /* At the end of the basic block, we must restore any registers that 48152284Sobrien remain saved. If the last insn in the block is a JUMP_INSN, put 48252284Sobrien the restore before the insn, otherwise, put it after the insn. */ 48318334Speter 48452284Sobrien if (n_regs_saved) 48552284Sobrien for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 48652284Sobrien if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) 487169689Skan regno += insert_restore (chain, JUMP_P (insn), 48890075Sobrien regno, MOVE_MAX_WORDS, save_mode); 48952284Sobrien } 490132718Skan } 49118334Speter} 49218334Speter 493169689Skan/* Here from note_stores, or directly from save_call_clobbered_regs, when 494169689Skan an insn stores a value in a register. 49552284Sobrien Set the proper bit or bits in this_insn_sets. All pseudos that have 49618334Speter been assigned hard regs have had their register number changed already, 49718334Speter so we can ignore pseudos. */ 49818334Speterstatic void 499169689Skanmark_set_regs (rtx reg, rtx setter ATTRIBUTE_UNUSED, void *data) 50018334Speter{ 50190075Sobrien int regno, endregno, i; 50218334Speter enum machine_mode mode = GET_MODE (reg); 503169689Skan HARD_REG_SET *this_insn_sets = data; 50418334Speter 50518334Speter if (GET_CODE (reg) == SUBREG) 50618334Speter { 50790075Sobrien rtx inner = SUBREG_REG (reg); 508169689Skan if (!REG_P (inner) || REGNO (inner) >= FIRST_PSEUDO_REGISTER) 50990075Sobrien return; 510169689Skan regno = subreg_regno (reg); 51190075Sobrien } 512169689Skan else if (REG_P (reg) 51390075Sobrien && REGNO (reg) < FIRST_PSEUDO_REGISTER) 51490075Sobrien regno = REGNO (reg); 51590075Sobrien else 51690075Sobrien return; 51790075Sobrien 518169689Skan endregno = regno + hard_regno_nregs[regno][mode]; 51990075Sobrien 52090075Sobrien for (i = regno; i < endregno; i++) 521169689Skan SET_HARD_REG_BIT (*this_insn_sets, i); 52290075Sobrien} 52390075Sobrien 52490075Sobrien/* Here from note_stores when an insn stores a value in a register. 52590075Sobrien Set the proper bit or bits in the passed regset. All pseudos that have 52690075Sobrien been assigned hard regs have had their register number changed already, 52790075Sobrien so we can ignore pseudos. */ 52890075Sobrienstatic void 529132718Skanadd_stored_regs (rtx reg, rtx setter, void *data) 53090075Sobrien{ 53190075Sobrien int regno, endregno, i; 53290075Sobrien enum machine_mode mode = GET_MODE (reg); 53390075Sobrien int offset = 0; 53490075Sobrien 53590075Sobrien if (GET_CODE (setter) == CLOBBER) 53690075Sobrien return; 53790075Sobrien 538169689Skan if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg))) 53990075Sobrien { 54090075Sobrien offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)), 54190075Sobrien GET_MODE (SUBREG_REG (reg)), 54290075Sobrien SUBREG_BYTE (reg), 54390075Sobrien GET_MODE (reg)); 54418334Speter reg = SUBREG_REG (reg); 54518334Speter } 54618334Speter 547169689Skan if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER) 54818334Speter return; 54918334Speter 55090075Sobrien regno = REGNO (reg) + offset; 551169689Skan endregno = regno + hard_regno_nregs[regno][mode]; 55218334Speter 55318334Speter for (i = regno; i < endregno; i++) 55490075Sobrien SET_REGNO_REG_SET ((regset) data, i); 55518334Speter} 55618334Speter 55752284Sobrien/* Walk X and record all referenced registers in REFERENCED_REGS. */ 55818334Speterstatic void 559132718Skanmark_referenced_regs (rtx x) 56018334Speter{ 56118334Speter enum rtx_code code = GET_CODE (x); 56290075Sobrien const char *fmt; 56318334Speter int i, j; 56418334Speter 56552284Sobrien if (code == SET) 56652284Sobrien mark_referenced_regs (SET_SRC (x)); 56752284Sobrien if (code == SET || code == CLOBBER) 56852284Sobrien { 56952284Sobrien x = SET_DEST (x); 57052284Sobrien code = GET_CODE (x); 571132718Skan if ((code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER) 572132718Skan || code == PC || code == CC0 573169689Skan || (code == SUBREG && REG_P (SUBREG_REG (x)) 574132718Skan && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER 57590075Sobrien /* If we're setting only part of a multi-word register, 57690075Sobrien we shall mark it as referenced, because the words 57790075Sobrien that are not being set should be restored. */ 57890075Sobrien && ((GET_MODE_SIZE (GET_MODE (x)) 57990075Sobrien >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 58090075Sobrien || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) 58190075Sobrien <= UNITS_PER_WORD)))) 58252284Sobrien return; 58352284Sobrien } 58452284Sobrien if (code == MEM || code == SUBREG) 58552284Sobrien { 58652284Sobrien x = XEXP (x, 0); 58752284Sobrien code = GET_CODE (x); 58852284Sobrien } 58918334Speter 59018334Speter if (code == REG) 59118334Speter { 59218334Speter int regno = REGNO (x); 59352284Sobrien int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno 59452284Sobrien : reg_renumber[regno]); 59518334Speter 59652284Sobrien if (hardregno >= 0) 59718334Speter { 598169689Skan int nregs = hard_regno_nregs[hardregno][GET_MODE (x)]; 59952284Sobrien while (nregs-- > 0) 60052284Sobrien SET_HARD_REG_BIT (referenced_regs, hardregno + nregs); 60118334Speter } 60252284Sobrien /* If this is a pseudo that did not get a hard register, scan its 60352284Sobrien memory location, since it might involve the use of another 60452284Sobrien register, which might be saved. */ 60552284Sobrien else if (reg_equiv_mem[regno] != 0) 60652284Sobrien mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0)); 60752284Sobrien else if (reg_equiv_address[regno] != 0) 60852284Sobrien mark_referenced_regs (reg_equiv_address[regno]); 60918334Speter return; 61018334Speter } 61152284Sobrien 61218334Speter fmt = GET_RTX_FORMAT (code); 61318334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 61418334Speter { 61518334Speter if (fmt[i] == 'e') 61652284Sobrien mark_referenced_regs (XEXP (x, i)); 61718334Speter else if (fmt[i] == 'E') 61818334Speter for (j = XVECLEN (x, i) - 1; j >= 0; j--) 61952284Sobrien mark_referenced_regs (XVECEXP (x, i, j)); 62018334Speter } 62118334Speter} 62218334Speter 62352284Sobrien/* Insert a sequence of insns to restore. Place these insns in front of 62452284Sobrien CHAIN if BEFORE_P is nonzero, behind the insn otherwise. MAXRESTORE is 62552284Sobrien the maximum number of registers which should be restored during this call. 62652284Sobrien It should never be less than 1 since we only work with entire registers. 62718334Speter 62818334Speter Note that we have verified in init_caller_save that we can do this 62918334Speter with a simple SET, so use it. Set INSN_CODE to what we save there 63018334Speter since the address might not be valid so the insn might not be recognized. 63118334Speter These insns will be reloaded and have register elimination done by 63218334Speter find_reload, so we need not worry about that here. 63318334Speter 63418334Speter Return the extra number of registers saved. */ 63518334Speter 63618334Speterstatic int 637132718Skaninsert_restore (struct insn_chain *chain, int before_p, int regno, 638132718Skan int maxrestore, enum machine_mode *save_mode) 63918334Speter{ 64090075Sobrien int i, k; 64150397Sobrien rtx pat = NULL_RTX; 64290075Sobrien int code; 64390075Sobrien unsigned int numregs = 0; 64490075Sobrien struct insn_chain *new; 64590075Sobrien rtx mem; 64618334Speter 647169689Skan /* A common failure mode if register status is not correct in the 648169689Skan RTL is for this routine to be called with a REGNO we didn't 649169689Skan expect to save. That will cause us to write an insn with a (nil) 650169689Skan SET_DEST or SET_SRC. Instead of doing so and causing a crash 651169689Skan later, check for this common case here instead. This will remove 652169689Skan one step in debugging such problems. */ 653169689Skan gcc_assert (regno_save_mem[regno][1]); 65418334Speter 65552284Sobrien /* Get the pattern to emit and update our status. 65618334Speter 65752284Sobrien See if we can restore `maxrestore' registers at once. Work 65852284Sobrien backwards to the single register case. */ 65952284Sobrien for (i = maxrestore; i > 0; i--) 66018334Speter { 66190075Sobrien int j; 66252284Sobrien int ok = 1; 66318334Speter 66452284Sobrien if (regno_save_mem[regno][i] == 0) 66552284Sobrien continue; 66652284Sobrien 66752284Sobrien for (j = 0; j < i; j++) 66852284Sobrien if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j)) 66952284Sobrien { 67052284Sobrien ok = 0; 67152284Sobrien break; 67252284Sobrien } 673132718Skan /* Must do this one restore at a time. */ 67452284Sobrien if (! ok) 67552284Sobrien continue; 67652284Sobrien 67752284Sobrien numregs = i; 67852284Sobrien break; 67952284Sobrien } 68018334Speter 68190075Sobrien mem = regno_save_mem [regno][numregs]; 68290075Sobrien if (save_mode [regno] != VOIDmode 68390075Sobrien && save_mode [regno] != GET_MODE (mem) 684169689Skan && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]]) 68590075Sobrien mem = adjust_address (mem, save_mode[regno], 0); 686169689Skan else 687169689Skan mem = copy_rtx (mem); 68890075Sobrien pat = gen_rtx_SET (VOIDmode, 689132718Skan gen_rtx_REG (GET_MODE (mem), 69090075Sobrien regno), mem); 69190075Sobrien code = reg_restore_code[regno][GET_MODE (mem)]; 69290075Sobrien new = insert_one_insn (chain, before_p, code, pat); 69318334Speter 69490075Sobrien /* Clear status for all registers we restored. */ 69590075Sobrien for (k = 0; k < i; k++) 69690075Sobrien { 69790075Sobrien CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k); 69890075Sobrien SET_REGNO_REG_SET (&new->dead_or_set, regno + k); 69990075Sobrien n_regs_saved--; 70090075Sobrien } 70190075Sobrien 702132718Skan /* Tell our callers how many extra registers we saved/restored. */ 70352284Sobrien return numregs - 1; 70452284Sobrien} 70518334Speter 70652284Sobrien/* Like insert_restore above, but save registers instead. */ 70790075Sobrien 70852284Sobrienstatic int 709132718Skaninsert_save (struct insn_chain *chain, int before_p, int regno, 710132718Skan HARD_REG_SET (*to_save), enum machine_mode *save_mode) 71152284Sobrien{ 71252284Sobrien int i; 71390075Sobrien unsigned int k; 71452284Sobrien rtx pat = NULL_RTX; 71590075Sobrien int code; 71690075Sobrien unsigned int numregs = 0; 71790075Sobrien struct insn_chain *new; 71890075Sobrien rtx mem; 71952284Sobrien 720169689Skan /* A common failure mode if register status is not correct in the 721169689Skan RTL is for this routine to be called with a REGNO we didn't 722169689Skan expect to save. That will cause us to write an insn with a (nil) 723169689Skan SET_DEST or SET_SRC. Instead of doing so and causing a crash 724169689Skan later, check for this common case here. This will remove one 72552284Sobrien step in debugging such problems. */ 726169689Skan gcc_assert (regno_save_mem[regno][1]); 72752284Sobrien 72852284Sobrien /* Get the pattern to emit and update our status. 72952284Sobrien 730132718Skan See if we can save several registers with a single instruction. 73152284Sobrien Work backwards to the single register case. */ 73252284Sobrien for (i = MOVE_MAX_WORDS; i > 0; i--) 73318334Speter { 73490075Sobrien int j; 73552284Sobrien int ok = 1; 73652284Sobrien if (regno_save_mem[regno][i] == 0) 73752284Sobrien continue; 73818334Speter 73952284Sobrien for (j = 0; j < i; j++) 74052284Sobrien if (! TEST_HARD_REG_BIT (*to_save, regno + j)) 74152284Sobrien { 74252284Sobrien ok = 0; 74352284Sobrien break; 74452284Sobrien } 745132718Skan /* Must do this one save at a time. */ 74652284Sobrien if (! ok) 74752284Sobrien continue; 74818334Speter 74952284Sobrien numregs = i; 75052284Sobrien break; 75118334Speter } 75218334Speter 75390075Sobrien mem = regno_save_mem [regno][numregs]; 75490075Sobrien if (save_mode [regno] != VOIDmode 75590075Sobrien && save_mode [regno] != GET_MODE (mem) 756169689Skan && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]]) 75790075Sobrien mem = adjust_address (mem, save_mode[regno], 0); 758169689Skan else 759169689Skan mem = copy_rtx (mem); 76090075Sobrien pat = gen_rtx_SET (VOIDmode, mem, 76190075Sobrien gen_rtx_REG (GET_MODE (mem), 76290075Sobrien regno)); 76390075Sobrien code = reg_save_code[regno][GET_MODE (mem)]; 76490075Sobrien new = insert_one_insn (chain, before_p, code, pat); 76518334Speter 76690075Sobrien /* Set hard_regs_saved and dead_or_set for all the registers we saved. */ 76790075Sobrien for (k = 0; k < numregs; k++) 76890075Sobrien { 76990075Sobrien SET_HARD_REG_BIT (hard_regs_saved, regno + k); 77090075Sobrien SET_REGNO_REG_SET (&new->dead_or_set, regno + k); 77190075Sobrien n_regs_saved++; 77290075Sobrien } 77390075Sobrien 774132718Skan /* Tell our callers how many extra registers we saved/restored. */ 77518334Speter return numregs - 1; 77618334Speter} 77752284Sobrien 77852284Sobrien/* Emit a new caller-save insn and set the code. */ 77990075Sobrienstatic struct insn_chain * 780132718Skaninsert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat) 78152284Sobrien{ 78252284Sobrien rtx insn = chain->insn; 78352284Sobrien struct insn_chain *new; 784132718Skan 78552284Sobrien#ifdef HAVE_cc0 78652284Sobrien /* If INSN references CC0, put our insns in front of the insn that sets 78752284Sobrien CC0. This is always safe, since the only way we could be passed an 78852284Sobrien insn that references CC0 is for a restore, and doing a restore earlier 78952284Sobrien isn't a problem. We do, however, assume here that CALL_INSNs don't 79052284Sobrien reference CC0. Guard against non-INSN's like CODE_LABEL. */ 79152284Sobrien 792169689Skan if ((NONJUMP_INSN_P (insn) || JUMP_P (insn)) 79352284Sobrien && before_p 79452284Sobrien && reg_referenced_p (cc0_rtx, PATTERN (insn))) 79552284Sobrien chain = chain->prev, insn = chain->insn; 79652284Sobrien#endif 79752284Sobrien 79852284Sobrien new = new_insn_chain (); 79952284Sobrien if (before_p) 80052284Sobrien { 80190075Sobrien rtx link; 80290075Sobrien 80352284Sobrien new->prev = chain->prev; 80452284Sobrien if (new->prev != 0) 80552284Sobrien new->prev->next = new; 80652284Sobrien else 80752284Sobrien reload_insn_chain = new; 80852284Sobrien 80952284Sobrien chain->prev = new; 81052284Sobrien new->next = chain; 81152284Sobrien new->insn = emit_insn_before (pat, insn); 81252284Sobrien /* ??? It would be nice if we could exclude the already / still saved 81352284Sobrien registers from the live sets. */ 81490075Sobrien COPY_REG_SET (&new->live_throughout, &chain->live_throughout); 81590075Sobrien /* Registers that die in CHAIN->INSN still live in the new insn. */ 81690075Sobrien for (link = REG_NOTES (chain->insn); link; link = XEXP (link, 1)) 81790075Sobrien { 81890075Sobrien if (REG_NOTE_KIND (link) == REG_DEAD) 81990075Sobrien { 82090075Sobrien rtx reg = XEXP (link, 0); 82190075Sobrien int regno, i; 82290075Sobrien 823169689Skan gcc_assert (REG_P (reg)); 82490075Sobrien regno = REGNO (reg); 82590075Sobrien if (regno >= FIRST_PSEUDO_REGISTER) 82690075Sobrien regno = reg_renumber[regno]; 82790075Sobrien if (regno < 0) 82890075Sobrien continue; 829169689Skan for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1; 83090075Sobrien i >= 0; i--) 83190075Sobrien SET_REGNO_REG_SET (&new->live_throughout, regno + i); 83290075Sobrien } 83390075Sobrien } 83490075Sobrien CLEAR_REG_SET (&new->dead_or_set); 835132718Skan if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block))) 836132718Skan BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn; 83752284Sobrien } 83852284Sobrien else 83952284Sobrien { 84052284Sobrien new->next = chain->next; 84152284Sobrien if (new->next != 0) 84252284Sobrien new->next->prev = new; 84352284Sobrien chain->next = new; 84452284Sobrien new->prev = chain; 84552284Sobrien new->insn = emit_insn_after (pat, insn); 84652284Sobrien /* ??? It would be nice if we could exclude the already / still saved 84752284Sobrien registers from the live sets, and observe REG_UNUSED notes. */ 84890075Sobrien COPY_REG_SET (&new->live_throughout, &chain->live_throughout); 84990075Sobrien /* Registers that are set in CHAIN->INSN live in the new insn. 850169689Skan (Unless there is a REG_UNUSED note for them, but we don't 85190075Sobrien look for them here.) */ 85290075Sobrien note_stores (PATTERN (chain->insn), add_stored_regs, 85390075Sobrien &new->live_throughout); 85490075Sobrien CLEAR_REG_SET (&new->dead_or_set); 855132718Skan if (chain->insn == BB_END (BASIC_BLOCK (chain->block))) 856132718Skan BB_END (BASIC_BLOCK (chain->block)) = new->insn; 85752284Sobrien } 85852284Sobrien new->block = chain->block; 85952284Sobrien new->is_caller_save_insn = 1; 86052284Sobrien 86152284Sobrien INSN_CODE (new->insn) = code; 86290075Sobrien return new; 86352284Sobrien} 864