OSDN Git Service

Make unsafe vector float optimizations dependent on -ffast-math.
[pf3gnuchains/gcc-fork.git] / gcc / reload1.c
index b234a6a..3eb20b0 100644 (file)
@@ -1,6 +1,6 @@
 /* Reload pseudo regs into hard regs for insns that require hard regs.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -77,10 +77,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    reload needs, spilling, assigning reload registers to use for
    fixing up each insn, and generating the new insns to copy values
    into the reload registers.  */
-
-#ifndef LOCAL_REGNO
-#define LOCAL_REGNO(REGNO)  0
-#endif
 \f
 /* During reload_as_needed, element N contains a REG rtx for the hard reg
    into which reg N has been reloaded (perhaps for a previous insn).  */
@@ -106,6 +102,10 @@ rtx *reg_equiv_constant;
    is transferred to either reg_equiv_address or reg_equiv_mem.  */
 rtx *reg_equiv_memory_loc;
 
+/* We allocate reg_equiv_memory_loc inside a varray so that the garbage
+   collector can keep track of what is inside.  */
+varray_type reg_equiv_memory_loc_varray;
+
 /* Element N is the address of stack slot to which pseudo reg N is equivalent.
    This is used when the address is not valid as a memory address
    (because its displacement is too big for the machine.)  */
@@ -142,6 +142,11 @@ static HARD_REG_SET reg_reloaded_valid;
    This is only valid if reg_reloaded_contents is set and valid.  */
 static HARD_REG_SET reg_reloaded_dead;
 
+/* Indicate whether the register's current value is one that is not
+   safe to retain across a call, even for registers that are normally
+   call-saved.  */
+static HARD_REG_SET reg_reloaded_call_part_clobbered;
+
 /* Number of spill-regs so far; number of valid elements of spill_regs.  */
 static int n_spills;
 
@@ -401,6 +406,7 @@ static int reload_reg_free_for_value_p (int, int, int, enum reload_type,
                                        rtx, rtx, int, int);
 static int free_for_value_p (int, enum machine_mode, int, enum reload_type,
                             rtx, rtx, int, int);
+static int function_invariant_p (rtx);
 static int reload_reg_reaches_end_p (unsigned int, int, enum reload_type);
 static int allocate_reload_reg (struct insn_chain *, int, int);
 static int conflicts_with_override (rtx);
@@ -415,6 +421,7 @@ static void emit_output_reload_insns (struct insn_chain *, struct reload *,
                                      int);
 static void do_input_reload (struct insn_chain *, struct reload *, int);
 static void do_output_reload (struct insn_chain *, struct reload *, int);
+static bool inherit_piecemeal_p (int, int);
 static void emit_reload_insns (struct insn_chain *);
 static void delete_output_reload (rtx, int, int);
 static void delete_address_reloads (rtx, rtx);
@@ -479,6 +486,7 @@ init_reload (void)
 
   INIT_REG_SET (&spilled_pseudos);
   INIT_REG_SET (&pseudos_counted);
+  VARRAY_RTX_INIT (reg_equiv_memory_loc_varray, 0, "reg_equiv_memory_loc");
 }
 
 /* List of insn chains that are currently unused.  */
@@ -533,7 +541,7 @@ compute_use_by_pseudos (HARD_REG_SET *to, regset from)
         }
        else
         {
-          nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (regno));
+          nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
           while (nregs-- > 0)
             SET_HARD_REG_BIT (*to, r + nregs);
         }
@@ -576,7 +584,7 @@ replace_pseudos_in (rtx *loc, enum machine_mode mem_mode, rtx usage)
        *loc = reg_equiv_mem[regno];
       else if (reg_equiv_address[regno])
        *loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address[regno]);
-      else if (GET_CODE (regno_reg_rtx[regno]) != REG
+      else if (!REG_P (regno_reg_rtx[regno])
               || REGNO (regno_reg_rtx[regno]) != regno)
        *loc = regno_reg_rtx[regno];
       else
@@ -706,10 +714,9 @@ reload (rtx first, int global)
 
   CLEAR_HARD_REG_SET (bad_spill_regs_global);
 
-  /* Look for REG_EQUIV notes; record what each pseudo is equivalent to.
-     Also find all paradoxical subregs and find largest such for each pseudo.
-     On machines with small register classes, record hard registers that
-     are used for user variables.  These can never be used for spills.  */
+  /* Look for REG_EQUIV notes; record what each pseudo is equivalent
+     to.  Also find all paradoxical subregs and find largest such for
+     each pseudo.  */
 
   num_eliminable_invariants = 0;
   for (insn = first; insn; insn = NEXT_INSN (insn))
@@ -723,20 +730,17 @@ reload (rtx first, int global)
          && GET_MODE (insn) != VOIDmode)
        PUT_MODE (insn, VOIDmode);
 
-      if (set != 0 && GET_CODE (SET_DEST (set)) == REG)
+      if (set != 0 && REG_P (SET_DEST (set)))
        {
          rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
          if (note
-#ifdef LEGITIMATE_PIC_OPERAND_P
              && (! function_invariant_p (XEXP (note, 0))
                  || ! flag_pic
                  /* A function invariant is often CONSTANT_P but may
                     include a register.  We promise to only pass
                     CONSTANT_P objects to LEGITIMATE_PIC_OPERAND_P.  */
                  || (CONSTANT_P (XEXP (note, 0))
-                     && LEGITIMATE_PIC_OPERAND_P (XEXP (note, 0))))
-#endif
-             )
+                     && LEGITIMATE_PIC_OPERAND_P (XEXP (note, 0)))))
            {
              rtx x = XEXP (note, 0);
              i = REGNO (SET_DEST (set));
@@ -786,7 +790,7 @@ reload (rtx first, int global)
                     and the MEM is not SET_SRC, the equivalencing insn
                     is one with the MEM as a SET_DEST and it occurs later.
                     So don't mark this insn now.  */
-                 if (GET_CODE (x) != MEM
+                 if (!MEM_P (x)
                      || rtx_equal_p (SET_SRC (set), x))
                    reg_equiv_init[i]
                      = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[i]);
@@ -796,8 +800,8 @@ reload (rtx first, int global)
 
       /* If this insn is setting a MEM from a register equivalent to it,
         this is the equivalencing insn.  */
-      else if (set && GET_CODE (SET_DEST (set)) == MEM
-              && GET_CODE (SET_SRC (set)) == REG
+      else if (set && MEM_P (SET_DEST (set))
+              && REG_P (SET_SRC (set))
               && reg_equiv_memory_loc[REGNO (SET_SRC (set))]
               && rtx_equal_p (SET_DEST (set),
                               reg_equiv_memory_loc[REGNO (SET_SRC (set))]))
@@ -835,8 +839,7 @@ reload (rtx first, int global)
      main reload loop in the most common case where register elimination
      cannot be done.  */
   for (insn = first; insn && num_eliminable; insn = NEXT_INSN (insn))
-    if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-       || GET_CODE (insn) == CALL_INSN)
+    if (INSN_P (insn))
       note_stores (PATTERN (insn), mark_not_eliminable, NULL);
 
   maybe_fix_stack_asms ();
@@ -849,9 +852,22 @@ reload (rtx first, int global)
 
   /* Spill any hard regs that we know we can't eliminate.  */
   CLEAR_HARD_REG_SET (used_spill_regs);
-  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-    if (! ep->can_eliminate)
-      spill_hard_reg (ep->from, 1);
+  /* There can be multiple ways to eliminate a register;
+     they should be listed adjacently.
+     Elimination for any register fails only if all possible ways fail.  */
+  for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; )
+    {
+      int from = ep->from;
+      int can_eliminate = 0;
+      do
+       {
+          can_eliminate |= ep->can_eliminate;
+          ep++;
+       }
+      while (ep < &reg_eliminate[NUM_ELIMINABLE_REGS] && ep->from == from);
+      if (! can_eliminate)
+       spill_hard_reg (from, 1);
+    }
 
 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
   if (frame_pointer_needed)
@@ -918,10 +934,10 @@ reload (rtx first, int global)
                                         XEXP (x, 0)))
              reg_equiv_mem[i] = x, reg_equiv_address[i] = 0;
            else if (CONSTANT_P (XEXP (x, 0))
-                    || (GET_CODE (XEXP (x, 0)) == REG
+                    || (REG_P (XEXP (x, 0))
                         && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
                     || (GET_CODE (XEXP (x, 0)) == PLUS
-                        && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+                        && REG_P (XEXP (XEXP (x, 0), 0))
                         && (REGNO (XEXP (XEXP (x, 0), 0))
                             < FIRST_PSEUDO_REGISTER)
                         && CONSTANT_P (XEXP (XEXP (x, 0), 1))))
@@ -1033,17 +1049,13 @@ reload (rtx first, int global)
                 if an insn has a variable address, gets a REG_EH_REGION
                 note added to it, and then gets converted into an load
                 from a constant address.  */
-             if (GET_CODE (equiv_insn) == NOTE
+             if (NOTE_P (equiv_insn)
                  || can_throw_internal (equiv_insn))
                ;
              else if (reg_set_p (regno_reg_rtx[i], PATTERN (equiv_insn)))
                delete_dead_insn (equiv_insn);
              else
-               {
-                 PUT_CODE (equiv_insn, NOTE);
-                 NOTE_SOURCE_FILE (equiv_insn) = 0;
-                 NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED;
-               }
+               SET_INSN_DELETED (equiv_insn);
            }
        }
     }
