/* Save and restore call-clobbered registers which are live across a call.
   Copyright (C) 1989-2022 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "predict.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "reload.h"
#include "alias.h"
#include "addresses.h"
#include "dumpfile.h"
#include "rtl-iter.h"
#include "target.h"
#include "function-abi.h"

#define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD)

#define regno_save_mode \
  (this_target_reload->x_regno_save_mode)
#define cached_reg_save_code \
  (this_target_reload->x_cached_reg_save_code)
#define cached_reg_restore_code \
  (this_target_reload->x_cached_reg_restore_code)

/* For each hard register, a place on the stack where it can be saved,
   if needed.  */

static rtx
  regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];

/* The number of elements in the subsequent array.  */
static int save_slots_num;

/* Allocated slots so far.  */
static rtx save_slots[FIRST_PSEUDO_REGISTER];

/* Set of hard regs currently residing in save area (during insn scan).  */

static HARD_REG_SET hard_regs_saved;

/* Number of registers currently in hard_regs_saved.  */

static int n_regs_saved;

/* Computed by mark_referenced_regs, all regs referenced in a given
   insn.  */
static HARD_REG_SET referenced_regs;


typedef void refmarker_fn (rtx *loc, machine_mode mode, int hardregno,
			   void *mark_arg);

static int reg_save_code (int, machine_mode);
static int reg_restore_code (int, machine_mode);

struct saved_hard_reg;
static void initiate_saved_hard_regs (void);
static void new_saved_hard_reg (int, int);
static void finish_saved_hard_regs (void);
static int saved_hard_reg_compare_func (const void *, const void *);

static void mark_set_regs (rtx, const_rtx, void *);
static void mark_referenced_regs (rtx *, refmarker_fn *mark, void *mark_arg);
static refmarker_fn mark_reg_as_referenced;
static refmarker_fn replace_reg_with_saved_mem;
static int insert_save (class insn_chain *, int, HARD_REG_SET *,
			machine_mode *);
static int insert_restore (class insn_chain *, int, int, int,
			   machine_mode *);
static class insn_chain *insert_one_insn (class insn_chain *, int, int,
					   rtx);
static void add_stored_regs (rtx, const_rtx, void *);



static GTY(()) rtx savepat;
static GTY(()) rtx restpat;
static GTY(()) rtx test_reg;
static GTY(()) rtx test_mem;
static GTY(()) rtx_insn *saveinsn;
static GTY(()) rtx_insn *restinsn;

/* Return the INSN_CODE used to save register REG in mode MODE.  */
static int
reg_save_code (int reg, machine_mode mode)
{
  bool ok;
  if (cached_reg_save_code[reg][mode])
     return cached_reg_save_code[reg][mode];
  if (!targetm.hard_regno_mode_ok (reg, mode))
    {
      /* Depending on how targetm.hard_regno_mode_ok is defined, range
	 propagation might deduce here that reg >= FIRST_PSEUDO_REGISTER.
	 So the assert below silences a warning.  */
      gcc_assert (reg < FIRST_PSEUDO_REGISTER);
      cached_reg_save_code[reg][mode] = -1;
      cached_reg_restore_code[reg][mode] = -1;
      return -1;
    }

  /* Update the register number and modes of the register
     and memory operand.  */
  set_mode_and_regno (test_reg, mode, reg);
  PUT_MODE (test_mem, mode);

  /* Force re-recognition of the modified insns.  */
  INSN_CODE (saveinsn) = -1;
  INSN_CODE (restinsn) = -1;

  cached_reg_save_code[reg][mode] = recog_memoized (saveinsn);
  cached_reg_restore_code[reg][mode] = recog_memoized (restinsn);

  /* Now extract both insns and see if we can meet their
     constraints.  We don't know here whether the save and restore will
     be in size- or speed-tuned code, so just use the set of enabled
     alternatives.  */
  ok = (cached_reg_save_code[reg][mode] != -1
	&& cached_reg_restore_code[reg][mode] != -1);
  if (ok)
    {
      extract_insn (saveinsn);
      ok = constrain_operands (1, get_enabled_alternatives (saveinsn));
      extract_insn (restinsn);
      ok &= constrain_operands (1, get_enabled_alternatives (restinsn));
    }

  if (! ok)
    {
      cached_reg_save_code[reg][mode] = -1;
      cached_reg_restore_code[reg][mode] = -1;
    }
  gcc_assert (cached_reg_save_code[reg][mode]);
  return cached_reg_save_code[reg][mode];
}

/* Return the INSN_CODE used to restore register REG in mode MODE.  */
static int
reg_restore_code (int reg, machine_mode mode)
{
  if (cached_reg_restore_code[reg][mode])
     return cached_reg_restore_code[reg][mode];
  /* Populate our cache.  */
  reg_save_code (reg, mode);
  return cached_reg_restore_code[reg][mode];
}

/* Initialize for caller-save.

   Look at all the hard registers that are used by a call and for which
   reginfo.cc has not already excluded from being used across a call.

   Ensure that we can find a mode to save the register and that there is a
   simple insn to save and restore the register.  This latter check avoids
   problems that would occur if we tried to save the MQ register of some
   machines directly into memory.  */

