xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/caller-save.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Save and restore call-clobbered registers which are live across a call.
2*8feb0f0bSmrg    Copyright (C) 1989-2020 Free Software Foundation, Inc.
31debfc3dSmrg 
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg 
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
71debfc3dSmrg the terms of the GNU General Public License as published by the Free
81debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
91debfc3dSmrg version.
101debfc3dSmrg 
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
141debfc3dSmrg for more details.
151debfc3dSmrg 
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3.  If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>.  */
191debfc3dSmrg 
201debfc3dSmrg #include "config.h"
211debfc3dSmrg #include "system.h"
221debfc3dSmrg #include "coretypes.h"
231debfc3dSmrg #include "backend.h"
241debfc3dSmrg #include "rtl.h"
251debfc3dSmrg #include "tree.h"
261debfc3dSmrg #include "predict.h"
271debfc3dSmrg #include "df.h"
281debfc3dSmrg #include "memmodel.h"
291debfc3dSmrg #include "tm_p.h"
301debfc3dSmrg #include "insn-config.h"
311debfc3dSmrg #include "regs.h"
321debfc3dSmrg #include "emit-rtl.h"
331debfc3dSmrg #include "recog.h"
341debfc3dSmrg #include "reload.h"
351debfc3dSmrg #include "alias.h"
361debfc3dSmrg #include "addresses.h"
371debfc3dSmrg #include "dumpfile.h"
381debfc3dSmrg #include "rtl-iter.h"
39a2dc1f3fSmrg #include "target.h"
40*8feb0f0bSmrg #include "function-abi.h"
411debfc3dSmrg 
421debfc3dSmrg #define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD)
431debfc3dSmrg 
441debfc3dSmrg #define regno_save_mode \
451debfc3dSmrg   (this_target_reload->x_regno_save_mode)
461debfc3dSmrg #define cached_reg_save_code \
471debfc3dSmrg   (this_target_reload->x_cached_reg_save_code)
481debfc3dSmrg #define cached_reg_restore_code \
491debfc3dSmrg   (this_target_reload->x_cached_reg_restore_code)
501debfc3dSmrg 
511debfc3dSmrg /* For each hard register, a place on the stack where it can be saved,
521debfc3dSmrg    if needed.  */
531debfc3dSmrg 
541debfc3dSmrg static rtx
551debfc3dSmrg   regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
561debfc3dSmrg 
571debfc3dSmrg /* The number of elements in the subsequent array.  */
581debfc3dSmrg static int save_slots_num;
591debfc3dSmrg 
601debfc3dSmrg /* Allocated slots so far.  */
611debfc3dSmrg static rtx save_slots[FIRST_PSEUDO_REGISTER];
621debfc3dSmrg 
631debfc3dSmrg /* Set of hard regs currently residing in save area (during insn scan).  */
641debfc3dSmrg 
651debfc3dSmrg static HARD_REG_SET hard_regs_saved;
661debfc3dSmrg 
671debfc3dSmrg /* Number of registers currently in hard_regs_saved.  */
681debfc3dSmrg 
691debfc3dSmrg static int n_regs_saved;
701debfc3dSmrg 
711debfc3dSmrg /* Computed by mark_referenced_regs, all regs referenced in a given
721debfc3dSmrg    insn.  */
731debfc3dSmrg static HARD_REG_SET referenced_regs;
741debfc3dSmrg 
751debfc3dSmrg 
761debfc3dSmrg typedef void refmarker_fn (rtx *loc, machine_mode mode, int hardregno,
771debfc3dSmrg 			   void *mark_arg);
781debfc3dSmrg 
791debfc3dSmrg static int reg_save_code (int, machine_mode);
801debfc3dSmrg static int reg_restore_code (int, machine_mode);
811debfc3dSmrg 
821debfc3dSmrg struct saved_hard_reg;
831debfc3dSmrg static void initiate_saved_hard_regs (void);
841debfc3dSmrg static void new_saved_hard_reg (int, int);
851debfc3dSmrg static void finish_saved_hard_regs (void);
861debfc3dSmrg static int saved_hard_reg_compare_func (const void *, const void *);
871debfc3dSmrg 
881debfc3dSmrg static void mark_set_regs (rtx, const_rtx, void *);
891debfc3dSmrg static void mark_referenced_regs (rtx *, refmarker_fn *mark, void *mark_arg);
901debfc3dSmrg static refmarker_fn mark_reg_as_referenced;
911debfc3dSmrg static refmarker_fn replace_reg_with_saved_mem;
92*8feb0f0bSmrg static int insert_save (class insn_chain *, int, HARD_REG_SET *,
931debfc3dSmrg 			machine_mode *);
94*8feb0f0bSmrg static int insert_restore (class insn_chain *, int, int, int,
951debfc3dSmrg 			   machine_mode *);
96*8feb0f0bSmrg static class insn_chain *insert_one_insn (class insn_chain *, int, int,
971debfc3dSmrg 					   rtx);
981debfc3dSmrg static void add_stored_regs (rtx, const_rtx, void *);
991debfc3dSmrg 
1001debfc3dSmrg 
1011debfc3dSmrg 
1021debfc3dSmrg static GTY(()) rtx savepat;
1031debfc3dSmrg static GTY(()) rtx restpat;
1041debfc3dSmrg static GTY(()) rtx test_reg;
1051debfc3dSmrg static GTY(()) rtx test_mem;
1061debfc3dSmrg static GTY(()) rtx_insn *saveinsn;
1071debfc3dSmrg static GTY(()) rtx_insn *restinsn;
1081debfc3dSmrg 
1091debfc3dSmrg /* Return the INSN_CODE used to save register REG in mode MODE.  */
1101debfc3dSmrg static int
reg_save_code(int reg,machine_mode mode)1111debfc3dSmrg reg_save_code (int reg, machine_mode mode)
1121debfc3dSmrg {
1131debfc3dSmrg   bool ok;
1141debfc3dSmrg   if (cached_reg_save_code[reg][mode])
1151debfc3dSmrg      return cached_reg_save_code[reg][mode];
116a2dc1f3fSmrg   if (!targetm.hard_regno_mode_ok (reg, mode))
1171debfc3dSmrg     {
118a2dc1f3fSmrg       /* Depending on how targetm.hard_regno_mode_ok is defined, range
119a2dc1f3fSmrg 	 propagation might deduce here that reg >= FIRST_PSEUDO_REGISTER.
120a2dc1f3fSmrg 	 So the assert below silences a warning.  */
1211debfc3dSmrg       gcc_assert (reg < FIRST_PSEUDO_REGISTER);
1221debfc3dSmrg       cached_reg_save_code[reg][mode] = -1;
1231debfc3dSmrg       cached_reg_restore_code[reg][mode] = -1;
1241debfc3dSmrg       return -1;
1251debfc3dSmrg     }
1261debfc3dSmrg 
1271debfc3dSmrg   /* Update the register number and modes of the register
1281debfc3dSmrg      and memory operand.  */
1291debfc3dSmrg   set_mode_and_regno (test_reg, mode, reg);
1301debfc3dSmrg   PUT_MODE (test_mem, mode);
1311debfc3dSmrg 
1321debfc3dSmrg   /* Force re-recognition of the modified insns.  */
1331debfc3dSmrg   INSN_CODE (saveinsn) = -1;
1341debfc3dSmrg   INSN_CODE (restinsn) = -1;
1351debfc3dSmrg 
1361debfc3dSmrg   cached_reg_save_code[reg][mode] = recog_memoized (saveinsn);
1371debfc3dSmrg   cached_reg_restore_code[reg][mode] = recog_memoized (restinsn);
1381debfc3dSmrg 
1391debfc3dSmrg   /* Now extract both insns and see if we can meet their
1401debfc3dSmrg      constraints.  We don't know here whether the save and restore will
1411debfc3dSmrg      be in size- or speed-tuned code, so just use the set of enabled
1421debfc3dSmrg      alternatives.  */
1431debfc3dSmrg   ok = (cached_reg_save_code[reg][mode] != -1
1441debfc3dSmrg 	&& cached_reg_restore_code[reg][mode] != -1);
1451debfc3dSmrg   if (ok)
1461debfc3dSmrg     {
1471debfc3dSmrg       extract_insn (saveinsn);
1481debfc3dSmrg       ok = constrain_operands (1, get_enabled_alternatives (saveinsn));
1491debfc3dSmrg       extract_insn (restinsn);
1501debfc3dSmrg       ok &= constrain_operands (1, get_enabled_alternatives (restinsn));
1511debfc3dSmrg     }
1521debfc3dSmrg 
1531debfc3dSmrg   if (! ok)
1541debfc3dSmrg     {
1551debfc3dSmrg       cached_reg_save_code[reg][mode] = -1;
1561debfc3dSmrg       cached_reg_restore_code[reg][mode] = -1;
1571debfc3dSmrg     }
1581debfc3dSmrg   gcc_assert (cached_reg_save_code[reg][mode]);
1591debfc3dSmrg   return cached_reg_save_code[reg][mode];
1601debfc3dSmrg }
1611debfc3dSmrg 
1621debfc3dSmrg /* Return the INSN_CODE used to restore register REG in mode MODE.  */
1631debfc3dSmrg static int
reg_restore_code(int reg,machine_mode mode)1641debfc3dSmrg reg_restore_code (int reg, machine_mode mode)
1651debfc3dSmrg {
1661debfc3dSmrg   if (cached_reg_restore_code[reg][mode])
1671debfc3dSmrg      return cached_reg_restore_code[reg][mode];
1681debfc3dSmrg   /* Populate our cache.  */
1691debfc3dSmrg   reg_save_code (reg, mode);
1701debfc3dSmrg   return cached_reg_restore_code[reg][mode];
1711debfc3dSmrg }
1721debfc3dSmrg 
1731debfc3dSmrg /* Initialize for caller-save.
1741debfc3dSmrg 
1751debfc3dSmrg    Look at all the hard registers that are used by a call and for which
1761debfc3dSmrg    reginfo.c has not already excluded from being used across a call.
1771debfc3dSmrg 
1781debfc3dSmrg    Ensure that we can find a mode to save the register and that there is a
1791debfc3dSmrg    simple insn to save and restore the register.  This latter check avoids
1801debfc3dSmrg    problems that would occur if we tried to save the MQ register of some
1811debfc3dSmrg    machines directly into memory.  */
1821debfc3dSmrg 
1831debfc3dSmrg void
init_caller_save(void)1841debfc3dSmrg init_caller_save (void)
1851debfc3dSmrg {
1861debfc3dSmrg   rtx addr_reg;
1871debfc3dSmrg   int offset;
1881debfc3dSmrg   rtx address;
1891debfc3dSmrg   int i, j;
1901debfc3dSmrg 
1911debfc3dSmrg   if (caller_save_initialized_p)
1921debfc3dSmrg     return;
1931debfc3dSmrg 
1941debfc3dSmrg   caller_save_initialized_p = true;
1951debfc3dSmrg 
1961debfc3dSmrg   /* First find all the registers that we need to deal with and all
1971debfc3dSmrg      the modes that they can have.  If we can't find a mode to use,
1981debfc3dSmrg      we can't have the register live over calls.  */
1991debfc3dSmrg 
2001debfc3dSmrg   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2011debfc3dSmrg     for (j = 1; j <= MOVE_MAX_WORDS; j++)
2021debfc3dSmrg       {
203*8feb0f0bSmrg 	regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j, VOIDmode);
2041debfc3dSmrg 	if (regno_save_mode[i][j] == VOIDmode && j == 1)
205*8feb0f0bSmrg 	  CLEAR_HARD_REG_BIT (savable_regs, i);
2061debfc3dSmrg       }
2071debfc3dSmrg 
2081debfc3dSmrg   /* The following code tries to approximate the conditions under which
2091debfc3dSmrg      we can easily save and restore a register without scratch registers or
2101debfc3dSmrg      other complexities.  It will usually work, except under conditions where
2111debfc3dSmrg      the validity of an insn operand is dependent on the address offset.
2121debfc3dSmrg      No such cases are currently known.
2131debfc3dSmrg 
2141debfc3dSmrg      We first find a typical offset from some BASE_REG_CLASS register.
2151debfc3dSmrg      This address is chosen by finding the first register in the class
2161debfc3dSmrg      and by finding the smallest power of two that is a valid offset from
2171debfc3dSmrg      that register in every mode we will use to save registers.  */
2181debfc3dSmrg 
2191debfc3dSmrg   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2201debfc3dSmrg     if (TEST_HARD_REG_BIT
2211debfc3dSmrg 	(reg_class_contents
2221debfc3dSmrg 	 [(int) base_reg_class (regno_save_mode[i][1], ADDR_SPACE_GENERIC,
2231debfc3dSmrg 				PLUS, CONST_INT)], i))
2241debfc3dSmrg       break;
2251debfc3dSmrg 
2261debfc3dSmrg   gcc_assert (i < FIRST_PSEUDO_REGISTER);
2271debfc3dSmrg 
2281debfc3dSmrg   addr_reg = gen_rtx_REG (Pmode, i);
2291debfc3dSmrg 
2301debfc3dSmrg   for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1)
2311debfc3dSmrg     {
2321debfc3dSmrg       address = gen_rtx_PLUS (Pmode, addr_reg, gen_int_mode (offset, Pmode));
2331debfc3dSmrg 
2341debfc3dSmrg       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2351debfc3dSmrg 	if (regno_save_mode[i][1] != VOIDmode
2361debfc3dSmrg 	  && ! strict_memory_address_p (regno_save_mode[i][1], address))
2371debfc3dSmrg 	  break;
2381debfc3dSmrg 
2391debfc3dSmrg       if (i == FIRST_PSEUDO_REGISTER)
2401debfc3dSmrg 	break;
2411debfc3dSmrg     }
2421debfc3dSmrg 
2431debfc3dSmrg   /* If we didn't find a valid address, we must use register indirect.  */
2441debfc3dSmrg   if (offset == 0)
2451debfc3dSmrg     address = addr_reg;
2461debfc3dSmrg 
2471debfc3dSmrg   /* Next we try to form an insn to save and restore the register.  We
2481debfc3dSmrg      see if such an insn is recognized and meets its constraints.
2491debfc3dSmrg 
2501debfc3dSmrg      To avoid lots of unnecessary RTL allocation, we construct all the RTL
2511debfc3dSmrg      once, then modify the memory and register operands in-place.  */
2521debfc3dSmrg 
2531debfc3dSmrg   test_reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
2541debfc3dSmrg   test_mem = gen_rtx_MEM (word_mode, address);
2551debfc3dSmrg   savepat = gen_rtx_SET (test_mem, test_reg);
2561debfc3dSmrg   restpat = gen_rtx_SET (test_reg, test_mem);
2571debfc3dSmrg 
2581debfc3dSmrg   saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, savepat, 0, -1, 0);
2591debfc3dSmrg   restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, restpat, 0, -1, 0);
2601debfc3dSmrg 
2611debfc3dSmrg   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2621debfc3dSmrg     for (j = 1; j <= MOVE_MAX_WORDS; j++)
2631debfc3dSmrg       if (reg_save_code (i,regno_save_mode[i][j]) == -1)
2641debfc3dSmrg 	{
2651debfc3dSmrg 	  regno_save_mode[i][j] = VOIDmode;
2661debfc3dSmrg 	  if (j == 1)
267*8feb0f0bSmrg 	    CLEAR_HARD_REG_BIT (savable_regs, i);
2681debfc3dSmrg 	}
2691debfc3dSmrg }
2701debfc3dSmrg 
2711debfc3dSmrg 
2721debfc3dSmrg 
2731debfc3dSmrg /* Initialize save areas by showing that we haven't allocated any yet.  */
2741debfc3dSmrg 
2751debfc3dSmrg void
init_save_areas(void)2761debfc3dSmrg init_save_areas (void)
2771debfc3dSmrg {
2781debfc3dSmrg   int i, j;
2791debfc3dSmrg 
2801debfc3dSmrg   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2811debfc3dSmrg     for (j = 1; j <= MOVE_MAX_WORDS; j++)
2821debfc3dSmrg       regno_save_mem[i][j] = 0;
2831debfc3dSmrg   save_slots_num = 0;
2841debfc3dSmrg 
2851debfc3dSmrg }
2861debfc3dSmrg 
2871debfc3dSmrg /* The structure represents a hard register which should be saved
2881debfc3dSmrg    through the call.  It is used when the integrated register
2891debfc3dSmrg    allocator (IRA) is used and sharing save slots is on.  */
2901debfc3dSmrg struct saved_hard_reg
2911debfc3dSmrg {
2921debfc3dSmrg   /* Order number starting with 0.  */
2931debfc3dSmrg   int num;
2941debfc3dSmrg   /* The hard regno.  */
2951debfc3dSmrg   int hard_regno;
2961debfc3dSmrg   /* Execution frequency of all calls through which given hard
2971debfc3dSmrg      register should be saved.  */
2981debfc3dSmrg   int call_freq;
2991debfc3dSmrg   /* Stack slot reserved to save the hard register through calls.  */
3001debfc3dSmrg   rtx slot;
3011debfc3dSmrg   /* True if it is first hard register in the chain of hard registers
3021debfc3dSmrg      sharing the same stack slot.  */
3031debfc3dSmrg   int first_p;
3041debfc3dSmrg   /* Order number of the next hard register structure with the same
3051debfc3dSmrg      slot in the chain.  -1 represents end of the chain.  */
3061debfc3dSmrg   int next;
3071debfc3dSmrg };
3081debfc3dSmrg 
3091debfc3dSmrg /* Map: hard register number to the corresponding structure.  */
3101debfc3dSmrg static struct saved_hard_reg *hard_reg_map[FIRST_PSEUDO_REGISTER];
3111debfc3dSmrg 
3121debfc3dSmrg /* The number of all structures representing hard registers should be
3131debfc3dSmrg    saved, in order words, the number of used elements in the following
3141debfc3dSmrg    array.  */
3151debfc3dSmrg static int saved_regs_num;
3161debfc3dSmrg 
3171debfc3dSmrg /* Pointers to all the structures.  Index is the order number of the
3181debfc3dSmrg    corresponding structure.  */
3191debfc3dSmrg static struct saved_hard_reg *all_saved_regs[FIRST_PSEUDO_REGISTER];
3201debfc3dSmrg 
3211debfc3dSmrg /* First called function for work with saved hard registers.  */
3221debfc3dSmrg static void
initiate_saved_hard_regs(void)3231debfc3dSmrg initiate_saved_hard_regs (void)
3241debfc3dSmrg {
3251debfc3dSmrg   int i;
3261debfc3dSmrg 
3271debfc3dSmrg   saved_regs_num = 0;
3281debfc3dSmrg   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3291debfc3dSmrg     hard_reg_map[i] = NULL;
3301debfc3dSmrg }
3311debfc3dSmrg 
3321debfc3dSmrg /* Allocate and return new saved hard register with given REGNO and
3331debfc3dSmrg    CALL_FREQ.  */
3341debfc3dSmrg static void
new_saved_hard_reg(int regno,int call_freq)3351debfc3dSmrg new_saved_hard_reg (int regno, int call_freq)
3361debfc3dSmrg {
3371debfc3dSmrg   struct saved_hard_reg *saved_reg;
3381debfc3dSmrg 
3391debfc3dSmrg   saved_reg
3401debfc3dSmrg     = (struct saved_hard_reg *) xmalloc (sizeof (struct saved_hard_reg));
3411debfc3dSmrg   hard_reg_map[regno] = all_saved_regs[saved_regs_num] = saved_reg;
3421debfc3dSmrg   saved_reg->num = saved_regs_num++;
3431debfc3dSmrg   saved_reg->hard_regno = regno;
3441debfc3dSmrg   saved_reg->call_freq = call_freq;
3451debfc3dSmrg   saved_reg->first_p = FALSE;
3461debfc3dSmrg   saved_reg->next = -1;
3471debfc3dSmrg }
3481debfc3dSmrg 
3491debfc3dSmrg /* Free memory allocated for the saved hard registers.  */
3501debfc3dSmrg static void
finish_saved_hard_regs(void)3511debfc3dSmrg finish_saved_hard_regs (void)
3521debfc3dSmrg {
3531debfc3dSmrg   int i;
3541debfc3dSmrg 
3551debfc3dSmrg   for (i = 0; i < saved_regs_num; i++)
3561debfc3dSmrg     free (all_saved_regs[i]);
3571debfc3dSmrg }
3581debfc3dSmrg 
3591debfc3dSmrg /* The function is used to sort the saved hard register structures
3601debfc3dSmrg    according their frequency.  */
3611debfc3dSmrg static int
saved_hard_reg_compare_func(const void * v1p,const void * v2p)3621debfc3dSmrg saved_hard_reg_compare_func (const void *v1p, const void *v2p)
3631debfc3dSmrg {
3641debfc3dSmrg   const struct saved_hard_reg *p1 = *(struct saved_hard_reg * const *) v1p;
3651debfc3dSmrg   const struct saved_hard_reg *p2 = *(struct saved_hard_reg * const *) v2p;
3661debfc3dSmrg 
3671debfc3dSmrg   if (flag_omit_frame_pointer)
3681debfc3dSmrg     {
3691debfc3dSmrg       if (p1->call_freq - p2->call_freq != 0)
3701debfc3dSmrg 	return p1->call_freq - p2->call_freq;
3711debfc3dSmrg     }
3721debfc3dSmrg   else if (p2->call_freq - p1->call_freq != 0)
3731debfc3dSmrg     return p2->call_freq - p1->call_freq;
3741debfc3dSmrg 
3751debfc3dSmrg   return p1->num - p2->num;
3761debfc3dSmrg }
3771debfc3dSmrg 
3781debfc3dSmrg /* Allocate save areas for any hard registers that might need saving.
3791debfc3dSmrg    We take a conservative approach here and look for call-clobbered hard
3801debfc3dSmrg    registers that are assigned to pseudos that cross calls.  This may
3811debfc3dSmrg    overestimate slightly (especially if some of these registers are later
3821debfc3dSmrg    used as spill registers), but it should not be significant.
3831debfc3dSmrg 
3841debfc3dSmrg    For IRA we use priority coloring to decrease stack slots needed for
3851debfc3dSmrg    saving hard registers through calls.  We build conflicts for them
3861debfc3dSmrg    to do coloring.
3871debfc3dSmrg 
3881debfc3dSmrg    Future work:
3891debfc3dSmrg 
3901debfc3dSmrg      In the fallback case we should iterate backwards across all possible
3911debfc3dSmrg      modes for the save, choosing the largest available one instead of
3921debfc3dSmrg      falling back to the smallest mode immediately.  (eg TF -> DF -> SF).
3931debfc3dSmrg 
3941debfc3dSmrg      We do not try to use "move multiple" instructions that exist
3951debfc3dSmrg      on some machines (such as the 68k moveml).  It could be a win to try
3961debfc3dSmrg      and use them when possible.  The hard part is doing it in a way that is
3971debfc3dSmrg      machine independent since they might be saving non-consecutive
3981debfc3dSmrg      registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */
3991debfc3dSmrg 
4001debfc3dSmrg void
setup_save_areas(void)4011debfc3dSmrg setup_save_areas (void)
4021debfc3dSmrg {
4031debfc3dSmrg   int i, j, k, freq;
4041debfc3dSmrg   HARD_REG_SET hard_regs_used;
4051debfc3dSmrg   struct saved_hard_reg *saved_reg;
4061debfc3dSmrg   rtx_insn *insn;
407*8feb0f0bSmrg   class insn_chain *chain, *next;
4081debfc3dSmrg   unsigned int regno;
4091debfc3dSmrg   HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets;
4101debfc3dSmrg   reg_set_iterator rsi;
4111debfc3dSmrg 
4121debfc3dSmrg   CLEAR_HARD_REG_SET (hard_regs_used);
4131debfc3dSmrg 
4141debfc3dSmrg   /* Find every CALL_INSN and record which hard regs are live across the
4151debfc3dSmrg      call into HARD_REG_MAP and HARD_REGS_USED.  */
4161debfc3dSmrg   initiate_saved_hard_regs ();
4171debfc3dSmrg   /* Create hard reg saved regs.  */
4181debfc3dSmrg   for (chain = reload_insn_chain; chain != 0; chain = next)
4191debfc3dSmrg     {
4201debfc3dSmrg       rtx cheap;
4211debfc3dSmrg 
4221debfc3dSmrg       insn = chain->insn;
4231debfc3dSmrg       next = chain->next;
4241debfc3dSmrg       if (!CALL_P (insn)
4251debfc3dSmrg 	  || find_reg_note (insn, REG_NORETURN, NULL))
4261debfc3dSmrg 	continue;
4271debfc3dSmrg       freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
4281debfc3dSmrg       REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
4291debfc3dSmrg 			       &chain->live_throughout);
430*8feb0f0bSmrg       used_regs = insn_callee_abi (insn).full_reg_clobbers ();
4311debfc3dSmrg 
4321debfc3dSmrg       /* Record all registers set in this call insn.  These don't
4331debfc3dSmrg 	 need to be saved.  N.B. the call insn might set a subreg
4341debfc3dSmrg 	 of a multi-hard-reg pseudo; then the pseudo is considered
4351debfc3dSmrg 	 live during the call, but the subreg that is set
4361debfc3dSmrg 	 isn't.  */
4371debfc3dSmrg       CLEAR_HARD_REG_SET (this_insn_sets);
438*8feb0f0bSmrg       note_stores (insn, mark_set_regs, &this_insn_sets);
4391debfc3dSmrg       /* Sibcalls are considered to set the return value.  */
4401debfc3dSmrg       if (SIBLING_CALL_P (insn) && crtl->return_rtx)
4411debfc3dSmrg 	mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets);
4421debfc3dSmrg 
443*8feb0f0bSmrg       used_regs &= ~(fixed_reg_set | this_insn_sets);
444*8feb0f0bSmrg       hard_regs_to_save &= used_regs & savable_regs;
4451debfc3dSmrg       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
4461debfc3dSmrg 	if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
4471debfc3dSmrg 	  {
4481debfc3dSmrg 	    if (hard_reg_map[regno] != NULL)
4491debfc3dSmrg 	      hard_reg_map[regno]->call_freq += freq;
4501debfc3dSmrg 	    else
4511debfc3dSmrg 	      new_saved_hard_reg (regno, freq);
4521debfc3dSmrg 	    SET_HARD_REG_BIT (hard_regs_used, regno);
4531debfc3dSmrg 	  }
4541debfc3dSmrg       cheap = find_reg_note (insn, REG_RETURNED, NULL);
4551debfc3dSmrg       if (cheap)
4561debfc3dSmrg 	cheap = XEXP (cheap, 0);
4571debfc3dSmrg       /* Look through all live pseudos, mark their hard registers.  */
4581debfc3dSmrg       EXECUTE_IF_SET_IN_REG_SET
4591debfc3dSmrg 	(&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
4601debfc3dSmrg 	{
4611debfc3dSmrg 	  int r = reg_renumber[regno];
4621debfc3dSmrg 	  int bound;
4631debfc3dSmrg 
4641debfc3dSmrg 	  if (r < 0 || regno_reg_rtx[regno] == cheap)
4651debfc3dSmrg 	    continue;
4661debfc3dSmrg 
467a2dc1f3fSmrg 	  bound = r + hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
4681debfc3dSmrg 	  for (; r < bound; r++)
4691debfc3dSmrg 	    if (TEST_HARD_REG_BIT (used_regs, r))
4701debfc3dSmrg 	      {
4711debfc3dSmrg 		if (hard_reg_map[r] != NULL)
4721debfc3dSmrg 		  hard_reg_map[r]->call_freq += freq;
4731debfc3dSmrg 		else
4741debfc3dSmrg 		  new_saved_hard_reg (r, freq);
4751debfc3dSmrg 		 SET_HARD_REG_BIT (hard_regs_to_save, r);
4761debfc3dSmrg 		 SET_HARD_REG_BIT (hard_regs_used, r);
4771debfc3dSmrg 	      }
4781debfc3dSmrg 	}
4791debfc3dSmrg     }
4801debfc3dSmrg 
4811debfc3dSmrg   /* If requested, figure out which hard regs can share save slots.  */
4821debfc3dSmrg   if (optimize && flag_ira_share_save_slots)
4831debfc3dSmrg     {
4841debfc3dSmrg       rtx slot;
4851debfc3dSmrg       char *saved_reg_conflicts;
4861debfc3dSmrg       int next_k;
4871debfc3dSmrg       struct saved_hard_reg *saved_reg2, *saved_reg3;
4881debfc3dSmrg       int call_saved_regs_num;
4891debfc3dSmrg       struct saved_hard_reg *call_saved_regs[FIRST_PSEUDO_REGISTER];
4901debfc3dSmrg       int best_slot_num;
4911debfc3dSmrg       int prev_save_slots_num;
4921debfc3dSmrg       rtx prev_save_slots[FIRST_PSEUDO_REGISTER];
4931debfc3dSmrg 
4941debfc3dSmrg       /* Find saved hard register conflicts.  */
4951debfc3dSmrg       saved_reg_conflicts = (char *) xmalloc (saved_regs_num * saved_regs_num);
4961debfc3dSmrg       memset (saved_reg_conflicts, 0, saved_regs_num * saved_regs_num);
4971debfc3dSmrg       for (chain = reload_insn_chain; chain != 0; chain = next)
4981debfc3dSmrg 	{
4991debfc3dSmrg 	  rtx cheap;
5001debfc3dSmrg 	  call_saved_regs_num = 0;
5011debfc3dSmrg 	  insn = chain->insn;
5021debfc3dSmrg 	  next = chain->next;
5031debfc3dSmrg 	  if (!CALL_P (insn)
5041debfc3dSmrg 	      || find_reg_note (insn, REG_NORETURN, NULL))
5051debfc3dSmrg 	    continue;
5061debfc3dSmrg 
5071debfc3dSmrg 	  cheap = find_reg_note (insn, REG_RETURNED, NULL);
5081debfc3dSmrg 	  if (cheap)
5091debfc3dSmrg 	    cheap = XEXP (cheap, 0);
5101debfc3dSmrg 
5111debfc3dSmrg 	  REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
5121debfc3dSmrg 				   &chain->live_throughout);
513*8feb0f0bSmrg 	  used_regs = insn_callee_abi (insn).full_reg_clobbers ();
5141debfc3dSmrg 
5151debfc3dSmrg 	  /* Record all registers set in this call insn.  These don't
5161debfc3dSmrg 	     need to be saved.  N.B. the call insn might set a subreg
5171debfc3dSmrg 	     of a multi-hard-reg pseudo; then the pseudo is considered
5181debfc3dSmrg 	     live during the call, but the subreg that is set
5191debfc3dSmrg 	     isn't.  */
5201debfc3dSmrg 	  CLEAR_HARD_REG_SET (this_insn_sets);
521*8feb0f0bSmrg 	  note_stores (insn, mark_set_regs, &this_insn_sets);
5221debfc3dSmrg 	  /* Sibcalls are considered to set the return value,
5231debfc3dSmrg 	     compare df-scan.c:df_get_call_refs.  */
5241debfc3dSmrg 	  if (SIBLING_CALL_P (insn) && crtl->return_rtx)
5251debfc3dSmrg 	    mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets);
5261debfc3dSmrg 
527*8feb0f0bSmrg 	  used_regs &= ~(fixed_reg_set | this_insn_sets);
528*8feb0f0bSmrg 	  hard_regs_to_save &= used_regs & savable_regs;
5291debfc3dSmrg 	  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
5301debfc3dSmrg 	    if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
5311debfc3dSmrg 	      {
5321debfc3dSmrg 		gcc_assert (hard_reg_map[regno] != NULL);
5331debfc3dSmrg 		call_saved_regs[call_saved_regs_num++] = hard_reg_map[regno];
5341debfc3dSmrg 	      }
5351debfc3dSmrg 	  /* Look through all live pseudos, mark their hard registers.  */
5361debfc3dSmrg 	  EXECUTE_IF_SET_IN_REG_SET
5371debfc3dSmrg 	    (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
5381debfc3dSmrg 	    {
5391debfc3dSmrg 	      int r = reg_renumber[regno];
5401debfc3dSmrg 	      int bound;
5411debfc3dSmrg 
5421debfc3dSmrg 	      if (r < 0 || regno_reg_rtx[regno] == cheap)
5431debfc3dSmrg 		continue;
5441debfc3dSmrg 
545a2dc1f3fSmrg 	      bound = r + hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
5461debfc3dSmrg 	      for (; r < bound; r++)
5471debfc3dSmrg 		if (TEST_HARD_REG_BIT (used_regs, r))
5481debfc3dSmrg 		  call_saved_regs[call_saved_regs_num++] = hard_reg_map[r];
5491debfc3dSmrg 	    }
5501debfc3dSmrg 	  for (i = 0; i < call_saved_regs_num; i++)
5511debfc3dSmrg 	    {
5521debfc3dSmrg 	      saved_reg = call_saved_regs[i];
5531debfc3dSmrg 	      for (j = 0; j < call_saved_regs_num; j++)
5541debfc3dSmrg 		if (i != j)
5551debfc3dSmrg 		  {
5561debfc3dSmrg 		    saved_reg2 = call_saved_regs[j];
5571debfc3dSmrg 		    saved_reg_conflicts[saved_reg->num * saved_regs_num
5581debfc3dSmrg 					+ saved_reg2->num]
5591debfc3dSmrg 		      = saved_reg_conflicts[saved_reg2->num * saved_regs_num
5601debfc3dSmrg 					    + saved_reg->num]
5611debfc3dSmrg 		      = TRUE;
5621debfc3dSmrg 		  }
5631debfc3dSmrg 	    }
5641debfc3dSmrg 	}
5651debfc3dSmrg       /* Sort saved hard regs.  */
5661debfc3dSmrg       qsort (all_saved_regs, saved_regs_num, sizeof (struct saved_hard_reg *),
5671debfc3dSmrg 	     saved_hard_reg_compare_func);
5681debfc3dSmrg       /* Initiate slots available from the previous reload
5691debfc3dSmrg 	 iteration.  */
5701debfc3dSmrg       prev_save_slots_num = save_slots_num;
5711debfc3dSmrg       memcpy (prev_save_slots, save_slots, save_slots_num * sizeof (rtx));
5721debfc3dSmrg       save_slots_num = 0;
5731debfc3dSmrg       /* Allocate stack slots for the saved hard registers.  */
5741debfc3dSmrg       for (i = 0; i < saved_regs_num; i++)
5751debfc3dSmrg 	{
5761debfc3dSmrg 	  saved_reg = all_saved_regs[i];
5771debfc3dSmrg 	  regno = saved_reg->hard_regno;
5781debfc3dSmrg 	  for (j = 0; j < i; j++)
5791debfc3dSmrg 	    {
5801debfc3dSmrg 	      saved_reg2 = all_saved_regs[j];
5811debfc3dSmrg 	      if (! saved_reg2->first_p)
5821debfc3dSmrg 		continue;
5831debfc3dSmrg 	      slot = saved_reg2->slot;
5841debfc3dSmrg 	      for (k = j; k >= 0; k = next_k)
5851debfc3dSmrg 		{
5861debfc3dSmrg 		  saved_reg3 = all_saved_regs[k];
5871debfc3dSmrg 		  next_k = saved_reg3->next;
5881debfc3dSmrg 		  if (saved_reg_conflicts[saved_reg->num * saved_regs_num
5891debfc3dSmrg 					  + saved_reg3->num])
5901debfc3dSmrg 		    break;
5911debfc3dSmrg 		}
5921debfc3dSmrg 	      if (k < 0
593a2dc1f3fSmrg 		  && known_le (GET_MODE_SIZE (regno_save_mode[regno][1]),
594a2dc1f3fSmrg 			       GET_MODE_SIZE (regno_save_mode
5951debfc3dSmrg 					      [saved_reg2->hard_regno][1])))
5961debfc3dSmrg 		{
5971debfc3dSmrg 		  saved_reg->slot
5981debfc3dSmrg 		    = adjust_address_nv
5991debfc3dSmrg 		      (slot, regno_save_mode[saved_reg->hard_regno][1], 0);
6001debfc3dSmrg 		  regno_save_mem[regno][1] = saved_reg->slot;
6011debfc3dSmrg 		  saved_reg->next = saved_reg2->next;
6021debfc3dSmrg 		  saved_reg2->next = i;
6031debfc3dSmrg 		  if (dump_file != NULL)
6041debfc3dSmrg 		    fprintf (dump_file, "%d uses slot of %d\n",
6051debfc3dSmrg 			     regno, saved_reg2->hard_regno);
6061debfc3dSmrg 		  break;
6071debfc3dSmrg 		}
6081debfc3dSmrg 	    }
6091debfc3dSmrg 	  if (j == i)
6101debfc3dSmrg 	    {
6111debfc3dSmrg 	      saved_reg->first_p = TRUE;
6121debfc3dSmrg 	      for (best_slot_num = -1, j = 0; j < prev_save_slots_num; j++)
6131debfc3dSmrg 		{
6141debfc3dSmrg 		  slot = prev_save_slots[j];
6151debfc3dSmrg 		  if (slot == NULL_RTX)
6161debfc3dSmrg 		    continue;
617a2dc1f3fSmrg 		  if (known_le (GET_MODE_SIZE (regno_save_mode[regno][1]),
618a2dc1f3fSmrg 				GET_MODE_SIZE (GET_MODE (slot)))
6191debfc3dSmrg 		      && best_slot_num < 0)
6201debfc3dSmrg 		    best_slot_num = j;
6211debfc3dSmrg 		  if (GET_MODE (slot) == regno_save_mode[regno][1])
6221debfc3dSmrg 		    break;
6231debfc3dSmrg 		}
6241debfc3dSmrg 	      if (best_slot_num >= 0)
6251debfc3dSmrg 		{
6261debfc3dSmrg 		  saved_reg->slot = prev_save_slots[best_slot_num];
6271debfc3dSmrg 		  saved_reg->slot
6281debfc3dSmrg 		    = adjust_address_nv
6291debfc3dSmrg 		      (saved_reg->slot,
6301debfc3dSmrg 		       regno_save_mode[saved_reg->hard_regno][1], 0);
6311debfc3dSmrg 		  if (dump_file != NULL)
6321debfc3dSmrg 		    fprintf (dump_file,
6331debfc3dSmrg 			     "%d uses a slot from prev iteration\n", regno);
6341debfc3dSmrg 		  prev_save_slots[best_slot_num] = NULL_RTX;
6351debfc3dSmrg 		  if (best_slot_num + 1 == prev_save_slots_num)
6361debfc3dSmrg 		    prev_save_slots_num--;
6371debfc3dSmrg 		}
6381debfc3dSmrg 	      else
6391debfc3dSmrg 		{
6401debfc3dSmrg 		  saved_reg->slot
6411debfc3dSmrg 		    = assign_stack_local_1
6421debfc3dSmrg 		      (regno_save_mode[regno][1],
6431debfc3dSmrg 		       GET_MODE_SIZE (regno_save_mode[regno][1]), 0,
6441debfc3dSmrg 		       ASLK_REDUCE_ALIGN);
6451debfc3dSmrg 		  if (dump_file != NULL)
6461debfc3dSmrg 		    fprintf (dump_file, "%d uses a new slot\n", regno);
6471debfc3dSmrg 		}
6481debfc3dSmrg 	      regno_save_mem[regno][1] = saved_reg->slot;
6491debfc3dSmrg 	      save_slots[save_slots_num++] = saved_reg->slot;
6501debfc3dSmrg 	    }
6511debfc3dSmrg 	}
6521debfc3dSmrg       free (saved_reg_conflicts);
6531debfc3dSmrg       finish_saved_hard_regs ();
6541debfc3dSmrg     }
6551debfc3dSmrg   else
6561debfc3dSmrg     {
6571debfc3dSmrg       /* We are not sharing slots.
6581debfc3dSmrg 
6591debfc3dSmrg 	 Run through all the call-used hard-registers and allocate
6601debfc3dSmrg 	 space for each in the caller-save area.  Try to allocate space
6611debfc3dSmrg 	 in a manner which allows multi-register saves/restores to be done.  */
6621debfc3dSmrg 
6631debfc3dSmrg       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6641debfc3dSmrg 	for (j = MOVE_MAX_WORDS; j > 0; j--)
6651debfc3dSmrg 	  {
6661debfc3dSmrg 	    int do_save = 1;
6671debfc3dSmrg 
6681debfc3dSmrg 	    /* If no mode exists for this size, try another.  Also break out
6691debfc3dSmrg 	       if we have already saved this hard register.  */
6701debfc3dSmrg 	    if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0)
6711debfc3dSmrg 	      continue;
6721debfc3dSmrg 
6731debfc3dSmrg 	    /* See if any register in this group has been saved.  */
6741debfc3dSmrg 	    for (k = 0; k < j; k++)
6751debfc3dSmrg 	      if (regno_save_mem[i + k][1])
6761debfc3dSmrg 		{
6771debfc3dSmrg 		  do_save = 0;
6781debfc3dSmrg 		  break;
6791debfc3dSmrg 		}
6801debfc3dSmrg 	    if (! do_save)
6811debfc3dSmrg 	      continue;
6821debfc3dSmrg 
6831debfc3dSmrg 	    for (k = 0; k < j; k++)
6841debfc3dSmrg 	      if (! TEST_HARD_REG_BIT (hard_regs_used, i + k))
6851debfc3dSmrg 		{
6861debfc3dSmrg 		  do_save = 0;
6871debfc3dSmrg 		  break;
6881debfc3dSmrg 		}
6891debfc3dSmrg 	    if (! do_save)
6901debfc3dSmrg 	      continue;
6911debfc3dSmrg 
6921debfc3dSmrg 	    /* We have found an acceptable mode to store in.  Since
6931debfc3dSmrg 	       hard register is always saved in the widest mode
6941debfc3dSmrg 	       available, the mode may be wider than necessary, it is
6951debfc3dSmrg 	       OK to reduce the alignment of spill space.  We will
6961debfc3dSmrg 	       verify that it is equal to or greater than required
6971debfc3dSmrg 	       when we restore and save the hard register in
6981debfc3dSmrg 	       insert_restore and insert_save.  */
6991debfc3dSmrg 	    regno_save_mem[i][j]
7001debfc3dSmrg 	      = assign_stack_local_1 (regno_save_mode[i][j],
7011debfc3dSmrg 				      GET_MODE_SIZE (regno_save_mode[i][j]),
7021debfc3dSmrg 				      0, ASLK_REDUCE_ALIGN);
7031debfc3dSmrg 
7041debfc3dSmrg 	    /* Setup single word save area just in case...  */
7051debfc3dSmrg 	    for (k = 0; k < j; k++)
7061debfc3dSmrg 	      /* This should not depend on WORDS_BIG_ENDIAN.
7071debfc3dSmrg 		 The order of words in regs is the same as in memory.  */
7081debfc3dSmrg 	      regno_save_mem[i + k][1]
7091debfc3dSmrg 		= adjust_address_nv (regno_save_mem[i][j],
7101debfc3dSmrg 				     regno_save_mode[i + k][1],
7111debfc3dSmrg 				     k * UNITS_PER_WORD);
7121debfc3dSmrg 	  }
7131debfc3dSmrg     }
7141debfc3dSmrg 
7151debfc3dSmrg   /* Now loop again and set the alias set of any save areas we made to
7161debfc3dSmrg      the alias set used to represent frame objects.  */
7171debfc3dSmrg   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7181debfc3dSmrg     for (j = MOVE_MAX_WORDS; j > 0; j--)
7191debfc3dSmrg       if (regno_save_mem[i][j] != 0)
7201debfc3dSmrg 	set_mem_alias_set (regno_save_mem[i][j], get_frame_alias_set ());
7211debfc3dSmrg }
7221debfc3dSmrg 
7231debfc3dSmrg 
7241debfc3dSmrg 
7251debfc3dSmrg /* Find the places where hard regs are live across calls and save them.  */
7261debfc3dSmrg 
7271debfc3dSmrg void
save_call_clobbered_regs(void)7281debfc3dSmrg save_call_clobbered_regs (void)
7291debfc3dSmrg {
730*8feb0f0bSmrg   class insn_chain *chain, *next, *last = NULL;
7311debfc3dSmrg   machine_mode save_mode [FIRST_PSEUDO_REGISTER];
7321debfc3dSmrg 
7331debfc3dSmrg   /* Computed in mark_set_regs, holds all registers set by the current
7341debfc3dSmrg      instruction.  */
7351debfc3dSmrg   HARD_REG_SET this_insn_sets;
7361debfc3dSmrg 
7371debfc3dSmrg   CLEAR_HARD_REG_SET (hard_regs_saved);
7381debfc3dSmrg   n_regs_saved = 0;
7391debfc3dSmrg 
7401debfc3dSmrg   for (chain = reload_insn_chain; chain != 0; chain = next)
7411debfc3dSmrg     {
7421debfc3dSmrg       rtx_insn *insn = chain->insn;
7431debfc3dSmrg       enum rtx_code code = GET_CODE (insn);
7441debfc3dSmrg 
7451debfc3dSmrg       next = chain->next;
7461debfc3dSmrg 
7471debfc3dSmrg       gcc_assert (!chain->is_caller_save_insn);
7481debfc3dSmrg 
7491debfc3dSmrg       if (NONDEBUG_INSN_P (insn))
7501debfc3dSmrg 	{
7511debfc3dSmrg 	  /* If some registers have been saved, see if INSN references
7521debfc3dSmrg 	     any of them.  We must restore them before the insn if so.  */
7531debfc3dSmrg 
7541debfc3dSmrg 	  if (n_regs_saved)
7551debfc3dSmrg 	    {
7561debfc3dSmrg 	      int regno;
7571debfc3dSmrg 	      HARD_REG_SET this_insn_sets;
7581debfc3dSmrg 
7591debfc3dSmrg 	      if (code == JUMP_INSN)
7601debfc3dSmrg 		/* Restore all registers if this is a JUMP_INSN.  */
761*8feb0f0bSmrg 		referenced_regs = hard_regs_saved;
7621debfc3dSmrg 	      else
7631debfc3dSmrg 		{
7641debfc3dSmrg 		  CLEAR_HARD_REG_SET (referenced_regs);
7651debfc3dSmrg 		  mark_referenced_regs (&PATTERN (insn),
7661debfc3dSmrg 					mark_reg_as_referenced, NULL);
767*8feb0f0bSmrg 		  referenced_regs &= hard_regs_saved;
7681debfc3dSmrg 		}
7691debfc3dSmrg 
7701debfc3dSmrg 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
7711debfc3dSmrg 		if (TEST_HARD_REG_BIT (referenced_regs, regno))
7721debfc3dSmrg 		  regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS,
7731debfc3dSmrg 					   save_mode);
7741debfc3dSmrg 	      /* If a saved register is set after the call, this means we no
7751debfc3dSmrg 		 longer should restore it.  This can happen when parts of a
7761debfc3dSmrg 		 multi-word pseudo do not conflict with other pseudos, so
7771debfc3dSmrg 		 IRA may allocate the same hard register for both.  One may
7781debfc3dSmrg 		 be live across the call, while the other is set
7791debfc3dSmrg 		 afterwards.  */
7801debfc3dSmrg 	      CLEAR_HARD_REG_SET (this_insn_sets);
781*8feb0f0bSmrg 	      note_stores (insn, mark_set_regs, &this_insn_sets);
782*8feb0f0bSmrg 	      hard_regs_saved &= ~this_insn_sets;
7831debfc3dSmrg 	    }
7841debfc3dSmrg 
7851debfc3dSmrg 	  if (code == CALL_INSN
7861debfc3dSmrg 	      && ! SIBLING_CALL_P (insn)
7871debfc3dSmrg 	      && ! find_reg_note (insn, REG_NORETURN, NULL))
7881debfc3dSmrg 	    {
7891debfc3dSmrg 	      unsigned regno;
7901debfc3dSmrg 	      HARD_REG_SET hard_regs_to_save;
7911debfc3dSmrg 	      reg_set_iterator rsi;
7921debfc3dSmrg 	      rtx cheap;
7931debfc3dSmrg 
7941debfc3dSmrg 	      cheap = find_reg_note (insn, REG_RETURNED, NULL);
7951debfc3dSmrg 	      if (cheap)
7961debfc3dSmrg 		cheap = XEXP (cheap, 0);
7971debfc3dSmrg 
7981debfc3dSmrg 	      /* Use the register life information in CHAIN to compute which
7991debfc3dSmrg 		 regs are live during the call.  */
8001debfc3dSmrg 	      REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
8011debfc3dSmrg 				       &chain->live_throughout);
8021debfc3dSmrg 	      /* Save hard registers always in the widest mode available.  */
8031debfc3dSmrg 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
8041debfc3dSmrg 		if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
8051debfc3dSmrg 		  save_mode [regno] = regno_save_mode [regno][1];
8061debfc3dSmrg 		else
8071debfc3dSmrg 		  save_mode [regno] = VOIDmode;
8081debfc3dSmrg 
8091debfc3dSmrg 	      /* Look through all live pseudos, mark their hard registers
8101debfc3dSmrg 		 and choose proper mode for saving.  */
8111debfc3dSmrg 	      EXECUTE_IF_SET_IN_REG_SET
8121debfc3dSmrg 		(&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
8131debfc3dSmrg 		{
8141debfc3dSmrg 		  int r = reg_renumber[regno];
8151debfc3dSmrg 		  int nregs;
8161debfc3dSmrg 		  machine_mode mode;
8171debfc3dSmrg 
8181debfc3dSmrg 		  if (r < 0 || regno_reg_rtx[regno] == cheap)
8191debfc3dSmrg 		    continue;
820a2dc1f3fSmrg 		  nregs = hard_regno_nregs (r, PSEUDO_REGNO_MODE (regno));
8211debfc3dSmrg 		  mode = HARD_REGNO_CALLER_SAVE_MODE
8221debfc3dSmrg 		    (r, nregs, PSEUDO_REGNO_MODE (regno));
823a2dc1f3fSmrg 		  if (partial_subreg_p (save_mode[r], mode))
8241debfc3dSmrg 		    save_mode[r] = mode;
8251debfc3dSmrg 		  while (nregs-- > 0)
8261debfc3dSmrg 		    SET_HARD_REG_BIT (hard_regs_to_save, r + nregs);
8271debfc3dSmrg 		}
8281debfc3dSmrg 
8291debfc3dSmrg 	      /* Record all registers set in this call insn.  These don't need
8301debfc3dSmrg 		 to be saved.  N.B. the call insn might set a subreg of a
8311debfc3dSmrg 		 multi-hard-reg pseudo; then the pseudo is considered live
8321debfc3dSmrg 		 during the call, but the subreg that is set isn't.  */
8331debfc3dSmrg 	      CLEAR_HARD_REG_SET (this_insn_sets);
834*8feb0f0bSmrg 	      note_stores (insn, mark_set_regs, &this_insn_sets);
8351debfc3dSmrg 
8361debfc3dSmrg 	      /* Compute which hard regs must be saved before this call.  */
837*8feb0f0bSmrg 	      function_abi callee_abi = insn_callee_abi (insn);
838*8feb0f0bSmrg 	      hard_regs_to_save &= ~(fixed_reg_set
839*8feb0f0bSmrg 				     | this_insn_sets
840*8feb0f0bSmrg 				     | hard_regs_saved);
841*8feb0f0bSmrg 	      hard_regs_to_save &= savable_regs;
842*8feb0f0bSmrg 	      hard_regs_to_save &= callee_abi.full_reg_clobbers ();
8431debfc3dSmrg 
8441debfc3dSmrg 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
8451debfc3dSmrg 		if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
846a2dc1f3fSmrg 		  regno += insert_save (chain, regno,
847a2dc1f3fSmrg 					&hard_regs_to_save, save_mode);
8481debfc3dSmrg 
8491debfc3dSmrg 	      /* Must recompute n_regs_saved.  */
8501debfc3dSmrg 	      n_regs_saved = 0;
8511debfc3dSmrg 	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
8521debfc3dSmrg 		if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
8531debfc3dSmrg 		  n_regs_saved++;
8541debfc3dSmrg 
8551debfc3dSmrg 	      if (cheap
8561debfc3dSmrg 		  && HARD_REGISTER_P (cheap)
857*8feb0f0bSmrg 		  && callee_abi.clobbers_reg_p (GET_MODE (cheap),
858*8feb0f0bSmrg 						REGNO (cheap)))
8591debfc3dSmrg 		{
8601debfc3dSmrg 		  rtx dest, newpat;
8611debfc3dSmrg 		  rtx pat = PATTERN (insn);
8621debfc3dSmrg 		  if (GET_CODE (pat) == PARALLEL)
8631debfc3dSmrg 		    pat = XVECEXP (pat, 0, 0);
8641debfc3dSmrg 		  dest = SET_DEST (pat);
8651debfc3dSmrg 		  /* For multiple return values dest is PARALLEL.
8661debfc3dSmrg 		     Currently we handle only single return value case.  */
8671debfc3dSmrg 		  if (REG_P (dest))
8681debfc3dSmrg 		    {
8691debfc3dSmrg 		      newpat = gen_rtx_SET (cheap, copy_rtx (dest));
8701debfc3dSmrg 		      chain = insert_one_insn (chain, 0, -1, newpat);
8711debfc3dSmrg 		    }
8721debfc3dSmrg 		}
8731debfc3dSmrg 	    }
8741debfc3dSmrg           last = chain;
8751debfc3dSmrg 	}
8761debfc3dSmrg       else if (DEBUG_INSN_P (insn) && n_regs_saved)
8771debfc3dSmrg 	mark_referenced_regs (&PATTERN (insn),
8781debfc3dSmrg 			      replace_reg_with_saved_mem,
8791debfc3dSmrg 			      save_mode);
8801debfc3dSmrg 
8811debfc3dSmrg       if (chain->next == 0 || chain->next->block != chain->block)
8821debfc3dSmrg 	{
8831debfc3dSmrg 	  int regno;
8841debfc3dSmrg 	  /* At the end of the basic block, we must restore any registers that
8851debfc3dSmrg 	     remain saved.  If the last insn in the block is a JUMP_INSN, put
8861debfc3dSmrg 	     the restore before the insn, otherwise, put it after the insn.  */
8871debfc3dSmrg 
8881debfc3dSmrg 	  if (n_regs_saved
8891debfc3dSmrg 	      && DEBUG_INSN_P (insn)
8901debfc3dSmrg 	      && last
8911debfc3dSmrg 	      && last->block == chain->block)
8921debfc3dSmrg 	    {
8931debfc3dSmrg 	      rtx_insn *ins, *prev;
8941debfc3dSmrg 	      basic_block bb = BLOCK_FOR_INSN (insn);
8951debfc3dSmrg 
8961debfc3dSmrg 	      /* When adding hard reg restores after a DEBUG_INSN, move
8971debfc3dSmrg 		 all notes between last real insn and this DEBUG_INSN after
8981debfc3dSmrg 		 the DEBUG_INSN, otherwise we could get code
8991debfc3dSmrg 		 -g/-g0 differences.  */
9001debfc3dSmrg 	      for (ins = PREV_INSN (insn); ins != last->insn; ins = prev)
9011debfc3dSmrg 		{
9021debfc3dSmrg 		  prev = PREV_INSN (ins);
9031debfc3dSmrg 		  if (NOTE_P (ins))
9041debfc3dSmrg 		    {
9051debfc3dSmrg 		      SET_NEXT_INSN (prev) = NEXT_INSN (ins);
9061debfc3dSmrg 		      SET_PREV_INSN (NEXT_INSN (ins)) = prev;
9071debfc3dSmrg 		      SET_PREV_INSN (ins) = insn;
9081debfc3dSmrg 		      SET_NEXT_INSN (ins) = NEXT_INSN (insn);
9091debfc3dSmrg 		      SET_NEXT_INSN (insn) = ins;
9101debfc3dSmrg 		      if (NEXT_INSN (ins))
9111debfc3dSmrg 			SET_PREV_INSN (NEXT_INSN (ins)) = ins;
9121debfc3dSmrg                       if (BB_END (bb) == insn)
9131debfc3dSmrg 			BB_END (bb) = ins;
9141debfc3dSmrg 		    }
9151debfc3dSmrg 		  else
9161debfc3dSmrg 		    gcc_assert (DEBUG_INSN_P (ins));
9171debfc3dSmrg 		}
9181debfc3dSmrg 	    }
9191debfc3dSmrg 	  last = NULL;
9201debfc3dSmrg 
9211debfc3dSmrg 	  if (n_regs_saved)
9221debfc3dSmrg 	    for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9231debfc3dSmrg 	      if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
9241debfc3dSmrg 		regno += insert_restore (chain, JUMP_P (insn),
9251debfc3dSmrg 					 regno, MOVE_MAX_WORDS, save_mode);
9261debfc3dSmrg 	}
9271debfc3dSmrg     }
9281debfc3dSmrg }
9291debfc3dSmrg 
9301debfc3dSmrg /* Here from note_stores, or directly from save_call_clobbered_regs, when
9311debfc3dSmrg    an insn stores a value in a register.
9321debfc3dSmrg    Set the proper bit or bits in this_insn_sets.  All pseudos that have
9331debfc3dSmrg    been assigned hard regs have had their register number changed already,
9341debfc3dSmrg    so we can ignore pseudos.  */
9351debfc3dSmrg static void
mark_set_regs(rtx reg,const_rtx setter ATTRIBUTE_UNUSED,void * data)9361debfc3dSmrg mark_set_regs (rtx reg, const_rtx setter ATTRIBUTE_UNUSED, void *data)
9371debfc3dSmrg {
9381debfc3dSmrg   int regno, endregno, i;
9391debfc3dSmrg   HARD_REG_SET *this_insn_sets = (HARD_REG_SET *) data;
9401debfc3dSmrg 
9411debfc3dSmrg   if (GET_CODE (reg) == SUBREG)
9421debfc3dSmrg     {
9431debfc3dSmrg       rtx inner = SUBREG_REG (reg);
9441debfc3dSmrg       if (!REG_P (inner) || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
9451debfc3dSmrg 	return;
9461debfc3dSmrg       regno = subreg_regno (reg);
9471debfc3dSmrg       endregno = regno + subreg_nregs (reg);
9481debfc3dSmrg     }
9491debfc3dSmrg   else if (REG_P (reg)
9501debfc3dSmrg 	   && REGNO (reg) < FIRST_PSEUDO_REGISTER)
9511debfc3dSmrg     {
9521debfc3dSmrg       regno = REGNO (reg);
9531debfc3dSmrg       endregno = END_REGNO (reg);
9541debfc3dSmrg     }
9551debfc3dSmrg   else
9561debfc3dSmrg     return;
9571debfc3dSmrg 
9581debfc3dSmrg   for (i = regno; i < endregno; i++)
9591debfc3dSmrg     SET_HARD_REG_BIT (*this_insn_sets, i);
9601debfc3dSmrg }
9611debfc3dSmrg 
9621debfc3dSmrg /* Here from note_stores when an insn stores a value in a register.
9631debfc3dSmrg    Set the proper bit or bits in the passed regset.  All pseudos that have
9641debfc3dSmrg    been assigned hard regs have had their register number changed already,
9651debfc3dSmrg    so we can ignore pseudos.  */
9661debfc3dSmrg static void
add_stored_regs(rtx reg,const_rtx setter,void * data)9671debfc3dSmrg add_stored_regs (rtx reg, const_rtx setter, void *data)
9681debfc3dSmrg {
9691debfc3dSmrg   int regno, endregno, i;
9701debfc3dSmrg   machine_mode mode = GET_MODE (reg);
9711debfc3dSmrg   int offset = 0;
9721debfc3dSmrg 
9731debfc3dSmrg   if (GET_CODE (setter) == CLOBBER)
9741debfc3dSmrg     return;
9751debfc3dSmrg 
9761debfc3dSmrg   if (GET_CODE (reg) == SUBREG
9771debfc3dSmrg       && REG_P (SUBREG_REG (reg))
9781debfc3dSmrg       && REGNO (SUBREG_REG (reg)) < FIRST_PSEUDO_REGISTER)
9791debfc3dSmrg     {
9801debfc3dSmrg       offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)),
9811debfc3dSmrg 				    GET_MODE (SUBREG_REG (reg)),
9821debfc3dSmrg 				    SUBREG_BYTE (reg),
9831debfc3dSmrg 				    GET_MODE (reg));
9841debfc3dSmrg       regno = REGNO (SUBREG_REG (reg)) + offset;
9851debfc3dSmrg       endregno = regno + subreg_nregs (reg);
9861debfc3dSmrg     }
9871debfc3dSmrg   else
9881debfc3dSmrg     {
9891debfc3dSmrg       if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
9901debfc3dSmrg 	return;
9911debfc3dSmrg 
9921debfc3dSmrg       regno = REGNO (reg) + offset;
9931debfc3dSmrg       endregno = end_hard_regno (mode, regno);
9941debfc3dSmrg     }
9951debfc3dSmrg 
9961debfc3dSmrg   for (i = regno; i < endregno; i++)
9971debfc3dSmrg     SET_REGNO_REG_SET ((regset) data, i);
9981debfc3dSmrg }
9991debfc3dSmrg 
10001debfc3dSmrg /* Walk X and record all referenced registers in REFERENCED_REGS.  */
10011debfc3dSmrg static void
mark_referenced_regs(rtx * loc,refmarker_fn * mark,void * arg)10021debfc3dSmrg mark_referenced_regs (rtx *loc, refmarker_fn *mark, void *arg)
10031debfc3dSmrg {
10041debfc3dSmrg   enum rtx_code code = GET_CODE (*loc);
10051debfc3dSmrg   const char *fmt;
10061debfc3dSmrg   int i, j;
10071debfc3dSmrg 
10081debfc3dSmrg   if (code == SET)
10091debfc3dSmrg     mark_referenced_regs (&SET_SRC (*loc), mark, arg);
10101debfc3dSmrg   if (code == SET || code == CLOBBER)
10111debfc3dSmrg     {
10121debfc3dSmrg       loc = &SET_DEST (*loc);
10131debfc3dSmrg       code = GET_CODE (*loc);
10141debfc3dSmrg       if ((code == REG && REGNO (*loc) < FIRST_PSEUDO_REGISTER)
10151debfc3dSmrg 	  || code == PC || code == CC0
10161debfc3dSmrg 	  || (code == SUBREG && REG_P (SUBREG_REG (*loc))
10171debfc3dSmrg 	      && REGNO (SUBREG_REG (*loc)) < FIRST_PSEUDO_REGISTER
10181debfc3dSmrg 	      /* If we're setting only part of a multi-word register,
10191debfc3dSmrg 		 we shall mark it as referenced, because the words
10201debfc3dSmrg 		 that are not being set should be restored.  */
1021a2dc1f3fSmrg 	      && !read_modify_subreg_p (*loc)))
10221debfc3dSmrg 	return;
10231debfc3dSmrg     }
10241debfc3dSmrg   if (code == MEM || code == SUBREG)
10251debfc3dSmrg     {
10261debfc3dSmrg       loc = &XEXP (*loc, 0);
10271debfc3dSmrg       code = GET_CODE (*loc);
10281debfc3dSmrg     }
10291debfc3dSmrg 
10301debfc3dSmrg   if (code == REG)
10311debfc3dSmrg     {
10321debfc3dSmrg       int regno = REGNO (*loc);
10331debfc3dSmrg       int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
10341debfc3dSmrg 		       : reg_renumber[regno]);
10351debfc3dSmrg 
10361debfc3dSmrg       if (hardregno >= 0)
10371debfc3dSmrg 	mark (loc, GET_MODE (*loc), hardregno, arg);
10381debfc3dSmrg       else if (arg)
10391debfc3dSmrg 	/* ??? Will we ever end up with an equiv expression in a debug
10401debfc3dSmrg 	   insn, that would have required restoring a reg, or will
10411debfc3dSmrg 	   reload take care of it for us?  */
10421debfc3dSmrg 	return;
10431debfc3dSmrg       /* If this is a pseudo that did not get a hard register, scan its
10441debfc3dSmrg 	 memory location, since it might involve the use of another
10451debfc3dSmrg 	 register, which might be saved.  */
10461debfc3dSmrg       else if (reg_equiv_mem (regno) != 0)
10471debfc3dSmrg 	mark_referenced_regs (&XEXP (reg_equiv_mem (regno), 0), mark, arg);
10481debfc3dSmrg       else if (reg_equiv_address (regno) != 0)
10491debfc3dSmrg 	mark_referenced_regs (&reg_equiv_address (regno), mark, arg);
10501debfc3dSmrg       return;
10511debfc3dSmrg     }
10521debfc3dSmrg 
10531debfc3dSmrg   fmt = GET_RTX_FORMAT (code);
10541debfc3dSmrg   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
10551debfc3dSmrg     {
10561debfc3dSmrg       if (fmt[i] == 'e')
10571debfc3dSmrg 	mark_referenced_regs (&XEXP (*loc, i), mark, arg);
10581debfc3dSmrg       else if (fmt[i] == 'E')
10591debfc3dSmrg 	for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
10601debfc3dSmrg 	  mark_referenced_regs (&XVECEXP (*loc, i, j), mark, arg);
10611debfc3dSmrg     }
10621debfc3dSmrg }
10631debfc3dSmrg 
10641debfc3dSmrg /* Parameter function for mark_referenced_regs() that adds registers
10651debfc3dSmrg    present in the insn and in equivalent mems and addresses to
10661debfc3dSmrg    referenced_regs.  */
10671debfc3dSmrg 
10681debfc3dSmrg static void
mark_reg_as_referenced(rtx * loc ATTRIBUTE_UNUSED,machine_mode mode,int hardregno,void * arg ATTRIBUTE_UNUSED)10691debfc3dSmrg mark_reg_as_referenced (rtx *loc ATTRIBUTE_UNUSED,
10701debfc3dSmrg 			machine_mode mode,
10711debfc3dSmrg 			int hardregno,
10721debfc3dSmrg 			void *arg ATTRIBUTE_UNUSED)
10731debfc3dSmrg {
10741debfc3dSmrg   add_to_hard_reg_set (&referenced_regs, mode, hardregno);
10751debfc3dSmrg }
10761debfc3dSmrg 
10771debfc3dSmrg /* Parameter function for mark_referenced_regs() that replaces
10781debfc3dSmrg    registers referenced in a debug_insn that would have been restored,
10791debfc3dSmrg    should it be a non-debug_insn, with their save locations.  */
10801debfc3dSmrg 
10811debfc3dSmrg static void
replace_reg_with_saved_mem(rtx * loc,machine_mode mode,int regno,void * arg)10821debfc3dSmrg replace_reg_with_saved_mem (rtx *loc,
10831debfc3dSmrg 			    machine_mode mode,
10841debfc3dSmrg 			    int regno,
10851debfc3dSmrg 			    void *arg)
10861debfc3dSmrg {
1087a2dc1f3fSmrg   unsigned int i, nregs = hard_regno_nregs (regno, mode);
10881debfc3dSmrg   rtx mem;
10891debfc3dSmrg   machine_mode *save_mode = (machine_mode *)arg;
10901debfc3dSmrg 
10911debfc3dSmrg   for (i = 0; i < nregs; i++)
10921debfc3dSmrg     if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
10931debfc3dSmrg       break;
10941debfc3dSmrg 
10951debfc3dSmrg   /* If none of the registers in the range would need restoring, we're
10961debfc3dSmrg      all set.  */
10971debfc3dSmrg   if (i == nregs)
10981debfc3dSmrg     return;
10991debfc3dSmrg 
11001debfc3dSmrg   while (++i < nregs)
11011debfc3dSmrg     if (!TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
11021debfc3dSmrg       break;
11031debfc3dSmrg 
11041debfc3dSmrg   if (i == nregs
11051debfc3dSmrg       && regno_save_mem[regno][nregs])
11061debfc3dSmrg     {
11071debfc3dSmrg       mem = copy_rtx (regno_save_mem[regno][nregs]);
11081debfc3dSmrg 
1109a2dc1f3fSmrg       if (nregs == hard_regno_nregs (regno, save_mode[regno]))
11101debfc3dSmrg 	mem = adjust_address_nv (mem, save_mode[regno], 0);
11111debfc3dSmrg 
11121debfc3dSmrg       if (GET_MODE (mem) != mode)
11131debfc3dSmrg 	{
11141debfc3dSmrg 	  /* This is gen_lowpart_if_possible(), but without validating
11151debfc3dSmrg 	     the newly-formed address.  */
1116a2dc1f3fSmrg 	  poly_int64 offset = byte_lowpart_offset (mode, GET_MODE (mem));
11171debfc3dSmrg 	  mem = adjust_address_nv (mem, mode, offset);
11181debfc3dSmrg 	}
11191debfc3dSmrg     }
11201debfc3dSmrg   else
11211debfc3dSmrg     {
11221debfc3dSmrg       mem = gen_rtx_CONCATN (mode, rtvec_alloc (nregs));
11231debfc3dSmrg       for (i = 0; i < nregs; i++)
11241debfc3dSmrg 	if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
11251debfc3dSmrg 	  {
11261debfc3dSmrg 	    gcc_assert (regno_save_mem[regno + i][1]);
11271debfc3dSmrg 	    XVECEXP (mem, 0, i) = copy_rtx (regno_save_mem[regno + i][1]);
11281debfc3dSmrg 	  }
11291debfc3dSmrg 	else
11301debfc3dSmrg 	  {
11311debfc3dSmrg 	    machine_mode smode = save_mode[regno];
11321debfc3dSmrg 	    gcc_assert (smode != VOIDmode);
1133a2dc1f3fSmrg 	    if (hard_regno_nregs (regno, smode) > 1)
1134a2dc1f3fSmrg 	      smode = mode_for_size (exact_div (GET_MODE_BITSIZE (mode),
1135a2dc1f3fSmrg 						nregs),
1136a2dc1f3fSmrg 				     GET_MODE_CLASS (mode), 0).require ();
11371debfc3dSmrg 	    XVECEXP (mem, 0, i) = gen_rtx_REG (smode, regno + i);
11381debfc3dSmrg 	  }
11391debfc3dSmrg     }
11401debfc3dSmrg 
11411debfc3dSmrg   gcc_assert (GET_MODE (mem) == mode);
11421debfc3dSmrg   *loc = mem;
11431debfc3dSmrg }
11441debfc3dSmrg 
11451debfc3dSmrg 
11461debfc3dSmrg /* Insert a sequence of insns to restore.  Place these insns in front of
11471debfc3dSmrg    CHAIN if BEFORE_P is nonzero, behind the insn otherwise.  MAXRESTORE is
11481debfc3dSmrg    the maximum number of registers which should be restored during this call.
11491debfc3dSmrg    It should never be less than 1 since we only work with entire registers.
11501debfc3dSmrg 
11511debfc3dSmrg    Note that we have verified in init_caller_save that we can do this
11521debfc3dSmrg    with a simple SET, so use it.  Set INSN_CODE to what we save there
11531debfc3dSmrg    since the address might not be valid so the insn might not be recognized.
11541debfc3dSmrg    These insns will be reloaded and have register elimination done by
11551debfc3dSmrg    find_reload, so we need not worry about that here.
11561debfc3dSmrg 
11571debfc3dSmrg    Return the extra number of registers saved.  */
11581debfc3dSmrg 
11591debfc3dSmrg static int
insert_restore(class insn_chain * chain,int before_p,int regno,int maxrestore,machine_mode * save_mode)1160*8feb0f0bSmrg insert_restore (class insn_chain *chain, int before_p, int regno,
11611debfc3dSmrg 		int maxrestore, machine_mode *save_mode)
11621debfc3dSmrg {
11631debfc3dSmrg   int i, k;
11641debfc3dSmrg   rtx pat = NULL_RTX;
11651debfc3dSmrg   int code;
11661debfc3dSmrg   unsigned int numregs = 0;
1167*8feb0f0bSmrg   class insn_chain *new_chain;
11681debfc3dSmrg   rtx mem;
11691debfc3dSmrg 
11701debfc3dSmrg   /* A common failure mode if register status is not correct in the
11711debfc3dSmrg      RTL is for this routine to be called with a REGNO we didn't
11721debfc3dSmrg      expect to save.  That will cause us to write an insn with a (nil)
11731debfc3dSmrg      SET_DEST or SET_SRC.  Instead of doing so and causing a crash
11741debfc3dSmrg      later, check for this common case here instead.  This will remove
11751debfc3dSmrg      one step in debugging such problems.  */
11761debfc3dSmrg   gcc_assert (regno_save_mem[regno][1]);
11771debfc3dSmrg 
11781debfc3dSmrg   /* Get the pattern to emit and update our status.
11791debfc3dSmrg 
11801debfc3dSmrg      See if we can restore `maxrestore' registers at once.  Work
11811debfc3dSmrg      backwards to the single register case.  */
11821debfc3dSmrg   for (i = maxrestore; i > 0; i--)
11831debfc3dSmrg     {
11841debfc3dSmrg       int j;
11851debfc3dSmrg       int ok = 1;
11861debfc3dSmrg 
11871debfc3dSmrg       if (regno_save_mem[regno][i] == 0)
11881debfc3dSmrg 	continue;
11891debfc3dSmrg 
11901debfc3dSmrg       for (j = 0; j < i; j++)
11911debfc3dSmrg 	if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
11921debfc3dSmrg 	  {
11931debfc3dSmrg 	    ok = 0;
11941debfc3dSmrg 	    break;
11951debfc3dSmrg 	  }
11961debfc3dSmrg       /* Must do this one restore at a time.  */
11971debfc3dSmrg       if (! ok)
11981debfc3dSmrg 	continue;
11991debfc3dSmrg 
12001debfc3dSmrg       numregs = i;
12011debfc3dSmrg       break;
12021debfc3dSmrg     }
12031debfc3dSmrg 
12041debfc3dSmrg   mem = regno_save_mem [regno][numregs];
12051debfc3dSmrg   if (save_mode [regno] != VOIDmode
12061debfc3dSmrg       && save_mode [regno] != GET_MODE (mem)
1207a2dc1f3fSmrg       && numregs == hard_regno_nregs (regno, save_mode [regno])
12081debfc3dSmrg       /* Check that insn to restore REGNO in save_mode[regno] is
12091debfc3dSmrg 	 correct.  */
12101debfc3dSmrg       && reg_save_code (regno, save_mode[regno]) >= 0)
12111debfc3dSmrg     mem = adjust_address_nv (mem, save_mode[regno], 0);
12121debfc3dSmrg   else
12131debfc3dSmrg     mem = copy_rtx (mem);
12141debfc3dSmrg 
12151debfc3dSmrg   /* Verify that the alignment of spill space is equal to or greater
12161debfc3dSmrg      than required.  */
12171debfc3dSmrg   gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT,
12181debfc3dSmrg 		   GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem));
12191debfc3dSmrg 
12201debfc3dSmrg   pat = gen_rtx_SET (gen_rtx_REG (GET_MODE (mem), regno), mem);
12211debfc3dSmrg   code = reg_restore_code (regno, GET_MODE (mem));
12221debfc3dSmrg   new_chain = insert_one_insn (chain, before_p, code, pat);
12231debfc3dSmrg 
12241debfc3dSmrg   /* Clear status for all registers we restored.  */
12251debfc3dSmrg   for (k = 0; k < i; k++)
12261debfc3dSmrg     {
12271debfc3dSmrg       CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k);
12281debfc3dSmrg       SET_REGNO_REG_SET (&new_chain->dead_or_set, regno + k);
12291debfc3dSmrg       n_regs_saved--;
12301debfc3dSmrg     }
12311debfc3dSmrg 
12321debfc3dSmrg   /* Tell our callers how many extra registers we saved/restored.  */
12331debfc3dSmrg   return numregs - 1;
12341debfc3dSmrg }
12351debfc3dSmrg 
12361debfc3dSmrg /* Like insert_restore above, but save registers instead.  */
12371debfc3dSmrg 
12381debfc3dSmrg static int
insert_save(class insn_chain * chain,int regno,HARD_REG_SET * to_save,machine_mode * save_mode)1239*8feb0f0bSmrg insert_save (class insn_chain *chain, int regno,
1240a2dc1f3fSmrg 	     HARD_REG_SET *to_save, machine_mode *save_mode)
12411debfc3dSmrg {
12421debfc3dSmrg   int i;
12431debfc3dSmrg   unsigned int k;
12441debfc3dSmrg   rtx pat = NULL_RTX;
12451debfc3dSmrg   int code;
12461debfc3dSmrg   unsigned int numregs = 0;
1247*8feb0f0bSmrg   class insn_chain *new_chain;
12481debfc3dSmrg   rtx mem;
12491debfc3dSmrg 
12501debfc3dSmrg   /* A common failure mode if register status is not correct in the
12511debfc3dSmrg      RTL is for this routine to be called with a REGNO we didn't
12521debfc3dSmrg      expect to save.  That will cause us to write an insn with a (nil)
12531debfc3dSmrg      SET_DEST or SET_SRC.  Instead of doing so and causing a crash
12541debfc3dSmrg      later, check for this common case here.  This will remove one
12551debfc3dSmrg      step in debugging such problems.  */
12561debfc3dSmrg   gcc_assert (regno_save_mem[regno][1]);
12571debfc3dSmrg 
12581debfc3dSmrg   /* Get the pattern to emit and update our status.
12591debfc3dSmrg 
12601debfc3dSmrg      See if we can save several registers with a single instruction.
12611debfc3dSmrg      Work backwards to the single register case.  */
12621debfc3dSmrg   for (i = MOVE_MAX_WORDS; i > 0; i--)
12631debfc3dSmrg     {
12641debfc3dSmrg       int j;
12651debfc3dSmrg       int ok = 1;
12661debfc3dSmrg       if (regno_save_mem[regno][i] == 0)
12671debfc3dSmrg 	continue;
12681debfc3dSmrg 
12691debfc3dSmrg       for (j = 0; j < i; j++)
12701debfc3dSmrg 	if (! TEST_HARD_REG_BIT (*to_save, regno + j))
12711debfc3dSmrg 	  {
12721debfc3dSmrg 	    ok = 0;
12731debfc3dSmrg 	    break;
12741debfc3dSmrg 	  }
12751debfc3dSmrg       /* Must do this one save at a time.  */
12761debfc3dSmrg       if (! ok)
12771debfc3dSmrg 	continue;
12781debfc3dSmrg 
12791debfc3dSmrg       numregs = i;
12801debfc3dSmrg       break;
12811debfc3dSmrg     }
12821debfc3dSmrg 
12831debfc3dSmrg   mem = regno_save_mem [regno][numregs];
12841debfc3dSmrg   if (save_mode [regno] != VOIDmode
12851debfc3dSmrg       && save_mode [regno] != GET_MODE (mem)
1286a2dc1f3fSmrg       && numregs == hard_regno_nregs (regno, save_mode [regno])
12871debfc3dSmrg       /* Check that insn to save REGNO in save_mode[regno] is
12881debfc3dSmrg 	 correct.  */
12891debfc3dSmrg       && reg_save_code (regno, save_mode[regno]) >= 0)
12901debfc3dSmrg     mem = adjust_address_nv (mem, save_mode[regno], 0);
12911debfc3dSmrg   else
12921debfc3dSmrg     mem = copy_rtx (mem);
12931debfc3dSmrg 
12941debfc3dSmrg   /* Verify that the alignment of spill space is equal to or greater
12951debfc3dSmrg      than required.  */
12961debfc3dSmrg   gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT,
12971debfc3dSmrg 		   GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem));
12981debfc3dSmrg 
12991debfc3dSmrg   pat = gen_rtx_SET (mem, gen_rtx_REG (GET_MODE (mem), regno));
13001debfc3dSmrg   code = reg_save_code (regno, GET_MODE (mem));
1301a2dc1f3fSmrg   new_chain = insert_one_insn (chain, 1, code, pat);
13021debfc3dSmrg 
13031debfc3dSmrg   /* Set hard_regs_saved and dead_or_set for all the registers we saved.  */
13041debfc3dSmrg   for (k = 0; k < numregs; k++)
13051debfc3dSmrg     {
13061debfc3dSmrg       SET_HARD_REG_BIT (hard_regs_saved, regno + k);
13071debfc3dSmrg       SET_REGNO_REG_SET (&new_chain->dead_or_set, regno + k);
13081debfc3dSmrg       n_regs_saved++;
13091debfc3dSmrg     }
13101debfc3dSmrg 
13111debfc3dSmrg   /* Tell our callers how many extra registers we saved/restored.  */
13121debfc3dSmrg   return numregs - 1;
13131debfc3dSmrg }
13141debfc3dSmrg 
13151debfc3dSmrg /* A note_uses callback used by insert_one_insn.  Add the hard-register
13161debfc3dSmrg    equivalent of each REG to regset DATA.  */
13171debfc3dSmrg 
13181debfc3dSmrg static void
add_used_regs(rtx * loc,void * data)13191debfc3dSmrg add_used_regs (rtx *loc, void *data)
13201debfc3dSmrg {
13211debfc3dSmrg   subrtx_iterator::array_type array;
13221debfc3dSmrg   FOR_EACH_SUBRTX (iter, array, *loc, NONCONST)
13231debfc3dSmrg     {
13241debfc3dSmrg       const_rtx x = *iter;
13251debfc3dSmrg       if (REG_P (x))
13261debfc3dSmrg 	{
13271debfc3dSmrg 	  unsigned int regno = REGNO (x);
13281debfc3dSmrg 	  if (HARD_REGISTER_NUM_P (regno))
1329a2dc1f3fSmrg 	    bitmap_set_range ((regset) data, regno, REG_NREGS (x));
13301debfc3dSmrg 	  else
13311debfc3dSmrg 	    gcc_checking_assert (reg_renumber[regno] < 0);
13321debfc3dSmrg 	}
13331debfc3dSmrg     }
13341debfc3dSmrg }
13351debfc3dSmrg 
13361debfc3dSmrg /* Emit a new caller-save insn and set the code.  */
1337*8feb0f0bSmrg static class insn_chain *
insert_one_insn(class insn_chain * chain,int before_p,int code,rtx pat)1338*8feb0f0bSmrg insert_one_insn (class insn_chain *chain, int before_p, int code, rtx pat)
13391debfc3dSmrg {
13401debfc3dSmrg   rtx_insn *insn = chain->insn;
1341*8feb0f0bSmrg   class insn_chain *new_chain;
13421debfc3dSmrg 
13431debfc3dSmrg   /* If INSN references CC0, put our insns in front of the insn that sets
13441debfc3dSmrg      CC0.  This is always safe, since the only way we could be passed an
13451debfc3dSmrg      insn that references CC0 is for a restore, and doing a restore earlier
13461debfc3dSmrg      isn't a problem.  We do, however, assume here that CALL_INSNs don't
13471debfc3dSmrg      reference CC0.  Guard against non-INSN's like CODE_LABEL.  */
13481debfc3dSmrg 
13491debfc3dSmrg   if (HAVE_cc0 && (NONJUMP_INSN_P (insn) || JUMP_P (insn))
13501debfc3dSmrg       && before_p
13511debfc3dSmrg       && reg_referenced_p (cc0_rtx, PATTERN (insn)))
13521debfc3dSmrg     chain = chain->prev, insn = chain->insn;
13531debfc3dSmrg 
13541debfc3dSmrg   new_chain = new_insn_chain ();
13551debfc3dSmrg   if (before_p)
13561debfc3dSmrg     {
13571debfc3dSmrg       rtx link;
13581debfc3dSmrg 
13591debfc3dSmrg       new_chain->prev = chain->prev;
13601debfc3dSmrg       if (new_chain->prev != 0)
13611debfc3dSmrg 	new_chain->prev->next = new_chain;
13621debfc3dSmrg       else
13631debfc3dSmrg 	reload_insn_chain = new_chain;
13641debfc3dSmrg 
13651debfc3dSmrg       chain->prev = new_chain;
13661debfc3dSmrg       new_chain->next = chain;
13671debfc3dSmrg       new_chain->insn = emit_insn_before (pat, insn);
13681debfc3dSmrg       /* ??? It would be nice if we could exclude the already / still saved
13691debfc3dSmrg 	 registers from the live sets.  */
13701debfc3dSmrg       COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
13711debfc3dSmrg       note_uses (&PATTERN (chain->insn), add_used_regs,
13721debfc3dSmrg 		 &new_chain->live_throughout);
13731debfc3dSmrg       /* If CHAIN->INSN is a call, then the registers which contain
13741debfc3dSmrg 	 the arguments to the function are live in the new insn.  */
13751debfc3dSmrg       if (CALL_P (chain->insn))
13761debfc3dSmrg 	for (link = CALL_INSN_FUNCTION_USAGE (chain->insn);
13771debfc3dSmrg 	     link != NULL_RTX;
13781debfc3dSmrg 	     link = XEXP (link, 1))
13791debfc3dSmrg 	  note_uses (&XEXP (link, 0), add_used_regs,
13801debfc3dSmrg 		     &new_chain->live_throughout);
13811debfc3dSmrg 
13821debfc3dSmrg       CLEAR_REG_SET (&new_chain->dead_or_set);
13831debfc3dSmrg       if (chain->insn == BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, chain->block)))
13841debfc3dSmrg 	BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, chain->block)) = new_chain->insn;
13851debfc3dSmrg     }
13861debfc3dSmrg   else
13871debfc3dSmrg     {
13881debfc3dSmrg       new_chain->next = chain->next;
13891debfc3dSmrg       if (new_chain->next != 0)
13901debfc3dSmrg 	new_chain->next->prev = new_chain;
13911debfc3dSmrg       chain->next = new_chain;
13921debfc3dSmrg       new_chain->prev = chain;
13931debfc3dSmrg       new_chain->insn = emit_insn_after (pat, insn);
13941debfc3dSmrg       /* ??? It would be nice if we could exclude the already / still saved
13951debfc3dSmrg 	 registers from the live sets, and observe REG_UNUSED notes.  */
13961debfc3dSmrg       COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
13971debfc3dSmrg       /* Registers that are set in CHAIN->INSN live in the new insn.
13981debfc3dSmrg 	 (Unless there is a REG_UNUSED note for them, but we don't
13991debfc3dSmrg 	  look for them here.) */
1400*8feb0f0bSmrg       note_stores (chain->insn, add_stored_regs, &new_chain->live_throughout);
14011debfc3dSmrg       CLEAR_REG_SET (&new_chain->dead_or_set);
14021debfc3dSmrg       if (chain->insn == BB_END (BASIC_BLOCK_FOR_FN (cfun, chain->block)))
14031debfc3dSmrg 	BB_END (BASIC_BLOCK_FOR_FN (cfun, chain->block)) = new_chain->insn;
14041debfc3dSmrg     }
14051debfc3dSmrg   new_chain->block = chain->block;
14061debfc3dSmrg   new_chain->is_caller_save_insn = 1;
14071debfc3dSmrg 
14081debfc3dSmrg   INSN_CODE (new_chain->insn) = code;
14091debfc3dSmrg   return new_chain;
14101debfc3dSmrg }
14111debfc3dSmrg #include "gt-caller-save.h"
1412