@@ -1146,7 +1158,7 @@ reload (rtx first, int global)
       {
        rtx *pnote;
 
-       if (GET_CODE (insn) == CALL_INSN)
+       if (CALL_P (insn))
          replace_pseudos_in (& CALL_INSN_FUNCTION_USAGE (insn),
                              VOIDmode, CALL_INSN_FUNCTION_USAGE (insn));
 
@@ -1155,12 +1167,12 @@ reload (rtx first, int global)
             && (GET_MODE (insn) == QImode
                 || find_reg_note (insn, REG_EQUAL, NULL_RTX)))
            || (GET_CODE (PATTERN (insn)) == CLOBBER
-               && (GET_CODE (XEXP (PATTERN (insn), 0)) != MEM
+               && (!MEM_P (XEXP (PATTERN (insn), 0))
                    || GET_MODE (XEXP (PATTERN (insn), 0)) != BLKmode
                    || (GET_CODE (XEXP (XEXP (PATTERN (insn), 0), 0)) != SCRATCH
                        && XEXP (XEXP (PATTERN (insn), 0), 0)
                                != stack_pointer_rtx))
-               && (GET_CODE (XEXP (PATTERN (insn), 0)) != REG
+               && (!REG_P (XEXP (PATTERN (insn), 0))
                    || ! REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))))
          {
            delete_insn (insn);
@@ -1221,8 +1233,7 @@ reload (rtx first, int global)
   if (reg_equiv_constant)
     free (reg_equiv_constant);
   reg_equiv_constant = 0;
-  if (reg_equiv_memory_loc)
-    free (reg_equiv_memory_loc);
+  VARRAY_GROW (reg_equiv_memory_loc_varray, 0);
   reg_equiv_memory_loc = 0;
 
   if (offsets_known_at)
@@ -1421,7 +1432,7 @@ calculate_needs_all_insns (int global)
         include REG_LABEL), we need to see what effects this has on the
         known offsets at labels.  */
 
-      if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN
+      if (LABEL_P (insn) || JUMP_P (insn)
          || (INSN_P (insn) && REG_NOTES (insn) != 0))
        set_label_offsets (insn, insn, 0);
 
@@ -1435,7 +1446,7 @@ calculate_needs_all_insns (int global)
          rtx set = single_set (insn);
 
          /* Skip insns that only set an equivalence.  */
-         if (set && GET_CODE (SET_DEST (set)) == REG
+         if (set && REG_P (SET_DEST (set))
              && reg_renumber[REGNO (SET_DEST (set))] < 0
              && reg_equiv_constant[REGNO (SET_DEST (set))])
            continue;
@@ -1460,7 +1471,7 @@ calculate_needs_all_insns (int global)
              rtx set = single_set (insn);
              if (set
                  && SET_SRC (set) == SET_DEST (set)
-                 && GET_CODE (SET_SRC (set)) == REG
+                 && REG_P (SET_SRC (set))
                  && REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER)
                {
                  delete_insn (insn);
@@ -1571,7 +1582,7 @@ count_pseudo (int reg)
 
   spill_add_cost[r] += freq;
 
-  nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
+  nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (reg)];
   while (nregs-- > 0)
     spill_cost[r + nregs] += freq;
 }
@@ -1633,7 +1644,7 @@ static void
 count_spilled_pseudo (int spilled, int spilled_nregs, int reg)
 {
   int r = reg_renumber[reg];
-  int nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
+  int nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (reg)];
 
   if (REGNO_REG_SET_P (&spilled_pseudos, reg)
       || spilled + spilled_nregs <= r || r + nregs <= spilled)
@@ -1684,7 +1695,7 @@ find_reg (struct insn_chain *chain, int order)
        {
          int this_cost = spill_cost[regno];
          int ok = 1;
-         unsigned int this_nregs = HARD_REGNO_NREGS (regno, rl->mode);
+         unsigned int this_nregs = hard_regno_nregs[regno][rl->mode];
 
          for (j = 1; j < this_nregs; j++)
            {
@@ -1695,9 +1706,9 @@ find_reg (struct insn_chain *chain, int order)
            }
          if (! ok)
            continue;
-         if (rl->in && GET_CODE (rl->in) == REG && REGNO (rl->in) == regno)
+         if (rl->in && REG_P (rl->in) && REGNO (rl->in) == regno)
            this_cost--;
-         if (rl->out && GET_CODE (rl->out) == REG && REGNO (rl->out) == regno)
+         if (rl->out && REG_P (rl->out) && REGNO (rl->out) == regno)
            this_cost--;
          if (this_cost < best_cost
              /* Among registers with equal cost, prefer caller-saved ones, or
@@ -1720,10 +1731,10 @@ find_reg (struct insn_chain *chain, int order)
   if (best_reg == -1)
     return 0;
 
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, "Using reg %d for reload %d\n", best_reg, rnum);
+  if (dump_file)
+    fprintf (dump_file, "Using reg %d for reload %d\n", best_reg, rnum);
 
-  rl->nregs = HARD_REGNO_NREGS (best_reg, rl->mode);
+  rl->nregs = hard_regno_nregs[best_reg][rl->mode];
   rl->regno = best_reg;
 
   EXECUTE_IF_SET_IN_REG_SET
@@ -1771,7 +1782,7 @@ find_reload_regs (struct insn_chain *chain)
          int regno = REGNO (chain->rld[i].reg_rtx);
          chain->rld[i].regno = regno;
          chain->rld[i].nregs
-           = HARD_REGNO_NREGS (regno, GET_MODE (chain->rld[i].reg_rtx));
+           = hard_regno_nregs[regno][GET_MODE (chain->rld[i].reg_rtx)];
        }
       else
        chain->rld[i].regno = -1;
@@ -1783,8 +1794,8 @@ find_reload_regs (struct insn_chain *chain)
 
   CLEAR_HARD_REG_SET (used_spill_regs_local);
 
-  if (rtl_dump_file)
-    fprintf (rtl_dump_file, "Spilling for insn %d.\n", INSN_UID (chain->insn));
+  if (dump_file)
+    fprintf (dump_file, "Spilling for insn %d.\n", INSN_UID (chain->insn));
 
   qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower);
 
@@ -1886,15 +1897,13 @@ delete_dead_insn (rtx insn)
   /* If the previous insn sets a register that dies in our insn, delete it
      too.  */
   if (prev && GET_CODE (PATTERN (prev)) == SET
-      && (prev_dest = SET_DEST (PATTERN (prev)), GET_CODE (prev_dest) == REG)
+      && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
       && reg_mentioned_p (prev_dest, PATTERN (insn))
       && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
       && ! side_effects_p (SET_SRC (PATTERN (prev))))
     delete_dead_insn (prev);
 
-  PUT_CODE (insn, NOTE);
-  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-  NOTE_SOURCE_FILE (insn) = 0;
+  SET_INSN_DELETED (insn);
 }
 
 /* Modify the home of pseudo-reg I.
@@ -1915,7 +1924,7 @@ alter_reg (int i, int from_reg)
 
   /* If the reg got changed to a MEM at rtl-generation time,
      ignore it.  */
-  if (GET_CODE (regno_reg_rtx[i]) != REG)
+  if (!REG_P (regno_reg_rtx[i]))
     return;
 
   /* Modify the reg-rtx to contain the new hard reg
@@ -2036,7 +2045,7 @@ alter_reg (int i, int from_reg)
             any copies of it, since otherwise when the stack slot
             is reused, nonoverlapping_memrefs_p might think they
             cannot overlap.  */
-         if (decl && GET_CODE (decl) == REG && REGNO (decl) == (unsigned) i)
+         if (decl && REG_P (decl) && REGNO (decl) == (unsigned) i)
            {
              if (from_reg != -1 && spill_stack_slot[from_reg] == x)
                x = copy_rtx (x);
@@ -2061,7 +2070,7 @@ mark_home_live (int regno)
   i = reg_renumber[regno];
   if (i < 0)
     return;
-  lim = i + HARD_REGNO_NREGS (i, PSEUDO_REGNO_MODE (regno));
+  lim = i + hard_regno_nregs[i][PSEUDO_REGNO_MODE (regno)];
   while (i < lim)
     regs_ever_live[i++] = 1;
 }
@@ -2117,7 +2126,7 @@ set_label_offsets (rtx x, rtx insn, int initial_p)
 
       else if (x == insn
               && (tem = prev_nonnote_insn (insn)) != 0
-              && GET_CODE (tem) == BARRIER)
+              && BARRIER_P (tem))
        set_offsets_for_label (insn);
       else
        /* If neither of the above cases is true, compare each offset
@@ -2269,15 +2278,6 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
     case RETURN:
       return x;
 
-    case ADDRESSOF:
-      /* This is only for the benefit of the debugging backends, which call
-        eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are
-        removed after CSE.  */
-      new = eliminate_regs (XEXP (x, 0), 0, insn);
-      if (GET_CODE (new) == MEM)
-       return XEXP (new, 0);
-      return x;
-
     case REG:
       regno = REGNO (x);
 
@@ -2306,7 +2306,7 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
        and require special code to handle code a reloaded PLUS operand.
 
        Also consider backends where the flags register is clobbered by a