void
init_caller_save (void)
{
  rtx addr_reg;
  int offset;
  rtx address;
  int i, j;

  if (caller_save_initialized_p)
    return;

  caller_save_initialized_p = true;

  /* First find all the registers that we need to deal with and all
     the modes that they can have.  If we can't find a mode to use,
     we can't have the register live over calls.  */

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    for (j = 1; j <= MOVE_MAX_WORDS; j++)
      {
	regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, VOIDmode);
	if (regno_save_mode[i][j] == VOIDmode && j == 1)
	  CLEAR_HARD_REG_BIT (savable_regs, i);
      }

  /* The following code tries to approximate the conditions under which
     we can easily save and restore a register without scratch registers or
     other complexities.  It will usually work, except under conditions where
     the validity of an insn operand is dependent on the address offset.
     No such cases are currently known.

     We first find a typical offset from some BASE_REG_CLASS register.
     This address is chosen by finding the first register in the class
     and by finding the smallest power of two that is a valid offset from
     that register in every mode we will use to save registers.  */

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (TEST_HARD_REG_BIT
	(reg_class_contents
	 [(int) base_reg_class (regno_save_mode[i][1], ADDR_SPACE_GENERIC,
				PLUS, CONST_INT)], i))
      break;

  gcc_assert (i < FIRST_PSEUDO_REGISTER);

  addr_reg = gen_rtx_REG (Pmode, i);

  for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1)
    {
      address = gen_rtx_PLUS (Pmode, addr_reg, gen_int_mode (offset, Pmode));

      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (regno_save_mode[i][1] != VOIDmode
	  && ! strict_memory_address_p (regno_save_mode[i][1], address))
	  break;

      if (i == FIRST_PSEUDO_REGISTER)
	break;
    }

  /* If we didn't find a valid address, we must use register indirect.  */
  if (offset == 0)
    address = addr_reg;

  /* Next we try to form an insn to save and restore the register.  We
     see if such an insn is recognized and meets its constraints.

     To avoid lots of unnecessary RTL allocation, we construct all the RTL
     once, then modify the memory and register operands in-place.  */

  test_reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
  test_mem = gen_rtx_MEM (word_mode, address);
  savepat = gen_rtx_SET (test_mem, test_reg);
  restpat = gen_rtx_SET (test_reg, test_mem);

  saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, savepat, 0, -1, 0);
  restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, restpat, 0, -1, 0);

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    for (j = 1; j <= MOVE_MAX_WORDS; j++)
      if (reg_save_code (i,regno_save_mode[i][j]) == -1)
	{
	  regno_save_mode[i][j] = VOIDmode;
	  if (j == 1)
	    CLEAR_HARD_REG_BIT (savable_regs, i);
	}
}



/* Initialize save areas by showing that we haven't allocated any yet.  */

void
init_save_areas (void)
{
  int i, j;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    for (j = 1; j <= MOVE_MAX_WORDS; j++)
      regno_save_mem[i][j] = 0;
  save_slots_num = 0;

}

/* The structure represents a hard register which should be saved
   through the call.  It is used when the integrated register
   allocator (IRA) is used and sharing save slots is on.  */
struct saved_hard_reg
{
  /* Order number starting with 0.  */
  int num;
  /* The hard regno.  */
  int hard_regno;
  /* Execution frequency of all calls through which given hard
     register should be saved.  */
  int call_freq;
  /* Stack slot reserved to save the hard register through calls.  */
  rtx slot;
  /* True if it is first hard register in the chain of hard registers
     sharing the same stack slot.  */
  int first_p;
  /* Order number of the next hard register structure with the same
     slot in the chain.  -1 represents end of the chain.  */
  int next;
};

/* Map: hard register number to the corresponding structure.  */
static struct saved_hard_reg *hard_reg_map[FIRST_PSEUDO_REGISTER];

/* The number of all structures representing hard registers should be
   saved, in order words, the number of used elements in the following
   array.  */
static int saved_regs_num;

/* Pointers to all the structures.  Index is the order number of the
   corresponding structure.  */
static struct saved_hard_reg *all_saved_regs[FIRST_PSEUDO_REGISTER];

/* First called function for work with saved hard registers.  */
static void
initiate_saved_hard_regs (void)
{
  int i;

  saved_regs_num = 0;
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    hard_reg_map[i] = NULL;
}

/* Allocate and return new saved hard register with given REGNO and
   CALL_FREQ.  */
static void
new_saved_hard_reg (int regno, int call_freq)
{
  struct saved_hard_reg *saved_reg;

  saved_reg
    = (struct saved_hard_reg *) xmalloc (sizeof (struct saved_hard_reg));
  hard_reg_map[regno] = all_saved_regs[saved_regs_num] = saved_reg;
  saved_reg->num = saved_regs_num++;
  saved_reg->hard_regno = regno;
  saved_reg->call_freq = call_freq;
  saved_reg->first_p = FALSE;
  saved_reg->next = -1;
}

/* Free memory allocated for the saved hard registers.  */
static void
finish_saved_hard_regs (void)
{
  int i;

  for (i = 0; i < saved_regs_num; i++)
    free (all_saved_regs[i]);
}

/* The function is used to sort the saved hard register structures
   according their frequency.  */
static int
saved_hard_reg_compare_func (const void *v1p, const void *v2p)
{
  const struct saved_hard_reg *p1 = *(struct saved_hard_reg * const *) v1p;
  const struct saved_hard_reg *p2 = *(struct saved_hard_reg * const *) v2p;

  if (flag_omit_frame_pointer)
    {
      if (p1->call_freq - p2->call_freq != 0)
	return p1->call_freq - p2->call_freq;
    }
  else if (p2->call_freq - p1->call_freq != 0)
    return p2->call_freq - p1->call_freq;

  return p1->num - p2->num;
}

/* Allocate save areas for any hard registers that might need saving.
   We take a conservative approach here and look for call-clobbered hard
   registers that are assigned to pseudos that cross calls.  This may
   overestimate slightly (especially if some of these registers are later
   used as spill registers), but it should not be significant.

   For IRA we use priority coloring to decrease stack slots needed for
   saving hard registers through calls.  We build conflicts for them
   to do coloring.

   Future work:

     In the fallback case we should iterate backwards across all possible
     modes for the save, choosing the largest available one instead of
     falling back to the smallest mode immediately.  (eg TF -> DF -> SF).

     We do not try to use "move multiple" instructions that exist
     on some machines (such as the 68k moveml).  It could be a win to try
     and use them when possible.  The hard part is doing it in a way that is
     machine independent since they might be saving non-consecutive
     registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */

