Annotation of GNUtools/cc/caller-save.c, revision 1.1

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

unix.superglobalmegacorp.com

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