| 1 | 
         684 | 
         jeremybenn | 
         /* Save and restore call-clobbered registers which are live across a call.
  | 
      
      
         | 2 | 
          | 
          | 
            Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998, 1999, 2000,
  | 
      
      
         | 3 | 
          | 
          | 
            2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
  | 
      
      
         | 4 | 
          | 
          | 
            Free Software Foundation, Inc.
  | 
      
      
         | 5 | 
          | 
          | 
          
  | 
      
      
         | 6 | 
          | 
          | 
         This file is part of GCC.
  | 
      
      
         | 7 | 
          | 
          | 
          
  | 
      
      
         | 8 | 
          | 
          | 
         GCC is free software; you can redistribute it and/or modify it under
  | 
      
      
         | 9 | 
          | 
          | 
         the terms of the GNU General Public License as published by the Free
  | 
      
      
         | 10 | 
          | 
          | 
         Software Foundation; either version 3, or (at your option) any later
  | 
      
      
         | 11 | 
          | 
          | 
         version.
  | 
      
      
         | 12 | 
          | 
          | 
          
  | 
      
      
         | 13 | 
          | 
          | 
         GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  | 
      
      
         | 14 | 
          | 
          | 
         WARRANTY; without even the implied warranty of MERCHANTABILITY or
  | 
      
      
         | 15 | 
          | 
          | 
         FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  | 
      
      
         | 16 | 
          | 
          | 
         for more details.
  | 
      
      
         | 17 | 
          | 
          | 
          
  | 
      
      
         | 18 | 
          | 
          | 
         You should have received a copy of the GNU General Public License
  | 
      
      
         | 19 | 
          | 
          | 
         along with GCC; see the file COPYING3.  If not see
  | 
      
      
         | 20 | 
          | 
          | 
         <http://www.gnu.org/licenses/>.  */
  | 
      
      
         | 21 | 
          | 
          | 
          
  | 
      
      
         | 22 | 
          | 
          | 
         #include "config.h"
  | 
      
      
         | 23 | 
          | 
          | 
         #include "system.h"
  | 
      
      
         | 24 | 
          | 
          | 
         #include "coretypes.h"
  | 
      
      
         | 25 | 
          | 
          | 
         #include "tm.h"
  | 
      
      
         | 26 | 
          | 
          | 
         #include "rtl.h"
  | 
      
      
         | 27 | 
          | 
          | 
         #include "regs.h"
  | 
      
      
         | 28 | 
          | 
          | 
         #include "insn-config.h"
  | 
      
      
         | 29 | 
          | 
          | 
         #include "flags.h"
  | 
      
      
         | 30 | 
          | 
          | 
         #include "hard-reg-set.h"
  | 
      
      
         | 31 | 
          | 
          | 
         #include "recog.h"
  | 
      
      
         | 32 | 
          | 
          | 
         #include "basic-block.h"
  | 
      
      
         | 33 | 
          | 
          | 
         #include "df.h"
  | 
      
      
         | 34 | 
          | 
          | 
         #include "reload.h"
  | 
      
      
         | 35 | 
          | 
          | 
         #include "function.h"
  | 
      
      
         | 36 | 
          | 
          | 
         #include "expr.h"
  | 
      
      
         | 37 | 
          | 
          | 
         #include "diagnostic-core.h"
  | 
      
      
         | 38 | 
          | 
          | 
         #include "tm_p.h"
  | 
      
      
         | 39 | 
          | 
          | 
         #include "addresses.h"
  | 
      
      
         | 40 | 
          | 
          | 
         #include "output.h"
  | 
      
      
         | 41 | 
          | 
          | 
         #include "ggc.h"
  | 
      
      
         | 42 | 
          | 
          | 
          
  | 
      
      
         | 43 | 
          | 
          | 
         #define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD)
  | 
      
      
         | 44 | 
          | 
          | 
          
  | 
      
      
         | 45 | 
          | 
          | 
         #define regno_save_mode \
  | 
      
      
         | 46 | 
          | 
          | 
           (this_target_reload->x_regno_save_mode)
  | 
      
      
         | 47 | 
          | 
          | 
         #define cached_reg_save_code \
  | 
      
      
         | 48 | 
          | 
          | 
           (this_target_reload->x_cached_reg_save_code)
  | 
      
      
         | 49 | 
          | 
          | 
         #define cached_reg_restore_code \
  | 
      
      
         | 50 | 
          | 
          | 
           (this_target_reload->x_cached_reg_restore_code)
  | 
      
      
         | 51 | 
          | 
          | 
          
  | 
      
      
         | 52 | 
          | 
          | 
         /* For each hard register, a place on the stack where it can be saved,
  | 
      
      
         | 53 | 
          | 
          | 
            if needed.  */
  | 
      
      
         | 54 | 
          | 
          | 
          
  | 
      
      
         | 55 | 
          | 
          | 
         static rtx
  | 
      
      
         | 56 | 
          | 
          | 
           regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
  | 
      
      
         | 57 | 
          | 
          | 
          
  | 
      
      
         | 58 | 
          | 
          | 
         /* The number of elements in the subsequent array.  */
  | 
      
      
         | 59 | 
          | 
          | 
         static int save_slots_num;
  | 
      
      
         | 60 | 
          | 
          | 
          
  | 
      
      
         | 61 | 
          | 
          | 
         /* Allocated slots so far.  */
  | 
      
      
         | 62 | 
          | 
          | 
         static rtx save_slots[FIRST_PSEUDO_REGISTER];
  | 
      
      
         | 63 | 
          | 
          | 
          
  | 
      
      
         | 64 | 
          | 
          | 
         /* Set of hard regs currently residing in save area (during insn scan).  */
  | 
      
      
         | 65 | 
          | 
          | 
          
  | 
      
      
         | 66 | 
          | 
          | 
         static HARD_REG_SET hard_regs_saved;
  | 
      
      
         | 67 | 
          | 
          | 
          
  | 
      
      
         | 68 | 
          | 
          | 
         /* Number of registers currently in hard_regs_saved.  */
  | 
      
      
         | 69 | 
          | 
          | 
          
  | 
      
      
         | 70 | 
          | 
          | 
         static int n_regs_saved;
  | 
      
      
         | 71 | 
          | 
          | 
          
  | 
      
      
         | 72 | 
          | 
          | 
         /* Computed by mark_referenced_regs, all regs referenced in a given
  | 
      
      
         | 73 | 
          | 
          | 
            insn.  */
  | 
      
      
         | 74 | 
          | 
          | 
         static HARD_REG_SET referenced_regs;
  | 
      
      
         | 75 | 
          | 
          | 
          
  | 
      
      
         | 76 | 
          | 
          | 
          
  | 
      
      
         | 77 | 
          | 
          | 
         typedef void refmarker_fn (rtx *loc, enum machine_mode mode, int hardregno,
  | 
      
      
         | 78 | 
          | 
          | 
                                    void *mark_arg);
  | 
      
      
         | 79 | 
          | 
          | 
          
  | 
      
      
         | 80 | 
          | 
          | 
         static int reg_save_code (int, enum machine_mode);
  | 
      
      
         | 81 | 
          | 
          | 
         static int reg_restore_code (int, enum machine_mode);
  | 
      
      
         | 82 | 
          | 
          | 
          
  | 
      
      
         | 83 | 
          | 
          | 
         struct saved_hard_reg;
  | 
      
      
         | 84 | 
          | 
          | 
         static void initiate_saved_hard_regs (void);
  | 
      
      
         | 85 | 
          | 
          | 
         static void new_saved_hard_reg (int, int);
  | 
      
      
         | 86 | 
          | 
          | 
         static void finish_saved_hard_regs (void);
  | 
      
      
         | 87 | 
          | 
          | 
         static int saved_hard_reg_compare_func (const void *, const void *);
  | 
      
      
         | 88 | 
          | 
          | 
          
  | 
      
      
         | 89 | 
          | 
          | 
         static void mark_set_regs (rtx, const_rtx, void *);
  | 
      
      
         | 90 | 
          | 
          | 
         static void mark_referenced_regs (rtx *, refmarker_fn *mark, void *mark_arg);
  | 
      
      
         | 91 | 
          | 
          | 
         static refmarker_fn mark_reg_as_referenced;
  | 
      
      
         | 92 | 
          | 
          | 
         static refmarker_fn replace_reg_with_saved_mem;
  | 
      
      
         | 93 | 
          | 
          | 
         static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *,
  | 
      
      
         | 94 | 
          | 
          | 
                                 enum machine_mode *);
  | 
      
      
         | 95 | 
          | 
          | 
         static int insert_restore (struct insn_chain *, int, int, int,
  | 
      
      
         | 96 | 
          | 
          | 
                                    enum machine_mode *);
  | 
      
      
         | 97 | 
          | 
          | 
         static struct insn_chain *insert_one_insn (struct insn_chain *, int, int,
  | 
      
      
         | 98 | 
          | 
          | 
                                                    rtx);
  | 
      
      
         | 99 | 
          | 
          | 
         static void add_stored_regs (rtx, const_rtx, void *);
  | 
      
      
         | 100 | 
          | 
          | 
          
  | 
      
      
         | 101 | 
          | 
          | 
          
  | 
      
      
         | 102 | 
          | 
          | 
          
  | 
      
      
         | 103 | 
          | 
          | 
         static GTY(()) rtx savepat;
  | 
      
      
         | 104 | 
          | 
          | 
         static GTY(()) rtx restpat;
  | 
      
      
         | 105 | 
          | 
          | 
         static GTY(()) rtx test_reg;
  | 
      
      
         | 106 | 
          | 
          | 
         static GTY(()) rtx test_mem;
  | 
      
      
         | 107 | 
          | 
          | 
         static GTY(()) rtx saveinsn;
  | 
      
      
         | 108 | 
          | 
          | 
         static GTY(()) rtx restinsn;
  | 
      
      
         | 109 | 
          | 
          | 
          
  | 
      
      
         | 110 | 
          | 
          | 
         /* Return the INSN_CODE used to save register REG in mode MODE.  */
  | 
      
      
         | 111 | 
          | 
          | 
         static int
  | 
      
      
         | 112 | 
          | 
          | 
         reg_save_code (int reg, enum machine_mode mode)
  | 
      
      
         | 113 | 
          | 
          | 
         {
  | 
      
      
         | 114 | 
          | 
          | 
           bool ok;
  | 
      
      
         | 115 | 
          | 
          | 
           if (cached_reg_save_code[reg][mode])
  | 
      
      
         | 116 | 
          | 
          | 
              return cached_reg_save_code[reg][mode];
  | 
      
      
         | 117 | 
          | 
          | 
           if (!HARD_REGNO_MODE_OK (reg, mode))
  | 
      
      
         | 118 | 
          | 
          | 
             {
  | 
      
      
         | 119 | 
          | 
          | 
               /* Depending on how HARD_REGNO_MODE_OK is defined, range propagation
  | 
      
      
         | 120 | 
          | 
          | 
                  might deduce here that reg >= FIRST_PSEUDO_REGISTER.  So the assert
  | 
      
      
         | 121 | 
          | 
          | 
                  below silences a warning.  */
  | 
      
      
         | 122 | 
          | 
          | 
               gcc_assert (reg < FIRST_PSEUDO_REGISTER);
  | 
      
      
         | 123 | 
          | 
          | 
               cached_reg_save_code[reg][mode] = -1;
  | 
      
      
         | 124 | 
          | 
          | 
               cached_reg_restore_code[reg][mode] = -1;
  | 
      
      
         | 125 | 
          | 
          | 
               return -1;
  | 
      
      
         | 126 | 
          | 
          | 
             }
  | 
      
      
         | 127 | 
          | 
          | 
          
  | 
      
      
         | 128 | 
          | 
          | 
           /* Update the register number and modes of the register
  | 
      
      
         | 129 | 
          | 
          | 
              and memory operand.  */
  | 
      
      
         | 130 | 
          | 
          | 
           SET_REGNO_RAW (test_reg, reg);
  | 
      
      
         | 131 | 
          | 
          | 
           PUT_MODE (test_reg, mode);
  | 
      
      
         | 132 | 
          | 
          | 
           PUT_MODE (test_mem, mode);
  | 
      
      
         | 133 | 
          | 
          | 
          
  | 
      
      
         | 134 | 
          | 
          | 
           /* Force re-recognition of the modified insns.  */
  | 
      
      
         | 135 | 
          | 
          | 
           INSN_CODE (saveinsn) = -1;
  | 
      
      
         | 136 | 
          | 
          | 
           INSN_CODE (restinsn) = -1;
  | 
      
      
         | 137 | 
          | 
          | 
          
  | 
      
      
         | 138 | 
          | 
          | 
           cached_reg_save_code[reg][mode] = recog_memoized (saveinsn);
  | 
      
      
         | 139 | 
          | 
          | 
           cached_reg_restore_code[reg][mode] = recog_memoized (restinsn);
  | 
      
      
         | 140 | 
          | 
          | 
          
  | 
      
      
         | 141 | 
          | 
          | 
           /* Now extract both insns and see if we can meet their
  | 
      
      
         | 142 | 
          | 
          | 
              constraints.  */
  | 
      
      
         | 143 | 
          | 
          | 
           ok = (cached_reg_save_code[reg][mode] != -1
  | 
      
      
         | 144 | 
          | 
          | 
                 && cached_reg_restore_code[reg][mode] != -1);
  | 
      
      
         | 145 | 
          | 
          | 
           if (ok)
  | 
      
      
         | 146 | 
          | 
          | 
             {
  | 
      
      
         | 147 | 
          | 
          | 
               extract_insn (saveinsn);
  | 
      
      
         | 148 | 
          | 
          | 
               ok = constrain_operands (1);
  | 
      
      
         | 149 | 
          | 
          | 
               extract_insn (restinsn);
  | 
      
      
         | 150 | 
          | 
          | 
               ok &= constrain_operands (1);
  | 
      
      
         | 151 | 
          | 
          | 
             }
  | 
      
      
         | 152 | 
          | 
          | 
          
  | 
      
      
         | 153 | 
          | 
          | 
           if (! ok)
  | 
      
      
         | 154 | 
          | 
          | 
             {
  | 
      
      
         | 155 | 
          | 
          | 
               cached_reg_save_code[reg][mode] = -1;
  | 
      
      
         | 156 | 
          | 
          | 
               cached_reg_restore_code[reg][mode] = -1;
  | 
      
      
         | 157 | 
          | 
          | 
             }
  | 
      
      
         | 158 | 
          | 
          | 
           gcc_assert (cached_reg_save_code[reg][mode]);
  | 
      
      
         | 159 | 
          | 
          | 
           return cached_reg_save_code[reg][mode];
  | 
      
      
         | 160 | 
          | 
          | 
         }
  | 
      
      
         | 161 | 
          | 
          | 
          
  | 
      
      
         | 162 | 
          | 
          | 
         /* Return the INSN_CODE used to restore register REG in mode MODE.  */
  | 
      
      
         | 163 | 
          | 
          | 
         static int
  | 
      
      
         | 164 | 
          | 
          | 
         reg_restore_code (int reg, enum machine_mode mode)
  | 
      
      
         | 165 | 
          | 
          | 
         {
  | 
      
      
         | 166 | 
          | 
          | 
           if (cached_reg_restore_code[reg][mode])
  | 
      
      
         | 167 | 
          | 
          | 
              return cached_reg_restore_code[reg][mode];
  | 
      
      
         | 168 | 
          | 
          | 
           /* Populate our cache.  */
  | 
      
      
         | 169 | 
          | 
          | 
           reg_save_code (reg, mode);
  | 
      
      
         | 170 | 
          | 
          | 
           return cached_reg_restore_code[reg][mode];
  | 
      
      
         | 171 | 
          | 
          | 
         }
  | 
      
      
         | 172 | 
          | 
          | 
          
  | 
      
      
         | 173 | 
          | 
          | 
         /* Initialize for caller-save.
  | 
      
      
         | 174 | 
          | 
          | 
          
  | 
      
      
         | 175 | 
          | 
          | 
            Look at all the hard registers that are used by a call and for which
  | 
      
      
         | 176 | 
          | 
          | 
            reginfo.c has not already excluded from being used across a call.
  | 
      
      
         | 177 | 
          | 
          | 
          
  | 
      
      
         | 178 | 
          | 
          | 
            Ensure that we can find a mode to save the register and that there is a
  | 
      
      
         | 179 | 
          | 
          | 
            simple insn to save and restore the register.  This latter check avoids
  | 
      
      
         | 180 | 
          | 
          | 
            problems that would occur if we tried to save the MQ register of some
  | 
      
      
         | 181 | 
          | 
          | 
            machines directly into memory.  */
  | 
      
      
         | 182 | 
          | 
          | 
          
  | 
      
      
         | 183 | 
          | 
          | 
         void
  | 
      
      
         | 184 | 
          | 
          | 
         init_caller_save (void)
  | 
      
      
         | 185 | 
          | 
          | 
         {
  | 
      
      
         | 186 | 
          | 
          | 
           rtx addr_reg;
  | 
      
      
         | 187 | 
          | 
          | 
           int offset;
  | 
      
      
         | 188 | 
          | 
          | 
           rtx address;
  | 
      
      
         | 189 | 
          | 
          | 
           int i, j;
  | 
      
      
         | 190 | 
          | 
          | 
          
  | 
      
      
         | 191 | 
          | 
          | 
           if (caller_save_initialized_p)
  | 
      
      
         | 192 | 
          | 
          | 
             return;
  | 
      
      
         | 193 | 
          | 
          | 
          
  | 
      
      
         | 194 | 
          | 
          | 
           caller_save_initialized_p = true;
  | 
      
      
         | 195 | 
          | 
          | 
          
  | 
      
      
         | 196 | 
          | 
          | 
           CLEAR_HARD_REG_SET (no_caller_save_reg_set);
  | 
      
      
         | 197 | 
          | 
          | 
           /* First find all the registers that we need to deal with and all
  | 
      
      
         | 198 | 
          | 
          | 
              the modes that they can have.  If we can't find a mode to use,
  | 
      
      
         | 199 | 
          | 
          | 
              we can't have the register live over calls.  */
  | 
      
      
         | 200 | 
          | 
          | 
          
  | 
      
      
         | 201 | 
          | 
          | 
           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  | 
      
      
         | 202 | 
          | 
          | 
             {
  | 
      
      
         | 203 | 
          | 
          | 
               if (call_used_regs[i]
  | 
      
      
         | 204 | 
          | 
          | 
                   && !TEST_HARD_REG_BIT (call_fixed_reg_set, i))
  | 
      
      
         | 205 | 
          | 
          | 
                 {
  | 
      
      
         | 206 | 
          | 
          | 
                   for (j = 1; j <= MOVE_MAX_WORDS; j++)
  | 
      
      
         | 207 | 
          | 
          | 
                     {
  | 
      
      
         | 208 | 
          | 
          | 
                       regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j,
  | 
      
      
         | 209 | 
          | 
          | 
                                                                            VOIDmode);
  | 
      
      
         | 210 | 
          | 
          | 
                       if (regno_save_mode[i][j] == VOIDmode && j == 1)
  | 
      
      
         | 211 | 
          | 
          | 
                         {
  | 
      
      
         | 212 | 
          | 
          | 
                           SET_HARD_REG_BIT (call_fixed_reg_set, i);
  | 
      
      
         | 213 | 
          | 
          | 
                         }
  | 
      
      
         | 214 | 
          | 
          | 
                     }
  | 
      
      
         | 215 | 
          | 
          | 
                 }
  | 
      
      
         | 216 | 
          | 
          | 
               else
  | 
      
      
         | 217 | 
          | 
          | 
                 regno_save_mode[i][1] = VOIDmode;
  | 
      
      
         | 218 | 
          | 
          | 
             }
  | 
      
      
         | 219 | 
          | 
          | 
          
  | 
      
      
         | 220 | 
          | 
          | 
           /* The following code tries to approximate the conditions under which
  | 
      
      
         | 221 | 
          | 
          | 
              we can easily save and restore a register without scratch registers or
  | 
      
      
         | 222 | 
          | 
          | 
              other complexities.  It will usually work, except under conditions where
  | 
      
      
         | 223 | 
          | 
          | 
              the validity of an insn operand is dependent on the address offset.
  | 
      
      
         | 224 | 
          | 
          | 
              No such cases are currently known.
  | 
      
      
         | 225 | 
          | 
          | 
          
  | 
      
      
         | 226 | 
          | 
          | 
              We first find a typical offset from some BASE_REG_CLASS register.
  | 
      
      
         | 227 | 
          | 
          | 
              This address is chosen by finding the first register in the class
  | 
      
      
         | 228 | 
          | 
          | 
              and by finding the smallest power of two that is a valid offset from
  | 
      
      
         | 229 | 
          | 
          | 
              that register in every mode we will use to save registers.  */
  | 
      
      
         | 230 | 
          | 
          | 
          
  | 
      
      
         | 231 | 
          | 
          | 
           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  | 
      
      
         | 232 | 
          | 
          | 
             if (TEST_HARD_REG_BIT
  | 
      
      
         | 233 | 
          | 
          | 
                 (reg_class_contents
  | 
      
      
         | 234 | 
          | 
          | 
                  [(int) base_reg_class (regno_save_mode[i][1], ADDR_SPACE_GENERIC,
  | 
      
      
         | 235 | 
          | 
          | 
                                         PLUS, CONST_INT)], i))
  | 
      
      
         | 236 | 
          | 
          | 
               break;
  | 
      
      
         | 237 | 
          | 
          | 
          
  | 
      
      
         | 238 | 
          | 
          | 
           gcc_assert (i < FIRST_PSEUDO_REGISTER);
  | 
      
      
         | 239 | 
          | 
          | 
          
  | 
      
      
         | 240 | 
          | 
          | 
           addr_reg = gen_rtx_REG (Pmode, i);
  | 
      
      
         | 241 | 
          | 
          | 
          
  | 
      
      
         | 242 | 
          | 
          | 
           for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1)
  | 
      
      
         | 243 | 
          | 
          | 
             {
  | 
      
      
         | 244 | 
          | 
          | 
               address = gen_rtx_PLUS (Pmode, addr_reg, GEN_INT (offset));
  | 
      
      
         | 245 | 
          | 
          | 
          
  | 
      
      
         | 246 | 
          | 
          | 
               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  | 
      
      
         | 247 | 
          | 
          | 
                 if (regno_save_mode[i][1] != VOIDmode
  | 
      
      
         | 248 | 
          | 
          | 
                   && ! strict_memory_address_p (regno_save_mode[i][1], address))
  | 
      
      
         | 249 | 
          | 
          | 
                   break;
  | 
      
      
         | 250 | 
          | 
          | 
          
  | 
      
      
         | 251 | 
          | 
          | 
               if (i == FIRST_PSEUDO_REGISTER)
  | 
      
      
         | 252 | 
          | 
          | 
                 break;
  | 
      
      
         | 253 | 
          | 
          | 
             }
  | 
      
      
         | 254 | 
          | 
          | 
          
  | 
      
      
         | 255 | 
          | 
          | 
           /* If we didn't find a valid address, we must use register indirect.  */
  | 
      
      
         | 256 | 
          | 
          | 
           if (offset == 0)
  | 
      
      
         | 257 | 
          | 
          | 
             address = addr_reg;
  | 
      
      
         | 258 | 
          | 
          | 
          
  | 
      
      
         | 259 | 
          | 
          | 
           /* Next we try to form an insn to save and restore the register.  We
  | 
      
      
         | 260 | 
          | 
          | 
              see if such an insn is recognized and meets its constraints.
  | 
      
      
         | 261 | 
          | 
          | 
          
  | 
      
      
         | 262 | 
          | 
          | 
              To avoid lots of unnecessary RTL allocation, we construct all the RTL
  | 
      
      
         | 263 | 
          | 
          | 
              once, then modify the memory and register operands in-place.  */
  | 
      
      
         | 264 | 
          | 
          | 
          
  | 
      
      
         | 265 | 
          | 
          | 
           test_reg = gen_rtx_REG (VOIDmode, 0);
  | 
      
      
         | 266 | 
          | 
          | 
           test_mem = gen_rtx_MEM (VOIDmode, address);
  | 
      
      
         | 267 | 
          | 
          | 
           savepat = gen_rtx_SET (VOIDmode, test_mem, test_reg);
  | 
      
      
         | 268 | 
          | 
          | 
           restpat = gen_rtx_SET (VOIDmode, test_reg, test_mem);
  | 
      
      
         | 269 | 
          | 
          | 
          
  | 
      
      
         | 270 | 
          | 
          | 
           saveinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, savepat, 0, -1, 0);
  | 
      
      
         | 271 | 
          | 
          | 
           restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, restpat, 0, -1, 0);
  | 
      
      
         | 272 | 
          | 
          | 
          
  | 
      
      
         | 273 | 
          | 
          | 
           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  | 
      
      
         | 274 | 
          | 
          | 
             for (j = 1; j <= MOVE_MAX_WORDS; j++)
  | 
      
      
         | 275 | 
          | 
          | 
               if (reg_save_code (i,regno_save_mode[i][j]) == -1)
  | 
      
      
         | 276 | 
          | 
          | 
                 {
  | 
      
      
         | 277 | 
          | 
          | 
                   regno_save_mode[i][j] = VOIDmode;
  | 
      
      
         | 278 | 
          | 
          | 
                   if (j == 1)
  | 
      
      
         | 279 | 
          | 
          | 
                     {
  | 
      
      
         | 280 | 
          | 
          | 
                       SET_HARD_REG_BIT (call_fixed_reg_set, i);
  | 
      
      
         | 281 | 
          | 
          | 
                       if (call_used_regs[i])
  | 
      
      
         | 282 | 
          | 
          | 
                         SET_HARD_REG_BIT (no_caller_save_reg_set, i);
  | 
      
      
         | 283 | 
          | 
          | 
                     }
  | 
      
      
         | 284 | 
          | 
          | 
                 }
  | 
      
      
         | 285 | 
          | 
          | 
         }
  | 
      
      
         | 286 | 
          | 
          | 
          
  | 
      
      
         | 287 | 
          | 
          | 
          
  | 
      
      
         | 288 | 
          | 
          | 
          
  | 
      
      
         | 289 | 
          | 
          | 
         /* Initialize save areas by showing that we haven't allocated any yet.  */
  | 
      
      
         | 290 | 
          | 
          | 
          
  | 
      
      
         | 291 | 
          | 
          | 
         void
  | 
      
      
         | 292 | 
          | 
          | 
         init_save_areas (void)
  | 
      
      
         | 293 | 
          | 
          | 
         {
  | 
      
      
         | 294 | 
          | 
          | 
           int i, j;
  | 
      
      
         | 295 | 
          | 
          | 
          
  | 
      
      
         | 296 | 
          | 
          | 
           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  | 
      
      
         | 297 | 
          | 
          | 
             for (j = 1; j <= MOVE_MAX_WORDS; j++)
  | 
      
      
         | 298 | 
          | 
          | 
               regno_save_mem[i][j] = 0;
  | 
      
      
         | 299 | 
          | 
          | 
           save_slots_num = 0;
  | 
      
      
         | 300 | 
          | 
          | 
          
  | 
      
      
         | 301 | 
          | 
          | 
         }
  | 
      
      
         | 302 | 
          | 
          | 
          
  | 
      
      
         | 303 | 
          | 
          | 
         /* The structure represents a hard register which should be saved
  | 
      
      
         | 304 | 
          | 
          | 
            through the call.  It is used when the integrated register
  | 
      
      
         | 305 | 
          | 
          | 
            allocator (IRA) is used and sharing save slots is on.  */
  | 
      
      
         | 306 | 
          | 
          | 
         struct saved_hard_reg
  | 
      
      
         | 307 | 
          | 
          | 
         {
  | 
      
      
         | 308 | 
          | 
          | 
           /* Order number starting with 0.  */
  | 
      
      
         | 309 | 
          | 
          | 
           int num;
  | 
      
      
         | 310 | 
          | 
          | 
           /* The hard regno.  */
  | 
      
      
         | 311 | 
          | 
          | 
           int hard_regno;
  | 
      
      
         | 312 | 
          | 
          | 
           /* Execution frequency of all calls through which given hard
  | 
      
      
         | 313 | 
          | 
          | 
              register should be saved.  */
  | 
      
      
         | 314 | 
          | 
          | 
           int call_freq;
  | 
      
      
         | 315 | 
          | 
          | 
           /* Stack slot reserved to save the hard register through calls.  */
  | 
      
      
         | 316 | 
          | 
          | 
           rtx slot;
  | 
      
      
         | 317 | 
          | 
          | 
           /* True if it is first hard register in the chain of hard registers
  | 
      
      
         | 318 | 
          | 
          | 
              sharing the same stack slot.  */
  | 
      
      
         | 319 | 
          | 
          | 
           int first_p;
  | 
      
      
         | 320 | 
          | 
          | 
           /* Order number of the next hard register structure with the same
  | 
      
      
         | 321 | 
          | 
          | 
              slot in the chain.  -1 represents end of the chain.  */
  | 
      
      
         | 322 | 
          | 
          | 
           int next;
  | 
      
      
         | 323 | 
          | 
          | 
         };
  | 
      
      
         | 324 | 
          | 
          | 
          
  | 
      
      
         | 325 | 
          | 
          | 
         /* Map: hard register number to the corresponding structure.  */
  | 
      
      
         | 326 | 
          | 
          | 
         static struct saved_hard_reg *hard_reg_map[FIRST_PSEUDO_REGISTER];
  | 
      
      
         | 327 | 
          | 
          | 
          
  | 
      
      
         | 328 | 
          | 
          | 
         /* The number of all structures representing hard registers should be
  | 
      
      
         | 329 | 
          | 
          | 
            saved, in order words, the number of used elements in the following
  | 
      
      
         | 330 | 
          | 
          | 
            array.  */
  | 
      
      
         | 331 | 
          | 
          | 
         static int saved_regs_num;
  | 
      
      
         | 332 | 
          | 
          | 
          
  | 
      
      
         | 333 | 
          | 
          | 
         /* Pointers to all the structures.  Index is the order number of the
  | 
      
      
         | 334 | 
          | 
          | 
            corresponding structure.  */
  | 
      
      
         | 335 | 
          | 
          | 
         static struct saved_hard_reg *all_saved_regs[FIRST_PSEUDO_REGISTER];
  | 
      
      
         | 336 | 
          | 
          | 
          
  | 
      
      
         | 337 | 
          | 
          | 
         /* First called function for work with saved hard registers.  */
  | 
      
      
         | 338 | 
          | 
          | 
         static void
  | 
      
      
         | 339 | 
          | 
          | 
         initiate_saved_hard_regs (void)
  | 
      
      
         | 340 | 
          | 
          | 
         {
  | 
      
      
         | 341 | 
          | 
          | 
           int i;
  | 
      
      
         | 342 | 
          | 
          | 
          
  | 
      
      
         | 343 | 
          | 
          | 
           saved_regs_num = 0;
  | 
      
      
         | 344 | 
          | 
          | 
           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  | 
      
      
         | 345 | 
          | 
          | 
             hard_reg_map[i] = NULL;
  | 
      
      
         | 346 | 
          | 
          | 
         }
  | 
      
      
         | 347 | 
          | 
          | 
          
  | 
      
      
         | 348 | 
          | 
          | 
         /* Allocate and return new saved hard register with given REGNO and
  | 
      
      
         | 349 | 
          | 
          | 
            CALL_FREQ.  */
  | 
      
      
         | 350 | 
          | 
          | 
         static void
  | 
      
      
         | 351 | 
          | 
          | 
         new_saved_hard_reg (int regno, int call_freq)
  | 
      
      
         | 352 | 
          | 
          | 
         {
  | 
      
      
         | 353 | 
          | 
          | 
           struct saved_hard_reg *saved_reg;
  | 
      
      
         | 354 | 
          | 
          | 
          
  | 
      
      
         | 355 | 
          | 
          | 
           saved_reg
  | 
      
      
         | 356 | 
          | 
          | 
             = (struct saved_hard_reg *) xmalloc (sizeof (struct saved_hard_reg));
  | 
      
      
         | 357 | 
          | 
          | 
           hard_reg_map[regno] = all_saved_regs[saved_regs_num] = saved_reg;
  | 
      
      
         | 358 | 
          | 
          | 
           saved_reg->num = saved_regs_num++;
  | 
      
      
         | 359 | 
          | 
          | 
           saved_reg->hard_regno = regno;
  | 
      
      
         | 360 | 
          | 
          | 
           saved_reg->call_freq = call_freq;
  | 
      
      
         | 361 | 
          | 
          | 
           saved_reg->first_p = FALSE;
  | 
      
      
         | 362 | 
          | 
          | 
           saved_reg->next = -1;
  | 
      
      
         | 363 | 
          | 
          | 
         }
  | 
      
      
         | 364 | 
          | 
          | 
          
  | 
      
      
         | 365 | 
          | 
          | 
         /* Free memory allocated for the saved hard registers.  */
  | 
      
      
         | 366 | 
          | 
          | 
         static void
  | 
      
      
         | 367 | 
          | 
          | 
         finish_saved_hard_regs (void)
  | 
      
      
         | 368 | 
          | 
          | 
         {
  | 
      
      
         | 369 | 
          | 
          | 
           int i;
  | 
      
      
         | 370 | 
          | 
          | 
          
  | 
      
      
         | 371 | 
          | 
          | 
           for (i = 0; i < saved_regs_num; i++)
  | 
      
      
         | 372 | 
          | 
          | 
             free (all_saved_regs[i]);
  | 
      
      
         | 373 | 
          | 
          | 
         }
  | 
      
      
         | 374 | 
          | 
          | 
          
  | 
      
      
         | 375 | 
          | 
          | 
         /* The function is used to sort the saved hard register structures
  | 
      
      
         | 376 | 
          | 
          | 
            according their frequency.  */
  | 
      
      
         | 377 | 
          | 
          | 
         static int
  | 
      
      
         | 378 | 
          | 
          | 
         saved_hard_reg_compare_func (const void *v1p, const void *v2p)
  | 
      
      
         | 379 | 
          | 
          | 
         {
  | 
      
      
         | 380 | 
          | 
          | 
           const struct saved_hard_reg *p1 = *(struct saved_hard_reg * const *) v1p;
  | 
      
      
         | 381 | 
          | 
          | 
           const struct saved_hard_reg *p2 = *(struct saved_hard_reg * const *) v2p;
  | 
      
      
         | 382 | 
          | 
          | 
          
  | 
      
      
         | 383 | 
          | 
          | 
           if (flag_omit_frame_pointer)
  | 
      
      
         | 384 | 
          | 
          | 
             {
  | 
      
      
         | 385 | 
          | 
          | 
               if (p1->call_freq - p2->call_freq != 0)
  | 
      
      
         | 386 | 
          | 
          | 
                 return p1->call_freq - p2->call_freq;
  | 
      
      
         | 387 | 
          | 
          | 
             }
  | 
      
      
         | 388 | 
          | 
          | 
           else if (p2->call_freq - p1->call_freq != 0)
  | 
      
      
         | 389 | 
          | 
          | 
             return p2->call_freq - p1->call_freq;
  | 
      
      
         | 390 | 
          | 
          | 
          
  | 
      
      
         | 391 | 
          | 
          | 
           return p1->num - p2->num;
  | 
      
      
         | 392 | 
          | 
          | 
         }
  | 
      
      
         | 393 | 
          | 
          | 
          
  | 
      
      
         | 394 | 
          | 
          | 
         /* Allocate save areas for any hard registers that might need saving.
  | 
      
      
         | 395 | 
          | 
          | 
            We take a conservative approach here and look for call-clobbered hard
  | 
      
      
         | 396 | 
          | 
          | 
            registers that are assigned to pseudos that cross calls.  This may
  | 
      
      
         | 397 | 
          | 
          | 
            overestimate slightly (especially if some of these registers are later
  | 
      
      
         | 398 | 
          | 
          | 
            used as spill registers), but it should not be significant.
  | 
      
      
         | 399 | 
          | 
          | 
          
  | 
      
      
         | 400 | 
          | 
          | 
            For IRA we use priority coloring to decrease stack slots needed for
  | 
      
      
         | 401 | 
          | 
          | 
            saving hard registers through calls.  We build conflicts for them
  | 
      
      
         | 402 | 
          | 
          | 
            to do coloring.
  | 
      
      
         | 403 | 
          | 
          | 
          
  | 
      
      
         | 404 | 
          | 
          | 
            Future work:
  | 
      
      
         | 405 | 
          | 
          | 
          
  | 
      
      
         | 406 | 
          | 
          | 
              In the fallback case we should iterate backwards across all possible
  | 
      
      
         | 407 | 
          | 
          | 
              modes for the save, choosing the largest available one instead of
  | 
      
      
         | 408 | 
          | 
          | 
              falling back to the smallest mode immediately.  (eg TF -> DF -> SF).
  | 
      
      
         | 409 | 
          | 
          | 
          
  | 
      
      
         | 410 | 
          | 
          | 
              We do not try to use "move multiple" instructions that exist
  | 
      
      
         | 411 | 
          | 
          | 
              on some machines (such as the 68k moveml).  It could be a win to try
  | 
      
      
         | 412 | 
          | 
          | 
              and use them when possible.  The hard part is doing it in a way that is
  | 
      
      
         | 413 | 
          | 
          | 
              machine independent since they might be saving non-consecutive
  | 
      
      
         | 414 | 
          | 
          | 
              registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */
  | 
      
      
         | 415 | 
          | 
          | 
          
  | 
      
      
         | 416 | 
          | 
          | 
         void
  | 
      
      
         | 417 | 
          | 
          | 
         setup_save_areas (void)
  | 
      
      
         | 418 | 
          | 
          | 
         {
  | 
      
      
         | 419 | 
          | 
          | 
           int i, j, k, freq;
  | 
      
      
         | 420 | 
          | 
          | 
           HARD_REG_SET hard_regs_used;
  | 
      
      
         | 421 | 
          | 
          | 
           struct saved_hard_reg *saved_reg;
  | 
      
      
         | 422 | 
          | 
          | 
           rtx insn;
  | 
      
      
         | 423 | 
          | 
          | 
           struct insn_chain *chain, *next;
  | 
      
      
         | 424 | 
          | 
          | 
           unsigned int regno;
  | 
      
      
         | 425 | 
          | 
          | 
           HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets;
  | 
      
      
         | 426 | 
          | 
          | 
           reg_set_iterator rsi;
  | 
      
      
         | 427 | 
          | 
          | 
          
  | 
      
      
         | 428 | 
          | 
          | 
           CLEAR_HARD_REG_SET (hard_regs_used);
  | 
      
      
         | 429 | 
          | 
          | 
          
  | 
      
      
         | 430 | 
          | 
          | 
           /* Find every CALL_INSN and record which hard regs are live across the
  | 
      
      
         | 431 | 
          | 
          | 
              call into HARD_REG_MAP and HARD_REGS_USED.  */
  | 
      
      
         | 432 | 
          | 
          | 
           initiate_saved_hard_regs ();
  | 
      
      
         | 433 | 
          | 
          | 
           /* Create hard reg saved regs.  */
  | 
      
      
         | 434 | 
          | 
          | 
           for (chain = reload_insn_chain; chain != 0; chain = next)
  | 
      
      
         | 435 | 
          | 
          | 
             {
  | 
      
      
         | 436 | 
          | 
          | 
               insn = chain->insn;
  | 
      
      
         | 437 | 
          | 
          | 
               next = chain->next;
  | 
      
      
         | 438 | 
          | 
          | 
               if (!CALL_P (insn)
  | 
      
      
         | 439 | 
          | 
          | 
                   || find_reg_note (insn, REG_NORETURN, NULL))
  | 
      
      
         | 440 | 
          | 
          | 
                 continue;
  | 
      
      
         | 441 | 
          | 
          | 
               freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn));
  | 
      
      
         | 442 | 
          | 
          | 
               REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
  | 
      
      
         | 443 | 
          | 
          | 
                                        &chain->live_throughout);
  | 
      
      
         | 444 | 
          | 
          | 
               COPY_HARD_REG_SET (used_regs, call_used_reg_set);
  | 
      
      
         | 445 | 
          | 
          | 
          
  | 
      
      
         | 446 | 
          | 
          | 
               /* Record all registers set in this call insn.  These don't
  | 
      
      
         | 447 | 
          | 
          | 
                  need to be saved.  N.B. the call insn might set a subreg
  | 
      
      
         | 448 | 
          | 
          | 
                  of a multi-hard-reg pseudo; then the pseudo is considered
  | 
      
      
         | 449 | 
          | 
          | 
                  live during the call, but the subreg that is set
  | 
      
      
         | 450 | 
          | 
          | 
                  isn't.  */
  | 
      
      
         | 451 | 
          | 
          | 
               CLEAR_HARD_REG_SET (this_insn_sets);
  | 
      
      
         | 452 | 
          | 
          | 
               note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets);
  | 
      
      
         | 453 | 
          | 
          | 
               /* Sibcalls are considered to set the return value.  */
  | 
      
      
         | 454 | 
          | 
          | 
               if (SIBLING_CALL_P (insn) && crtl->return_rtx)
  | 
      
      
         | 455 | 
          | 
          | 
                 mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets);
  | 
      
      
         | 456 | 
          | 
          | 
          
  | 
      
      
         | 457 | 
          | 
          | 
               AND_COMPL_HARD_REG_SET (used_regs, call_fixed_reg_set);
  | 
      
      
         | 458 | 
          | 
          | 
               AND_COMPL_HARD_REG_SET (used_regs, this_insn_sets);
  | 
      
      
         | 459 | 
          | 
          | 
               AND_HARD_REG_SET (hard_regs_to_save, used_regs);
  | 
      
      
         | 460 | 
          | 
          | 
               for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  | 
      
      
         | 461 | 
          | 
          | 
                 if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
  | 
      
      
         | 462 | 
          | 
          | 
                   {
  | 
      
      
         | 463 | 
          | 
          | 
                     if (hard_reg_map[regno] != NULL)
  | 
      
      
         | 464 | 
          | 
          | 
                       hard_reg_map[regno]->call_freq += freq;
  | 
      
      
         | 465 | 
          | 
          | 
                     else
  | 
      
      
         | 466 | 
          | 
          | 
                       new_saved_hard_reg (regno, freq);
  | 
      
      
         | 467 | 
          | 
          | 
                     SET_HARD_REG_BIT (hard_regs_used, regno);
  | 
      
      
         | 468 | 
          | 
          | 
                   }
  | 
      
      
         | 469 | 
          | 
          | 
               /* Look through all live pseudos, mark their hard registers.  */
  | 
      
      
         | 470 | 
          | 
          | 
               EXECUTE_IF_SET_IN_REG_SET
  | 
      
      
         | 471 | 
          | 
          | 
                 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
  | 
      
      
         | 472 | 
          | 
          | 
                 {
  | 
      
      
         | 473 | 
          | 
          | 
                   int r = reg_renumber[regno];
  | 
      
      
         | 474 | 
          | 
          | 
                   int bound;
  | 
      
      
         | 475 | 
          | 
          | 
          
  | 
      
      
         | 476 | 
          | 
          | 
                   if (r < 0)
  | 
      
      
         | 477 | 
          | 
          | 
                     continue;
  | 
      
      
         | 478 | 
          | 
          | 
          
  | 
      
      
         | 479 | 
          | 
          | 
                   bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
  | 
      
      
         | 480 | 
          | 
          | 
                   for (; r < bound; r++)
  | 
      
      
         | 481 | 
          | 
          | 
                     if (TEST_HARD_REG_BIT (used_regs, r))
  | 
      
      
         | 482 | 
          | 
          | 
                       {
  | 
      
      
         | 483 | 
          | 
          | 
                         if (hard_reg_map[r] != NULL)
  | 
      
      
         | 484 | 
          | 
          | 
                           hard_reg_map[r]->call_freq += freq;
  | 
      
      
         | 485 | 
          | 
          | 
                         else
  | 
      
      
         | 486 | 
          | 
          | 
                           new_saved_hard_reg (r, freq);
  | 
      
      
         | 487 | 
          | 
          | 
                          SET_HARD_REG_BIT (hard_regs_to_save, r);
  | 
      
      
         | 488 | 
          | 
          | 
                          SET_HARD_REG_BIT (hard_regs_used, r);
  | 
      
      
         | 489 | 
          | 
          | 
                       }
  | 
      
      
         | 490 | 
          | 
          | 
                 }
  | 
      
      
         | 491 | 
          | 
          | 
             }
  | 
      
      
         | 492 | 
          | 
          | 
          
  | 
      
      
         | 493 | 
          | 
          | 
           /* If requested, figure out which hard regs can share save slots.  */
  | 
      
      
         | 494 | 
          | 
          | 
           if (optimize && flag_ira_share_save_slots)
  | 
      
      
         | 495 | 
          | 
          | 
             {
  | 
      
      
         | 496 | 
          | 
          | 
               rtx slot;
  | 
      
      
         | 497 | 
          | 
          | 
               char *saved_reg_conflicts;
  | 
      
      
         | 498 | 
          | 
          | 
               int next_k;
  | 
      
      
         | 499 | 
          | 
          | 
               struct saved_hard_reg *saved_reg2, *saved_reg3;
  | 
      
      
         | 500 | 
          | 
          | 
               int call_saved_regs_num;
  | 
      
      
         | 501 | 
          | 
          | 
               struct saved_hard_reg *call_saved_regs[FIRST_PSEUDO_REGISTER];
  | 
      
      
         | 502 | 
          | 
          | 
               int best_slot_num;
  | 
      
      
         | 503 | 
          | 
          | 
               int prev_save_slots_num;
  | 
      
      
         | 504 | 
          | 
          | 
               rtx prev_save_slots[FIRST_PSEUDO_REGISTER];
  | 
      
      
         | 505 | 
          | 
          | 
          
  | 
      
      
         | 506 | 
          | 
          | 
               /* Find saved hard register conflicts.  */
  | 
      
      
         | 507 | 
          | 
          | 
               saved_reg_conflicts = (char *) xmalloc (saved_regs_num * saved_regs_num);
  | 
      
      
         | 508 | 
          | 
          | 
               memset (saved_reg_conflicts, 0, saved_regs_num * saved_regs_num);
  | 
      
      
         | 509 | 
          | 
          | 
               for (chain = reload_insn_chain; chain != 0; chain = next)
  | 
      
      
         | 510 | 
          | 
          | 
                 {
  | 
      
      
         | 511 | 
          | 
          | 
                   call_saved_regs_num = 0;
  | 
      
      
         | 512 | 
          | 
          | 
                   insn = chain->insn;
  | 
      
      
         | 513 | 
          | 
          | 
                   next = chain->next;
  | 
      
      
         | 514 | 
          | 
          | 
                   if (!CALL_P (insn)
  | 
      
      
         | 515 | 
          | 
          | 
                       || find_reg_note (insn, REG_NORETURN, NULL))
  | 
      
      
         | 516 | 
          | 
          | 
                     continue;
  | 
      
      
         | 517 | 
          | 
          | 
                   REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
  | 
      
      
         | 518 | 
          | 
          | 
                                            &chain->live_throughout);
  | 
      
      
         | 519 | 
          | 
          | 
                   COPY_HARD_REG_SET (used_regs, call_used_reg_set);
  | 
      
      
         | 520 | 
          | 
          | 
          
  | 
      
      
         | 521 | 
          | 
          | 
                   /* Record all registers set in this call insn.  These don't
  | 
      
      
         | 522 | 
          | 
          | 
                      need to be saved.  N.B. the call insn might set a subreg
  | 
      
      
         | 523 | 
          | 
          | 
                      of a multi-hard-reg pseudo; then the pseudo is considered
  | 
      
      
         | 524 | 
          | 
          | 
                      live during the call, but the subreg that is set
  | 
      
      
         | 525 | 
          | 
          | 
                      isn't.  */
  | 
      
      
         | 526 | 
          | 
          | 
                   CLEAR_HARD_REG_SET (this_insn_sets);
  | 
      
      
         | 527 | 
          | 
          | 
                   note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets);
  | 
      
      
         | 528 | 
          | 
          | 
                   /* Sibcalls are considered to set the return value,
  | 
      
      
         | 529 | 
          | 
          | 
                      compare df-scan.c:df_get_call_refs.  */
  | 
      
      
         | 530 | 
          | 
          | 
                   if (SIBLING_CALL_P (insn) && crtl->return_rtx)
  | 
      
      
         | 531 | 
          | 
          | 
                     mark_set_regs (crtl->return_rtx, NULL_RTX, &this_insn_sets);
  | 
      
      
         | 532 | 
          | 
          | 
          
  | 
      
      
         | 533 | 
          | 
          | 
                   AND_COMPL_HARD_REG_SET (used_regs, call_fixed_reg_set);
  | 
      
      
         | 534 | 
          | 
          | 
                   AND_COMPL_HARD_REG_SET (used_regs, this_insn_sets);
  | 
      
      
         | 535 | 
          | 
          | 
                   AND_HARD_REG_SET (hard_regs_to_save, used_regs);
  | 
      
      
         | 536 | 
          | 
          | 
                   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  | 
      
      
         | 537 | 
          | 
          | 
                     if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
  | 
      
      
         | 538 | 
          | 
          | 
                       {
  | 
      
      
         | 539 | 
          | 
          | 
                         gcc_assert (hard_reg_map[regno] != NULL);
  | 
      
      
         | 540 | 
          | 
          | 
                         call_saved_regs[call_saved_regs_num++] = hard_reg_map[regno];
  | 
      
      
         | 541 | 
          | 
          | 
                       }
  | 
      
      
         | 542 | 
          | 
          | 
                   /* Look through all live pseudos, mark their hard registers.  */
  | 
      
      
         | 543 | 
          | 
          | 
                   EXECUTE_IF_SET_IN_REG_SET
  | 
      
      
         | 544 | 
          | 
          | 
                     (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
  | 
      
      
         | 545 | 
          | 
          | 
                     {
  | 
      
      
         | 546 | 
          | 
          | 
                       int r = reg_renumber[regno];
  | 
      
      
         | 547 | 
          | 
          | 
                       int bound;
  | 
      
      
         | 548 | 
          | 
          | 
          
  | 
      
      
         | 549 | 
          | 
          | 
                       if (r < 0)
  | 
      
      
         | 550 | 
          | 
          | 
                         continue;
  | 
      
      
         | 551 | 
          | 
          | 
          
  | 
      
      
         | 552 | 
          | 
          | 
                       bound = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
  | 
      
      
         | 553 | 
          | 
          | 
                       for (; r < bound; r++)
  | 
      
      
         | 554 | 
          | 
          | 
                         if (TEST_HARD_REG_BIT (used_regs, r))
  | 
      
      
         | 555 | 
          | 
          | 
                           call_saved_regs[call_saved_regs_num++] = hard_reg_map[r];
  | 
      
      
         | 556 | 
          | 
          | 
                     }
  | 
      
      
         | 557 | 
          | 
          | 
                   for (i = 0; i < call_saved_regs_num; i++)
  | 
      
      
         | 558 | 
          | 
          | 
                     {
  | 
      
      
         | 559 | 
          | 
          | 
                       saved_reg = call_saved_regs[i];
  | 
      
      
         | 560 | 
          | 
          | 
                       for (j = 0; j < call_saved_regs_num; j++)
  | 
      
      
         | 561 | 
          | 
          | 
                         if (i != j)
  | 
      
      
         | 562 | 
          | 
          | 
                           {
  | 
      
      
         | 563 | 
          | 
          | 
                             saved_reg2 = call_saved_regs[j];
  | 
      
      
         | 564 | 
          | 
          | 
                             saved_reg_conflicts[saved_reg->num * saved_regs_num
  | 
      
      
         | 565 | 
          | 
          | 
                                                 + saved_reg2->num]
  | 
      
      
         | 566 | 
          | 
          | 
                               = saved_reg_conflicts[saved_reg2->num * saved_regs_num
  | 
      
      
         | 567 | 
          | 
          | 
                                                     + saved_reg->num]
  | 
      
      
         | 568 | 
          | 
          | 
                               = TRUE;
  | 
      
      
         | 569 | 
          | 
          | 
                           }
  | 
      
      
         | 570 | 
          | 
          | 
                     }
  | 
      
      
         | 571 | 
          | 
          | 
                 }
  | 
      
      
         | 572 | 
          | 
          | 
               /* Sort saved hard regs.  */
  | 
      
      
         | 573 | 
          | 
          | 
               qsort (all_saved_regs, saved_regs_num, sizeof (struct saved_hard_reg *),
  | 
      
      
         | 574 | 
          | 
          | 
                      saved_hard_reg_compare_func);
  | 
      
      
         | 575 | 
          | 
          | 
               /* Initiate slots available from the previous reload
  | 
      
      
         | 576 | 
          | 
          | 
                  iteration.  */
  | 
      
      
         | 577 | 
          | 
          | 
               prev_save_slots_num = save_slots_num;
  | 
      
      
         | 578 | 
          | 
          | 
               memcpy (prev_save_slots, save_slots, save_slots_num * sizeof (rtx));
  | 
      
      
         | 579 | 
          | 
          | 
               save_slots_num = 0;
  | 
      
      
         | 580 | 
          | 
          | 
               /* Allocate stack slots for the saved hard registers.  */
  | 
      
      
         | 581 | 
          | 
          | 
               for (i = 0; i < saved_regs_num; i++)
  | 
      
      
         | 582 | 
          | 
          | 
                 {
  | 
      
      
         | 583 | 
          | 
          | 
                   saved_reg = all_saved_regs[i];
  | 
      
      
         | 584 | 
          | 
          | 
                   regno = saved_reg->hard_regno;
  | 
      
      
         | 585 | 
          | 
          | 
                   for (j = 0; j < i; j++)
  | 
      
      
         | 586 | 
          | 
          | 
                     {
  | 
      
      
         | 587 | 
          | 
          | 
                       saved_reg2 = all_saved_regs[j];
  | 
      
      
         | 588 | 
          | 
          | 
                       if (! saved_reg2->first_p)
  | 
      
      
         | 589 | 
          | 
          | 
                         continue;
  | 
      
      
         | 590 | 
          | 
          | 
                       slot = saved_reg2->slot;
  | 
      
      
         | 591 | 
          | 
          | 
                       for (k = j; k >= 0; k = next_k)
  | 
      
      
         | 592 | 
          | 
          | 
                         {
  | 
      
      
         | 593 | 
          | 
          | 
                           saved_reg3 = all_saved_regs[k];
  | 
      
      
         | 594 | 
          | 
          | 
                           next_k = saved_reg3->next;
  | 
      
      
         | 595 | 
          | 
          | 
                           if (saved_reg_conflicts[saved_reg->num * saved_regs_num
  | 
      
      
         | 596 | 
          | 
          | 
                                                   + saved_reg3->num])
  | 
      
      
         | 597 | 
          | 
          | 
                             break;
  | 
      
      
         | 598 | 
          | 
          | 
                         }
  | 
      
      
         | 599 | 
          | 
          | 
                       if (k < 0
  | 
      
      
         | 600 | 
          | 
          | 
                           && (GET_MODE_SIZE (regno_save_mode[regno][1])
  | 
      
      
         | 601 | 
          | 
          | 
                               <= GET_MODE_SIZE (regno_save_mode
  | 
      
      
         | 602 | 
          | 
          | 
                                                 [saved_reg2->hard_regno][1])))
  | 
      
      
         | 603 | 
          | 
          | 
                         {
  | 
      
      
         | 604 | 
          | 
          | 
                           saved_reg->slot
  | 
      
      
         | 605 | 
          | 
          | 
                             = adjust_address_nv
  | 
      
      
         | 606 | 
          | 
          | 
                               (slot, regno_save_mode[saved_reg->hard_regno][1], 0);
  | 
      
      
         | 607 | 
          | 
          | 
                           regno_save_mem[regno][1] = saved_reg->slot;
  | 
      
      
         | 608 | 
          | 
          | 
                           saved_reg->next = saved_reg2->next;
  | 
      
      
         | 609 | 
          | 
          | 
                           saved_reg2->next = i;
  | 
      
      
         | 610 | 
          | 
          | 
                           if (dump_file != NULL)
  | 
      
      
         | 611 | 
          | 
          | 
                             fprintf (dump_file, "%d uses slot of %d\n",
  | 
      
      
         | 612 | 
          | 
          | 
                                      regno, saved_reg2->hard_regno);
  | 
      
      
         | 613 | 
          | 
          | 
                           break;
  | 
      
      
         | 614 | 
          | 
          | 
                         }
  | 
      
      
         | 615 | 
          | 
          | 
                     }
  | 
      
      
         | 616 | 
          | 
          | 
                   if (j == i)
  | 
      
      
         | 617 | 
          | 
          | 
                     {
  | 
      
      
         | 618 | 
          | 
          | 
                       saved_reg->first_p = TRUE;
  | 
      
      
         | 619 | 
          | 
          | 
                       for (best_slot_num = -1, j = 0; j < prev_save_slots_num; j++)
  | 
      
      
         | 620 | 
          | 
          | 
                         {
  | 
      
      
         | 621 | 
          | 
          | 
                           slot = prev_save_slots[j];
  | 
      
      
         | 622 | 
          | 
          | 
                           if (slot == NULL_RTX)
  | 
      
      
         | 623 | 
          | 
          | 
                             continue;
  | 
      
      
         | 624 | 
          | 
          | 
                           if (GET_MODE_SIZE (regno_save_mode[regno][1])
  | 
      
      
         | 625 | 
          | 
          | 
                               <= GET_MODE_SIZE (GET_MODE (slot))
  | 
      
      
         | 626 | 
          | 
          | 
                               && best_slot_num < 0)
  | 
      
      
         | 627 | 
          | 
          | 
                             best_slot_num = j;
  | 
      
      
         | 628 | 
          | 
          | 
                           if (GET_MODE (slot) == regno_save_mode[regno][1])
  | 
      
      
         | 629 | 
          | 
          | 
                             break;
  | 
      
      
         | 630 | 
          | 
          | 
                         }
  | 
      
      
         | 631 | 
          | 
          | 
                       if (best_slot_num >= 0)
  | 
      
      
         | 632 | 
          | 
          | 
                         {
  | 
      
      
         | 633 | 
          | 
          | 
                           saved_reg->slot = prev_save_slots[best_slot_num];
  | 
      
      
         | 634 | 
          | 
          | 
                           saved_reg->slot
  | 
      
      
         | 635 | 
          | 
          | 
                             = adjust_address_nv
  | 
      
      
         | 636 | 
          | 
          | 
                               (saved_reg->slot,
  | 
      
      
         | 637 | 
          | 
          | 
                                regno_save_mode[saved_reg->hard_regno][1], 0);
  | 
      
      
         | 638 | 
          | 
          | 
                           if (dump_file != NULL)
  | 
      
      
         | 639 | 
          | 
          | 
                             fprintf (dump_file,
  | 
      
      
         | 640 | 
          | 
          | 
                                      "%d uses a slot from prev iteration\n", regno);
  | 
      
      
         | 641 | 
          | 
          | 
                           prev_save_slots[best_slot_num] = NULL_RTX;
  | 
      
      
         | 642 | 
          | 
          | 
                           if (best_slot_num + 1 == prev_save_slots_num)
  | 
      
      
         | 643 | 
          | 
          | 
                             prev_save_slots_num--;
  | 
      
      
         | 644 | 
          | 
          | 
                         }
  | 
      
      
         | 645 | 
          | 
          | 
                       else
  | 
      
      
         | 646 | 
          | 
          | 
                         {
  | 
      
      
         | 647 | 
          | 
          | 
                           saved_reg->slot
  | 
      
      
         | 648 | 
          | 
          | 
                             = assign_stack_local_1
  | 
      
      
         | 649 | 
          | 
          | 
                               (regno_save_mode[regno][1],
  | 
      
      
         | 650 | 
          | 
          | 
                                GET_MODE_SIZE (regno_save_mode[regno][1]), 0,
  | 
      
      
         | 651 | 
          | 
          | 
                                ASLK_REDUCE_ALIGN);
  | 
      
      
         | 652 | 
          | 
          | 
                           if (dump_file != NULL)
  | 
      
      
         | 653 | 
          | 
          | 
                             fprintf (dump_file, "%d uses a new slot\n", regno);
  | 
      
      
         | 654 | 
          | 
          | 
                         }
  | 
      
      
         | 655 | 
          | 
          | 
                       regno_save_mem[regno][1] = saved_reg->slot;
  | 
      
      
         | 656 | 
          | 
          | 
                       save_slots[save_slots_num++] = saved_reg->slot;
  | 
      
      
         | 657 | 
          | 
          | 
                     }
  | 
      
      
         | 658 | 
          | 
          | 
                 }
  | 
      
      
         | 659 | 
          | 
          | 
               free (saved_reg_conflicts);
  | 
      
      
         | 660 | 
          | 
          | 
               finish_saved_hard_regs ();
  | 
      
      
         | 661 | 
          | 
          | 
             }
  | 
      
      
         | 662 | 
          | 
          | 
           else
  | 
      
      
         | 663 | 
          | 
          | 
             {
  | 
      
      
         | 664 | 
          | 
          | 
               /* We are not sharing slots.
  | 
      
      
         | 665 | 
          | 
          | 
          
  | 
      
      
         | 666 | 
          | 
          | 
                  Run through all the call-used hard-registers and allocate
  | 
      
      
         | 667 | 
          | 
          | 
                  space for each in the caller-save area.  Try to allocate space
  | 
      
      
         | 668 | 
          | 
          | 
                  in a manner which allows multi-register saves/restores to be done.  */
  | 
      
      
         | 669 | 
          | 
          | 
          
  | 
      
      
         | 670 | 
          | 
          | 
               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  | 
      
      
         | 671 | 
          | 
          | 
                 for (j = MOVE_MAX_WORDS; j > 0; j--)
  | 
      
      
         | 672 | 
          | 
          | 
                   {
  | 
      
      
         | 673 | 
          | 
          | 
                     int do_save = 1;
  | 
      
      
         | 674 | 
          | 
          | 
          
  | 
      
      
         | 675 | 
          | 
          | 
                     /* If no mode exists for this size, try another.  Also break out
  | 
      
      
         | 676 | 
          | 
          | 
                        if we have already saved this hard register.  */
  | 
      
      
         | 677 | 
          | 
          | 
                     if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0)
  | 
      
      
         | 678 | 
          | 
          | 
                       continue;
  | 
      
      
         | 679 | 
          | 
          | 
          
  | 
      
      
         | 680 | 
          | 
          | 
                     /* See if any register in this group has been saved.  */
  | 
      
      
         | 681 | 
          | 
          | 
                     for (k = 0; k < j; k++)
  | 
      
      
         | 682 | 
          | 
          | 
                       if (regno_save_mem[i + k][1])
  | 
      
      
         | 683 | 
          | 
          | 
                         {
  | 
      
      
         | 684 | 
          | 
          | 
                           do_save = 0;
  | 
      
      
         | 685 | 
          | 
          | 
                           break;
  | 
      
      
         | 686 | 
          | 
          | 
                         }
  | 
      
      
         | 687 | 
          | 
          | 
                     if (! do_save)
  | 
      
      
         | 688 | 
          | 
          | 
                       continue;
  | 
      
      
         | 689 | 
          | 
          | 
          
  | 
      
      
         | 690 | 
          | 
          | 
                     for (k = 0; k < j; k++)
  | 
      
      
         | 691 | 
          | 
          | 
                       if (! TEST_HARD_REG_BIT (hard_regs_used, i + k))
  | 
      
      
         | 692 | 
          | 
          | 
                         {
  | 
      
      
         | 693 | 
          | 
          | 
                           do_save = 0;
  | 
      
      
         | 694 | 
          | 
          | 
                           break;
  | 
      
      
         | 695 | 
          | 
          | 
                         }
  | 
      
      
         | 696 | 
          | 
          | 
                     if (! do_save)
  | 
      
      
         | 697 | 
          | 
          | 
                       continue;
  | 
      
      
         | 698 | 
          | 
          | 
          
  | 
      
      
         | 699 | 
          | 
          | 
                     /* We have found an acceptable mode to store in.  Since
  | 
      
      
         | 700 | 
          | 
          | 
                        hard register is always saved in the widest mode
  | 
      
      
         | 701 | 
          | 
          | 
                        available, the mode may be wider than necessary, it is
  | 
      
      
         | 702 | 
          | 
          | 
                        OK to reduce the alignment of spill space.  We will
  | 
      
      
         | 703 | 
          | 
          | 
                        verify that it is equal to or greater than required
  | 
      
      
         | 704 | 
          | 
          | 
                        when we restore and save the hard register in
  | 
      
      
         | 705 | 
          | 
          | 
                        insert_restore and insert_save.  */
  | 
      
      
         | 706 | 
          | 
          | 
                     regno_save_mem[i][j]
  | 
      
      
         | 707 | 
          | 
          | 
                       = assign_stack_local_1 (regno_save_mode[i][j],
  | 
      
      
         | 708 | 
          | 
          | 
                                               GET_MODE_SIZE (regno_save_mode[i][j]),
  | 
      
      
         | 709 | 
          | 
          | 
                                               0, ASLK_REDUCE_ALIGN);
  | 
      
      
         | 710 | 
          | 
          | 
          
  | 
      
      
         | 711 | 
          | 
          | 
                     /* Setup single word save area just in case...  */
  | 
      
      
         | 712 | 
          | 
          | 
                     for (k = 0; k < j; k++)
  | 
      
      
         | 713 | 
          | 
          | 
                       /* This should not depend on WORDS_BIG_ENDIAN.
  | 
      
      
         | 714 | 
          | 
          | 
                          The order of words in regs is the same as in memory.  */
  | 
      
      
         | 715 | 
          | 
          | 
                       regno_save_mem[i + k][1]
  | 
      
      
         | 716 | 
          | 
          | 
                         = adjust_address_nv (regno_save_mem[i][j],
  | 
      
      
         | 717 | 
          | 
          | 
                                              regno_save_mode[i + k][1],
  | 
      
      
         | 718 | 
          | 
          | 
                                              k * UNITS_PER_WORD);
  | 
      
      
         | 719 | 
          | 
          | 
                   }
  | 
      
      
         | 720 | 
          | 
          | 
             }
  | 
      
      
         | 721 | 
          | 
          | 
          
  | 
      
      
         | 722 | 
          | 
          | 
           /* Now loop again and set the alias set of any save areas we made to
  | 
      
      
         | 723 | 
          | 
          | 
              the alias set used to represent frame objects.  */
  | 
      
      
         | 724 | 
          | 
          | 
           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  | 
      
      
         | 725 | 
          | 
          | 
             for (j = MOVE_MAX_WORDS; j > 0; j--)
  | 
      
      
         | 726 | 
          | 
          | 
               if (regno_save_mem[i][j] != 0)
  | 
      
      
         | 727 | 
          | 
          | 
                 set_mem_alias_set (regno_save_mem[i][j], get_frame_alias_set ());
  | 
      
      
         | 728 | 
          | 
          | 
         }
  | 
      
      
         | 729 | 
          | 
          | 
          
  | 
      
      
         | 730 | 
          | 
          | 
          
  | 
      
      
         | 731 | 
          | 
          | 
          
  | 
      
      
         | 732 | 
          | 
          | 
         /* Find the places where hard regs are live across calls and save them.  */
  | 
      
      
         | 733 | 
          | 
          | 
          
  | 
      
      
         | 734 | 
          | 
          | 
         void
  | 
      
      
         | 735 | 
          | 
          | 
         save_call_clobbered_regs (void)
  | 
      
      
         | 736 | 
          | 
          | 
         {
  | 
      
      
         | 737 | 
          | 
          | 
           struct insn_chain *chain, *next, *last = NULL;
  | 
      
      
         | 738 | 
          | 
          | 
           enum machine_mode save_mode [FIRST_PSEUDO_REGISTER];
  | 
      
      
         | 739 | 
          | 
          | 
          
  | 
      
      
         | 740 | 
          | 
          | 
           /* Computed in mark_set_regs, holds all registers set by the current
  | 
      
      
         | 741 | 
          | 
          | 
              instruction.  */
  | 
      
      
         | 742 | 
          | 
          | 
           HARD_REG_SET this_insn_sets;
  | 
      
      
         | 743 | 
          | 
          | 
          
  | 
      
      
         | 744 | 
          | 
          | 
           CLEAR_HARD_REG_SET (hard_regs_saved);
  | 
      
      
         | 745 | 
          | 
          | 
           n_regs_saved = 0;
  | 
      
      
         | 746 | 
          | 
          | 
          
  | 
      
      
         | 747 | 
          | 
          | 
           for (chain = reload_insn_chain; chain != 0; chain = next)
  | 
      
      
         | 748 | 
          | 
          | 
             {
  | 
      
      
         | 749 | 
          | 
          | 
               rtx insn = chain->insn;
  | 
      
      
         | 750 | 
          | 
          | 
               enum rtx_code code = GET_CODE (insn);
  | 
      
      
         | 751 | 
          | 
          | 
          
  | 
      
      
         | 752 | 
          | 
          | 
               next = chain->next;
  | 
      
      
         | 753 | 
          | 
          | 
          
  | 
      
      
         | 754 | 
          | 
          | 
               gcc_assert (!chain->is_caller_save_insn);
  | 
      
      
         | 755 | 
          | 
          | 
          
  | 
      
      
         | 756 | 
          | 
          | 
               if (NONDEBUG_INSN_P (insn))
  | 
      
      
         | 757 | 
          | 
          | 
                 {
  | 
      
      
         | 758 | 
          | 
          | 
                   /* If some registers have been saved, see if INSN references
  | 
      
      
         | 759 | 
          | 
          | 
                      any of them.  We must restore them before the insn if so.  */
  | 
      
      
         | 760 | 
          | 
          | 
          
  | 
      
      
         | 761 | 
          | 
          | 
                   if (n_regs_saved)
  | 
      
      
         | 762 | 
          | 
          | 
                     {
  | 
      
      
         | 763 | 
          | 
          | 
                       int regno;
  | 
      
      
         | 764 | 
          | 
          | 
                       HARD_REG_SET this_insn_sets;
  | 
      
      
         | 765 | 
          | 
          | 
          
  | 
      
      
         | 766 | 
          | 
          | 
                       if (code == JUMP_INSN)
  | 
      
      
         | 767 | 
          | 
          | 
                         /* Restore all registers if this is a JUMP_INSN.  */
  | 
      
      
         | 768 | 
          | 
          | 
                         COPY_HARD_REG_SET (referenced_regs, hard_regs_saved);
  | 
      
      
         | 769 | 
          | 
          | 
                       else
  | 
      
      
         | 770 | 
          | 
          | 
                         {
  | 
      
      
         | 771 | 
          | 
          | 
                           CLEAR_HARD_REG_SET (referenced_regs);
  | 
      
      
         | 772 | 
          | 
          | 
                           mark_referenced_regs (&PATTERN (insn),
  | 
      
      
         | 773 | 
          | 
          | 
                                                 mark_reg_as_referenced, NULL);
  | 
      
      
         | 774 | 
          | 
          | 
                           AND_HARD_REG_SET (referenced_regs, hard_regs_saved);
  | 
      
      
         | 775 | 
          | 
          | 
                         }
  | 
      
      
         | 776 | 
          | 
          | 
          
  | 
      
      
         | 777 | 
          | 
          | 
                       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  | 
      
      
         | 778 | 
          | 
          | 
                         if (TEST_HARD_REG_BIT (referenced_regs, regno))
  | 
      
      
         | 779 | 
          | 
          | 
                           regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS,
  | 
      
      
         | 780 | 
          | 
          | 
                                                    save_mode);
  | 
      
      
         | 781 | 
          | 
          | 
                       /* If a saved register is set after the call, this means we no
  | 
      
      
         | 782 | 
          | 
          | 
                          longer should restore it.  This can happen when parts of a
  | 
      
      
         | 783 | 
          | 
          | 
                          multi-word pseudo do not conflict with other pseudos, so
  | 
      
      
         | 784 | 
          | 
          | 
                          IRA may allocate the same hard register for both.  One may
  | 
      
      
         | 785 | 
          | 
          | 
                          be live across the call, while the other is set
  | 
      
      
         | 786 | 
          | 
          | 
                          afterwards.  */
  | 
      
      
         | 787 | 
          | 
          | 
                       CLEAR_HARD_REG_SET (this_insn_sets);
  | 
      
      
         | 788 | 
          | 
          | 
                       note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets);
  | 
      
      
         | 789 | 
          | 
          | 
                       AND_COMPL_HARD_REG_SET (hard_regs_saved, this_insn_sets);
  | 
      
      
         | 790 | 
          | 
          | 
                     }
  | 
      
      
         | 791 | 
          | 
          | 
          
  | 
      
      
         | 792 | 
          | 
          | 
                   if (code == CALL_INSN
  | 
      
      
         | 793 | 
          | 
          | 
                       && ! SIBLING_CALL_P (insn)
  | 
      
      
         | 794 | 
          | 
          | 
                       && ! find_reg_note (insn, REG_NORETURN, NULL))
  | 
      
      
         | 795 | 
          | 
          | 
                     {
  | 
      
      
         | 796 | 
          | 
          | 
                       unsigned regno;
  | 
      
      
         | 797 | 
          | 
          | 
                       HARD_REG_SET hard_regs_to_save;
  | 
      
      
         | 798 | 
          | 
          | 
                       reg_set_iterator rsi;
  | 
      
      
         | 799 | 
          | 
          | 
          
  | 
      
      
         | 800 | 
          | 
          | 
                       /* Use the register life information in CHAIN to compute which
  | 
      
      
         | 801 | 
          | 
          | 
                          regs are live during the call.  */
  | 
      
      
         | 802 | 
          | 
          | 
                       REG_SET_TO_HARD_REG_SET (hard_regs_to_save,
  | 
      
      
         | 803 | 
          | 
          | 
                                                &chain->live_throughout);
  | 
      
      
         | 804 | 
          | 
          | 
                       /* Save hard registers always in the widest mode available.  */
  | 
      
      
         | 805 | 
          | 
          | 
                       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  | 
      
      
         | 806 | 
          | 
          | 
                         if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
  | 
      
      
         | 807 | 
          | 
          | 
                           save_mode [regno] = regno_save_mode [regno][1];
  | 
      
      
         | 808 | 
          | 
          | 
                         else
  | 
      
      
         | 809 | 
          | 
          | 
                           save_mode [regno] = VOIDmode;
  | 
      
      
         | 810 | 
          | 
          | 
          
  | 
      
      
         | 811 | 
          | 
          | 
                       /* Look through all live pseudos, mark their hard registers
  | 
      
      
         | 812 | 
          | 
          | 
                          and choose proper mode for saving.  */
  | 
      
      
         | 813 | 
          | 
          | 
                       EXECUTE_IF_SET_IN_REG_SET
  | 
      
      
         | 814 | 
          | 
          | 
                         (&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
  | 
      
      
         | 815 | 
          | 
          | 
                         {
  | 
      
      
         | 816 | 
          | 
          | 
                           int r = reg_renumber[regno];
  | 
      
      
         | 817 | 
          | 
          | 
                           int nregs;
  | 
      
      
         | 818 | 
          | 
          | 
                           enum machine_mode mode;
  | 
      
      
         | 819 | 
          | 
          | 
          
  | 
      
      
         | 820 | 
          | 
          | 
                           if (r < 0)
  | 
      
      
         | 821 | 
          | 
          | 
                             continue;
  | 
      
      
         | 822 | 
          | 
          | 
                           nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
  | 
      
      
         | 823 | 
          | 
          | 
                           mode = HARD_REGNO_CALLER_SAVE_MODE
  | 
      
      
         | 824 | 
          | 
          | 
                             (r, nregs, PSEUDO_REGNO_MODE (regno));
  | 
      
      
         | 825 | 
          | 
          | 
                           if (GET_MODE_BITSIZE (mode)
  | 
      
      
         | 826 | 
          | 
          | 
                               > GET_MODE_BITSIZE (save_mode[r]))
  | 
      
      
         | 827 | 
          | 
          | 
                             save_mode[r] = mode;
  | 
      
      
         | 828 | 
          | 
          | 
                           while (nregs-- > 0)
  | 
      
      
         | 829 | 
          | 
          | 
                             SET_HARD_REG_BIT (hard_regs_to_save, r + nregs);
  | 
      
      
         | 830 | 
          | 
          | 
                         }
  | 
      
      
         | 831 | 
          | 
          | 
          
  | 
      
      
         | 832 | 
          | 
          | 
                       /* Record all registers set in this call insn.  These don't need
  | 
      
      
         | 833 | 
          | 
          | 
                          to be saved.  N.B. the call insn might set a subreg of a
  | 
      
      
         | 834 | 
          | 
          | 
                          multi-hard-reg pseudo; then the pseudo is considered live
  | 
      
      
         | 835 | 
          | 
          | 
                          during the call, but the subreg that is set isn't.  */
  | 
      
      
         | 836 | 
          | 
          | 
                       CLEAR_HARD_REG_SET (this_insn_sets);
  | 
      
      
         | 837 | 
          | 
          | 
                       note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets);
  | 
      
      
         | 838 | 
          | 
          | 
          
  | 
      
      
         | 839 | 
          | 
          | 
                       /* Compute which hard regs must be saved before this call.  */
  | 
      
      
         | 840 | 
          | 
          | 
                       AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set);
  | 
      
      
         | 841 | 
          | 
          | 
                       AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets);
  | 
      
      
         | 842 | 
          | 
          | 
                       AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved);
  | 
      
      
         | 843 | 
          | 
          | 
                       AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set);
  | 
      
      
         | 844 | 
          | 
          | 
          
  | 
      
      
         | 845 | 
          | 
          | 
                       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  | 
      
      
         | 846 | 
          | 
          | 
                         if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
  | 
      
      
         | 847 | 
          | 
          | 
                           regno += insert_save (chain, 1, regno, &hard_regs_to_save, save_mode);
  | 
      
      
         | 848 | 
          | 
          | 
          
  | 
      
      
         | 849 | 
          | 
          | 
                       /* Must recompute n_regs_saved.  */
  | 
      
      
         | 850 | 
          | 
          | 
                       n_regs_saved = 0;
  | 
      
      
         | 851 | 
          | 
          | 
                       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  | 
      
      
         | 852 | 
          | 
          | 
                         if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
  | 
      
      
         | 853 | 
          | 
          | 
                           n_regs_saved++;
  | 
      
      
         | 854 | 
          | 
          | 
                     }
  | 
      
      
         | 855 | 
          | 
          | 
                   last = chain;
  | 
      
      
         | 856 | 
          | 
          | 
                 }
  | 
      
      
         | 857 | 
          | 
          | 
               else if (DEBUG_INSN_P (insn) && n_regs_saved)
  | 
      
      
         | 858 | 
          | 
          | 
                 mark_referenced_regs (&PATTERN (insn),
  | 
      
      
         | 859 | 
          | 
          | 
                                       replace_reg_with_saved_mem,
  | 
      
      
         | 860 | 
          | 
          | 
                                       save_mode);
  | 
      
      
         | 861 | 
          | 
          | 
          
  | 
      
      
         | 862 | 
          | 
          | 
               if (chain->next == 0 || chain->next->block != chain->block)
  | 
      
      
         | 863 | 
          | 
          | 
                 {
  | 
      
      
         | 864 | 
          | 
          | 
                   int regno;
  | 
      
      
         | 865 | 
          | 
          | 
                   /* At the end of the basic block, we must restore any registers that
  | 
      
      
         | 866 | 
          | 
          | 
                      remain saved.  If the last insn in the block is a JUMP_INSN, put
  | 
      
      
         | 867 | 
          | 
          | 
                      the restore before the insn, otherwise, put it after the insn.  */
  | 
      
      
         | 868 | 
          | 
          | 
          
  | 
      
      
         | 869 | 
          | 
          | 
                   if (n_regs_saved
  | 
      
      
         | 870 | 
          | 
          | 
                       && DEBUG_INSN_P (insn)
  | 
      
      
         | 871 | 
          | 
          | 
                       && last
  | 
      
      
         | 872 | 
          | 
          | 
                       && last->block == chain->block)
  | 
      
      
         | 873 | 
          | 
          | 
                     {
  | 
      
      
         | 874 | 
          | 
          | 
                       rtx ins, prev;
  | 
      
      
         | 875 | 
          | 
          | 
                       basic_block bb = BLOCK_FOR_INSN (insn);
  | 
      
      
         | 876 | 
          | 
          | 
          
  | 
      
      
         | 877 | 
          | 
          | 
                       /* When adding hard reg restores after a DEBUG_INSN, move
  | 
      
      
         | 878 | 
          | 
          | 
                          all notes between last real insn and this DEBUG_INSN after
  | 
      
      
         | 879 | 
          | 
          | 
                          the DEBUG_INSN, otherwise we could get code
  | 
      
      
         | 880 | 
          | 
          | 
                          -g/-g0 differences.  */
  | 
      
      
         | 881 | 
          | 
          | 
                       for (ins = PREV_INSN (insn); ins != last->insn; ins = prev)
  | 
      
      
         | 882 | 
          | 
          | 
                         {
  | 
      
      
         | 883 | 
          | 
          | 
                           prev = PREV_INSN (ins);
  | 
      
      
         | 884 | 
          | 
          | 
                           if (NOTE_P (ins))
  | 
      
      
         | 885 | 
          | 
          | 
                             {
  | 
      
      
         | 886 | 
          | 
          | 
                               NEXT_INSN (prev) = NEXT_INSN (ins);
  | 
      
      
         | 887 | 
          | 
          | 
                               PREV_INSN (NEXT_INSN (ins)) = prev;
  | 
      
      
         | 888 | 
          | 
          | 
                               PREV_INSN (ins) = insn;
  | 
      
      
         | 889 | 
          | 
          | 
                               NEXT_INSN (ins) = NEXT_INSN (insn);
  | 
      
      
         | 890 | 
          | 
          | 
                               NEXT_INSN (insn) = ins;
  | 
      
      
         | 891 | 
          | 
          | 
                               if (NEXT_INSN (ins))
  | 
      
      
         | 892 | 
          | 
          | 
                                 PREV_INSN (NEXT_INSN (ins)) = ins;
  | 
      
      
         | 893 | 
          | 
          | 
                               if (BB_END (bb) == insn)
  | 
      
      
         | 894 | 
          | 
          | 
                                 BB_END (bb) = ins;
  | 
      
      
         | 895 | 
          | 
          | 
                             }
  | 
      
      
         | 896 | 
          | 
          | 
                           else
  | 
      
      
         | 897 | 
          | 
          | 
                             gcc_assert (DEBUG_INSN_P (ins));
  | 
      
      
         | 898 | 
          | 
          | 
                         }
  | 
      
      
         | 899 | 
          | 
          | 
                     }
  | 
      
      
         | 900 | 
          | 
          | 
                   last = NULL;
  | 
      
      
         | 901 | 
          | 
          | 
          
  | 
      
      
         | 902 | 
          | 
          | 
                   if (n_regs_saved)
  | 
      
      
         | 903 | 
          | 
          | 
                     for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  | 
      
      
         | 904 | 
          | 
          | 
                       if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
  | 
      
      
         | 905 | 
          | 
          | 
                         regno += insert_restore (chain, JUMP_P (insn),
  | 
      
      
         | 906 | 
          | 
          | 
                                                  regno, MOVE_MAX_WORDS, save_mode);
  | 
      
      
         | 907 | 
          | 
          | 
                 }
  | 
      
      
         | 908 | 
          | 
          | 
             }
  | 
      
      
         | 909 | 
          | 
          | 
         }
  | 
      
      
         | 910 | 
          | 
          | 
          
  | 
      
      
         | 911 | 
          | 
          | 
         /* Here from note_stores, or directly from save_call_clobbered_regs, when
  | 
      
      
         | 912 | 
          | 
          | 
            an insn stores a value in a register.
  | 
      
      
         | 913 | 
          | 
          | 
            Set the proper bit or bits in this_insn_sets.  All pseudos that have
  | 
      
      
         | 914 | 
          | 
          | 
            been assigned hard regs have had their register number changed already,
  | 
      
      
         | 915 | 
          | 
          | 
            so we can ignore pseudos.  */
  | 
      
      
         | 916 | 
          | 
          | 
         static void
  | 
      
      
         | 917 | 
          | 
          | 
         mark_set_regs (rtx reg, const_rtx setter ATTRIBUTE_UNUSED, void *data)
  | 
      
      
         | 918 | 
          | 
          | 
         {
  | 
      
      
         | 919 | 
          | 
          | 
           int regno, endregno, i;
  | 
      
      
         | 920 | 
          | 
          | 
           HARD_REG_SET *this_insn_sets = (HARD_REG_SET *) data;
  | 
      
      
         | 921 | 
          | 
          | 
          
  | 
      
      
         | 922 | 
          | 
          | 
           if (GET_CODE (reg) == SUBREG)
  | 
      
      
         | 923 | 
          | 
          | 
             {
  | 
      
      
         | 924 | 
          | 
          | 
               rtx inner = SUBREG_REG (reg);
  | 
      
      
         | 925 | 
          | 
          | 
               if (!REG_P (inner) || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
  | 
      
      
         | 926 | 
          | 
          | 
                 return;
  | 
      
      
         | 927 | 
          | 
          | 
               regno = subreg_regno (reg);
  | 
      
      
         | 928 | 
          | 
          | 
               endregno = regno + subreg_nregs (reg);
  | 
      
      
         | 929 | 
          | 
          | 
             }
  | 
      
      
         | 930 | 
          | 
          | 
           else if (REG_P (reg)
  | 
      
      
         | 931 | 
          | 
          | 
                    && REGNO (reg) < FIRST_PSEUDO_REGISTER)
  | 
      
      
         | 932 | 
          | 
          | 
             {
  | 
      
      
         | 933 | 
          | 
          | 
               regno = REGNO (reg);
  | 
      
      
         | 934 | 
          | 
          | 
               endregno = END_HARD_REGNO (reg);
  | 
      
      
         | 935 | 
          | 
          | 
             }
  | 
      
      
         | 936 | 
          | 
          | 
           else
  | 
      
      
         | 937 | 
          | 
          | 
             return;
  | 
      
      
         | 938 | 
          | 
          | 
          
  | 
      
      
         | 939 | 
          | 
          | 
           for (i = regno; i < endregno; i++)
  | 
      
      
         | 940 | 
          | 
          | 
             SET_HARD_REG_BIT (*this_insn_sets, i);
  | 
      
      
         | 941 | 
          | 
          | 
         }
  | 
      
      
         | 942 | 
          | 
          | 
          
  | 
      
      
         | 943 | 
          | 
          | 
         /* Here from note_stores when an insn stores a value in a register.
  | 
      
      
         | 944 | 
          | 
          | 
            Set the proper bit or bits in the passed regset.  All pseudos that have
  | 
      
      
         | 945 | 
          | 
          | 
            been assigned hard regs have had their register number changed already,
  | 
      
      
         | 946 | 
          | 
          | 
            so we can ignore pseudos.  */
  | 
      
      
         | 947 | 
          | 
          | 
         static void
  | 
      
      
         | 948 | 
          | 
          | 
         add_stored_regs (rtx reg, const_rtx setter, void *data)
  | 
      
      
         | 949 | 
          | 
          | 
         {
  | 
      
      
         | 950 | 
          | 
          | 
           int regno, endregno, i;
  | 
      
      
         | 951 | 
          | 
          | 
           enum machine_mode mode = GET_MODE (reg);
  | 
      
      
         | 952 | 
          | 
          | 
           int offset = 0;
  | 
      
      
         | 953 | 
          | 
          | 
          
  | 
      
      
         | 954 | 
          | 
          | 
           if (GET_CODE (setter) == CLOBBER)
  | 
      
      
         | 955 | 
          | 
          | 
             return;
  | 
      
      
         | 956 | 
          | 
          | 
          
  | 
      
      
         | 957 | 
          | 
          | 
           if (GET_CODE (reg) == SUBREG
  | 
      
      
         | 958 | 
          | 
          | 
               && REG_P (SUBREG_REG (reg))
  | 
      
      
         | 959 | 
          | 
          | 
               && REGNO (SUBREG_REG (reg)) < FIRST_PSEUDO_REGISTER)
  | 
      
      
         | 960 | 
          | 
          | 
             {
  | 
      
      
         | 961 | 
          | 
          | 
               offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)),
  | 
      
      
         | 962 | 
          | 
          | 
                                             GET_MODE (SUBREG_REG (reg)),
  | 
      
      
         | 963 | 
          | 
          | 
                                             SUBREG_BYTE (reg),
  | 
      
      
         | 964 | 
          | 
          | 
                                             GET_MODE (reg));
  | 
      
      
         | 965 | 
          | 
          | 
               regno = REGNO (SUBREG_REG (reg)) + offset;
  | 
      
      
         | 966 | 
          | 
          | 
               endregno = regno + subreg_nregs (reg);
  | 
      
      
         | 967 | 
          | 
          | 
             }
  | 
      
      
         | 968 | 
          | 
          | 
           else
  | 
      
      
         | 969 | 
          | 
          | 
             {
  | 
      
      
         | 970 | 
          | 
          | 
               if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
  | 
      
      
         | 971 | 
          | 
          | 
                 return;
  | 
      
      
         | 972 | 
          | 
          | 
          
  | 
      
      
         | 973 | 
          | 
          | 
               regno = REGNO (reg) + offset;
  | 
      
      
         | 974 | 
          | 
          | 
               endregno = end_hard_regno (mode, regno);
  | 
      
      
         | 975 | 
          | 
          | 
             }
  | 
      
      
         | 976 | 
          | 
          | 
          
  | 
      
      
         | 977 | 
          | 
          | 
           for (i = regno; i < endregno; i++)
  | 
      
      
         | 978 | 
          | 
          | 
             SET_REGNO_REG_SET ((regset) data, i);
  | 
      
      
         | 979 | 
          | 
          | 
         }
  | 
      
      
         | 980 | 
          | 
          | 
          
  | 
      
      
         | 981 | 
          | 
          | 
         /* Walk X and record all referenced registers in REFERENCED_REGS.  */
  | 
      
      
         | 982 | 
          | 
          | 
         static void
  | 
      
      
         | 983 | 
          | 
          | 
         mark_referenced_regs (rtx *loc, refmarker_fn *mark, void *arg)
  | 
      
      
         | 984 | 
          | 
          | 
         {
  | 
      
      
         | 985 | 
          | 
          | 
           enum rtx_code code = GET_CODE (*loc);
  | 
      
      
         | 986 | 
          | 
          | 
           const char *fmt;
  | 
      
      
         | 987 | 
          | 
          | 
           int i, j;
  | 
      
      
         | 988 | 
          | 
          | 
          
  | 
      
      
         | 989 | 
          | 
          | 
           if (code == SET)
  | 
      
      
         | 990 | 
          | 
          | 
             mark_referenced_regs (&SET_SRC (*loc), mark, arg);
  | 
      
      
         | 991 | 
          | 
          | 
           if (code == SET || code == CLOBBER)
  | 
      
      
         | 992 | 
          | 
          | 
             {
  | 
      
      
         | 993 | 
          | 
          | 
               loc = &SET_DEST (*loc);
  | 
      
      
         | 994 | 
          | 
          | 
               code = GET_CODE (*loc);
  | 
      
      
         | 995 | 
          | 
          | 
               if ((code == REG && REGNO (*loc) < FIRST_PSEUDO_REGISTER)
  | 
      
      
         | 996 | 
          | 
          | 
                   || code == PC || code == CC0
  | 
      
      
         | 997 | 
          | 
          | 
                   || (code == SUBREG && REG_P (SUBREG_REG (*loc))
  | 
      
      
         | 998 | 
          | 
          | 
                       && REGNO (SUBREG_REG (*loc)) < FIRST_PSEUDO_REGISTER
  | 
      
      
         | 999 | 
          | 
          | 
                       /* If we're setting only part of a multi-word register,
  | 
      
      
         | 1000 | 
          | 
          | 
                          we shall mark it as referenced, because the words
  | 
      
      
         | 1001 | 
          | 
          | 
                          that are not being set should be restored.  */
  | 
      
      
         | 1002 | 
          | 
          | 
                       && ((GET_MODE_SIZE (GET_MODE (*loc))
  | 
      
      
         | 1003 | 
          | 
          | 
                            >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc))))
  | 
      
      
         | 1004 | 
          | 
          | 
                           || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc)))
  | 
      
      
         | 1005 | 
          | 
          | 
                               <= UNITS_PER_WORD))))
  | 
      
      
         | 1006 | 
          | 
          | 
                 return;
  | 
      
      
         | 1007 | 
          | 
          | 
             }
  | 
      
      
         | 1008 | 
          | 
          | 
           if (code == MEM || code == SUBREG)
  | 
      
      
         | 1009 | 
          | 
          | 
             {
  | 
      
      
         | 1010 | 
          | 
          | 
               loc = &XEXP (*loc, 0);
  | 
      
      
         | 1011 | 
          | 
          | 
               code = GET_CODE (*loc);
  | 
      
      
         | 1012 | 
          | 
          | 
             }
  | 
      
      
         | 1013 | 
          | 
          | 
          
  | 
      
      
         | 1014 | 
          | 
          | 
           if (code == REG)
  | 
      
      
         | 1015 | 
          | 
          | 
             {
  | 
      
      
         | 1016 | 
          | 
          | 
               int regno = REGNO (*loc);
  | 
      
      
         | 1017 | 
          | 
          | 
               int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
  | 
      
      
         | 1018 | 
          | 
          | 
                                : reg_renumber[regno]);
  | 
      
      
         | 1019 | 
          | 
          | 
          
  | 
      
      
         | 1020 | 
          | 
          | 
               if (hardregno >= 0)
  | 
      
      
         | 1021 | 
          | 
          | 
                 mark (loc, GET_MODE (*loc), hardregno, arg);
  | 
      
      
         | 1022 | 
          | 
          | 
               else if (arg)
  | 
      
      
         | 1023 | 
          | 
          | 
                 /* ??? Will we ever end up with an equiv expression in a debug
  | 
      
      
         | 1024 | 
          | 
          | 
                    insn, that would have required restoring a reg, or will
  | 
      
      
         | 1025 | 
          | 
          | 
                    reload take care of it for us?  */
  | 
      
      
         | 1026 | 
          | 
          | 
                 return;
  | 
      
      
         | 1027 | 
          | 
          | 
               /* If this is a pseudo that did not get a hard register, scan its
  | 
      
      
         | 1028 | 
          | 
          | 
                  memory location, since it might involve the use of another
  | 
      
      
         | 1029 | 
          | 
          | 
                  register, which might be saved.  */
  | 
      
      
         | 1030 | 
          | 
          | 
               else if (reg_equiv_mem (regno) != 0)
  | 
      
      
         | 1031 | 
          | 
          | 
                 mark_referenced_regs (&XEXP (reg_equiv_mem (regno), 0), mark, arg);
  | 
      
      
         | 1032 | 
          | 
          | 
               else if (reg_equiv_address (regno) != 0)
  | 
      
      
         | 1033 | 
          | 
          | 
                 mark_referenced_regs (®_equiv_address (regno), mark, arg);
  | 
      
      
         | 1034 | 
          | 
          | 
               return;
  | 
      
      
         | 1035 | 
          | 
          | 
             }
  | 
      
      
         | 1036 | 
          | 
          | 
          
  | 
      
      
         | 1037 | 
          | 
          | 
           fmt = GET_RTX_FORMAT (code);
  | 
      
      
         | 1038 | 
          | 
          | 
           for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  | 
      
      
         | 1039 | 
          | 
          | 
             {
  | 
      
      
         | 1040 | 
          | 
          | 
               if (fmt[i] == 'e')
  | 
      
      
         | 1041 | 
          | 
          | 
                 mark_referenced_regs (&XEXP (*loc, i), mark, arg);
  | 
      
      
         | 1042 | 
          | 
          | 
               else if (fmt[i] == 'E')
  | 
      
      
         | 1043 | 
          | 
          | 
                 for (j = XVECLEN (*loc, i) - 1; j >= 0; j--)
  | 
      
      
         | 1044 | 
          | 
          | 
                   mark_referenced_regs (&XVECEXP (*loc, i, j), mark, arg);
  | 
      
      
         | 1045 | 
          | 
          | 
             }
  | 
      
      
         | 1046 | 
          | 
          | 
         }
  | 
      
      
         | 1047 | 
          | 
          | 
          
  | 
      
      
         | 1048 | 
          | 
          | 
         /* Parameter function for mark_referenced_regs() that adds registers
  | 
      
      
         | 1049 | 
          | 
          | 
            present in the insn and in equivalent mems and addresses to
  | 
      
      
         | 1050 | 
          | 
          | 
            referenced_regs.  */
  | 
      
      
         | 1051 | 
          | 
          | 
          
  | 
      
      
         | 1052 | 
          | 
          | 
         static void
  | 
      
      
         | 1053 | 
          | 
          | 
         mark_reg_as_referenced (rtx *loc ATTRIBUTE_UNUSED,
  | 
      
      
         | 1054 | 
          | 
          | 
                                 enum machine_mode mode,
  | 
      
      
         | 1055 | 
          | 
          | 
                                 int hardregno,
  | 
      
      
         | 1056 | 
          | 
          | 
                                 void *arg ATTRIBUTE_UNUSED)
  | 
      
      
         | 1057 | 
          | 
          | 
         {
  | 
      
      
         | 1058 | 
          | 
          | 
           add_to_hard_reg_set (&referenced_regs, mode, hardregno);
  | 
      
      
         | 1059 | 
          | 
          | 
         }
  | 
      
      
         | 1060 | 
          | 
          | 
          
  | 
      
      
         | 1061 | 
          | 
          | 
         /* Parameter function for mark_referenced_regs() that replaces
  | 
      
      
         | 1062 | 
          | 
          | 
            registers referenced in a debug_insn that would have been restored,
  | 
      
      
         | 1063 | 
          | 
          | 
            should it be a non-debug_insn, with their save locations.  */
  | 
      
      
         | 1064 | 
          | 
          | 
          
  | 
      
      
         | 1065 | 
          | 
          | 
         static void
  | 
      
      
         | 1066 | 
          | 
          | 
         replace_reg_with_saved_mem (rtx *loc,
  | 
      
      
         | 1067 | 
          | 
          | 
                                     enum machine_mode mode,
  | 
      
      
         | 1068 | 
          | 
          | 
                                     int regno,
  | 
      
      
         | 1069 | 
          | 
          | 
                                     void *arg)
  | 
      
      
         | 1070 | 
          | 
          | 
         {
  | 
      
      
         | 1071 | 
          | 
          | 
           unsigned int i, nregs = hard_regno_nregs [regno][mode];
  | 
      
      
         | 1072 | 
          | 
          | 
           rtx mem;
  | 
      
      
         | 1073 | 
          | 
          | 
           enum machine_mode *save_mode = (enum machine_mode *)arg;
  | 
      
      
         | 1074 | 
          | 
          | 
          
  | 
      
      
         | 1075 | 
          | 
          | 
           for (i = 0; i < nregs; i++)
  | 
      
      
         | 1076 | 
          | 
          | 
             if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
  | 
      
      
         | 1077 | 
          | 
          | 
               break;
  | 
      
      
         | 1078 | 
          | 
          | 
          
  | 
      
      
         | 1079 | 
          | 
          | 
           /* If none of the registers in the range would need restoring, we're
  | 
      
      
         | 1080 | 
          | 
          | 
              all set.  */
  | 
      
      
         | 1081 | 
          | 
          | 
           if (i == nregs)
  | 
      
      
         | 1082 | 
          | 
          | 
             return;
  | 
      
      
         | 1083 | 
          | 
          | 
          
  | 
      
      
         | 1084 | 
          | 
          | 
           while (++i < nregs)
  | 
      
      
         | 1085 | 
          | 
          | 
             if (!TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
  | 
      
      
         | 1086 | 
          | 
          | 
               break;
  | 
      
      
         | 1087 | 
          | 
          | 
          
  | 
      
      
         | 1088 | 
          | 
          | 
           if (i == nregs
  | 
      
      
         | 1089 | 
          | 
          | 
               && regno_save_mem[regno][nregs])
  | 
      
      
         | 1090 | 
          | 
          | 
             {
  | 
      
      
         | 1091 | 
          | 
          | 
               mem = copy_rtx (regno_save_mem[regno][nregs]);
  | 
      
      
         | 1092 | 
          | 
          | 
          
  | 
      
      
         | 1093 | 
          | 
          | 
               if (nregs == (unsigned int) hard_regno_nregs[regno][save_mode[regno]])
  | 
      
      
         | 1094 | 
          | 
          | 
                 mem = adjust_address_nv (mem, save_mode[regno], 0);
  | 
      
      
         | 1095 | 
          | 
          | 
          
  | 
      
      
         | 1096 | 
          | 
          | 
               if (GET_MODE (mem) != mode)
  | 
      
      
         | 1097 | 
          | 
          | 
                 {
  | 
      
      
         | 1098 | 
          | 
          | 
                   /* This is gen_lowpart_if_possible(), but without validating
  | 
      
      
         | 1099 | 
          | 
          | 
                      the newly-formed address.  */
  | 
      
      
         | 1100 | 
          | 
          | 
                   int offset = 0;
  | 
      
      
         | 1101 | 
          | 
          | 
          
  | 
      
      
         | 1102 | 
          | 
          | 
                   if (WORDS_BIG_ENDIAN)
  | 
      
      
         | 1103 | 
          | 
          | 
                     offset = (MAX (GET_MODE_SIZE (GET_MODE (mem)), UNITS_PER_WORD)
  | 
      
      
         | 1104 | 
          | 
          | 
                               - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
  | 
      
      
         | 1105 | 
          | 
          | 
                   if (BYTES_BIG_ENDIAN)
  | 
      
      
         | 1106 | 
          | 
          | 
                     /* Adjust the address so that the address-after-the-data is
  | 
      
      
         | 1107 | 
          | 
          | 
                        unchanged.  */
  | 
      
      
         | 1108 | 
          | 
          | 
                     offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
  | 
      
      
         | 1109 | 
          | 
          | 
                                - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (mem))));
  | 
      
      
         | 1110 | 
          | 
          | 
          
  | 
      
      
         | 1111 | 
          | 
          | 
                   mem = adjust_address_nv (mem, mode, offset);
  | 
      
      
         | 1112 | 
          | 
          | 
                 }
  | 
      
      
         | 1113 | 
          | 
          | 
             }
  | 
      
      
         | 1114 | 
          | 
          | 
           else
  | 
      
      
         | 1115 | 
          | 
          | 
             {
  | 
      
      
         | 1116 | 
          | 
          | 
               mem = gen_rtx_CONCATN (mode, rtvec_alloc (nregs));
  | 
      
      
         | 1117 | 
          | 
          | 
               for (i = 0; i < nregs; i++)
  | 
      
      
         | 1118 | 
          | 
          | 
                 if (TEST_HARD_REG_BIT (hard_regs_saved, regno + i))
  | 
      
      
         | 1119 | 
          | 
          | 
                   {
  | 
      
      
         | 1120 | 
          | 
          | 
                     gcc_assert (regno_save_mem[regno + i][1]);
  | 
      
      
         | 1121 | 
          | 
          | 
                     XVECEXP (mem, 0, i) = copy_rtx (regno_save_mem[regno + i][1]);
  | 
      
      
         | 1122 | 
          | 
          | 
                   }
  | 
      
      
         | 1123 | 
          | 
          | 
                 else
  | 
      
      
         | 1124 | 
          | 
          | 
                   {
  | 
      
      
         | 1125 | 
          | 
          | 
                     gcc_assert (save_mode[regno] != VOIDmode);
  | 
      
      
         | 1126 | 
          | 
          | 
                     XVECEXP (mem, 0, i) = gen_rtx_REG (save_mode [regno],
  | 
      
      
         | 1127 | 
          | 
          | 
                                                        regno + i);
  | 
      
      
         | 1128 | 
          | 
          | 
                   }
  | 
      
      
         | 1129 | 
          | 
          | 
             }
  | 
      
      
         | 1130 | 
          | 
          | 
          
  | 
      
      
         | 1131 | 
          | 
          | 
           gcc_assert (GET_MODE (mem) == mode);
  | 
      
      
         | 1132 | 
          | 
          | 
           *loc = mem;
  | 
      
      
         | 1133 | 
          | 
          | 
         }
  | 
      
      
         | 1134 | 
          | 
          | 
          
  | 
      
      
         | 1135 | 
          | 
          | 
          
  | 
      
      
         | 1136 | 
          | 
          | 
         /* Insert a sequence of insns to restore.  Place these insns in front of
  | 
      
      
         | 1137 | 
          | 
          | 
            CHAIN if BEFORE_P is nonzero, behind the insn otherwise.  MAXRESTORE is
  | 
      
      
         | 1138 | 
          | 
          | 
            the maximum number of registers which should be restored during this call.
  | 
      
      
         | 1139 | 
          | 
          | 
            It should never be less than 1 since we only work with entire registers.
  | 
      
      
         | 1140 | 
          | 
          | 
          
  | 
      
      
         | 1141 | 
          | 
          | 
            Note that we have verified in init_caller_save that we can do this
  | 
      
      
         | 1142 | 
          | 
          | 
            with a simple SET, so use it.  Set INSN_CODE to what we save there
  | 
      
      
         | 1143 | 
          | 
          | 
            since the address might not be valid so the insn might not be recognized.
  | 
      
      
         | 1144 | 
          | 
          | 
            These insns will be reloaded and have register elimination done by
  | 
      
      
         | 1145 | 
          | 
          | 
            find_reload, so we need not worry about that here.
  | 
      
      
         | 1146 | 
          | 
          | 
          
  | 
      
      
         | 1147 | 
          | 
          | 
            Return the extra number of registers saved.  */
  | 
      
      
         | 1148 | 
          | 
          | 
          
  | 
      
      
         | 1149 | 
          | 
          | 
         static int
  | 
      
      
         | 1150 | 
          | 
          | 
         insert_restore (struct insn_chain *chain, int before_p, int regno,
  | 
      
      
         | 1151 | 
          | 
          | 
                         int maxrestore, enum machine_mode *save_mode)
  | 
      
      
         | 1152 | 
          | 
          | 
         {
  | 
      
      
         | 1153 | 
          | 
          | 
           int i, k;
  | 
      
      
         | 1154 | 
          | 
          | 
           rtx pat = NULL_RTX;
  | 
      
      
         | 1155 | 
          | 
          | 
           int code;
  | 
      
      
         | 1156 | 
          | 
          | 
           unsigned int numregs = 0;
  | 
      
      
         | 1157 | 
          | 
          | 
           struct insn_chain *new_chain;
  | 
      
      
         | 1158 | 
          | 
          | 
           rtx mem;
  | 
      
      
         | 1159 | 
          | 
          | 
          
  | 
      
      
         | 1160 | 
          | 
          | 
           /* A common failure mode if register status is not correct in the
  | 
      
      
         | 1161 | 
          | 
          | 
              RTL is for this routine to be called with a REGNO we didn't
  | 
      
      
         | 1162 | 
          | 
          | 
              expect to save.  That will cause us to write an insn with a (nil)
  | 
      
      
         | 1163 | 
          | 
          | 
              SET_DEST or SET_SRC.  Instead of doing so and causing a crash
  | 
      
      
         | 1164 | 
          | 
          | 
              later, check for this common case here instead.  This will remove
  | 
      
      
         | 1165 | 
          | 
          | 
              one step in debugging such problems.  */
  | 
      
      
         | 1166 | 
          | 
          | 
           gcc_assert (regno_save_mem[regno][1]);
  | 
      
      
         | 1167 | 
          | 
          | 
          
  | 
      
      
         | 1168 | 
          | 
          | 
           /* Get the pattern to emit and update our status.
  | 
      
      
         | 1169 | 
          | 
          | 
          
  | 
      
      
         | 1170 | 
          | 
          | 
              See if we can restore `maxrestore' registers at once.  Work
  | 
      
      
         | 1171 | 
          | 
          | 
              backwards to the single register case.  */
  | 
      
      
         | 1172 | 
          | 
          | 
           for (i = maxrestore; i > 0; i--)
  | 
      
      
         | 1173 | 
          | 
          | 
             {
  | 
      
      
         | 1174 | 
          | 
          | 
               int j;
  | 
      
      
         | 1175 | 
          | 
          | 
               int ok = 1;
  | 
      
      
         | 1176 | 
          | 
          | 
          
  | 
      
      
         | 1177 | 
          | 
          | 
               if (regno_save_mem[regno][i] == 0)
  | 
      
      
         | 1178 | 
          | 
          | 
                 continue;
  | 
      
      
         | 1179 | 
          | 
          | 
          
  | 
      
      
         | 1180 | 
          | 
          | 
               for (j = 0; j < i; j++)
  | 
      
      
         | 1181 | 
          | 
          | 
                 if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
  | 
      
      
         | 1182 | 
          | 
          | 
                   {
  | 
      
      
         | 1183 | 
          | 
          | 
                     ok = 0;
  | 
      
      
         | 1184 | 
          | 
          | 
                     break;
  | 
      
      
         | 1185 | 
          | 
          | 
                   }
  | 
      
      
         | 1186 | 
          | 
          | 
               /* Must do this one restore at a time.  */
  | 
      
      
         | 1187 | 
          | 
          | 
               if (! ok)
  | 
      
      
         | 1188 | 
          | 
          | 
                 continue;
  | 
      
      
         | 1189 | 
          | 
          | 
          
  | 
      
      
         | 1190 | 
          | 
          | 
               numregs = i;
  | 
      
      
         | 1191 | 
          | 
          | 
               break;
  | 
      
      
         | 1192 | 
          | 
          | 
             }
  | 
      
      
         | 1193 | 
          | 
          | 
          
  | 
      
      
         | 1194 | 
          | 
          | 
           mem = regno_save_mem [regno][numregs];
  | 
      
      
         | 1195 | 
          | 
          | 
           if (save_mode [regno] != VOIDmode
  | 
      
      
         | 1196 | 
          | 
          | 
               && save_mode [regno] != GET_MODE (mem)
  | 
      
      
         | 1197 | 
          | 
          | 
               && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]]
  | 
      
      
         | 1198 | 
          | 
          | 
               /* Check that insn to restore REGNO in save_mode[regno] is
  | 
      
      
         | 1199 | 
          | 
          | 
                  correct.  */
  | 
      
      
         | 1200 | 
          | 
          | 
               && reg_save_code (regno, save_mode[regno]) >= 0)
  | 
      
      
         | 1201 | 
          | 
          | 
             mem = adjust_address_nv (mem, save_mode[regno], 0);
  | 
      
      
         | 1202 | 
          | 
          | 
           else
  | 
      
      
         | 1203 | 
          | 
          | 
             mem = copy_rtx (mem);
  | 
      
      
         | 1204 | 
          | 
          | 
          
  | 
      
      
         | 1205 | 
          | 
          | 
           /* Verify that the alignment of spill space is equal to or greater
  | 
      
      
         | 1206 | 
          | 
          | 
              than required.  */
  | 
      
      
         | 1207 | 
          | 
          | 
           gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT,
  | 
      
      
         | 1208 | 
          | 
          | 
                            GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem));
  | 
      
      
         | 1209 | 
          | 
          | 
          
  | 
      
      
         | 1210 | 
          | 
          | 
           pat = gen_rtx_SET (VOIDmode,
  | 
      
      
         | 1211 | 
          | 
          | 
                              gen_rtx_REG (GET_MODE (mem),
  | 
      
      
         | 1212 | 
          | 
          | 
                                           regno), mem);
  | 
      
      
         | 1213 | 
          | 
          | 
           code = reg_restore_code (regno, GET_MODE (mem));
  | 
      
      
         | 1214 | 
          | 
          | 
           new_chain = insert_one_insn (chain, before_p, code, pat);
  | 
      
      
         | 1215 | 
          | 
          | 
          
  | 
      
      
         | 1216 | 
          | 
          | 
           /* Clear status for all registers we restored.  */
  | 
      
      
         | 1217 | 
          | 
          | 
           for (k = 0; k < i; k++)
  | 
      
      
         | 1218 | 
          | 
          | 
             {
  | 
      
      
         | 1219 | 
          | 
          | 
               CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k);
  | 
      
      
         | 1220 | 
          | 
          | 
               SET_REGNO_REG_SET (&new_chain->dead_or_set, regno + k);
  | 
      
      
         | 1221 | 
          | 
          | 
               n_regs_saved--;
  | 
      
      
         | 1222 | 
          | 
          | 
             }
  | 
      
      
         | 1223 | 
          | 
          | 
          
  | 
      
      
         | 1224 | 
          | 
          | 
           /* Tell our callers how many extra registers we saved/restored.  */
  | 
      
      
         | 1225 | 
          | 
          | 
           return numregs - 1;
  | 
      
      
         | 1226 | 
          | 
          | 
         }
  | 
      
      
         | 1227 | 
          | 
          | 
          
  | 
      
      
         | 1228 | 
          | 
          | 
         /* Like insert_restore above, but save registers instead.  */
  | 
      
      
         | 1229 | 
          | 
          | 
          
  | 
      
      
         | 1230 | 
          | 
          | 
         static int
  | 
      
      
         | 1231 | 
          | 
          | 
         insert_save (struct insn_chain *chain, int before_p, int regno,
  | 
      
      
         | 1232 | 
          | 
          | 
                      HARD_REG_SET (*to_save), enum machine_mode *save_mode)
  | 
      
      
         | 1233 | 
          | 
          | 
         {
  | 
      
      
         | 1234 | 
          | 
          | 
           int i;
  | 
      
      
         | 1235 | 
          | 
          | 
           unsigned int k;
  | 
      
      
         | 1236 | 
          | 
          | 
           rtx pat = NULL_RTX;
  | 
      
      
         | 1237 | 
          | 
          | 
           int code;
  | 
      
      
         | 1238 | 
          | 
          | 
           unsigned int numregs = 0;
  | 
      
      
         | 1239 | 
          | 
          | 
           struct insn_chain *new_chain;
  | 
      
      
         | 1240 | 
          | 
          | 
           rtx mem;
  | 
      
      
         | 1241 | 
          | 
          | 
          
  | 
      
      
         | 1242 | 
          | 
          | 
           /* A common failure mode if register status is not correct in the
  | 
      
      
         | 1243 | 
          | 
          | 
              RTL is for this routine to be called with a REGNO we didn't
  | 
      
      
         | 1244 | 
          | 
          | 
              expect to save.  That will cause us to write an insn with a (nil)
  | 
      
      
         | 1245 | 
          | 
          | 
              SET_DEST or SET_SRC.  Instead of doing so and causing a crash
  | 
      
      
         | 1246 | 
          | 
          | 
              later, check for this common case here.  This will remove one
  | 
      
      
         | 1247 | 
          | 
          | 
              step in debugging such problems.  */
  | 
      
      
         | 1248 | 
          | 
          | 
           gcc_assert (regno_save_mem[regno][1]);
  | 
      
      
         | 1249 | 
          | 
          | 
          
  | 
      
      
         | 1250 | 
          | 
          | 
           /* Get the pattern to emit and update our status.
  | 
      
      
         | 1251 | 
          | 
          | 
          
  | 
      
      
         | 1252 | 
          | 
          | 
              See if we can save several registers with a single instruction.
  | 
      
      
         | 1253 | 
          | 
          | 
              Work backwards to the single register case.  */
  | 
      
      
         | 1254 | 
          | 
          | 
           for (i = MOVE_MAX_WORDS; i > 0; i--)
  | 
      
      
         | 1255 | 
          | 
          | 
             {
  | 
      
      
         | 1256 | 
          | 
          | 
               int j;
  | 
      
      
         | 1257 | 
          | 
          | 
               int ok = 1;
  | 
      
      
         | 1258 | 
          | 
          | 
               if (regno_save_mem[regno][i] == 0)
  | 
      
      
         | 1259 | 
          | 
          | 
                 continue;
  | 
      
      
         | 1260 | 
          | 
          | 
          
  | 
      
      
         | 1261 | 
          | 
          | 
               for (j = 0; j < i; j++)
  | 
      
      
         | 1262 | 
          | 
          | 
                 if (! TEST_HARD_REG_BIT (*to_save, regno + j))
  | 
      
      
         | 1263 | 
          | 
          | 
                   {
  | 
      
      
         | 1264 | 
          | 
          | 
                     ok = 0;
  | 
      
      
         | 1265 | 
          | 
          | 
                     break;
  | 
      
      
         | 1266 | 
          | 
          | 
                   }
  | 
      
      
         | 1267 | 
          | 
          | 
               /* Must do this one save at a time.  */
  | 
      
      
         | 1268 | 
          | 
          | 
               if (! ok)
  | 
      
      
         | 1269 | 
          | 
          | 
                 continue;
  | 
      
      
         | 1270 | 
          | 
          | 
          
  | 
      
      
         | 1271 | 
          | 
          | 
               numregs = i;
  | 
      
      
         | 1272 | 
          | 
          | 
               break;
  | 
      
      
         | 1273 | 
          | 
          | 
             }
  | 
      
      
         | 1274 | 
          | 
          | 
          
  | 
      
      
         | 1275 | 
          | 
          | 
           mem = regno_save_mem [regno][numregs];
  | 
      
      
         | 1276 | 
          | 
          | 
           if (save_mode [regno] != VOIDmode
  | 
      
      
         | 1277 | 
          | 
          | 
               && save_mode [regno] != GET_MODE (mem)
  | 
      
      
         | 1278 | 
          | 
          | 
               && numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]]
  | 
      
      
         | 1279 | 
          | 
          | 
               /* Check that insn to save REGNO in save_mode[regno] is
  | 
      
      
         | 1280 | 
          | 
          | 
                  correct.  */
  | 
      
      
         | 1281 | 
          | 
          | 
               && reg_save_code (regno, save_mode[regno]) >= 0)
  | 
      
      
         | 1282 | 
          | 
          | 
             mem = adjust_address_nv (mem, save_mode[regno], 0);
  | 
      
      
         | 1283 | 
          | 
          | 
           else
  | 
      
      
         | 1284 | 
          | 
          | 
             mem = copy_rtx (mem);
  | 
      
      
         | 1285 | 
          | 
          | 
          
  | 
      
      
         | 1286 | 
          | 
          | 
           /* Verify that the alignment of spill space is equal to or greater
  | 
      
      
         | 1287 | 
          | 
          | 
              than required.  */
  | 
      
      
         | 1288 | 
          | 
          | 
           gcc_assert (MIN (MAX_SUPPORTED_STACK_ALIGNMENT,
  | 
      
      
         | 1289 | 
          | 
          | 
                            GET_MODE_ALIGNMENT (GET_MODE (mem))) <= MEM_ALIGN (mem));
  | 
      
      
         | 1290 | 
          | 
          | 
          
  | 
      
      
         | 1291 | 
          | 
          | 
           pat = gen_rtx_SET (VOIDmode, mem,
  | 
      
      
         | 1292 | 
          | 
          | 
                              gen_rtx_REG (GET_MODE (mem),
  | 
      
      
         | 1293 | 
          | 
          | 
                                           regno));
  | 
      
      
         | 1294 | 
          | 
          | 
           code = reg_save_code (regno, GET_MODE (mem));
  | 
      
      
         | 1295 | 
          | 
          | 
           new_chain = insert_one_insn (chain, before_p, code, pat);
  | 
      
      
         | 1296 | 
          | 
          | 
          
  | 
      
      
         | 1297 | 
          | 
          | 
           /* Set hard_regs_saved and dead_or_set for all the registers we saved.  */
  | 
      
      
         | 1298 | 
          | 
          | 
           for (k = 0; k < numregs; k++)
  | 
      
      
         | 1299 | 
          | 
          | 
             {
  | 
      
      
         | 1300 | 
          | 
          | 
               SET_HARD_REG_BIT (hard_regs_saved, regno + k);
  | 
      
      
         | 1301 | 
          | 
          | 
               SET_REGNO_REG_SET (&new_chain->dead_or_set, regno + k);
  | 
      
      
         | 1302 | 
          | 
          | 
               n_regs_saved++;
  | 
      
      
         | 1303 | 
          | 
          | 
             }
  | 
      
      
         | 1304 | 
          | 
          | 
          
  | 
      
      
         | 1305 | 
          | 
          | 
           /* Tell our callers how many extra registers we saved/restored.  */
  | 
      
      
         | 1306 | 
          | 
          | 
           return numregs - 1;
  | 
      
      
         | 1307 | 
          | 
          | 
         }
  | 
      
      
         | 1308 | 
          | 
          | 
          
  | 
      
      
         | 1309 | 
          | 
          | 
         /* A for_each_rtx callback used by add_used_regs.  Add the hard-register
  | 
      
      
         | 1310 | 
          | 
          | 
            equivalent of each REG to regset DATA.  */
  | 
      
      
         | 1311 | 
          | 
          | 
          
  | 
      
      
         | 1312 | 
          | 
          | 
         static int
  | 
      
      
         | 1313 | 
          | 
          | 
         add_used_regs_1 (rtx *loc, void *data)
  | 
      
      
         | 1314 | 
          | 
          | 
         {
  | 
      
      
         | 1315 | 
          | 
          | 
           unsigned int regno;
  | 
      
      
         | 1316 | 
          | 
          | 
           regset live;
  | 
      
      
         | 1317 | 
          | 
          | 
           rtx x;
  | 
      
      
         | 1318 | 
          | 
          | 
          
  | 
      
      
         | 1319 | 
          | 
          | 
           x = *loc;
  | 
      
      
         | 1320 | 
          | 
          | 
           live = (regset) data;
  | 
      
      
         | 1321 | 
          | 
          | 
           if (REG_P (x))
  | 
      
      
         | 1322 | 
          | 
          | 
             {
  | 
      
      
         | 1323 | 
          | 
          | 
               regno = REGNO (x);
  | 
      
      
         | 1324 | 
          | 
          | 
               if (HARD_REGISTER_NUM_P (regno))
  | 
      
      
         | 1325 | 
          | 
          | 
                 bitmap_set_range (live, regno, hard_regno_nregs[regno][GET_MODE (x)]);
  | 
      
      
         | 1326 | 
          | 
          | 
               else
  | 
      
      
         | 1327 | 
          | 
          | 
                 regno = reg_renumber[regno];
  | 
      
      
         | 1328 | 
          | 
          | 
             }
  | 
      
      
         | 1329 | 
          | 
          | 
           return 0;
  | 
      
      
         | 1330 | 
          | 
          | 
         }
  | 
      
      
         | 1331 | 
          | 
          | 
          
  | 
      
      
         | 1332 | 
          | 
          | 
         /* A note_uses callback used by insert_one_insn.  Add the hard-register
  | 
      
      
         | 1333 | 
          | 
          | 
            equivalent of each REG to regset DATA.  */
  | 
      
      
         | 1334 | 
          | 
          | 
          
  | 
      
      
         | 1335 | 
          | 
          | 
         static void
  | 
      
      
         | 1336 | 
          | 
          | 
         add_used_regs (rtx *loc, void *data)
  | 
      
      
         | 1337 | 
          | 
          | 
         {
  | 
      
      
         | 1338 | 
          | 
          | 
           for_each_rtx (loc, add_used_regs_1, data);
  | 
      
      
         | 1339 | 
          | 
          | 
         }
  | 
      
      
         | 1340 | 
          | 
          | 
          
  | 
      
      
         | 1341 | 
          | 
          | 
         /* Emit a new caller-save insn and set the code.  */
  | 
      
      
         | 1342 | 
          | 
          | 
         static struct insn_chain *
  | 
      
      
         | 1343 | 
          | 
          | 
         insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
  | 
      
      
         | 1344 | 
          | 
          | 
         {
  | 
      
      
         | 1345 | 
          | 
          | 
           rtx insn = chain->insn;
  | 
      
      
         | 1346 | 
          | 
          | 
           struct insn_chain *new_chain;
  | 
      
      
         | 1347 | 
          | 
          | 
          
  | 
      
      
         | 1348 | 
          | 
          | 
         #ifdef HAVE_cc0
  | 
      
      
         | 1349 | 
          | 
          | 
           /* If INSN references CC0, put our insns in front of the insn that sets
  | 
      
      
         | 1350 | 
          | 
          | 
              CC0.  This is always safe, since the only way we could be passed an
  | 
      
      
         | 1351 | 
          | 
          | 
              insn that references CC0 is for a restore, and doing a restore earlier
  | 
      
      
         | 1352 | 
          | 
          | 
              isn't a problem.  We do, however, assume here that CALL_INSNs don't
  | 
      
      
         | 1353 | 
          | 
          | 
              reference CC0.  Guard against non-INSN's like CODE_LABEL.  */
  | 
      
      
         | 1354 | 
          | 
          | 
          
  | 
      
      
         | 1355 | 
          | 
          | 
           if ((NONJUMP_INSN_P (insn) || JUMP_P (insn))
  | 
      
      
         | 1356 | 
          | 
          | 
               && before_p
  | 
      
      
         | 1357 | 
          | 
          | 
               && reg_referenced_p (cc0_rtx, PATTERN (insn)))
  | 
      
      
         | 1358 | 
          | 
          | 
             chain = chain->prev, insn = chain->insn;
  | 
      
      
         | 1359 | 
          | 
          | 
         #endif
  | 
      
      
         | 1360 | 
          | 
          | 
          
  | 
      
      
         | 1361 | 
          | 
          | 
           new_chain = new_insn_chain ();
  | 
      
      
         | 1362 | 
          | 
          | 
           if (before_p)
  | 
      
      
         | 1363 | 
          | 
          | 
             {
  | 
      
      
         | 1364 | 
          | 
          | 
               rtx link;
  | 
      
      
         | 1365 | 
          | 
          | 
          
  | 
      
      
         | 1366 | 
          | 
          | 
               new_chain->prev = chain->prev;
  | 
      
      
         | 1367 | 
          | 
          | 
               if (new_chain->prev != 0)
  | 
      
      
         | 1368 | 
          | 
          | 
                 new_chain->prev->next = new_chain;
  | 
      
      
         | 1369 | 
          | 
          | 
               else
  | 
      
      
         | 1370 | 
          | 
          | 
                 reload_insn_chain = new_chain;
  | 
      
      
         | 1371 | 
          | 
          | 
          
  | 
      
      
         | 1372 | 
          | 
          | 
               chain->prev = new_chain;
  | 
      
      
         | 1373 | 
          | 
          | 
               new_chain->next = chain;
  | 
      
      
         | 1374 | 
          | 
          | 
               new_chain->insn = emit_insn_before (pat, insn);
  | 
      
      
         | 1375 | 
          | 
          | 
               /* ??? It would be nice if we could exclude the already / still saved
  | 
      
      
         | 1376 | 
          | 
          | 
                  registers from the live sets.  */
  | 
      
      
         | 1377 | 
          | 
          | 
               COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
  | 
      
      
         | 1378 | 
          | 
          | 
               note_uses (&PATTERN (chain->insn), add_used_regs,
  | 
      
      
         | 1379 | 
          | 
          | 
                          &new_chain->live_throughout);
  | 
      
      
         | 1380 | 
          | 
          | 
               /* If CHAIN->INSN is a call, then the registers which contain
  | 
      
      
         | 1381 | 
          | 
          | 
                  the arguments to the function are live in the new insn.  */
  | 
      
      
         | 1382 | 
          | 
          | 
               if (CALL_P (chain->insn))
  | 
      
      
         | 1383 | 
          | 
          | 
                 for (link = CALL_INSN_FUNCTION_USAGE (chain->insn);
  | 
      
      
         | 1384 | 
          | 
          | 
                      link != NULL_RTX;
  | 
      
      
         | 1385 | 
          | 
          | 
                      link = XEXP (link, 1))
  | 
      
      
         | 1386 | 
          | 
          | 
                   note_uses (&XEXP (link, 0), add_used_regs,
  | 
      
      
         | 1387 | 
          | 
          | 
                              &new_chain->live_throughout);
  | 
      
      
         | 1388 | 
          | 
          | 
          
  | 
      
      
         | 1389 | 
          | 
          | 
               CLEAR_REG_SET (&new_chain->dead_or_set);
  | 
      
      
         | 1390 | 
          | 
          | 
               if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
  | 
      
      
         | 1391 | 
          | 
          | 
                 BB_HEAD (BASIC_BLOCK (chain->block)) = new_chain->insn;
  | 
      
      
         | 1392 | 
          | 
          | 
             }
  | 
      
      
         | 1393 | 
          | 
          | 
           else
  | 
      
      
         | 1394 | 
          | 
          | 
             {
  | 
      
      
         | 1395 | 
          | 
          | 
               new_chain->next = chain->next;
  | 
      
      
         | 1396 | 
          | 
          | 
               if (new_chain->next != 0)
  | 
      
      
         | 1397 | 
          | 
          | 
                 new_chain->next->prev = new_chain;
  | 
      
      
         | 1398 | 
          | 
          | 
               chain->next = new_chain;
  | 
      
      
         | 1399 | 
          | 
          | 
               new_chain->prev = chain;
  | 
      
      
         | 1400 | 
          | 
          | 
               new_chain->insn = emit_insn_after (pat, insn);
  | 
      
      
         | 1401 | 
          | 
          | 
               /* ??? It would be nice if we could exclude the already / still saved
  | 
      
      
         | 1402 | 
          | 
          | 
                  registers from the live sets, and observe REG_UNUSED notes.  */
  | 
      
      
         | 1403 | 
          | 
          | 
               COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
  | 
      
      
         | 1404 | 
          | 
          | 
               /* Registers that are set in CHAIN->INSN live in the new insn.
  | 
      
      
         | 1405 | 
          | 
          | 
                  (Unless there is a REG_UNUSED note for them, but we don't
  | 
      
      
         | 1406 | 
          | 
          | 
                   look for them here.) */
  | 
      
      
         | 1407 | 
          | 
          | 
               note_stores (PATTERN (chain->insn), add_stored_regs,
  | 
      
      
         | 1408 | 
          | 
          | 
                            &new_chain->live_throughout);
  | 
      
      
         | 1409 | 
          | 
          | 
               CLEAR_REG_SET (&new_chain->dead_or_set);
  | 
      
      
         | 1410 | 
          | 
          | 
               if (chain->insn == BB_END (BASIC_BLOCK (chain->block)))
  | 
      
      
         | 1411 | 
          | 
          | 
                 BB_END (BASIC_BLOCK (chain->block)) = new_chain->insn;
  | 
      
      
         | 1412 | 
          | 
          | 
             }
  | 
      
      
         | 1413 | 
          | 
          | 
           new_chain->block = chain->block;
  | 
      
      
         | 1414 | 
          | 
          | 
           new_chain->is_caller_save_insn = 1;
  | 
      
      
         | 1415 | 
          | 
          | 
          
  | 
      
      
         | 1416 | 
          | 
          | 
           INSN_CODE (new_chain->insn) = code;
  | 
      
      
         | 1417 | 
          | 
          | 
           return new_chain;
  | 
      
      
         | 1418 | 
          | 
          | 
         }
  | 
      
      
         | 1419 | 
          | 
          | 
         #include "gt-caller-save.h"
  |