void
setup_save_areas (void)
{
  int i, j, k, freq;
  HARD_REG_SET hard_regs_used;
  struct saved_hard_reg *saved_reg;
  rtx_insn *insn;
  class insn_chain *chain, *next;
  unsigned int regno;
  HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets;
  reg_set_iterator rsi;

  CLEAR_HARD_REG_SET (hard_regs_used);

  /* Find every CALL_INSN and record which hard regs are live across the
     call into HARD_REG_MAP and HARD_REGS_USED.  */
  initiate_saved_hard_regs ();
  /* Create hard reg saved regs.  */
  for (chain = reload_insn_chain; chain != 0; chain = next)
    {
      rtx cheap;

      insn = chain->insn;
      next = chain->next;
      if (!CALL_P (insn)
	  || find_reg_note (insn, REG_NORETURN, NULL))
	continue;
      freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
      REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
			       &chain->live_throughout);
      used_regs = insn_callee_abi (insn).full_reg_clobbers ();

      /* Record all registers set in this call insn.  These don't
	 need to be saved.  N.B. the call insn might set a subreg
	 of a multi-hard-reg pseudo; then the pseudo is considered
	 live during the call, but the subreg that is set
	 isn't.  */
      CLEAR_HARD_REG_SET (this_insn_sets);
      note_stores (insn, mark_set_regs, &this_insn_sets);
      /* Sibcalls are considered to set the return value.  */
      if (SIBLING_CALL_P (insn) && crtl->return_rtx)
	mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets);

      used_regs &= ~(fixed_reg_set | this_insn_sets);
      hard_regs_to_save &= used_regs & savable_regs;
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
	if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
	  {
	    if (hard_reg_map[regno] != NULL)
	      hard_reg_map[regno]->call_freq += freq;
	    else
	      new_saved_hard_reg (regno, freq);
	    SET_HARD_REG_BIT (hard_regs_used, regno);
	  }
      cheap = find_reg_note (insn, REG_RETURNED, NULL);
      if (cheap)
	cheap = XEXP (cheap, 0);
      /* Look through all live pseudos, mark their hard registers.  */
      EXECUTE_IF_SET_IN_REG_SET
	(&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
	{
	  int r = reg_renumber[regno];
	  int bound;

	  if (r < 0 || regno_reg_rtx[regno] == cheap)
	    continue;

	  bound = r + hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
	  for (; r < bound; r++)
	    if (TEST_HARD_REG_BIT (used_regs, r))
	      {
		if (hard_reg_map[r] != NULL)
		  hard_reg_map[r]->call_freq += freq;
		else
		  new_saved_hard_reg (r, freq);
		 SET_HARD_REG_BIT (hard_regs_to_save, r);
		 SET_HARD_REG_BIT (hard_regs_used, r);
	      }
	}
    }

  /* If requested, figure out which hard regs can share save slots.  */
  if (optimize && flag_ira_share_save_slots)
    {
      rtx slot;
      char *saved_reg_conflicts;
      int next_k;
      struct saved_hard_reg *saved_reg2, *saved_reg3;
      int call_saved_regs_num;
      struct saved_hard_reg *call_saved_regs[FIRST_PSEUDO_REGISTER];
      int best_slot_num;
      int prev_save_slots_num;
      rtx prev_save_slots[FIRST_PSEUDO_REGISTER];

      /* Find saved hard register conflicts.  */
      saved_reg_conflicts = (char *) xmalloc (saved_regs_num * saved_regs_num);
      memset (saved_reg_conflicts, 0, saved_regs_num * saved_regs_num);
      for (chain = reload_insn_chain; chain != 0; chain = next)
	{
	  rtx cheap;
	  call_saved_regs_num = 0;
	  insn = chain->insn;
	  next = chain->next;
	  if (!CALL_P (insn)
	      || find_reg_note (insn, REG_NORETURN, NULL))
	    continue;

	  cheap = find_reg_note (insn, REG_RETURNED, NULL);
	  if (cheap)
	    cheap = XEXP (cheap, 0);

	  REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
				   &chain->live_throughout);
	  used_regs = insn_callee_abi (insn).full_reg_clobbers ();

	  /* Record all registers set in this call insn.  These don't
	     need to be saved.  N.B. the call insn might set a subreg
	     of a multi-hard-reg pseudo; then the pseudo is considered
	     live during the call, but the subreg that is set
	     isn't.  */
	  CLEAR_HARD_REG_SET (this_insn_sets);
	  note_stores (insn, mark_set_regs, &this_insn_sets);
	  /* Sibcalls are considered to set the return value,
	     compare df-scan.cc:df_get_call_refs.  */
	  if (SIBLING_CALL_P (insn) && crtl->return_rtx)
	    mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets);

	  used_regs &= ~(fixed_reg_set | this_insn_sets);
	  hard_regs_to_save &= used_regs & savable_regs;
	  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
	    if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
	      {
		gcc_assert (hard_reg_map[regno] != NULL);
		call_saved_regs[call_saved_regs_num++] = hard_reg_map[regno];
	      }
	  /* Look through all live pseudos, mark their hard registers.  */
	  EXECUTE_IF_SET_IN_REG_SET
	    (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
	    {
	      int r = reg_renumber[regno];
	      int bound;

	      if (r < 0 || regno_reg_rtx[regno] == cheap)
		continue;

	      bound = r + hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
	      for (; r < bound; r++)
		if (TEST_HARD_REG_BIT (used_regs, r))
		  call_saved_regs[call_saved_regs_num++] = hard_reg_map[r];
	    }
	  for (i = 0; i < call_saved_regs_num; i++)
	    {
	      saved_reg = call_saved_regs[i];
	      for (j = 0; j < call_saved_regs_num; j++)
		if (i != j)
		  {
		    saved_reg2 = call_saved_regs[j];
		    saved_reg_conflicts[saved_reg->num * saved_regs_num
					+ saved_reg2->num]
		      = saved_reg_conflicts[saved_reg2->num * saved_regs_num
					    + saved_reg->num]
		      = TRUE;
		  }
	    }
	}
      /* Sort saved hard regs.  */
      qsort (all_saved_regs, saved_regs_num, sizeof (struct saved_hard_reg *),
	     saved_hard_reg_compare_func);
      /* Initiate slots available from the previous reload
	 iteration.  */
      prev_save_slots_num = save_slots_num;
      memcpy (prev_save_slots, save_slots, save_slots_num * sizeof (rtx));
      save_slots_num = 0;
      /* Allocate stack slots for the saved hard registers.  */
      for (i = 0; i < saved_regs_num; i++)
	{
	  saved_reg = all_saved_regs[i];
	  regno = saved_reg->hard_regno;
	  for (j = 0; j < i; j++)
	    {
	      saved_reg2 = all_saved_regs[j];
	      if (! saved_reg2->first_p)
		continue;
	      slot = saved_reg2->slot;
	      for (k = j; k >= 0; k = next_k)
		{
		  saved_reg3 = all_saved_regs[k];
		  next_k = saved_reg3->next;
		  if (saved_reg_conflicts[saved_reg->num * saved_regs_num
					  + saved_reg3->num])
		    break;
		}
	      if (k < 0
		  && known_le (GET_MODE_SIZE (regno_save_mode[regno][1]),
			       GET_MODE_SIZE (regno_save_mode
					      [saved_reg2->hard_regno][1])))
		{
		  saved_reg->slot
		    = adjust_address_nv
		      (slot, regno_save_mode[saved_reg->hard_regno][1], 0);
		  regno_save_mem[regno][1] = saved_reg->slot;
		  saved_reg->next = saved_reg2->next;
		  saved_reg2->next = i;
		  if (dump_file != NULL)
		    fprintf (dump_file, "%d uses slot of %d\n",
			     regno, saved_reg2->hard_regno);
		  break;
		}
	    }
	  if (j == i)
	    {
	      saved_reg->first_p = TRUE;
	      for (best_slot_num = -1, j = 0; j < prev_save_slots_num; j++)
		{
		  slot = prev_save_slots[j];
		  if (slot == NULL_RTX)
		    continue;
		  if (known_le (GET_MODE_SIZE (regno_save_mode[regno][1]),
				GET_MODE_SIZE (GET_MODE (slot)))
		      && best_slot_num < 0)
		    best_slot_num = j;
		  if (GET_MODE (slot) == regno_save_mode[regno][1])
		    break;
		}
	      if (best_slot_num >= 0)
		{
		  saved_reg->slot = prev_save_slots[best_slot_num];
		  saved_reg->slot
		    = adjust_address_nv
		      (saved_reg->slot,
		       regno_save_mode[saved_reg->hard_regno][1], 0);
		  if (dump_file != NULL)
		    fprintf (dump_file,
			     "%d uses a slot from prev iteration\n", regno);
		  prev_save_slots[best_slot_num] = NULL_RTX;
		  if (best_slot_num + 1 == prev_save_slots_num)
		    prev_save_slots_num--;
		}
	      else
		{
		  saved_reg->slot
		    = assign_stack_local_1
		      (regno_save_mode[regno][1],
		       GET_MODE_SIZE (regno_save_mode[regno][1]), 0,
		       ASLK_REDUCE_ALIGN);
		  if (dump_file != NULL)
		    fprintf (dump_file, "%d uses a new slot\n", regno);
		}
	      regno_save_mem[regno][1] = saved_reg->slot;
	      save_slots[save_slots_num++] = saved_reg->slot;
	    }
	}
      free (saved_reg_conflicts);
      finish_saved_hard_regs ();
    }
  else
    {
      /* We are not sharing slots. 

	 Run through all the call-used hard-registers and allocate
	 space for each in the caller-save area.  Try to allocate space
	 in a manner which allows multi-register saves/restores to be done.  */

      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	for (j = MOVE_MAX_WORDS; j > 0; j--)
	  {
	    int do_save = 1;

	    /* If no mode exists for this size, try another.  Also break out
	       if we have already saved this hard register.  */
	    if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0)
	      continue;

	    /* See if any register in this group has been saved.  */
	    for (k = 0; k < j; k++)
	      if (regno_save_mem[i + k][1])
		{
		  do_save = 0;
		  break;
		}
	    if (! do_save)
	      continue;

	    for (k = 0; k < j; k++)
	      if (! TEST_HARD_REG_BIT (hard_regs_used, i + k))
		{
		  do_save = 0;
		  break;
		}
	    if (! do_save)
	      continue;

	    /* We have found an acceptable mode to store in.  Since
	       hard register is always saved in the widest mode
	       available, the mode may be wider than necessary, it is
	       OK to reduce the alignment of spill space.  We will
	       verify that it is equal to or greater than required
	       when we restore and save the hard register in
	       insert_restore and insert_save.  */
	    regno_save_mem[i][j]
	      = assign_stack_local_1 (regno_save_mode[i][j],
				      GET_MODE_SIZE (regno_save_mode[i][j]),
				      0, ASLK_REDUCE_ALIGN);

	    /* Setup single word save area just in case...  */
	    for (k = 0; k < j; k++)
	      /* This should not depend on WORDS_BIG_ENDIAN.
		 The order of words in regs is the same as in memory.  */
	      regno_save_mem[i + k][1]
		= adjust_address_nv (regno_save_mem[i][j],
				     regno_save_mode[i + k][1],
				     k * UNITS_PER_WORD);
	  }
    }

  /* Now loop again and set the alias set of any save areas we made to
     the alias set used to represent frame objects.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    for (j = MOVE_MAX_WORDS; j > 0; j--)
      if (regno_save_mem[i][j] != 0)
	set_mem_alias_set (regno_save_mem[i][j], get_frame_alias_set ());
}



/* Find the places where hard regs are live across calls and save them.  */

