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