home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / caller-save.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  24KB  |  765 lines

  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. #define CEIL(x,y) (((x) + (y) - 1) / (y))
  32.  
  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];
  40.  
  41. /* For each hard register, a place on the stack where it can be saved,
  42.    if needed.  */
  43.  
  44. static rtx 
  45.   regno_save_mem[FIRST_PSEUDO_REGISTER][MOVE_MAX / UNITS_PER_WORD + 1];
  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.  
  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];
  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.  
  66. /* Set of hard regs which need to be restored before referenced.  */
  67.  
  68. static HARD_REG_SET hard_regs_need_restore;
  69.  
  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 ();
  77. static int insert_save_restore ();
  78.  
  79. /* Return a machine mode that is legitimate for hard reg REGNO and large
  80.    enough to save nregs.  If we can't find one, return VOIDmode.  */
  81.  
  82. static enum machine_mode
  83. choose_hard_reg_mode (regno, nregs)
  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))
  94.     if (HARD_REGNO_NREGS (regno, mode) == nregs
  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))
  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.   if (HARD_REGNO_NREGS (regno, CCmode) == nregs
  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;
  135.   int i, j;
  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.     {
  145.       for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
  146.         {
  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.         }
  153.         }
  154.     }
  155.       else
  156.     regno_save_mode[i][1] = VOIDmode;
  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.     {
  181.       address = gen_rtx (PLUS, Pmode, addr_reg, GEN_INT (offset));
  182.  
  183.       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  184.     if (regno_save_mode[i][1] != VOIDmode
  185.       && ! strict_memory_address_p (regno_save_mode[i][1], address))
  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++)
  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.         }
  225.  
  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.         }
  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. {
  247.   int i, j;
  248.  
  249.   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
  250.     for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
  251.       regno_save_mem[i][j] = 0;
  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 ma