void
save_call_clobbered_regs (void)
{
  class insn_chain *chain, *next, *last = NULL;
  machine_mode save_mode [FIRST_PSEUDO_REGISTER];

  /* Computed in mark_set_regs, holds all registers set by the current
     instruction.  */
  HARD_REG_SET this_insn_sets;

  CLEAR_HARD_REG_SET (hard_regs_saved);
  n_regs_saved = 0;

  for (chain = reload_insn_chain; chain != 0; chain = next)
    {
      rtx_insn *insn = chain->insn;
      enum rtx_code code = GET_CODE (insn);

      next = chain->next;

      gcc_assert (!chain->is_caller_save_insn);

      if (NONDEBUG_INSN_P (insn))
	{
	  /* If some registers have been saved, see if INSN references
	     any of them.  We must restore them before the insn if so.  */

	  if (n_regs_saved)
	    {
	      int regno;
	      HARD_REG_SET this_insn_sets;

	      if (code == JUMP_INSN)
		/* Restore all registers if this is a JUMP_INSN.  */
		referenced_regs = hard_regs_saved;
	      else
		{
		  CLEAR_HARD_REG_SET (referenced_regs);
		  mark_referenced_regs (&PATTERN (insn),
					mark_reg_as_referenced, NULL);
		  referenced_regs &= hard_regs_saved;
		}

	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
		if (TEST_HARD_REG_BIT (referenced_regs, regno))
		  regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS,
					   save_mode);
	      /* If a saved register is set after the call, this means we no
		 longer should restore it.  This can happen when parts of a
		 multi-word pseudo do not conflict with other pseudos, so
		 IRA may allocate the same hard register for both.  One may
		 be live across the call, while the other is set
		 afterwards.  */
	      CLEAR_HARD_REG_SET (this_insn_sets);
	      note_stores (insn, mark_set_regs, &this_insn_sets);
	      hard_regs_saved &= ~this_insn_sets;
	    }

	  if (code == CALL_INSN
	      && ! SIBLING_CALL_P (insn)
	      && ! find_reg_note (insn, REG_NORETURN, NULL))
	    {
	      unsigned regno;
	      HARD_REG_SET hard_regs_to_save;
	      reg_set_iterator rsi;
	      rtx cheap;

	      cheap = find_reg_note (insn, REG_RETURNED, NULL);
	      if (cheap)
		cheap = XEXP (cheap, 0);

	      /* Use the register life information in CHAIN to compute which
		 regs are live during the call.  */
	      REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
				       &chain->live_throughout);
	      /* Save hard registers always in the widest mode available.  */
	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
		if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
		  save_mode [regno] = regno_save_mode [regno][1];
		else
		  save_mode [regno] = VOIDmode;

	      /* Look through all live pseudos, mark their hard registers
		 and choose proper mode for saving.  */
	      EXECUTE_IF_SET_IN_REG_SET
		(&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
		{
		  int r = reg_renumber[regno];
		  int nregs;
		  machine_mode mode;

		  if (r < 0 || regno_reg_rtx[regno] == cheap)
		    continue;
		  nregs = hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
		  mode = HARD_REGNO_CALLER_SAVE_MODE
		    (r, nregs, PSEUDO_REGNO_MODE (regno));
		  if (partial_subreg_p (save_mode[r], mode))
		    save_mode[r] = mode;
		  while (nregs-- > 0)
		    SET_HARD_REG_BIT (hard_regs_to_save, r + nregs);
		}

	      /* Record all registers set in this call insn.  These don't need
		 to be saved.  N.B. the call insn might set a subreg of a
		 multi-hard-reg pseudo; then the pseudo is considered live
		 during the call, but the subreg that is set isn't.  */
	      CLEAR_HARD_REG_SET (this_insn_sets);
	      note_stores (insn, mark_set_regs, &this_insn_sets);

	      /* Compute which hard regs must be saved before this call.  */
	      function_abi callee_abi = insn_callee_abi (insn);
	      hard_regs_to_save &= ~(fixed_reg_set
				     | this_insn_sets
				     | hard_regs_saved);
	      hard_regs_to_save &= savable_regs;
	      hard_regs_to_save &= callee_abi.full_reg_clobbers ();

	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
		if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
		  regno += insert_save (chain, regno,
					&hard_regs_to_save, save_mode);

	      /* Must recompute n_regs_saved.  */
	      n_regs_saved = 0;
	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
		if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
		  n_regs_saved++;
	      
	      if (cheap
		  && HARD_REGISTER_P (cheap)
		  && callee_abi.clobbers_reg_p (GET_MODE (cheap),
						REGNO (cheap)))
		{
		  rtx dest, newpat;
		  rtx pat = PATTERN (insn);
		  if (GET_CODE (pat) == PARALLEL)
		    pat = XVECEXP (pat, 0, 0);
		  dest = SET_DEST (pat);
		  /* For multiple return values dest is PARALLEL.
		     Currently we handle only single return value case.  */
		  if (REG_P (dest))
		    {
		      newpat = gen_rtx_SET (cheap, copy_rtx (dest));
		      chain = insert_one_insn (chain, 0, -1, newpat);
		    }
		}
	    }
          last = chain;
	}
      else if (DEBUG_INSN_P (insn) && n_regs_saved)
	mark_referenced_regs (&PATTERN (insn),
			      replace_reg_with_saved_mem,
			      save_mode);

      if (chain->next == 0 || chain->next->block != chain->block)
	{
	  int regno;
	  /* At the end of the basic block, we must restore any registers that
	     remain saved.  If the last insn in the block is a JUMP_INSN, put
	     the restore before the insn, otherwise, put it after the insn.  */

	  if (n_regs_saved
	      && DEBUG_INSN_P (insn)
	      && last
	      && last->block == chain->block)
	    {
	      rtx_insn *ins, *prev;
	      basic_block bb = BLOCK_FOR_INSN (insn);

	      /* When adding hard reg restores after a DEBUG_INSN, move
		 all notes between last real insn and this DEBUG_INSN after
		 the DEBUG_INSN, otherwise we could get code
		 -g/-g0 differences.  */
	      for (ins = PREV_INSN (insn); ins != last->insn; ins = prev)
		{
		  prev = PREV_INSN (ins);
		  if (NOTE_P (ins))
		    {
		      SET_NEXT_INSN (prev) = NEXT_INSN (ins);
		      SET_PREV_INSN (NEXT_INSN (ins)) = prev;
		      SET_PREV_INSN (ins) = insn;
		      SET_NEXT_INSN (ins) = NEXT_INSN (insn);
		      SET_NEXT_INSN (insn) = ins;
		      if (NEXT_INSN (ins))
			SET_PREV_INSN (NEXT_INSN (ins)) = ins;
                      if (BB_END (bb) == insn)
			BB_END (bb) = ins;
		    }
		  else
		    gcc_assert (DEBUG_INSN_P (ins));
		}
	    }
	  last = NULL;

	  if (n_regs_saved)
	    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
	      if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
		regno += insert_restore (chain, JUMP_P (insn),
					 regno, MOVE_MAX_WORDS, save_mode);
	}
    }
}

