Annotation of gcc/caller-save.c, revision 1.1.1.3

1.1       root        1: /* Save and restore call-clobbered registers which are live across a call.
                      2:    Copyright (C) 1989, 1992 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: #include "config.h"
                     21: #include "rtl.h"
                     22: #include "insn-config.h"
                     23: #include "flags.h"
                     24: #include "regs.h"
                     25: #include "hard-reg-set.h"
                     26: #include "recog.h"
                     27: #include "basic-block.h"
                     28: #include "reload.h"
                     29: #include "expr.h"
                     30: 
1.1.1.3 ! root       31: #define CEIL(x,y) (((x) + (y) - 1) / (y))
1.1       root       32: 
1.1.1.3 ! root       33: /* Modes for each hard register that we can save.  The smallest mode is wide
        !            34:    enough to save the entire contents of the register.  When saving the
        !            35:    register because it is live we first try to save in multi-register modes.
        !            36:    If that is not possible the save is done one register at a time.  */
        !            37: 
        !            38: static enum machine_mode 
        !            39:   regno_save_mode[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1];
1.1       root       40: 
                     41: /* For each hard register, a place on the stack where it can be saved,
                     42:    if needed.  */
                     43: 
1.1.1.3 ! root       44: static rtx 
        !            45:   regno_save_mem[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1];
1.1       root       46: 
                     47: /* We will only make a register eligible for caller-save if it can be
                     48:    saved in its widest mode with a simple SET insn as long as the memory
                     49:    address is valid.  We record the INSN_CODE is those insns here since
                     50:    when we emit them, the addresses might not be valid, so they might not
                     51:    be recognized.  */
                     52: 
1.1.1.3 ! root       53: static enum insn_code 
        !            54:   reg_save_code[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1];
        !            55: static enum insn_code 
        !            56:   reg_restore_code[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1];
1.1       root       57: 
                     58: /* Set of hard regs currently live (during scan of all insns).  */
                     59: 
                     60: static HARD_REG_SET hard_regs_live;
                     61: 
                     62: /* Set of hard regs currently residing in save area (during insn scan).  */
                     63: 
                     64: static HARD_REG_SET hard_regs_saved;
                     65: 
1.1.1.3 ! root       66: /* Set of hard regs which need to be restored before referenced.  */
        !            67: 
        !            68: static HARD_REG_SET hard_regs_need_restore;
        !            69: 
1.1       root       70: /* Number of registers currently in hard_regs_saved.  */
                     71: 
                     72: int n_regs_saved;
                     73: 
                     74: static void set_reg_live ();
                     75: static void clear_reg_live ();
                     76: static void restore_referenced_regs ();
1.1.1.3 ! root       77: static int insert_save_restore ();
1.1       root       78: 
                     79: /* Return a machine mode that is legitimate for hard reg REGNO and large
1.1.1.3 ! root       80:    enough to save nregs.  If we can't find one, return VOIDmode.  */
1.1       root       81: 
                     82: static enum machine_mode
1.1.1.3 ! root       83: choose_hard_reg_mode (regno, nregs)
1.1       root       84:      int regno;
                     85: {
                     86:   enum machine_mode found_mode = VOIDmode, mode;
                     87: 
                     88:   /* We first look for the largest integer mode that can be validly
                     89:      held in REGNO.  If none, we look for the largest floating-point mode.
                     90:      If we still didn't find a valid mode, try CCmode.  */
                     91: 
                     92:   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
                     93:        mode = GET_MODE_WIDER_MODE (mode))
1.1.1.3 ! root       94:     if (HARD_REGNO_NREGS (regno, mode) == nregs
1.1       root       95:        && HARD_REGNO_MODE_OK (regno, mode))
                     96:       found_mode = mode;
                     97: 
                     98:   if (found_mode != VOIDmode)
                     99:     return found_mode;
                    100: 
                    101:   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
                    102:        mode = GET_MODE_WIDER_MODE (mode))
1.1.1.3 ! root      103:     if (HARD_REGNO_NREGS (regno, mode) == nregs
1.1       root      104:        && HARD_REGNO_MODE_OK (regno, mode))
                    105:       found_mode = mode;
                    106: 
                    107:   if (found_mode != VOIDmode)
                    108:     return found_mode;
                    109: 
