OSDN Git Service

2001-08-01 H.J. Lu <hjl@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / regrename.c
index bca986d..d24a695 100644 (file)
@@ -1,5 +1,5 @@
 /* Register renaming for the GNU compiler.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GNU CC.
 
@@ -219,9 +219,14 @@ regrename_optimize ()
       /* Don't clobber traceback for noreturn functions.  */
       if (frame_pointer_needed)
        {
-         SET_HARD_REG_BIT (unavailable, FRAME_POINTER_REGNUM);
+         int i;
+         
+         for (i = HARD_REGNO_NREGS (FRAME_POINTER_REGNUM, Pmode); i--;)
+           SET_HARD_REG_BIT (unavailable, FRAME_POINTER_REGNUM + i);
+         
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-         SET_HARD_REG_BIT (unavailable, HARD_FRAME_POINTER_REGNUM);
+         for (i = HARD_REGNO_NREGS (HARD_FRAME_POINTER_REGNUM, Pmode); i--;)
+           SET_HARD_REG_BIT (unavailable, HARD_FRAME_POINTER_REGNUM + i);
 #endif
        }
 
@@ -233,8 +238,7 @@ regrename_optimize ()
          struct du_chain *this = all_chains;
          struct du_chain *tmp, *last;
          HARD_REG_SET this_unavailable;
-         int reg = REGNO (*this->loc), treg;
-         int nregs = HARD_REGNO_NREGS (reg, GET_MODE (*this->loc));
+         int reg = REGNO (*this->loc);
          int i;
 
          all_chains = this->next_chain;
@@ -248,7 +252,13 @@ regrename_optimize ()
            }
 #endif
 
-         if (fixed_regs[reg] || global_regs[reg])
+         if (fixed_regs[reg] || global_regs[reg]
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+             || (frame_pointer_needed && reg == HARD_FRAME_POINTER_REGNUM)
+#else
+             || (frame_pointer_needed && reg == FRAME_POINTER_REGNUM)
+#endif
+             )
            continue;
 
          COPY_HARD_REG_SET (this_unavailable, unavailable);
@@ -276,9 +286,10 @@ regrename_optimize ()
 
          /* Now potential_regs is a reasonable approximation, let's
             have a closer look at each register still in there.  */
-         for (treg = 0; treg < FIRST_PSEUDO_REGISTER; treg++)
+         for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
            {
-             new_reg = treg;
+             int nregs = HARD_REGNO_NREGS (new_reg, GET_MODE (*this->loc));
+
              for (i = nregs - 1; i >= 0; --i)
                if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
                    || fixed_regs[new_reg + i]
@@ -286,6 +297,12 @@ regrename_optimize ()
                    /* Can't use regs which aren't saved by the prologue.  */
                    || (! regs_ever_live[new_reg + i]
                        && ! call_used_regs[new_reg + i])
+#ifdef LEAF_REGISTERS
+                   /* We can't use a non-leaf register if we're in a 
+                      leaf function.  */
+                   || (current_function_is_leaf 
+                       && !LEAF_REGISTERS[new_reg + i])
+#endif
 #ifdef HARD_REGNO_RENAME_OK
                    || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)
 #endif
@@ -349,7 +366,10 @@ do_replace (chain, reg)
 {
   while (chain)
     {
-      *chain->loc = gen_rtx_REG (GET_MODE (*chain->loc), reg);
+      unsigned int regno = ORIGINAL_REGNO (*chain->loc);
+      *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
+      if (regno >= FIRST_PSEUDO_REGISTER)
+       ORIGINAL_REGNO (*chain->loc) = regno;
       chain = chain->next_use;
     }
 }