/* Here from note_stores, or directly from save_call_clobbered_regs, when
   an insn stores a value in a register.
   Set the proper bit or bits in this_insn_sets.  All pseudos that have
   been assigned hard regs have had their register number changed already,
   so we can ignore pseudos.  */
static void
mark_set_regs (rtx reg, const_rtx setter ATTRIBUTE_UNUSED, void *data)
{
  int regno, endregno, i;
  HARD_REG_SET *this_insn_sets = (HARD_REG_SET *) data;

  if (GET_CODE (reg) == SUBREG)
    {
      rtx inner = SUBREG_REG (reg);
      if (!REG_P (inner) || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
	return;
      regno = subreg_regno (reg);
      endregno = regno + subreg_nregs (reg);
    }
  else if (REG_P (reg)
	   && REGNO (reg) < FIRST_PSEUDO_REGISTER)
    {
      regno = REGNO (reg);
      endregno = END_REGNO (reg);
    }
  else
    return;

  for (i = regno; i < endregno; i++)
    SET_HARD_REG_BIT (*this_insn_sets, i);
}

/* Here from note_stores when an insn stores a value in a register.
   Set the proper bit or bits in the passed regset.  All pseudos that have
   been assigned hard regs have had their register number changed already,
   so we can ignore pseudos.  */
static void
add_stored_regs (rtx reg, const_rtx setter, void *data)
{
  int regno, endregno, i;
  machine_mode mode = GET_MODE (reg);
  int offset = 0;

  if (GET_CODE (setter) == CLOBBER)
    return;

  if (GET_CODE (reg) == SUBREG
      && REG_P (SUBREG_REG (reg))
      && REGNO (SUBREG_REG (reg)) < FIRST_PSEUDO_REGISTER)
    {
      offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)),
				    GET_MODE (SUBREG_REG (reg)),
				    SUBREG_BYTE (reg),
				    GET_MODE (reg));
      regno = REGNO (SUBREG_REG (reg)) + offset;
      endregno = regno + subreg_nregs (reg);
    }
  else
    {
      if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
	return;

      regno = REGNO (reg) + offset;
      endregno = end_hard_regno (mode, regno);
    }

  for (i = regno; i < endregno; i++)
    SET_REGNO_REG_SET ((regset) data, i);
}