1.1.1.3 ! root      110:   if (HARD_REGNO_NREGS (regno, CCmode) == nregs
1.1       root      111:       && HARD_REGNO_MODE_OK (regno, CCmode))
                    112:     return CCmode;
                    113: 
                    114:   /* We can't find a mode valid for this register.  */
                    115:   return VOIDmode;
                    116: }
                    117: 
                    118: /* Initialize for caller-save.
                    119: 
                    120:    Look at all the hard registers that are used by a call and for which
                    121:    regclass.c has not already excluded from being used across a call.
                    122: 
                    123:    Ensure that we can find a mode to save the register and that there is a 
                    124:    simple insn to save and restore the register.  This latter check avoids
                    125:    problems that would occur if we tried to save the MQ register of some
                    126:    machines directly into memory.  */
                    127: 
                    128: void
                    129: init_caller_save ()
                    130: {
                    131:   char *first_obj = (char *) oballoc (0);
                    132:   rtx addr_reg;
                    133:   int offset;
                    134:   rtx address;
1.1.1.3 ! root      135:   int i, j;
1.1       root      136: 
                    137:   /* First find all the registers that we need to deal with and all
                    138:      the modes that they can have.  If we can't find a mode to use,
                    139:      we can't have the register live over calls.  */
                    140: 
                    141:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
                    142:     {
                    143:       if (call_used_regs[i] && ! call_fixed_regs[i])
                    144:        {
1.1.1.3 ! root      145:          for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
1.1       root      146:            {
1.1.1.3 ! root      147:              regno_save_mode[i][j] = choose_hard_reg_mode (i, j);
        !           148:              if (regno_save_mode[i][j] == VOIDmode && j == 1)
        !           149:                {
        !           150:                  call_fixed_regs[i] = 1;
        !           151:                  SET_HARD_REG_BIT (call_fixed_reg_set, i);
        !           152:                }
1.1       root      153:            }
                    154:        }
                    155:       else
1.1.1.3 ! root      156:        regno_save_mode[i][1] = VOIDmode;
1.1       root      157:     }
                    158: 
                    159:   /* The following code tries to approximate the conditions under which
                    160:      we can easily save and restore a register without scratch registers or
                    161:      other complexities.  It will usually work, except under conditions where
                    162:      the validity of an insn operand is dependent on the address offset.
                    163:      No such cases are currently known.
                    164: 
                    165:      We first find a typical offset from some BASE_REG_CLASS register.
                    166:      This address is chosen by finding the first register in the class
                    167:      and by finding the smallest power of two that is a valid offset from
                    168:      that register in every mode we will use to save registers.  */
                    169: 
                    170:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
                    171:     if (TEST_HARD_REG_BIT (reg_class_contents[(int) BASE_REG_CLASS], i))
                    172:       break;
                    173: 
                    174:   if (i == FIRST_PSEUDO_REGISTER)
                    175:     abort ();
                    176: 
                    177:   addr_reg = gen_rtx (REG, Pmode, i);
                    178: 
                    179:   for (offset = 1 << (HOST_BITS_PER_INT / 2); offset; offset >>= 1)
                    180:     {
1.1.1.3 ! root      181:       address = gen_rtx (PLUS, Pmode, addr_reg, GEN_INT (offset));
1.1       root      182: 
                    183:       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1.1.1.3 ! root      184:        if (regno_save_mode[i][1] != VOIDmode
        !           185:          && ! strict_memory_address_p (regno_save_mode[i][1], address))
1.1       root      186:          break;
                    187: 
                    188:       if (i == FIRST_PSEUDO_REGISTER)
                    189:        break;
                    190:     }
                    191: 
                    192:   /* If we didn't find a valid address, we must use register indirect.  */
                    193:   if (offset == 0)
                    194:     address = addr_reg;
                    195: 
                    196:   /* Next we try to form an insn to save and restore the register.  We
                    197:      see if such an insn is recognized and meets its constraints.  */
                    198: 
                    199:   start_sequence ();
                    200: 
                    201:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1.1.1.3 ! root      202:     for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
        !           203:       if (regno_save_mode[i][j] != VOIDmode)
        !           204:         {
        !           205:          rtx mem = gen_rtx (MEM, regno_save_mode[i][j], address);
        !           206:          rtx reg = gen_rtx (REG, regno_save_mode[i][j], i);
        !           207:          rtx savepat = gen_rtx (SET, VOIDmode, mem, reg);
        !           208:          rtx restpat = gen_rtx (SET, VOIDmode, reg, mem);
        !           209:          rtx saveinsn = emit_insn (savepat);
        !           210:          rtx restinsn = emit_insn (restpat);
        !           211:          int ok;
        !           212: 
        !           213:          reg_save_code[i][j] = recog_memoized (saveinsn);
        !           214:          reg_restore_code[i][j] = recog_memoized (restinsn);
        !           215: 
        !           216:          /* Now extract both insns and see if we can meet their constraints. */
        !           217:          ok = (reg_save_code[i][j] != -1 && reg_restore_code[i][j] != -1);
        !           218:          if (ok)
        !           219:            {
        !           220:              insn_extract (saveinsn);
        !           221:              ok = constrain_operands (reg_save_code[i][j], 1);
        !           222:              insn_extract (restinsn);
        !           223:              ok &= constrain_operands (reg_restore_code[i][j], 1);
        !           224:            }
1.1       root      225: 
1.1.1.3 ! root      226:          if (! ok)
        !           227:            {
        !           228:              regno_save_mode[i][j] = VOIDmode;
        !           229:              if (j == 1)
        !           230:                {
        !           231:                  call_fixed_regs[i] = 1;
        !           232:                  SET_HARD_REG_BIT (call_fixed_reg_set, i);
        !           233:                }
        !           234:            }
1.1       root      235:       }
                    236: 
                    237:   end_sequence ();
                    238: 
                    239:   obfree (first_obj);
                    240: }
                    241: 
                    242: /* Initialize save areas by showing that we haven't allocated any yet.  */
                    243: 
                    244: void
                    245: init_save_areas ()
                    246: {
1.1.1.3 ! root      247:   int i, j;
1.1       root      248: 
                    249:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1.1.1.3 ! root      250:     for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
        !           251:       regno_save_mem[i][j] = 0;
1.1       root      252: }
                    253: 
                    254: /* Allocate save areas for any hard registers that might need saving.
                    255:    We take a conservative approach here and look for call-clobbered hard
                    256:    registers that are assigned to pseudos that cross calls.  This may
                    257:    overestimate slightly (especially if some of these registers are later
                    258:    used as spill registers), but it should not be significant.
                    259: 
                    260:    Then perform register elimination in the addresses of the save area
                    261:    locations; return 1 if all eliminated addresses are strictly valid.
                    262:    We assume that our caller has set up the elimination table to the
                    263:    worst (largest) possible offsets.
                    264: 
1.1.1.3 ! root      265:    Set *PCHANGED to 1 if we had to allocate some memory for the save area.  
        !           266: 
        !           267:    Future work:
        !           268: 
        !           269:      In the fallback case we should iterate backwards across all possible
        !           270:      modes for the save, choosing the largest available one instead of 
        !           271:      falling back to the smallest mode immediately.  (eg TF -> DF -> SF).
        !           272: 
        !           273:      We do not try to use "move multiple" instructions that exist
        !           274:      on some machines (such as the 68k moveml).  It could be a win to try 
        !           275:      and use them when possible.  The hard part is doing it in a way that is
        !           276:      machine independent since they might be saving non-consecutive 
        !           277:      registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */
1.1       root      278: 
                    279: int
                    280: setup_save_areas (pchanged)
                    281:      int *pchanged;
                    282: {
1.1.1.3 ! root      283:   int i, j, k;
        !           284:   HARD_REG_SET hard_regs_used;
1.1       root      285:   int ok = 1;
                    286: 
1.1.1.3 ! root      287: 
        !           288:   /* Allocate space in the save area for the largest multi-register
        !           289:      pseudos first, then work backwards to single register
        !           290:      pseudos.  */
        !           291: 
        !           292:   /* Find and record all call-used hard-registers in this function.  */
        !           293:   CLEAR_HARD_REG_SET (hard_regs_used);
1.1       root      294:   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
                    295:     if (reg_renumber[i] >= 0 && reg_n_calls_crossed[i] > 0)
                    296:       {
                    297:        int regno = reg_renumber[i];
1.1.1.3 ! root      298:        int endregno 
1.1       root      299:          = regno + HARD_REGNO_NREGS (regno, GET_MODE (regno_reg_rtx[i]));
1.1.1.3 ! root      300:        int nregs = endregno - regno;
        !           301: 
        !           302:        for (j = 0; j < nregs; j++)
        !           303:          {
        !           304:            if (call_used_regs[regno+j]) 
        !           305:              SET_HARD_REG_BIT (hard_regs_used, regno+j);
        !           306:          }
        !           307:       }
        !           308: 
        !           309:   /* Now run through all the call-used hard-registers and allocate
        !           310:      space for them in the caller-save area.  Try to allocate space
        !           311:      in a manner which allows multi-register saves/restores to be done.  */
1.1       root      312: 
1.1.1.3 ! root      313:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        !           314:     for (j = MOVE_MAX / UNITS_PER_WORD; j > 0; j--)
        !           315:       {
        !           316:        int ok = 1;
        !           317: 
        !           318:        /* If no mode exists for this size, try another.  Also break out
        !           319:           if we have already saved this hard register.  */
        !           320:        if (regno_save_mode[i][j] == VOIDmode || regno_save_mem[i][1] != 0)
        !           321:          continue;
        !           322: 
        !           323:        for (k = 0; k < j; k++)
1.1       root      324:            {
1.1.1.3 ! root      325:              int regno = i + k;
        !           326:              ok &= (TEST_HARD_REG_BIT (hard_regs_used, regno) != 0);
1.1       root      327:            }
1.1.1.3 ! root      328: 
        !           329:        /* We have found an acceptable mode to store in. */
        !           330:        if (ok)
        !           331:          {
        !           332: 
        !           333:            regno_save_mem[i][j]
        !           334:              = assign_stack_local (regno_save_mode[i][j],
        !           335:                                    GET_MODE_SIZE (regno_save_mode[i][j]), 0);
        !           336: 
        !           337:            /* Setup single word save area just in case... */
        !           338:            for (k = 0; k < j; k++)
        !           339:              {
        !           340:                /* This should not depend on WORDS_BIG_ENDIAN.
        !           341:                   The order of words in regs is the same as in memory.  */
        !           342:                rtx temp = gen_rtx (MEM, regno_save_mode[i+k][1], 
        !           343:                                    XEXP (regno_save_mem[i][j], 0));
        !           344: 
        !           345:                regno_save_mem[i+k][1] 
        !           346:                  = adj_offsettable_operand (temp, k * UNITS_PER_WORD);
        !           347:              }
        !           348:            *pchanged = 1;
        !           349:          }
1.1       root      350:       }
                    351: 
                    352:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1.1.1.3 ! root      353:     for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
        !           354:       if (regno_save_mem[i][j] != 0)
        !           355:        ok &= strict_memory_address_p (GET_MODE (regno_save_mem[i][j]),
        !           356:                                       XEXP (eliminate_regs (regno_save_mem[i][j], 0, NULL_RTX), 0));
1.1       root      357: 
                    358:   return ok;
                    359: }
                    360: 
                    361: /* Find the places where hard regs are live across calls and save them.
                    362: 
                    363:    INSN_MODE is the mode to assign to any insns that we add.  This is used
                    364:    by reload to determine whether or not reloads or register eliminations
                    365:    need be done on these insns.  */
                    366: 
                    367: void
                    368: save_call_clobbered_regs (insn_mode)
                    369:      enum machine_mode insn_mode;
                    370: {
                    371:   rtx insn;
                    372:   int b;
                    373: 
                    374:   for (b = 0; b < n_basic_blocks; b++)
                    375:     {
                    376:       regset regs_live = basic_block_live_at_start[b];
1.1.1.3 ! root      377:       rtx prev_block_last = PREV_INSN (basic_block_head[b]);
        !           378:       REGSET_ELT_TYPE bit;
        !           379:       int offset, i, j;
1.1       root      380:       int regno;
                    381: 
                    382:       /* Compute hard regs live at start of block -- this is the
                    383:         real hard regs marked live, plus live pseudo regs that
                    384:         have been renumbered to hard regs.  No registers have yet been
                    385:         saved because we restore all of them before the end of the basic
                    386:         block.  */
                    387: 
                    388: #ifdef HARD_REG_SET
                    389:       hard_regs_live = *regs_live;
                    390: #else
                    391:       COPY_HARD_REG_SET (hard_regs_live, regs_live);
                    392: #endif
                    393: 
                    394:       CLEAR_HARD_REG_SET (hard_regs_saved);
1.1.1.3 ! root      395:       CLEAR_HARD_REG_SET (hard_regs_need_restore);
1.1       root      396:       n_regs_saved = 0;
                    397: 
                    398:       for (offset = 0, i = 0; offset < regset_size; offset++)
                    399:        {
                    400:          if (regs_live[offset] == 0)
1.1.1.3 ! root      401:            i += REGSET_ELT_BITS;
1.1       root      402:          else
                    403:            for (bit = 1; bit && i < max_regno; bit <<= 1, i++)
                    404:              if ((regs_live[offset] & bit)
                    405:                  && (regno = reg_renumber[i]) >= 0)
                    406:                for (j = regno;
                    407:                     j < regno + HARD_REGNO_NREGS (regno,
                    408:                                                   PSEUDO_REGNO_MODE (i));
                    409:                     j++)
                    410:                  SET_HARD_REG_BIT (hard_regs_live, j);
1.1.1.3 ! root      411: 
1.1       root      412:        }
                    413: 
                    414:       /* Now scan the insns in the block, keeping track of what hard
                    415:         regs are live as we go.  When we see a call, save the live
                    416:         call-clobbered hard regs.  */
                    417: 
                    418:       for (insn = basic_block_head[b]; ; insn = NEXT_INSN (insn))
                    419:        {
                    420:          RTX_CODE code = GET_CODE (insn);
                    421: 
                    422:          if (GET_RTX_CLASS (code) == 'i')
                    423:            {
                    424:              rtx link;
                    425: 
                    426:              /* If some registers have been saved, see if INSN references
                    427:                 any of them.  We must restore them before the insn if so.  */
                    428: 
                    429:              if (n_regs_saved)
                    430:                restore_referenced_regs (PATTERN (insn), insn, insn_mode);
                    431: 
                    432:              /* NB: the normal procedure is to first enliven any
                    433:                 registers set by insn, then deaden any registers that
                    434:                 had their last use at insn.  This is incorrect now,
                    435:                 since multiple pseudos may have been mapped to the
                    436:                 same hard reg, and the death notes are ambiguous.  So
                    437:                 it must be done in the other, safe, order.  */
                    438: 
                    439:              for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
                    440:                if (REG_NOTE_KIND (link) == REG_DEAD)
                    441:                  clear_reg_live (XEXP (link, 0));
                    442: 
                    443:              /* When we reach a call, we need to save all registers that are
                    444:                 live, call-used, not fixed, and not already saved.  We must
                    445:                 test at this point because registers that die in a CALL_INSN
                    446:                 are not live across the call and likewise for registers that
                    447:                 are born in the CALL_INSN.  */
                    448: 
                    449:              if (code == CALL_INSN)
1.1.1.3 ! root      450:                {
        !           451:                  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
        !           452:                    if (call_used_regs[regno] && ! call_fixed_regs[regno]
        !           453:                        && TEST_HARD_REG_BIT (hard_regs_live, regno)
        !           454:                        && ! TEST_HARD_REG_BIT (hard_regs_saved, regno))
        !           455:                      regno += insert_save_restore (insn, 1, regno, 
        !           456:                                                    insn_mode, 0);
        !           457: #ifdef HARD_REG_SET
        !           458:                  hard_regs_need_restore = hard_regs_saved;
        !           459: #else
        !           460:                  COPY_HARD_REG_SET (hard_regs_need_restore,
        !           461:                                     hard_regs_saved);
        !           462: #endif
        !           463: 
        !           464:                  /* Must recompute n_regs_saved.  */
        !           465:                  n_regs_saved = 0;
        !           466:                  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
        !           467:                    if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
        !           468:                      n_regs_saved++;
        !           469:                  
        !           470:                }
1.1       root      471:              
                    472:              note_stores (PATTERN (insn), set_reg_live);
                    473: 
                    474:              for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
                    475:                if (REG_NOTE_KIND (link) == REG_UNUSED)
                    476:                  clear_reg_live (XEXP (link, 0));
                    477:            }
                    478: 
                    479:          if (insn == basic_block_end[b])
                    480:            break;
                    481:        }
                    482: 
                    483:       /* At the end of the basic block, we must restore any registers that
                    484:         remain saved.  If the last insn in the block is a JUMP_INSN, put
                    485:         the restore before the insn, otherwise, put it after the insn.  */
                    486: 
                    487:       if (n_regs_saved)
                    488:        for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1.1.1.3 ! root      489:          if (TEST_HARD_REG_BIT (hard_regs_need_restore, regno))
        !           490:            regno += insert_save_restore ((GET_CODE (insn) == JUMP_INSN
        !           491:                                  ? insn : NEXT_INSN (insn)), 0,
        !           492:                                  regno, insn_mode, MOVE_MAX / UNITS_PER_WORD);
        !           493: 
        !           494:       /* If we added any insns at the start of the block, update the start
        !           495:         of the block to point at those insns.  */
        !           496:       basic_block_head[b] = NEXT_INSN (prev_block_last);
1.1       root      497:     }
                    498: }
                    499: 
                    500: /* Here from note_stores when an insn stores a value in a register.
                    501:    Set the proper bit or bits in hard_regs_live.  All pseudos that have
                    502:    been assigned hard regs have had their register number changed already,
                    503:    so we can ignore pseudos.  */
                    504: 
                    505: static void
                    506: set_reg_live (reg, setter)
                    507:      rtx reg, setter;
                    508: {
                    509:   register int regno, endregno, i;
                    510:   enum machine_mode mode = GET_MODE (reg);
                    511:   int word = 0;
                    512: 
                    513:   if (GET_CODE (reg) == SUBREG)
                    514:     {
                    515:       word = SUBREG_WORD (reg);
                    516:       reg = SUBREG_REG (reg);
                    517:     }
                    518: 
                    519:   if (GET_CODE (reg) != REG || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
                    520:     return;
                    521: 
                    522:   regno = REGNO (reg) + word;
                    523:   endregno = regno + HARD_REGNO_NREGS (regno, mode);
                    524: 
                    525:   for (i = regno; i < endregno; i++)
1.1.1.3 ! root      526:     {
        !           527:       SET_HARD_REG_BIT (hard_regs_live, i);
        !           528:       CLEAR_HARD_REG_BIT (hard_regs_saved, i);
        !           529:       CLEAR_HARD_REG_BIT (hard_regs_need_restore, i);
        !           530:     }
1.1       root      531: }
                    532: 
                    533: /* Here when a REG_DEAD note records the last use of a reg.  Clear
                    534:    the appropriate bit or bits in hard_regs_live.  Again we can ignore
                    535:    pseudos.  */
                    536: 
                    537: static void
                    538: clear_reg_live (reg)
                    539:      rtx reg;
                    540: {
                    541:   register int regno, endregno, i;
                    542: 
                    543:   if (GET_CODE (reg) != REG || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
                    544:     return;
                    545: 
                    546:   regno = REGNO (reg);
                    547:   endregno= regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
                    548: 
                    549:   for (i = regno; i < endregno; i++)
1.1.1.3 ! root      550:     {
        !           551:       CLEAR_HARD_REG_BIT (hard_regs_live, i);
        !           552:       CLEAR_HARD_REG_BIT (hard_regs_need_restore, i);
        !           553:       CLEAR_HARD_REG_BIT (hard_regs_saved, i);
        !           554:     }
1.1       root      555: }      
                    556: 
                    557: /* If any register currently residing in the save area is referenced in X,
                    558:    which is part of INSN, emit code to restore the register in front of INSN.
                    559:    INSN_MODE is the mode to assign to any insns that we add.  */
                    560: 
                    561: static void
                    562: restore_referenced_regs (x, insn, insn_mode)
                    563:      rtx x;
                    564:      rtx insn;
                    565:      enum machine_mode insn_mode;
                    566: {
                    567:   enum rtx_code code = GET_CODE (x);
                    568:   char *fmt;
                    569:   int i, j;
                    570: 
1.1.1.3 ! root      571:   if (code == CLOBBER)
        !           572:     return;
        !           573: 
1.1       root      574:   if (code == REG)
                    575:     {
                    576:       int regno = REGNO (x);
                    577: 
                    578:       /* If this is a pseudo, scan its memory location, since it might
                    579:         involve the use of another register, which might be saved.  */
                    580: 
                    581:       if (regno >= FIRST_PSEUDO_REGISTER
                    582:          && reg_equiv_mem[regno] != 0)
                    583:        restore_referenced_regs (XEXP (reg_equiv_mem[regno], 0),
                    584:                                 insn, insn_mode);
                    585:       else if (regno >= FIRST_PSEUDO_REGISTER
                    586:               && reg_equiv_address[regno] != 0)
1.1.1.2   root      587:        restore_referenced_regs (reg_equiv_address[regno],
1.1       root      588:                                 insn, insn_mode);
                    589: 
                    590:       /* Otherwise if this is a hard register, restore any piece of it that
                    591:         is currently saved.  */
                    592: 
                    593:       else if (regno < FIRST_PSEUDO_REGISTER)
                    594:        {
                    595:          int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
                    596: 
1.1.1.3 ! root      597:          for (i = regno; i < endregno; i++)
        !           598:            if (TEST_HARD_REG_BIT (hard_regs_need_restore, i))
        !           599:              i += insert_save_restore (insn, 0, i, insn_mode, 
        !           600:                   CEIL (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD));
1.1       root      601:        }
                    602: 
                    603:       return;
                    604:     }
                    605:          
                    606:   fmt = GET_RTX_FORMAT (code);
                    607:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                    608:     {
                    609:       if (fmt[i] == 'e')
                    610:        restore_referenced_regs (XEXP (x, i), insn, insn_mode);
                    611:       else if (fmt[i] == 'E')
                    612:        for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                    613:          restore_referenced_regs (XVECEXP (x, i, j), insn, insn_mode);
                    614:     }
                    615: }
                    616: 
                    617: /* Insert a sequence of insns to save or restore, SAVE_P says which,
                    618:    REGNO.  Place these insns in front of INSN.  INSN_MODE is the mode
1.1.1.3 ! root      619:    to assign to these insns.   MAXRESTORE is the maximum number of registers
        !           620:    which should be restored during this call (when SAVE_P == 0).  It should
        !           621:    never be less than 1 since we only work with entire registers.
1.1       root      622: 
                    623:    Note that we have verified in init_caller_save that we can do this
                    624:    with a simple SET, so use it.  Set INSN_CODE to what we save there
                    625:    since the address might not be valid so the insn might not be recognized.
                    626:    These insns will be reloaded and have register elimination done by
1.1.1.3 ! root      627:    find_reload, so we need not worry about that here.
1.1       root      628: 
1.1.1.3 ! root      629:    Return the extra number of registers saved.  */
        !           630: 
        !           631: static int
        !           632: insert_save_restore (insn, save_p, regno, insn_mode, maxrestore)
1.1       root      633:      rtx insn;
                    634:      int save_p;
                    635:      int regno;
                    636:      enum machine_mode insn_mode;
1.1.1.3 ! root      637:      int maxrestore;
1.1       root      638: {
                    639:   rtx pat;
                    640:   enum insn_code code;
1.1.1.3 ! root      641:   int i, numregs;
1.1       root      642: 
1.1.1.2   root      643:   /* A common failure mode if register status is not correct in the RTL
                    644:      is for this routine to be called with a REGNO we didn't expect to
                    645:      save.  That will cause us to write an insn with a (nil) SET_DEST
                    646:      or SET_SRC.  Instead of doing so and causing a crash later, check
                    647:      for this common case and abort here instead.  This will remove one
                    648:      step in debugging such problems.  */
                    649: 
1.1.1.3 ! root      650:   if (regno_save_mem[regno][1] == 0)
1.1.1.2   root      651:     abort ();
                    652: 
1.1       root      653:   /* If INSN is a CALL_INSN, we must insert our insns before any
                    654:      USE insns in front of the CALL_INSN.  */
                    655: 
                    656:   if (GET_CODE (insn) == CALL_INSN)
                    657:     while (GET_CODE (PREV_INSN (insn)) == INSN
                    658:           && GET_CODE (PATTERN (PREV_INSN (insn))) == USE)
                    659:       insn = PREV_INSN (insn);
                    660: 
                    661: #ifdef HAVE_cc0
                    662:   /* If INSN references CC0, put our insns in front of the insn that sets
                    663:      CC0.  This is always safe, since the only way we could be passed an
                    664:      insn that references CC0 is for a restore, and doing a restore earlier
                    665:      isn't a problem.  We do, however, assume here that CALL_INSNs don't
                    666:      reference CC0.  Guard against non-INSN's like CODE_LABEL.  */
                    667: 
                    668:   if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
                    669:       && reg_referenced_p (cc0_rtx, PATTERN (insn)))
                    670:     insn = prev_nonnote_insn (insn);
                    671: #endif
                    672: 
                    673:   /* Get the pattern to emit and update our status.  */
                    674:   if (save_p)
                    675:     {
1.1.1.3 ! root      676:       int i, j, k;
        !           677:       int ok;
        !           678: 
        !           679:       /* See if we can save several registers with a single instruction.  
        !           680:         Work backwards to the single register case.  */
        !           681:       for (i = MOVE_MAX / UNITS_PER_WORD; i > 0; i--)
        !           682:        {
        !           683:          ok = 1;
        !           684:          if (regno_save_mem[regno][i] != 0)
        !           685:            for (j = 0; j < i; j++)
        !           686:              {
        !           687:                if (! call_used_regs[regno + j] || call_fixed_regs[regno + j]
        !           688:                    || ! TEST_HARD_REG_BIT (hard_regs_live, regno + j)
        !           689:                    || TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
        !           690:                  ok = 0;
        !           691:              }
        !           692:          else 
        !           693:            continue;
        !           694: 
        !           695:          /* Must do this one save at a time */
        !           696:          if (! ok)
        !           697:            continue;
        !           698: 
        !           699:           pat = gen_rtx (SET, VOIDmode, regno_save_mem[regno][i],
        !           700:                     gen_rtx (REG, GET_MODE (regno_save_mem[regno][i]), regno));
        !           701:           code = reg_save_code[regno][i];
        !           702: 
        !           703:          /* Set hard_regs_saved for all the registers we saved.  */
        !           704:          for (k = 0; k < i; k++)
        !           705:            {
        !           706:              SET_HARD_REG_BIT (hard_regs_saved, regno + k);
        !           707:              SET_HARD_REG_BIT (hard_regs_need_restore, regno + k);
        !           708:              n_regs_saved++;
        !           709:            }
        !           710: 
        !           711:          numregs = i;
        !           712:          break;
        !           713:         }
1.1       root      714:     }
                    715:   else
                    716:     {
1.1.1.3 ! root      717:       int i, j, k;
        !           718:       int ok;
        !           719: 
        !           720:       /* See if we can restore `maxrestore' registers at once.  Work
        !           721:         backwards to the single register case.  */
        !           722:       for (i = maxrestore; i > 0; i--)
        !           723:        {
        !           724:          ok = 1;
        !           725:          if (regno_save_mem[regno][i])
        !           726:            for (j = 0; j < i; j++)
        !           727:              {
        !           728:                if (! TEST_HARD_REG_BIT (hard_regs_need_restore, regno + j))
        !           729:                  ok = 0;
        !           730:              }
        !           731:          else
        !           732:            continue;
1.1       root      733: 
1.1.1.3 ! root      734:          /* Must do this one restore at a time */
        !           735:          if (! ok)
        !           736:            continue;
        !           737:            
        !           738:           pat = gen_rtx (SET, VOIDmode,
        !           739:                         gen_rtx (REG, GET_MODE (regno_save_mem[regno][i]), 
        !           740:                                  regno), 
        !           741:                         regno_save_mem[regno][i]);
        !           742:           code = reg_restore_code[regno][i];
        !           743: 
        !           744: 
        !           745:          /* Clear status for all registers we restored.  */
        !           746:          for (k = 0; k < i; k++)
        !           747:            {
        !           748:              CLEAR_HARD_REG_BIT (hard_regs_need_restore, regno + k);
        !           749:              n_regs_saved--;
        !           750:            }
        !           751: 
        !           752:          numregs = i;
        !           753:          break;
        !           754:         }
        !           755:     }
1.1       root      756:   /* Emit the insn and set the code and mode.  */
                    757: 
                    758:   insn = emit_insn_before (pat, insn);
                    759:   PUT_MODE (insn, insn_mode);
                    760:   INSN_CODE (insn) = code;
1.1.1.3 ! root      761: 
        !           762:   /* Tell our callers how many extra registers we saved/restored */
        !           763:   return numregs - 1;
1.1       root      764: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.