-       MINUS, but we can emit a PLUS that does not clobber flags (ia32,
+       MINUS, but we can emit a PLUS that does not clobber flags (IA-32,
        lea instruction comes to mind).  If we try to reload a MINUS, we
        may kill the flags register that was holding a useful value.
 
@@ -2315,7 +2315,7 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
     case PLUS:
       /* If this is the sum of an eliminable register and a constant, rework
         the sum.  */
-      if (GET_CODE (XEXP (x, 0)) == REG
+      if (REG_P (XEXP (x, 0))
          && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
          && CONSTANT_P (XEXP (x, 1)))
        {
@@ -2364,13 +2364,13 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
               didn't get a hard register but has a reg_equiv_constant,
               we must replace the constant here since it may no longer
               be in the position of any operand.  */
-           if (GET_CODE (new0) == PLUS && GET_CODE (new1) == REG
+           if (GET_CODE (new0) == PLUS && REG_P (new1)
                && REGNO (new1) >= FIRST_PSEUDO_REGISTER
                && reg_renumber[REGNO (new1)] < 0
                && reg_equiv_constant != 0
                && reg_equiv_constant[REGNO (new1)] != 0)
              new1 = reg_equiv_constant[REGNO (new1)];
-           else if (GET_CODE (new1) == PLUS && GET_CODE (new0) == REG
+           else if (GET_CODE (new1) == PLUS && REG_P (new0)
                     && REGNO (new0) >= FIRST_PSEUDO_REGISTER
                     && reg_renumber[REGNO (new0)] < 0
                     && reg_equiv_constant[REGNO (new0)] != 0)
@@ -2395,7 +2395,7 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
         so that we have (plus (mult ..) ..).  This is needed in order
         to keep load-address insns valid.   This case is pathological.
         We ignore the possibility of overflow here.  */
-      if (GET_CODE (XEXP (x, 0)) == REG
+      if (REG_P (XEXP (x, 0))
          && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
          && GET_CODE (XEXP (x, 1)) == CONST_INT)
        for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
@@ -2500,7 +2500,7 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
         pseudo didn't get a hard reg, we must replace this with the
         eliminated version of the memory location because push_reload
         may do the replacement in certain circumstances.  */
-      if (GET_CODE (SUBREG_REG (x)) == REG
+      if (REG_P (SUBREG_REG (x))
          && (GET_MODE_SIZE (GET_MODE (x))
              <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
          && reg_equiv_memory_loc != 0
@@ -2516,7 +2516,7 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
          int x_size = GET_MODE_SIZE (GET_MODE (x));
          int new_size = GET_MODE_SIZE (GET_MODE (new));
 
-         if (GET_CODE (new) == MEM
+         if (MEM_P (new)
              && ((x_size < new_size
 #ifdef WORD_REGISTER_OPERATIONS
                   /* On these machines, combine can create rtl of the form
@@ -2540,12 +2540,6 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
       return x;
 
     case MEM:
-      /* This is only for the benefit of the debugging backends, which call
-        eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are
-        removed after CSE.  */
-      if (GET_CODE (XEXP (x, 0)) == ADDRESSOF)
-       return eliminate_regs (XEXP (XEXP (x, 0), 0), 0, insn);
-
       /* Our only special processing is to pass the mode of the MEM to our
         recursive call and copy the flags.  While we are here, handle this
         case more efficiently.  */
@@ -2644,9 +2638,6 @@ elimination_effects (rtx x, enum machine_mode mem_mode)
     case RETURN:
       return;
 
-    case ADDRESSOF:
-      abort ();
-
     case REG:
       regno = REGNO (x);
 
@@ -2719,7 +2710,7 @@ elimination_effects (rtx x, enum machine_mode mem_mode)
       return;
 
     case SUBREG:
-      if (GET_CODE (SUBREG_REG (x)) == REG
+      if (REG_P (SUBREG_REG (x))
          && (GET_MODE_SIZE (GET_MODE (x))
              <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
          && reg_equiv_memory_loc != 0
@@ -2753,7 +2744,7 @@ elimination_effects (rtx x, enum machine_mode mem_mode)
 
     case SET:
       /* Check for setting a register that we know about.  */
-      if (GET_CODE (SET_DEST (x)) == REG)
+      if (REG_P (SET_DEST (x)))
        {
          /* See if this is setting the replacement register for an
             elimination.
@@ -2789,9 +2780,6 @@ elimination_effects (rtx x, enum machine_mode mem_mode)
       return;
 
     case MEM:
-      if (GET_CODE (XEXP (x, 0)) == ADDRESSOF)
-       abort ();
-
       /* Our only special processing is to pass the mode of the MEM to our
         recursive call.  */
       elimination_effects (XEXP (x, 0), GET_MODE (x));
@@ -2833,7 +2821,7 @@ check_eliminable_occurrences (rtx x)
       struct elim_table *ep;
 
       for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-       if (ep->from_rtx == x && ep->can_eliminate)
+       if (ep->from_rtx == x)
          ep->can_eliminate = 0;
       return;
     }
@@ -2878,6 +2866,7 @@ eliminate_regs_in_insn (rtx insn, int replace)
   rtx substed_operand[MAX_RECOG_OPERANDS];
   rtx orig_operand[MAX_RECOG_OPERANDS];
   struct elim_table *ep;
+  rtx plus_src;
 
   if (! insn_is_asm && icode < 0)
     {
@@ -2890,7 +2879,7 @@ eliminate_regs_in_insn (rtx insn, int replace)
       abort ();
     }
 
-  if (old_set != 0 && GET_CODE (SET_DEST (old_set)) == REG
+  if (old_set != 0 && REG_P (SET_DEST (old_set))
       && REGNO (SET_DEST (old_set)) < FIRST_PSEUDO_REGISTER)
     {
       /* Check for setting an eliminable register.  */
@@ -2981,17 +2970,40 @@ eliminate_regs_in_insn (rtx insn, int replace)
     }
 
   /* We allow one special case which happens to work on all machines we
-     currently support: a single set with the source being a PLUS of an
-     eliminable register and a constant.  */
-  if (old_set
-      && GET_CODE (SET_DEST (old_set)) == REG
-      && GET_CODE (SET_SRC (old_set)) == PLUS
-      && GET_CODE (XEXP (SET_SRC (old_set), 0)) == REG
-      && GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT
-      && REGNO (XEXP (SET_SRC (old_set), 0)) < FIRST_PSEUDO_REGISTER)
+     currently support: a single set with the source or a REG_EQUAL
+     note being a PLUS of an eliminable register and a constant.  */
+  plus_src = 0;
+  if (old_set && REG_P (SET_DEST (old_set)))
+    {
+      /* First see if the source is of the form (plus (reg) CST).  */
+      if (GET_CODE (SET_SRC (old_set)) == PLUS
+         && REG_P (XEXP (SET_SRC (old_set), 0))
+         && GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT
+         && REGNO (XEXP (SET_SRC (old_set), 0)) < FIRST_PSEUDO_REGISTER)
+       plus_src = SET_SRC (old_set);
+      else if (REG_P (SET_SRC (old_set)))
+       {
+         /* Otherwise, see if we have a REG_EQUAL note of the form
+            (plus (reg) CST).  */
+         rtx links;
+         for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
+           {
+             if (REG_NOTE_KIND (links) == REG_EQUAL
+                 && GET_CODE (XEXP (links, 0)) == PLUS
+                 && REG_P (XEXP (XEXP (links, 0), 0))
+                 && GET_CODE (XEXP (XEXP (links, 0), 1)) == CONST_INT
+                 && REGNO (XEXP (XEXP (links, 0), 0)) < FIRST_PSEUDO_REGISTER)
+               {
+                 plus_src = XEXP (links, 0);
+                 break;
+               }
+           }
+       }
+    }
+  if (plus_src)
     {
-      rtx reg = XEXP (SET_SRC (old_set), 0);
-      HOST_WIDE_INT offset = INTVAL (XEXP (SET_SRC (old_set), 1));
+      rtx reg = XEXP (plus_src, 0);
+      HOST_WIDE_INT offset = INTVAL (XEXP (plus_src, 1));
 
       for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
        if (ep->from_rtx == reg && ep->can_eliminate)
@@ -3021,7 +3033,12 @@ eliminate_regs_in_insn (rtx insn, int replace)
                if (INSN_CODE (insn) < 0)
                  abort ();
              }
-           else
+           /* If we have a nonzero offset, and the source is already
+              a simple REG, the following transformation would
+              increase the cost of the insn by replacing a simple REG
+              with (plus (reg sp) CST).  So try only when plus_src
+              comes from old_set proper, not REG_NOTES.  */
+           else if (SET_SRC (old_set) == plus_src)
              {
                new_body = old_body;
                if (! replace)
@@ -3036,6 +3053,9 @@ eliminate_regs_in_insn (rtx insn, int replace)
                XEXP (SET_SRC (old_set), 0) = ep->to_rtx;
                XEXP (SET_SRC (old_set), 1) = GEN_INT (offset);
              }
+           else
+             break;
+
            val = 1;
            /* This can't have an effect on elimination offsets, so skip right
               to the end.  */
@@ -3059,7 +3079,7 @@ eliminate_regs_in_insn (rtx insn, int replace)
        {
          /* Check for setting a register that we know about.  */
          if (recog_data.operand_type[i] != OP_IN
-             && GET_CODE (orig_operand[i]) == REG)
+             && REG_P (orig_operand[i]))
            {
              /* If we are assigning to a register that can be eliminated, it
                 must be as part of a PARALLEL, since the code above handles
@@ -3067,7 +3087,7 @@ eliminate_regs_in_insn (rtx insn, int replace)
                 eliminate this reg.  */
              for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
                   ep++)
-               if (ep->from_rtx == orig_operand[i] && ep->can_eliminate)
+               if (ep->from_rtx == orig_operand[i])
                  ep->can_eliminate = 0;
            }
 
@@ -3082,8 +3102,8 @@ eliminate_regs_in_insn (rtx insn, int replace)
        /* If an output operand changed from a REG to a MEM and INSN is an
           insn, write a CLOBBER insn.  */
          if (recog_data.operand_type[i] != OP_IN
-             && GET_CODE (orig_operand[i]) == REG
-             && GET_CODE (substed_operand[i]) == MEM
+             && REG_P (orig_operand[i])
+             && MEM_P (substed_operand[i])
              && replace)
            emit_insn_after (gen_rtx_CLOBBER (VOIDmode, orig_operand[i]),
                             insn);
@@ -3137,16 +3157,16 @@ eliminate_regs_in_insn (rtx insn, int replace)
         thing always?  */
       if (! insn_is_asm
          && old_set != 0
-         && ((GET_CODE (SET_SRC (old_set)) == REG
+         && ((REG_P (SET_SRC (old_set))
               && (GET_CODE (new_body) != SET
-                  || GET_CODE (SET_SRC (new_body)) != REG))
+                  || !REG_P (SET_SRC (new_body))))
              /* If this was a load from or store to memory, compare
                 the MEM in recog_data.operand to the one in the insn.
                 If they are not equal, then rerecognize the insn.  */
              || (old_set != 0
-                 && ((GET_CODE (SET_SRC (old_set)) == MEM
+                 && ((MEM_P (SET_SRC (old_set))
                       && SET_SRC (old_set) != recog_data.operand[1])
-                     || (GET_CODE (SET_DEST (old_set)) == MEM
+                     || (MEM_P (SET_DEST (old_set))
                          && SET_DEST (old_set) != recog_data.operand[0])))
              /* If this was an add insn before, rerecognize.  */
              || GET_CODE (SET_SRC (old_set)) == PLUS))
@@ -3447,7 +3467,6 @@ init_elim_table (void)
   /* Does this function require a frame pointer?  */
 
   frame_pointer_needed = (! flag_omit_frame_pointer
-#ifdef EXIT_IGNORE_STACK
                          /* ?? If EXIT_IGNORE_STACK is set, we will not save
                             and restore sp for alloca.  So we can't eliminate
                             the frame pointer in that case.  At some point,
@@ -3455,7 +3474,6 @@ init_elim_table (void)
                             sp-adjusting insns for this case.  */
                          || (current_function_calls_alloca
                              && EXIT_IGNORE_STACK)
-#endif
                          || FRAME_POINTER_REQUIRED);
 
   num_eliminable = 0;
@@ -3478,8 +3496,8 @@ init_elim_table (void)
 #endif
 
   /* Count the number of eliminable registers and build the FROM and TO
-     REG rtx's.  Note that code in gen_rtx will cause, e.g.,
-     gen_rtx (REG, Pmode, STACK_POINTER_REGNUM) to equal stack_pointer_rtx.
+     REG rtx's.  Note that code in gen_rtx_REG will cause, e.g.,
+     gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to equal stack_pointer_rtx.
      We depend on this.  */
   for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
     {
@@ -3517,8 +3535,8 @@ spill_hard_reg (unsigned int regno, int cant_eliminate)
     if (reg_renumber[i] >= 0
        && (unsigned int) reg_renumber[i] <= regno
        && ((unsigned int) reg_renumber[i]
-           + HARD_REGNO_NREGS ((unsigned int) reg_renumber[i],
-                               PSEUDO_REGNO_MODE (i))
+           + hard_regno_nregs[(unsigned int) reg_renumber[i]]
+                             [PSEUDO_REGNO_MODE (i)]
            > regno))
       SET_REGNO_REG_SET (&spilled_pseudos, i);
 }
@@ -3669,12 +3687,12 @@ finish_spills (int global)
 
       alter_reg (i, reg_old_renumber[i]);
       reg_old_renumber[i] = regno;
-      if (rtl_dump_file)
+      if (dump_file)
        {
          if (regno == -1)
-           fprintf (rtl_dump_file, " Register %d now on stack.\n\n", i);
+           fprintf (dump_file, " Register %d now on stack.\n\n", i);
          else
-           fprintf (rtl_dump_file, " Register %d now in %d.\n\n",
+           fprintf (dump_file, " Register %d now in %d.\n\n",
                     i, reg_renumber[i]);
        }
     }
@@ -3682,9 +3700,7 @@ finish_spills (int global)
   return something_changed;
 }
 \f
-/* Find all paradoxical subregs within X and update reg_max_ref_width.
-   Also mark any hard registers used to store user variables as
-   forbidden from being used for spill registers.  */
+/* Find all paradoxical subregs within X and update reg_max_ref_width.  */
 
 static void
 scan_paradoxical_subregs (rtx x)
@@ -3696,13 +3712,6 @@ scan_paradoxical_subregs (rtx x)
   switch (code)
     {
     case REG:
-#if 0
-      if (SMALL_REGISTER_CLASSES && REGNO (x) < FIRST_PSEUDO_REGISTER
-         && REG_USERVAR_P (x))
-       SET_HARD_REG_BIT (bad_spill_regs_global, REGNO (x));
-#endif
-      return;
-
     case CONST_INT:
     case CONST:
     case SYMBOL_REF:
@@ -3716,7 +3725,7 @@ scan_paradoxical_subregs (rtx x)
       return;
 
     case SUBREG:
-      if (GET_CODE (SUBREG_REG (x)) == REG
+      if (REG_P (SUBREG_REG (x))
          && GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
        reg_max_ref_width[REGNO (SUBREG_REG (x))]
          = GET_MODE_SIZE (GET_MODE (x));
@@ -3763,6 +3772,7 @@ reload_as_needed (int live_known)
   reg_last_reload_reg = xcalloc (max_regno, sizeof (rtx));
   reg_has_output_reload = xmalloc (max_regno);
   CLEAR_HARD_REG_SET (reg_reloaded_valid);
+  CLEAR_HARD_REG_SET (reg_reloaded_call_part_clobbered);
 
   set_initial_elim_offsets ();
 
@@ -3774,7 +3784,7 @@ reload_as_needed (int live_known)
 
       /* If we pass a label, copy the offsets from the label information
         into the current offsets of each elimination.  */
-      if (GET_CODE (insn) == CODE_LABEL)
+      if (LABEL_P (insn))
        set_offsets_for_label (insn);
 
       else if (INSN_P (insn))
@@ -3786,7 +3796,7 @@ reload_as_needed (int live_known)
 
          if ((GET_CODE (PATTERN (insn)) == USE
               || GET_CODE (PATTERN (insn)) == CLOBBER)
-             && GET_CODE (XEXP (PATTERN (insn), 0)) == MEM)
+             && MEM_P (XEXP (PATTERN (insn), 0)))
            XEXP (XEXP (PATTERN (insn), 0), 0)
              = eliminate_regs (XEXP (XEXP (PATTERN (insn), 0), 0),
                                GET_MODE (XEXP (PATTERN (insn), 0)),
@@ -3797,7 +3807,7 @@ reload_as_needed (int live_known)
          if ((num_eliminable || num_eliminable_invariants) && chain->need_elim)
            {
              eliminate_regs_in_insn (insn, 1);
-             if (GET_CODE (insn) == NOTE)
+             if (NOTE_P (insn))
                {
                  update_eliminable_offsets ();
                  continue;
@@ -3887,7 +3897,7 @@ reload_as_needed (int live_known)
          /* There may have been CLOBBER insns placed after INSN.  So scan
             between INSN and NEXT and use them to forget old reloads.  */
          for (x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x))
-           if (GET_CODE (x) == INSN && GET_CODE (PATTERN (x)) == CLOBBER)
+           if (NONJUMP_INSN_P (x) && GET_CODE (PATTERN (x)) == CLOBBER)
              note_stores (PATTERN (x), forget_old_reloads_1, NULL);
 
 #ifdef AUTO_INC_DEC
@@ -3932,8 +3942,9 @@ reload_as_needed (int live_known)
                          if (n == 1)
                            {
                              n = validate_replace_rtx (reload_reg,
-                                                       gen_rtx (code, mode,
-                                                                reload_reg),
+                                                       gen_rtx_fmt_e (code,
+                                                                      mode,
+                                                                      reload_reg),
                                                        p);
 
                              /* We must also verify that the constraints
@@ -3948,8 +3959,9 @@ reload_as_needed (int live_known)
                                 undo the replacement.  */
                              if (!n)
                                {
-                                 validate_replace_rtx (gen_rtx (code, mode,
-                                                                reload_reg),
+                                 validate_replace_rtx (gen_rtx_fmt_e (code,
+                                                                      mode,
+                                                                      reload_reg),
                                                        reload_reg, p);
                                  break;
                                }
@@ -4006,13 +4018,17 @@ reload_as_needed (int live_known)
 #endif
        }
       /* A reload reg's contents are unknown after a label.  */
-      if (GET_CODE (insn) == CODE_LABEL)
+      if (LABEL_P (insn))
        CLEAR_HARD_REG_SET (reg_reloaded_valid);
 
       /* Don't assume a reload reg is still good after a call insn
-        if it is a call-used reg.  */
-      else if (GET_CODE (insn) == CALL_INSN)
+        if it is a call-used reg, or if it contains a value that will
+         be partially clobbered by the call.  */
+      else if (CALL_P (insn))
+       {
        AND_COMPL_HARD_REG_SET (reg_reloaded_valid, call_used_reg_set);
+       AND_COMPL_HARD_REG_SET (reg_reloaded_valid, reg_reloaded_call_part_clobbered);
+       }
     }
 
   /* Clean up.  */
@@ -4044,7 +4060,7 @@ forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
       x = SUBREG_REG (x);
     }
 
-  if (GET_CODE (x) != REG)
+  if (!REG_P (x))
     return;
 
   regno = REGNO (x);
@@ -4055,7 +4071,7 @@ forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
     {
       unsigned int i;
 
-      nr = HARD_REGNO_NREGS (regno, GET_MODE (x));
+      nr = hard_regno_nregs[regno][GET_MODE (x)];
       /* Storing into a spilled-reg invalidates its contents.
         This can happen if a block-local pseudo is allocated to that reg
         and it wasn't spilled because this block's total need is 0.
@@ -4067,6 +4083,7 @@ forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
            || ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
          {
            CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
+           CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, regno + i);
            spill_reg_store[regno + i] = 0;
          }
     }
@@ -4128,7 +4145,7 @@ static void
 mark_reload_reg_in_use (unsigned int regno, int opnum, enum reload_type type,
                        enum machine_mode mode)
 {
-  unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
+  unsigned int nregs = hard_regno_nregs[regno][mode];
   unsigned int i;
 
   for (i = regno; i < nregs + regno; i++)
@@ -4190,7 +4207,7 @@ static void
 clear_reload_reg_in_use (unsigned int regno, int opnum,
                         enum reload_type type, enum machine_mode mode)
 {
-  unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
+  unsigned int nregs = hard_regno_nregs[regno][mode];
   unsigned int start_regno, end_regno, r;
   int i;
   /* A complication is that for some reload types, inheritance might
@@ -4274,7 +4291,7 @@ clear_reload_reg_in_use (unsigned int regno, int opnum,
              unsigned int conflict_start = true_regnum (rld[i].reg_rtx);
              unsigned int conflict_end
                = (conflict_start
-                  + HARD_REGNO_NREGS (conflict_start, rld[i].mode));
+                  + hard_regno_nregs[conflict_start][rld[i].mode]);
 
              /* If there is an overlap with the first to-be-freed register,
                 adjust the interval start.  */
@@ -4311,6 +4328,7 @@ reload_reg_free_p (unsigned int regno, int opnum, enum reload_type type)
       /* In use for anything means we can't use it for RELOAD_OTHER.  */
       if (TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno)
          || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
+         || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
          || TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
        return 0;
 
@@ -4489,6 +4507,7 @@ reload_reg_reaches_end_p (unsigned int regno, int opnum, enum reload_type type)
          return 0;
 
       return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
+             && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
              && ! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
              && ! TEST_HARD_REG_BIT (reload_reg_used, regno));
 
@@ -4765,9 +4784,9 @@ reload_reg_free_for_value_p (int start_regno, int regno, int opnum,
   for (i = 0; i < n_reloads; i++)
     {
       rtx reg = rld[i].reg_rtx;
-      if (reg && GET_CODE (reg) == REG
+      if (reg && REG_P (reg)
          && ((unsigned) regno - true_regnum (reg)
-             <= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - (unsigned) 1)
+             <= hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] - (unsigned) 1)
          && i != reloadnum)
        {
          rtx other_input = rld[i].in;
@@ -4923,7 +4942,7 @@ free_for_value_p (int regno, enum machine_mode mode, int opnum,
                  enum reload_type type, rtx value, rtx out, int reloadnum,
                  int ignore_address_reloads)
 {
-  int nregs = HARD_REGNO_NREGS (regno, mode);
+  int nregs = hard_regno_nregs[regno][mode];
   while (nregs-- > 0)
     if (! reload_reg_free_for_value_p (regno, regno + nregs, opnum, type,
                                       value, out, reloadnum,
@@ -4932,6 +4951,27 @@ free_for_value_p (int regno, enum machine_mode mode, int opnum,
   return 1;
 }
 
+/* Return nonzero if the rtx X is invariant over the current function.  */
+/* ??? Actually, the places where we use this expect exactly what
+ * is tested here, and not everything that is function invariant.  In
+ * particular, the frame pointer and arg pointer are special cased;
+ * pic_offset_table_rtx is not, and this will cause aborts when we
+ *             go to spill these things to memory.  */
+
+static int
+function_invariant_p (rtx x)
+{
+  if (CONSTANT_P (x))
+    return 1;
+  if (x == frame_pointer_rtx || x == arg_pointer_rtx)
+    return 1;
+  if (GET_CODE (x) == PLUS
+      && (XEXP (x, 0) == frame_pointer_rtx || XEXP (x, 0) == arg_pointer_rtx)
+      && CONSTANT_P (XEXP (x, 1)))
+    return 1;
+  return 0;
+}
+
 /* Determine whether the reload reg X overlaps any rtx'es used for
    overriding inheritance.  Return nonzero if so.  */
 
@@ -5096,7 +5136,7 @@ allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
                      && ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
                                              regnum))))
            {
-             int nr = HARD_REGNO_NREGS (regnum, rld[r].mode);
+             int nr = hard_regno_nregs[regnum][rld[r].mode];
              /* Avoid the problem where spilling a GENERAL_OR_FP_REG
                 (on 68000) got us two FP regs.  If NR is 1,
                 we would reject both of them.  */
@@ -5289,7 +5329,7 @@ choose_reload_regs (struct insn_chain *chain)
          if (rld[r].in != 0 && rld[r].reg_rtx != 0
              && (rtx_equal_p (rld[r].in, rld[r].reg_rtx)
                  || (rtx_equal_p (rld[r].out, rld[r].reg_rtx)
-                     && GET_CODE (rld[r].in) != MEM
+                     && !MEM_P (rld[r].in)
                      && true_regnum (rld[r].in) < FIRST_PSEUDO_REGISTER)))
            continue;
 
@@ -5331,18 +5371,18 @@ choose_reload_regs (struct insn_chain *chain)
 
              if (rld[r].in == 0)
                ;
-             else if (GET_CODE (rld[r].in) == REG)
+             else if (REG_P (rld[r].in))
                {
                  regno = REGNO (rld[r].in);
                  mode = GET_MODE (rld[r].in);
                }
-             else if (GET_CODE (rld[r].in_reg) == REG)
+             else if (REG_P (rld[r].in_reg))
                {
                  regno = REGNO (rld[r].in_reg);
                  mode = GET_MODE (rld[r].in_reg);
                }
              else if (GET_CODE (rld[r].in_reg) == SUBREG
-                      && GET_CODE (SUBREG_REG (rld[r].in_reg)) == REG)
+                      && REG_P (SUBREG_REG (rld[r].in_reg)))
                {
                  byte = SUBREG_BYTE (rld[r].in_reg);
                  regno = REGNO (SUBREG_REG (rld[r].in_reg));
@@ -5355,7 +5395,7 @@ choose_reload_regs (struct insn_chain *chain)
                        || GET_CODE (rld[r].in_reg) == PRE_DEC
                        || GET_CODE (rld[r].in_reg) == POST_INC
                        || GET_CODE (rld[r].in_reg) == POST_DEC)
-                      && GET_CODE (XEXP (rld[r].in_reg, 0)) == REG)
+                      && REG_P (XEXP (rld[r].in_reg, 0)))
                {
                  regno = REGNO (XEXP (rld[r].in_reg, 0));
                  mode = GET_MODE (XEXP (rld[r].in_reg, 0));
@@ -5367,7 +5407,7 @@ choose_reload_regs (struct insn_chain *chain)
                 Also, it takes much more hair to keep track of all the things
                 that can invalidate an inherited reload of part of a pseudoreg.  */
              else if (GET_CODE (rld[r].in) == SUBREG
-                      && GET_CODE (SUBREG_REG (rld[r].in)) == REG)
+                      && REG_P (SUBREG_REG (rld[r].in)))
                regno = subreg_regno (rld[r].in);
 #endif
 
@@ -5429,7 +5469,7 @@ choose_reload_regs (struct insn_chain *chain)
                    {
                      /* If a group is needed, verify that all the subsequent
                         registers still have their values intact.  */
-                     int nr = HARD_REGNO_NREGS (i, rld[r].mode);
+                     int nr = hard_regno_nregs[i][rld[r].mode];
                      int k;
 
                      for (k = 1; k < nr; k++)
@@ -5526,8 +5566,8 @@ choose_reload_regs (struct insn_chain *chain)
              && rld[r].out == 0
              && (CONSTANT_P (rld[r].in)
                  || GET_CODE (rld[r].in) == PLUS
-                 || GET_CODE (rld[r].in) == REG
-                 || GET_CODE (rld[r].in) == MEM)
+                 || REG_P (rld[r].in)
+                 || MEM_P (rld[r].in))
              && (rld[r].nregs == max_group_size
                  || ! reg_classes_intersect_p (rld[r].class, group_class)))
            search_equiv = rld[r].in;
@@ -5552,7 +5592,7 @@ choose_reload_regs (struct insn_chain *chain)
 
              if (equiv != 0)
                {
-                 if (GET_CODE (equiv) == REG)
+                 if (REG_P (equiv))
                    regno = REGNO (equiv);
                  else if (GET_CODE (equiv) == SUBREG)
                    {
@@ -5662,7 +5702,7 @@ choose_reload_regs (struct insn_chain *chain)
                  && (regno != HARD_FRAME_POINTER_REGNUM
                      || !frame_pointer_needed))
                {
-                 int nr = HARD_REGNO_NREGS (regno, rld[r].mode);
+                 int nr = hard_regno_nregs[regno][rld[r].mode];
                  int k;
                  rld[r].reg_rtx = equiv;
                  reload_inherited[r] = 1;
@@ -5801,7 +5841,7 @@ choose_reload_regs (struct insn_chain *chain)
          if (reload_inherited[r] && rld[r].reg_rtx)
            check_reg = rld[r].reg_rtx;
          else if (reload_override_in[r]
-                  && (GET_CODE (reload_override_in[r]) == REG
+                  && (REG_P (reload_override_in[r])
                       || GET_CODE (reload_override_in[r]) == SUBREG))
            check_reg = reload_override_in[r];
          else
@@ -5870,21 +5910,21 @@ choose_reload_regs (struct insn_chain *chain)
       /* I is nonneg if this reload uses a register.
         If rld[r].reg_rtx is 0, this is an optional reload
         that we opted to ignore.  */
-      if (rld[r].out_reg != 0 && GET_CODE (rld[r].out_reg) == REG
+      if (rld[r].out_reg != 0 && REG_P (rld[r].out_reg)
          && rld[r].reg_rtx != 0)
        {
          int nregno = REGNO (rld[r].out_reg);
          int nr = 1;
 
          if (nregno < FIRST_PSEUDO_REGISTER)
-           nr = HARD_REGNO_NREGS (nregno, rld[r].mode);
+           nr = hard_regno_nregs[nregno][rld[r].mode];
 
          while (--nr >= 0)
            reg_has_output_reload[nregno + nr] = 1;
 
          if (i >= 0)
            {
-             nr = HARD_REGNO_NREGS (i, rld[r].mode);
+             nr = hard_regno_nregs[i][rld[r].mode];
              while (--nr >= 0)
                SET_HARD_REG_BIT (reg_is_output_reload, i + nr);
            }
@@ -6140,8 +6180,8 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
      because we will use this equiv reg right away.  */
 
   if (oldequiv == 0 && optimize
-      && (GET_CODE (old) == MEM
-         || (GET_CODE (old) == REG
+      && (MEM_P (old)
+         || (REG_P (old)
              && REGNO (old) >= FIRST_PSEUDO_REGISTER
              && reg_renumber[REGNO (old)] < 0)))
     oldequiv = find_equiv_reg (old, insn, ALL_REGS, -1, NULL, 0, mode);
@@ -6186,14 +6226,14 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
      find the pseudo in RELOAD_IN_REG.  */
   if (oldequiv == 0
       && reload_override_in[j]
-      && GET_CODE (rl->in_reg) == REG)
+      && REG_P (rl->in_reg))
     {
       oldequiv = old;
       old = rl->in_reg;
     }
   if (oldequiv == 0)
     oldequiv = old;
-  else if (GET_CODE (oldequiv) == REG)
+  else if (REG_P (oldequiv))
     oldequiv_reg = oldequiv;
   else if (GET_CODE (oldequiv) == SUBREG)
     oldequiv_reg = SUBREG_REG (oldequiv);
@@ -6202,10 +6242,10 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
      with an output-reload, see if we can prove there was
      actually no need to store the old value in it.  */
 
-  if (optimize && GET_CODE (oldequiv) == REG
+  if (optimize && REG_P (oldequiv)
       && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
       && spill_reg_store[REGNO (oldequiv)]
-      && GET_CODE (old) == REG
+      && REG_P (old)
       && (dead_or_set_p (insn, spill_reg_stored_to[REGNO (oldequiv)])
          || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
                          rl->out_reg)))
@@ -6275,10 +6315,10 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
 
       old = XEXP (rl->in_reg, 0);
 
-      if (optimize && GET_CODE (oldequiv) == REG
+      if (optimize && REG_P (oldequiv)
          && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
          && spill_reg_store[REGNO (oldequiv)]
-         && GET_CODE (old) == REG
+         && REG_P (old)
          && (dead_or_set_p (insn,
                             spill_reg_stored_to[REGNO (oldequiv)])
              || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
@@ -6297,7 +6337,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
      insn, see if we can get rid of that pseudo-register entirely
      by redirecting the previous insn into our reload register.  */
 
-  else if (optimize && GET_CODE (old) == REG
+  else if (optimize && REG_P (old)
           && REGNO (old) >= FIRST_PSEUDO_REGISTER
           && dead_or_set_p (insn, old)
           /* This is unsafe if some other reload
@@ -6307,10 +6347,10 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
                                rl->when_needed, old, rl->out, j, 0))
     {
       rtx temp = PREV_INSN (insn);
-      while (temp && GET_CODE (temp) == NOTE)
+      while (temp && NOTE_P (temp))
        temp = PREV_INSN (temp);
       if (temp
-         && GET_CODE (temp) == INSN
+         && NONJUMP_INSN_P (temp)
          && GET_CODE (PATTERN (temp)) == SET
          && SET_DEST (PATTERN (temp)) == old
          /* Make sure we can access insn_operand_constraint.  */
@@ -6331,7 +6371,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
                 a reload register, and its spill_reg_store entry will
                 contain the previous destination.  This is now
                 invalid.  */
-             if (GET_CODE (SET_SRC (PATTERN (temp))) == REG
+             if (REG_P (SET_SRC (PATTERN (temp)))
                  && REGNO (SET_SRC (PATTERN (temp))) < FIRST_PSEUDO_REGISTER)
                {
                  spill_reg_store[REGNO (SET_SRC (PATTERN (temp)))] = 0;
@@ -6394,7 +6434,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
       tmp = oldequiv;
       if (GET_CODE (tmp) == SUBREG)
        tmp = SUBREG_REG (tmp);
-      if (GET_CODE (tmp) == REG
+      if (REG_P (tmp)
          && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
          && (reg_equiv_memory_loc[REGNO (tmp)] != 0
              || reg_equiv_constant[REGNO (tmp)] != 0))
@@ -6410,7 +6450,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
       tmp = old;
       if (GET_CODE (tmp) == SUBREG)
        tmp = SUBREG_REG (tmp);
-      if (GET_CODE (tmp) == REG
+      if (REG_P (tmp)
          && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
          && (reg_equiv_memory_loc[REGNO (tmp)] != 0
              || reg_equiv_constant[REGNO (tmp)] != 0))
@@ -6520,12 +6560,12 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
     {
       rtx real_oldequiv = oldequiv;
 
-      if ((GET_CODE (oldequiv) == REG
+      if ((REG_P (oldequiv)
           && REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER
           && (reg_equiv_memory_loc[REGNO (oldequiv)] != 0
               || reg_equiv_constant[REGNO (oldequiv)] != 0))
          || (GET_CODE (oldequiv) == SUBREG
-             && GET_CODE (SUBREG_REG (oldequiv)) == REG
+             && REG_P (SUBREG_REG (oldequiv))
              && (REGNO (SUBREG_REG (oldequiv))
                  >= FIRST_PSEUDO_REGISTER)
              && ((reg_equiv_memory_loc
@@ -6600,7 +6640,7 @@ emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
     {
       rtx real_old = old;
 
-      if (GET_CODE (old) == REG && REGNO (old) >= FIRST_PSEUDO_REGISTER
+      if (REG_P (old) && REGNO (old) >= FIRST_PSEUDO_REGISTER
          && reg_equiv_mem[REGNO (old)] != 0)
        real_old = reg_equiv_mem[REGNO (old)];
 
@@ -6678,7 +6718,7 @@ emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
       /* Don't output the last reload if OLD is not the dest of
         INSN and is in the src and is clobbered by INSN.  */
       if (! flag_expensive_optimizations
-         || GET_CODE (old) != REG
+         || !REG_P (old)
          || !(set = single_set (insn))
          || rtx_equal_p (old, SET_DEST (set))
          || !reg_mentioned_p (old, SET_SRC (set))
@@ -6772,7 +6812,7 @@ static void
 do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
 {
   rtx insn = chain->insn;
-  rtx old = (rl->in && GET_CODE (rl->in) == MEM
+  rtx old = (rl->in && MEM_P (rl->in)
             ? rl->in_reg : rl->in);
 
   if (old != 0
@@ -6787,8 +6827,8 @@ do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
      e.g. inheriting a SImode output reload for
      (mem:HI (plus:SI (reg:SI 14 fp) (const_int 10)))  */
   if (optimize && reload_inherited[j] && rl->in
-      && GET_CODE (rl->in) == MEM
-      && GET_CODE (rl->in_reg) == MEM
+      && MEM_P (rl->in)
+      && MEM_P (rl->in_reg)
       && reload_spill_index[j] >= 0
       && TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j]))
     rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]];
@@ -6800,7 +6840,7 @@ do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
   if (optimize
       && (reload_inherited[j] || reload_override_in[j])
       && rl->reg_rtx
-      && GET_CODE (rl->reg_rtx) == REG
+      && REG_P (rl->reg_rtx)
       && spill_reg_store[REGNO (rl->reg_rtx)] != 0
 #if 0
       /* There doesn't seem to be any reason to restrict this to pseudos
@@ -6835,7 +6875,7 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
 
   if (pseudo
       && optimize
-      && GET_CODE (pseudo) == REG
+      && REG_P (pseudo)
       && ! rtx_equal_p (rl->in_reg, pseudo)
       && REGNO (pseudo) >= FIRST_PSEUDO_REGISTER
       && reg_last_reload_reg[REGNO (pseudo)])
@@ -6862,7 +6902,7 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
   /* An output operand that dies right away does need a reload,
      but need not be copied from it.  Show the new location in the
      REG_UNUSED note.  */
-  if ((GET_CODE (old) == REG || GET_CODE (old) == SCRATCH)
+  if ((REG_P (old) || GET_CODE (old) == SCRATCH)
       && (note = find_reg_note (insn, REG_UNUSED, old)) != 0)
     {
       XEXP (note, 0) = rl->reg_rtx;
@@ -6870,7 +6910,7 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
     }
   /* Likewise for a SUBREG of an operand that dies.  */
   else if (GET_CODE (old) == SUBREG
-          && GET_CODE (SUBREG_REG (old)) == REG
+          && REG_P (SUBREG_REG (old))
           && 0 != (note = find_reg_note (insn, REG_UNUSED,
                                          SUBREG_REG (old))))
     {
@@ -6884,12 +6924,33 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
     return;
 
   /* If is a JUMP_INSN, we can't support output reloads yet.  */
-  if (GET_CODE (insn) == JUMP_INSN)
+  if (JUMP_P (insn))
     abort ();
 
   emit_output_reload_insns (chain, rld + j, j);
 }
 
+/* Reload number R reloads from or to a group of hard registers starting at
+   register REGNO.  Return true if it can be treated for inheritance purposes
+   like a group of reloads, each one reloading a single hard register.
+   The caller has already checked that the spill register and REGNO use
+   the same number of registers to store the reload value.  */
+
+static bool
+inherit_piecemeal_p (int r ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED)
+{
+#ifdef CANNOT_CHANGE_MODE_CLASS
+  return (!REG_CANNOT_CHANGE_MODE_P (reload_spill_index[r],
+                                    GET_MODE (rld[r].reg_rtx),
+                                    reg_raw_mode[reload_spill_index[r]])
+         && !REG_CANNOT_CHANGE_MODE_P (regno,
+                                       GET_MODE (rld[r].reg_rtx),
+                                       reg_raw_mode[regno]));
+#else
+  return true;
+#endif
+}
+
 /* Output insns to reload values in and out of the chosen reload regs.  */
 
 static void
@@ -6913,10 +6974,10 @@ emit_reload_insns (struct insn_chain *chain)
   other_operand_reload_insns = 0;
 
   /* Dump reloads into the dump file.  */
-  if (rtl_dump_file)
+  if (dump_file)
     {
-      fprintf (rtl_dump_file, "\nReloads for insn # %d\n", INSN_UID (insn));
-      debug_reload_to_stream (rtl_dump_file);
+      fprintf (dump_file, "\nReloads for insn # %d\n", INSN_UID (insn));
+      debug_reload_to_stream (dump_file);
     }
 
   /* Now output the instructions to copy the data into and out of the
@@ -6958,25 +7019,25 @@ emit_reload_insns (struct insn_chain *chain)
      reloads for the operand.  The RELOAD_OTHER output reloads are
      output in descending order by reload number.  */
 
-  emit_insn_before (other_input_address_reload_insns, insn);
-  emit_insn_before (other_input_reload_insns, insn);
+  emit_insn_before_sameloc (other_input_address_reload_insns, insn);
+  emit_insn_before_sameloc (other_input_reload_insns, insn);
 
   for (j = 0; j < reload_n_operands; j++)
     {
-      emit_insn_before (inpaddr_address_reload_insns[j], insn);
-      emit_insn_before (input_address_reload_insns[j], insn);
-      emit_insn_before (input_reload_insns[j], insn);
+      emit_insn_before_sameloc (inpaddr_address_reload_insns[j], insn);
+      emit_insn_before_sameloc (input_address_reload_insns[j], insn);
+      emit_insn_before_sameloc (input_reload_insns[j], insn);
     }
 
-  emit_insn_before (other_operand_reload_insns, insn);
-  emit_insn_before (operand_reload_insns, insn);
+  emit_insn_before_sameloc (other_operand_reload_insns, insn);
+  emit_insn_before_sameloc (operand_reload_insns, insn);
 
   for (j = 0; j < reload_n_operands; j++)
     {
-      rtx x = emit_insn_after (outaddr_address_reload_insns[j], insn);
-      x = emit_insn_after (output_address_reload_insns[j], x);
-      x = emit_insn_after (output_reload_insns[j], x);
-      emit_insn_after (other_output_reload_insns[j], x);
+      rtx x = emit_insn_after_sameloc (outaddr_address_reload_insns[j], insn);
+      x = emit_insn_after_sameloc (output_address_reload_insns[j], x);
+      x = emit_insn_after_sameloc (output_reload_insns[j], x);
+      emit_insn_after_sameloc (other_output_reload_insns[j], x);
     }
 
   /* For all the spill regs newly reloaded in this instruction,
@@ -7003,7 +7064,7 @@ emit_reload_insns (struct insn_chain *chain)
          if (GET_CODE (reg) == SUBREG)
            reg = SUBREG_REG (reg);
 
-         if (GET_CODE (reg) == REG
+         if (REG_P (reg)
              && REGNO (reg) >= FIRST_PSEUDO_REGISTER
              && ! reg_has_output_reload[REGNO (reg)])
            {
@@ -7025,7 +7086,7 @@ emit_reload_insns (struct insn_chain *chain)
 
       if (i >= 0 && rld[r].reg_rtx != 0)
        {
-         int nr = HARD_REGNO_NREGS (i, GET_MODE (rld[r].reg_rtx));
+         int nr = hard_regno_nregs[i][GET_MODE (rld[r].reg_rtx)];
          int k;
          int part_reaches_end = 0;
          int all_reaches_end = 1;
@@ -7049,30 +7110,38 @@ emit_reload_insns (struct insn_chain *chain)
                 If consecutive registers are used, clear them all.  */
 
              for (k = 0; k < nr; k++)
+               {
                CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
+                 CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
+               }
 
              /* Maybe the spill reg contains a copy of reload_out.  */
              if (rld[r].out != 0
-                 && (GET_CODE (rld[r].out) == REG
+                 && (REG_P (rld[r].out)
 #ifdef AUTO_INC_DEC
                      || ! rld[r].out_reg
 #endif
-                     || GET_CODE (rld[r].out_reg) == REG))
+                     || REG_P (rld[r].out_reg)))
                {
-                 rtx out = (GET_CODE (rld[r].out) == REG
+                 rtx out = (REG_P (rld[r].out)
                             ? rld[r].out
                             : rld[r].out_reg
                             ? rld[r].out_reg
 /* AUTO_INC */              : XEXP (rld[r].in_reg, 0));
                  int nregno = REGNO (out);
                  int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
-                            : HARD_REGNO_NREGS (nregno,
-                                                GET_MODE (rld[r].reg_rtx)));
+                            : hard_regno_nregs[nregno]
+                                              [GET_MODE (rld[r].reg_rtx)]);
+                 bool piecemeal;
 
                  spill_reg_store[i] = new_spill_reg_store[i];
                  spill_reg_stored_to[i] = out;
                  reg_last_reload_reg[nregno] = rld[r].reg_rtx;
 
+                 piecemeal = (nregno < FIRST_PSEUDO_REGISTER
+                              && nr == nnr
+                              && inherit_piecemeal_p (r, nregno));
+
                  /* If NREGNO is a hard register, it may occupy more than
                     one register.  If it does, say what is in the
                     rest of the registers assuming that both registers
@@ -7082,7 +7151,7 @@ emit_reload_insns (struct insn_chain *chain)
                  if (nregno < FIRST_PSEUDO_REGISTER)
                    for (k = 1; k < nnr; k++)
                      reg_last_reload_reg[nregno + k]
-                       = (nr == nnr
+                       = (piecemeal
                           ? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k]
                           : 0);
 
@@ -7091,11 +7160,13 @@ emit_reload_insns (struct insn_chain *chain)
                    {
                      CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
                      reg_reloaded_contents[i + k]
-                       = (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr
+                       = (nregno >= FIRST_PSEUDO_REGISTER || !piecemeal
                           ? nregno
                           : nregno + k);
                      reg_reloaded_insn[i + k] = insn;
                      SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
+                     if (HARD_REGNO_CALL_PART_CLOBBERED (i + k, GET_MODE (out)))
+                       SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
                    }
                }
 
@@ -7104,34 +7175,41 @@ emit_reload_insns (struct insn_chain *chain)
                 the register being reloaded.  */
              else if (rld[r].out_reg == 0
                       && rld[r].in != 0
-                      && ((GET_CODE (rld[r].in) == REG
+                      && ((REG_P (rld[r].in)
                            && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER
                            && ! reg_has_output_reload[REGNO (rld[r].in)])
-                          || (GET_CODE (rld[r].in_reg) == REG
+                          || (REG_P (rld[r].in_reg)
                               && ! reg_has_output_reload[REGNO (rld[r].in_reg)]))
                       && ! reg_set_p (rld[r].reg_rtx, PATTERN (insn)))
                {
                  int nregno;
                  int nnr;
+                 rtx in;
+                 bool piecemeal;
 
-                 if (GET_CODE (rld[r].in) == REG
+                 if (REG_P (rld[r].in)
                      && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER)
-                   nregno = REGNO (rld[r].in);
-                 else if (GET_CODE (rld[r].in_reg) == REG)
-                   nregno = REGNO (rld[r].in_reg);
+                   in = rld[r].in;
+                 else if (REG_P (rld[r].in_reg))
+                   in = rld[r].in_reg;
                  else
-                   nregno = REGNO (XEXP (rld[r].in_reg, 0));
+                   in = XEXP (rld[r].in_reg, 0);
+                 nregno = REGNO (in);
 
                  nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
-                        : HARD_REGNO_NREGS (nregno,
-                                            GET_MODE (rld[r].reg_rtx)));
+                        : hard_regno_nregs[nregno]
+                                          [GET_MODE (rld[r].reg_rtx)]);
 
                  reg_last_reload_reg[nregno] = rld[r].reg_rtx;
 
+                 piecemeal = (nregno < FIRST_PSEUDO_REGISTER
+                              && nr == nnr
+                              && inherit_piecemeal_p (r, nregno));
+
                  if (nregno < FIRST_PSEUDO_REGISTER)
                    for (k = 1; k < nnr; k++)
                      reg_last_reload_reg[nregno + k]
-                       = (nr == nnr
+                       = (piecemeal
                           ? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k]
                           : 0);
 
@@ -7147,11 +7225,13 @@ emit_reload_insns (struct insn_chain *chain)
                    {
                      CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
                      reg_reloaded_contents[i + k]
-                       = (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr
+                       = (nregno >= FIRST_PSEUDO_REGISTER || !piecemeal
                           ? nregno
                           : nregno + k);
                      reg_reloaded_insn[i + k] = insn;
                      SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
+                     if (HARD_REGNO_CALL_PART_CLOBBERED (i + k, GET_MODE (in)))
+                       SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
                    }
                }
            }
@@ -7177,11 +7257,11 @@ emit_reload_insns (struct insn_chain *chain)
         But forget_old_reloads_1 won't get to see it, because
         it thinks only about the original insn.  So invalidate it here.  */
       if (i < 0 && rld[r].out != 0
-         && (GET_CODE (rld[r].out) == REG
-             || (GET_CODE (rld[r].out) == MEM
-                 && GET_CODE (rld[r].out_reg) == REG)))
+         && (REG_P (rld[r].out)
+             || (MEM_P (rld[r].out)
+                 && REG_P (rld[r].out_reg))))
        {
-         rtx out = (GET_CODE (rld[r].out) == REG
+         rtx out = (REG_P (rld[r].out)
                     ? rld[r].out : rld[r].out_reg);
          int nregno = REGNO (out);
          if (nregno >= FIRST_PSEUDO_REGISTER)
@@ -7218,11 +7298,11 @@ emit_reload_insns (struct insn_chain *chain)
                }
              else
                store_insn = new_spill_reg_store[REGNO (src_reg)];
-             if (src_reg && GET_CODE (src_reg) == REG
+             if (src_reg && REG_P (src_reg)
                  && REGNO (src_reg) < FIRST_PSEUDO_REGISTER)
                {
                  int src_regno = REGNO (src_reg);
-                 int nr = HARD_REGNO_NREGS (src_regno, rld[r].mode);
+                 int nr = hard_regno_nregs[src_regno][rld[r].mode];
                  /* The place where to find a death note varies with
                     PRESERVE_DEATH_INFO_REGNO_P .  The condition is not
                     necessarily checked exactly in the code that moves
@@ -7238,6 +7318,10 @@ emit_reload_insns (struct insn_chain *chain)
                      reg_reloaded_insn[src_regno + nr] = store_insn;
                      CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + nr);
                      SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + nr);
+                     if (HARD_REGNO_CALL_PART_CLOBBERED (src_regno + nr, 
+                                                         GET_MODE (src_reg)))
+                       SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, 
+                                         src_regno + nr);
                      SET_HARD_REG_BIT (reg_is_output_reload, src_regno + nr);
                      if (note)
                        SET_HARD_REG_BIT (reg_reloaded_died, src_regno);
@@ -7245,11 +7329,15 @@ emit_reload_insns (struct insn_chain *chain)
                        CLEAR_HARD_REG_BIT (reg_reloaded_died, src_regno);
                    }
                  reg_last_reload_reg[nregno] = src_reg;
+                 /* We have to set reg_has_output_reload here, or else 
+                    forget_old_reloads_1 will clear reg_last_reload_reg
+                    right away.  */
+                 reg_has_output_reload[nregno] = 1;
                }
            }
          else
            {
-             int num_regs = HARD_REGNO_NREGS (nregno, GET_MODE (rld[r].out));
+             int num_regs = hard_regno_nregs[nregno][GET_MODE (rld[r].out)];
 
              while (num_regs-- > 0)
                reg_last_reload_reg[nregno + num_regs] = 0;
@@ -7311,13 +7399,13 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
      ??? At some point, this whole thing needs to be rethought.  */
 
   if (GET_CODE (in) == PLUS
-      && (GET_CODE (XEXP (in, 0)) == REG
+      && (REG_P (XEXP (in, 0))
          || GET_CODE (XEXP (in, 0)) == SUBREG
-         || GET_CODE (XEXP (in, 0)) == MEM)
-      && (GET_CODE (XEXP (in, 1)) == REG
+         || MEM_P (XEXP (in, 0)))
+      && (REG_P (XEXP (in, 1))
          || GET_CODE (XEXP (in, 1)) == SUBREG
          || CONSTANT_P (XEXP (in, 1))
-         || GET_CODE (XEXP (in, 1)) == MEM))
+         || MEM_P (XEXP (in, 1))))
     {
       /* We need to compute the sum of a register or a MEM and another
         register, constant, or MEM, and put it into the reload
@@ -7345,7 +7433,7 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
         the case.  If the insn would be A = B + A, rearrange it so
         it will be A = A + B as constrain_operands expects.  */
 
-      if (GET_CODE (XEXP (in, 1)) == REG
+      if (REG_P (XEXP (in, 1))
          && REGNO (out) == REGNO (XEXP (in, 1)))
        tem = op0, op0 = op1, op1 = tem;
 
@@ -7384,8 +7472,8 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
 
       code = (int) add_optab->handlers[(int) GET_MODE (out)].insn_code;
 
-      if (CONSTANT_P (op1) || GET_CODE (op1) == MEM || GET_CODE (op1) == SUBREG
-         || (GET_CODE (op1) == REG
+      if (CONSTANT_P (op1) || MEM_P (op1) || GET_CODE (op1) == SUBREG
+         || (REG_P (op1)
              && REGNO (op1) >= FIRST_PSEUDO_REGISTER)
          || (code != CODE_FOR_nothing
              && ! ((*insn_data[code].operand[2].predicate)
@@ -7432,9 +7520,9 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
 
 #ifdef SECONDARY_MEMORY_NEEDED
   /* If we need a memory location to do the move, do it that way.  */
-  else if ((GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
+  else if ((REG_P (in) || GET_CODE (in) == SUBREG)
           && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
-          && (GET_CODE (out) == REG || GET_CODE (out) == SUBREG)
+          && (REG_P (out) || GET_CODE (out) == SUBREG)
           && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
           && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
                                       REGNO_REG_CLASS (reg_or_subregno (out)),
@@ -7455,7 +7543,7 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
 #endif
 
   /* If IN is a simple operand, use gen_move_insn.  */
-  else if (GET_RTX_CLASS (GET_CODE (in)) == 'o' || GET_CODE (in) == SUBREG)
+  else if (OBJECT_P (in) || GET_CODE (in) == SUBREG)
     emit_insn (gen_move_insn (out, in));
 
 #ifdef HAVE_reload_load_address
@@ -7514,7 +7602,7 @@ delete_output_reload (rtx insn, int j, int last_reload_reg)
       rtx reg2 = rld[k].in;
       if (! reg2)
        continue;
-      if (GET_CODE (reg2) == MEM || reload_override_in[k])
+      if (MEM_P (reg2) || reload_override_in[k])
        reg2 = rld[k].in_reg;
 #ifdef AUTO_INC_DEC
       if (rld[k].out && ! rld[k].out_reg)
@@ -7555,14 +7643,14 @@ delete_output_reload (rtx insn, int j, int last_reload_reg)
   for (i1 = NEXT_INSN (output_reload_insn);
        i1 != insn; i1 = NEXT_INSN (i1))
     {
-      if (GET_CODE (i1) == CODE_LABEL || GET_CODE (i1) == JUMP_INSN)
+      if (LABEL_P (i1) || JUMP_P (i1))
        return;
-      if ((GET_CODE (i1) == INSN || GET_CODE (i1) == CALL_INSN)
+      if ((NONJUMP_INSN_P (i1) || CALL_P (i1))
          && reg_mentioned_p (reg, PATTERN (i1)))
        {
          /* If this is USE in front of INSN, we only have to check that
             there are no more references than accounted for by inheritance.  */
-         while (GET_CODE (i1) == INSN && GET_CODE (PATTERN (i1)) == USE)
+         while (NONJUMP_INSN_P (i1) && GET_CODE (PATTERN (i1)) == USE)
            {
              n_occurrences += rtx_equal_p (reg, XEXP (PATTERN (i1), 0)) != 0;
              i1 = NEXT_INSN (i1);
@@ -7574,7 +7662,7 @@ delete_output_reload (rtx insn, int j, int last_reload_reg)
     }
 
   /* We will be deleting the insn.  Remove the spill reg information.  */
-  for (k = HARD_REGNO_NREGS (last_reload_reg, GET_MODE (reg)); k-- > 0; )
+  for (k = hard_regno_nregs[last_reload_reg][GET_MODE (reg)]; k-- > 0; )
     {
       spill_reg_store[last_reload_reg + k] = 0;
       spill_reg_stored_to[last_reload_reg + k] = 0;
@@ -7608,10 +7696,10 @@ delete_output_reload (rtx insn, int j, int last_reload_reg)
             since if they are the only uses, they are dead.  */
          if (set != 0 && SET_DEST (set) == reg)
            continue;
-         if (GET_CODE (i2) == CODE_LABEL
-             || GET_CODE (i2) == JUMP_INSN)
+         if (LABEL_P (i2)
+             || JUMP_P (i2))
            break;
-         if ((GET_CODE (i2) == INSN || GET_CODE (i2) == CALL_INSN)
+         if ((NONJUMP_INSN_P (i2) || CALL_P (i2))
              && reg_mentioned_p (reg, PATTERN (i2)))
            {
              /* Some other ref remains; just delete the output reload we
@@ -7633,8 +7721,8 @@ delete_output_reload (rtx insn, int j, int last_reload_reg)
              delete_address_reloads (i2, insn);
              delete_insn (i2);
            }
-         if (GET_CODE (i2) == CODE_LABEL
-             || GET_CODE (i2) == JUMP_INSN)
+         if (LABEL_P (i2)
+             || JUMP_P (i2))
            break;
        }
 
@@ -7660,7 +7748,7 @@ delete_address_reloads (rtx dead_insn, rtx current_insn)
   if (set)
     {
       rtx dst = SET_DEST (set);
-      if (GET_CODE (dst) == MEM)
+      if (MEM_P (dst))
        delete_address_reloads_1 (dead_insn, XEXP (dst, 0), current_insn);
     }
   /* If we deleted the store from a reloaded post_{in,de}c expression,
@@ -7722,7 +7810,7 @@ delete_address_reloads_1 (rtx dead_insn, rtx x, rtx current_insn)
       code = GET_CODE (prev);
       if (code == CODE_LABEL || code == JUMP_INSN)
        return;
-      if (GET_RTX_CLASS (code) != 'i')
+      if (!INSN_P (prev))
        continue;
       if (reg_set_p (x, PATTERN (prev)))
        break;
@@ -7736,7 +7824,7 @@ delete_address_reloads_1 (rtx dead_insn, rtx x, rtx current_insn)
   if (! set)
     return;
   dst = SET_DEST (set);
-  if (GET_CODE (dst) != REG
+  if (!REG_P (dst)
       || ! rtx_equal_p (dst, x))
     return;
   if (! reg_set_p (dst, PATTERN (dead_insn)))
@@ -7745,7 +7833,7 @@ delete_address_reloads_1 (rtx dead_insn, rtx x, rtx current_insn)
         it might have been inherited.  */
       for (i2 = NEXT_INSN (dead_insn); i2; i2 = NEXT_INSN (i2))
        {
-         if (GET_CODE (i2) == CODE_LABEL)
+         if (LABEL_P (i2))
            break;
          if (! INSN_P (i2))
            continue;
@@ -7769,7 +7857,7 @@ delete_address_reloads_1 (rtx dead_insn, rtx x, rtx current_insn)
                }
              return;
            }
-         if (GET_CODE (i2) == JUMP_INSN)
+         if (JUMP_P (i2))
            break;
          /* If DST is still live at CURRENT_INSN, check if it is used for
             any reload.  Note that even if CURRENT_INSN sets DST, we still
@@ -7824,7 +7912,7 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
      inc/dec operation.  If REG_LAST_RELOAD_REG were nonzero,
      we could inc/dec that register as well (maybe even using it for
      the source), but I'm not sure it's worth worrying about.  */
-  if (GET_CODE (incloc) == REG)
+  if (REG_P (incloc))
     reg_last_reload_reg[REGNO (incloc)] = 0;
 
   if (GET_CODE (value) == PRE_DEC || GET_CODE (value) == POST_DEC)
@@ -7967,22 +8055,23 @@ fixup_abnormal_edges (void)
              == (EDGE_ABNORMAL | EDGE_EH))
            break;
        }
-      if (e && GET_CODE (bb->end) != CALL_INSN && !can_throw_internal (bb->end))
+      if (e && !CALL_P (BB_END (bb))
+         && !can_throw_internal (BB_END (bb)))
        {
-         rtx insn = bb->end, stop = NEXT_INSN (bb->end);
+         rtx insn = BB_END (bb), stop = NEXT_INSN (BB_END (bb));
          rtx next;
          for (e = bb->succ; e; e = e->succ_next)
            if (e->flags & EDGE_FALLTHRU)
              break;
          /* Get past the new insns generated. Allow notes, as the insns may
             be already deleted.  */
-         while ((GET_CODE (insn) == INSN || GET_CODE (insn) == NOTE)
+         while ((NONJUMP_INSN_P (insn) || NOTE_P (insn))
                 && !can_throw_internal (insn)
-                && insn != bb->head)
+                && insn != BB_HEAD (bb))
            insn = PREV_INSN (insn);
-         if (GET_CODE (insn) != CALL_INSN && !can_throw_internal (insn))
+         if (!CALL_P (insn) && !can_throw_internal (insn))
            abort ();
-         bb->end = insn;
+         BB_END (bb) = insn;
          inserted = true;
          insn = NEXT_INSN (insn);
          while (insn && insn != stop)