/* Walk X and record all referenced registers in REFERENCED_REGS.  */
static void
mark_referenced_regs (rtx *loc, refmarker_fn *mark, void *arg)
{
  enum rtx_code code = GET_CODE (*loc);
  const char *fmt;
  int i, j;

  if (code == SET)
    mark_referenced_regs (&SET_SRC (*loc), mark, arg);
  if (code == SET || code == CLOBBER)
    {
      loc = &SET_DEST (*loc);
      code = GET_CODE (*loc);
      if ((code == REG && REGNO (*loc) < FIRST_PSEUDO_REGISTER)
	  || code == PC
	  || (code == SUBREG && REG_P (SUBREG_REG (*loc))
	      && REGNO (SUBREG_REG (*loc)) < FIRST_PSEUDO_REGISTER
	      /* If we're setting only part of a multi-word register,
		 we shall mark it as referenced, because the words
		 that are not being set should be restored.  */
	      && !read_modify_subreg_p (*loc)))
	return;
    }
  if (code == MEM || code == SUBREG)
    {
      loc = &XEXP (*loc, 0);
      code = GET_CODE (*loc);
    }

  if (code == REG)
    {
      int regno = REGNO (*loc);
      int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
		       : reg_renumber[regno]);

      if (hardregno >= 0)
	mark (loc, GET_MODE (*loc), hardregno, arg);
      else if (arg)
	/* ??? Will we ever end up with an equiv expression in a debug
	   insn, that would have required restoring a reg, or will
	   reload take care of it for us?  */
	return;
      /* If this is a pseudo that did not get a hard register, scan its
	 memory location, since it might involve the use of another
	 register, which might be saved.  */
      else if (reg_equiv_mem (regno) != 0)
	mark_referenced_regs (&XEXP (reg_equiv_mem (regno), 0), mark, arg);
      else if (reg_equiv_address (regno) != 0)
	mark_referenced_regs (&reg_equiv_address (regno), mark, arg);
      return;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	mark_referenced_regs (&XEXP (*loc, i), mark, arg);
      else if (fmt[i] == 'E')
	for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
	  mark_referenced_regs (&XVECEXP (*loc, i, j), mark, arg);
    }
}

