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 (®_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