/* Parameter function for mark_referenced_regs() that adds registers
   present in the insn and in equivalent mems and addresses to
   referenced_regs.  */

static void
mark_reg_as_referenced (rtx *loc ATTRIBUTE_UNUSED,
			machine_mode mode,
			int hardregno,
			void *arg ATTRIBUTE_UNUSED)
{
  add_to_hard_reg_set (&referenced_regs, mode, hardregno);
}

/* Parameter function for mark_referenced_regs() that replaces
   registers referenced in a debug_insn that would have been restored,
   should it be a non-debug_insn, with their save locations.  */

static void
replace_reg_with_saved_mem (rtx *loc,
			    machine_mode mode,
			    int regno,
			    void *arg)
{
  unsigned int i, nregs = hard_regno_nregs (regno, mode);
  rtx mem;
  machine_mode *save_mode = (machine_mode *)arg;

  for (i = 0; i < nregs; i++)
    if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
      break;

  /* If none of the registers in the range would need restoring, we're
     all set.  */
  if (i == nregs)
    return;

  while (++i < nregs)
    if (!TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
      break;

  if (i == nregs
      && regno_save_mem[regno][nregs])
    {
      mem = copy_rtx (regno_save_mem[regno][nregs]);

      if (nregs == hard_regno_nregs (regno, save_mode[regno]))
	mem = adjust_address_nv (mem, save_mode[regno], 0);

      if (GET_MODE (mem) != mode)
	{
	  /* This is gen_lowpart_if_possible(), but without validating
	     the newly-formed address.  */
	  poly_int64 offset = byte_lowpart_offset (mode, GET_MODE (mem));
	  mem = adjust_address_nv (mem, mode, offset);
	}
    }
  else
    {
      mem = gen_rtx_CONCATN (mode, rtvec_alloc (nregs));
      for (i = 0; i < nregs; i++)
	if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
	  {
	    gcc_assert (regno_save_mem[regno + i][1]);
	    XVECEXP (mem, 0, i) = copy_rtx (regno_save_mem[regno + i][1]);
	  }
	else
	  {
	    machine_mode smode = save_mode[regno];
	    gcc_assert (smode != VOIDmode);
	    if (hard_regno_nregs (regno, smode) > 1)
	      smode = mode_for_size (exact_div (GET_MODE_BITSIZE (mode),
						nregs),
				     GET_MODE_CLASS (mode), 0).require ();
	    XVECEXP (mem, 0, i) = gen_rtx_REG (smode, regno + i);
	  }
    }

  gcc_assert (GET_MODE (mem) == mode);
  *loc = mem;
}


/* Insert a sequence of insns to restore.  Place these insns in front of
   CHAIN if BEFORE_P is nonzero, behind the insn otherwise.  MAXRESTORE is
   the maximum number of registers which should be restored during this call.
   It should never be less than 1 since we only work with entire registers.

   Note that we have verified in init_caller_save that we can do this
   with a simple SET, so use it.  Set INSN_CODE to what we save there
   since the address might not be valid so the insn might not be recognized.
   These insns will be reloaded and have register elimination done by
   find_reload, so we need not worry about that here.

   Return the extra number of registers saved.  */

static int
insert_restore (class insn_chain *chain, int before_p, int regno,
		int maxrestore, machine_mode *save_mode)
{
  int i, k;
  rtx pat = NULL_RTX;
  int code;
  unsigned int numregs = 0;
  class insn_chain *new_chain;
  rtx mem;

  /* A common failure mode if register status is not correct in the
     RTL is for this routine to be called with a REGNO we didn't
     expect to save.  That will cause us to write an insn with a (nil)
     SET_DEST or SET_SRC.  Instead of doing so and causing a crash
     later, check for this common case here instead.  This will remove
     one step in debugging such problems.  */
  gcc_assert (regno_save_mem[regno][1]);

  /* Get the pattern to emit and update our status.

     See if we can restore `maxrestore' registers at once.  Work
     backwards to the single register case.  */
  for (i = maxrestore; i > 0; i--)
    {
      int j;
      int ok = 1;

      if (regno_save_mem[regno][i] == 0)
	continue;

      for (j = 0; j < i; j++)
	if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
	  {
	    ok = 0;
	    break;
	  }
      /* Must do this one restore at a time.  */
      if (! ok)
	continue;

      numregs = i;
      break;
    }

  mem = regno_save_mem [regno][numregs];
  if (save_mode [regno] != VOIDmode
      && save_mode [regno] != GET_MODE (mem)
      && numregs == hard_regno_nregs (regno, save_mode [regno])
      /* Check that insn to restore REGNO in save_mode[regno] is
	 correct.  */
      && reg_save_code (regno, save_mode[regno]) >= 0)
    mem = adjust_address_nv (mem, save_mode[regno], 0);
  else
    mem = copy_rtx (mem);

  /* Verify that the alignment of spill space is equal to or greater
     than required.  */
  gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT,
		   GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem));

  pat = gen_rtx_SET (gen_rtx_REG (GET_MODE (mem), regno), mem);
  code = reg_restore_code (regno, GET_MODE (mem));
  new_chain = insert_one_insn (chain, before_p, code, pat);

  /* Clear status for all registers we restored.  */
  for (k = 0; k < i; k++)
    {
      CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k);
      SET_REGNO_REG_SET (&new_chain->dead_or_set, regno + k);
      n_regs_saved--;
    }

  /* Tell our callers how many extra registers we saved/restored.  */
  return numregs - 1;
}

/* Like insert_restore above, but save registers instead.  */

static int
insert_save (class insn_chain *chain, int regno,
	     HARD_REG_SET *to_save, machine_mode *save_mode)
{
  int i;
  unsigned int k;
  rtx pat = NULL_RTX;
  int code;
  unsigned int numregs = 0;
  class insn_chain *new_chain;
  rtx mem;

  /* A common failure mode if register status is not correct in the
     RTL is for this routine to be called with a REGNO we didn't
     expect to save.  That will cause us to write an insn with a (nil)
     SET_DEST or SET_SRC.  Instead of doing so and causing a crash
     later, check for this common case here.  This will remove one
     step in debugging such problems.  */
  gcc_assert (regno_save_mem[regno][1]);

  /* Get the pattern to emit and update our status.

     See if we can save several registers with a single instruction.
     Work backwards to the single register case.  */
  for (i = MOVE_MAX_WORDS; i > 0; i--)
    {
      int j;
      int ok = 1;
      if (regno_save_mem[regno][i] == 0)
	continue;

      for (j = 0; j < i; j++)
	if (! TEST_HARD_REG_BIT (*to_save, regno + j))
	  {
	    ok = 0;
	    break;
	  }
      /* Must do this one save at a time.  */
      if (! ok)
	continue;

      numregs = i;
      break;
    }

  mem = regno_save_mem [regno][numregs];
  if (save_mode [regno] != VOIDmode
      && save_mode [regno] != GET_MODE (mem)
      && numregs == hard_regno_nregs (regno, save_mode [regno])
      /* Check that insn to save REGNO in save_mode[regno] is
	 correct.  */
      && reg_save_code (regno, save_mode[regno]) >= 0)
    mem = adjust_address_nv (mem, save_mode[regno], 0);
  else
    mem = copy_rtx (mem);

  /* Verify that the alignment of spill space is equal to or greater
     than required.  */
  gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT,
		   GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem));

  pat = gen_rtx_SET (mem, gen_rtx_REG (GET_MODE (mem), regno));
  code = reg_save_code (regno, GET_MODE (mem));
  new_chain = insert_one_insn (chain, 1, code, pat);

  /* Set hard_regs_saved and dead_or_set for all the registers we saved.  */
  for (k = 0; k < numregs; k++)
    {
      SET_HARD_REG_BIT (hard_regs_saved, regno + k);
      SET_REGNO_REG_SET (&new_chain->dead_or_set, regno + k);
      n_regs_saved++;
    }

  /* Tell our callers how many extra registers we saved/restored.  */
  return numregs - 1;
}

/* A note_uses callback used by insert_one_insn.  Add the hard-register
   equivalent of each REG to regset DATA.  */

static void
add_used_regs (rtx *loc, void *data)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, *loc, NONCONST)
    {
      const_rtx x = *iter;
      if (REG_P (x))
	{
	  unsigned int regno = REGNO (x);
	  if (HARD_REGISTER_NUM_P (regno))
	    bitmap_set_range ((regset) data, regno, REG_NREGS (x));
	  else
	    gcc_checking_assert (reg_renumber[regno] < 0);
	}
    }
}

/* Emit a new caller-save insn and set the code.  */
static class insn_chain *
insert_one_insn (class insn_chain *chain, int before_p, int code, rtx pat)
{
  rtx_insn *insn = chain->insn;
  class insn_chain *new_chain;

  new_chain = new_insn_chain ();
  if (before_p)
    {
      rtx link;

      new_chain->prev = chain->prev;
      if (new_chain->prev != 0)
	new_chain->prev->next = new_chain;
      else
	reload_insn_chain = new_chain;

      chain->prev = new_chain;
      new_chain->next = chain;
      new_chain->insn = emit_insn_before (pat, insn);
      /* ??? It would be nice if we could exclude the already / still saved
	 registers from the live sets.  */
      COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
      note_uses (&PATTERN (chain->insn), add_used_regs,
		 &new_chain->live_throughout);
      /* If CHAIN->INSN is a call, then the registers which contain
	 the arguments to the function are live in the new insn.  */
      if (CALL_P (chain->insn))
	for (link = CALL_INSN_FUNCTION_USAGE (chain->insn);
	     link != NULL_RTX;
	     link = XEXP (link, 1))
	  note_uses (&XEXP (link, 0), add_used_regs,
		     &new_chain->live_throughout);

      CLEAR_REG_SET (&new_chain->dead_or_set);
      if (chain->insn == BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, chain->block)))
	BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, chain->block)) = new_chain->insn;
    }
  else
    {
      new_chain->next = chain->next;
      if (new_chain->next != 0)
	new_chain->next->prev = new_chain;
      chain->next = new_chain;
      new_chain->prev = chain;
      new_chain->insn = emit_insn_after (pat, insn);
      /* ??? It would be nice if we could exclude the already / still saved
	 registers from the live sets, and observe REG_UNUSED notes.  */
      COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
      /* Registers that are set in CHAIN->INSN live in the new insn.
	 (Unless there is a REG_UNUSED note for them, but we don't
	  look for them here.) */
      note_stores (chain->insn, add_stored_regs, &new_chain->live_throughout);
      CLEAR_REG_SET (&new_chain->dead_or_set);
      if (chain->insn == BB_END (BASIC_BLOCK_FOR_FN (cfun, chain->block)))
	BB_END (BASIC_BLOCK_FOR_FN (cfun, chain->block)) = new_chain->insn;
    }
  new_chain->block = chain->block;
  new_chain->is_caller_save_insn = 1;

  INSN_CODE (new_chain->insn) = code;
  return new_chain;
}
#include "gt-caller-save.h"
