OSDN Git Service

* config/arm/arm.c (arm_promote_prototypes): Use TARGET_AAPCS_BASED.
[pf3gnuchains/gcc-fork.git] / gcc / recog.c
index 6206be1..6d6135a 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines used by or related to instruction recognition.
    Copyright (C) 1987, 1988, 1991, 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.
 
@@ -56,10 +56,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #endif
 #endif
 
-static void validate_replace_rtx_1     PARAMS ((rtx *, rtx, rtx, rtx));
-static rtx *find_single_use_1          PARAMS ((rtx, rtx *));
-static void validate_replace_src_1     PARAMS ((rtx *, void *));
-static rtx split_insn                  PARAMS ((rtx));
+static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx);
+static rtx *find_single_use_1 (rtx, rtx *);
+static void validate_replace_src_1 (rtx *, void *);
+static rtx split_insn (rtx);
 
 /* Nonzero means allow operands to be volatile.
    This should be 0 if you are generating rtl, such as if you are calling
@@ -88,18 +88,21 @@ int which_alternative;
 
 int reload_completed;
 
+/* Nonzero after thread_prologue_and_epilogue_insns has run.  */
+int epilogue_completed;
+
 /* Initialize data used by the function `recog'.
    This must be called once in the compilation of a function
    before any insn recognition may be done in the function.  */
 
 void
-init_recog_no_volatile ()
+init_recog_no_volatile (void)
 {
   volatile_ok = 0;
 }
 
 void
-init_recog ()
+init_recog (void)
 {
   volatile_ok = 1;
 }
@@ -114,8 +117,7 @@ init_recog ()
    through this one.  (The only exception is in combine.c.)  */
 
 int
-recog_memoized_1 (insn)
-     rtx insn;
+recog_memoized_1 (rtx insn)
 {
   if (INSN_CODE (insn) < 0)
     INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
@@ -126,8 +128,7 @@ recog_memoized_1 (insn)
    and that the operands mentioned in it are legitimate.  */
 
 int
-check_asm_operands (x)
-     rtx x;
+check_asm_operands (rtx x)
 {
   int noperands;
   rtx *operands;
@@ -149,8 +150,8 @@ check_asm_operands (x)
   if (noperands == 0)
     return 1;
 
-  operands = (rtx *) alloca (noperands * sizeof (rtx));
-  constraints = (const char **) alloca (noperands * sizeof (char *));
+  operands = alloca (noperands * sizeof (rtx));
+  constraints = alloca (noperands * sizeof (char *));
 
   decode_asm_operands (x, operands, NULL, constraints, NULL);
 
@@ -203,11 +204,7 @@ static int num_changes = 0;
    Otherwise, perform the change and return 1.  */
 
 int
-validate_change (object, loc, new, in_group)
-    rtx object;
-    rtx *loc;
-    rtx new;
-    int in_group;
+validate_change (rtx object, rtx *loc, rtx new, int in_group)
 {
   rtx old = *loc;
 
@@ -229,9 +226,7 @@ validate_change (object, loc, new, in_group)
       else
        changes_allocated *= 2;
 
-      changes =
-       (change_t*) xrealloc (changes,
-                             sizeof (change_t) * changes_allocated);
+      changes = xrealloc (changes, sizeof (change_t) * changes_allocated);
     }
 
   changes[num_changes].object = object;
@@ -261,8 +256,7 @@ validate_change (object, loc, new, in_group)
    were valid; i.e. whether INSN can still be recognized.  */
 
 int
-insn_invalid_p (insn)
-     rtx insn;
+insn_invalid_p (rtx insn)
 {
   rtx pat = PATTERN (insn);
   int num_clobbers = 0;
@@ -312,7 +306,7 @@ insn_invalid_p (insn)
 
 /* Return number of changes made and not validated yet.  */
 int
-num_changes_pending ()
+num_changes_pending (void)
 {
   return num_changes;
 }
@@ -321,7 +315,7 @@ num_changes_pending ()
    Return 1 if all changes are valid, zero otherwise.  */
 
 int
-apply_change_group ()
+apply_change_group (void)
 {
   int i;
   rtx last_validated = NULL_RTX;
@@ -339,7 +333,7 @@ apply_change_group ()
     {
       rtx object = changes[i].object;
 
-      /* if there is no object to test or if it is the same as the one we
+      /* If there is no object to test or if it is the same as the one we
          already tested, ignore it.  */
       if (object == 0 || object == last_validated)
        continue;
@@ -422,7 +416,7 @@ apply_change_group ()
 /* Return the number of changes so far in the current group.  */
 
 int
-num_validated_changes ()
+num_validated_changes (void)
 {
   return num_changes;
 }
@@ -430,8 +424,7 @@ num_validated_changes ()
 /* Retract the changes numbered NUM and up.  */
 
 void
-cancel_changes (num)
-     int num;
+cancel_changes (int num)
 {
   int i;
 
@@ -450,9 +443,7 @@ cancel_changes (num)
    validate_change passing OBJECT.  */
 
 static void
-validate_replace_rtx_1 (loc, from, to, object)
-     rtx *loc;
-     rtx from, to, object;
+validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx object)
 {
   int i, j;
   const char *fmt;
@@ -485,16 +476,38 @@ validate_replace_rtx_1 (loc, from, to, object)
       return;
     }
 
-  /* Call ourself recursively to perform the replacements.  */
+  /* Call ourself recursively to perform the replacements.
+     We must not replace inside already replaced expression, otherwise we
+     get infinite recursion for replacements like (reg X)->(subreg (reg X))
+     done by regmove, so we must special case shared ASM_OPERANDS.  */
 
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+  if (GET_CODE (x) == PARALLEL)
     {
-      if (fmt[i] == 'e')
-       validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
-      else if (fmt[i] == 'E')
-       for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-         validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
+      for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
+       {
+         if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
+             && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
+           {
+             /* Verify that operands are really shared.  */
+             if (ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, 0))) !=
+                 ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, j))))
+               abort ();
+             validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
+                                     from, to, object);
+           }
+         else
+           validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object);
+       }
     }
+  else
+    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+      {
+       if (fmt[i] == 'e')
+         validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
+       else if (fmt[i] == 'E')
+         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+           validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
+      }
 
   /* If we didn't substitute, there is nothing more to do.  */
   if (num_changes == prev_changes)
@@ -508,11 +521,11 @@ validate_replace_rtx_1 (loc, from, to, object)
   /* Do changes needed to keep rtx consistent.  Don't do any other
      simplifications, as it is not our job.  */
 
-  if ((GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == 'c')
+  if (SWAPPABLE_OPERANDS_P (x)
       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
     {
       validate_change (object, loc,
-                      gen_rtx_fmt_ee (GET_RTX_CLASS (code) == 'c' ? code
+                      gen_rtx_fmt_ee (COMMUTATIVE_ARITH_P (x) ? code
                                       : swap_condition (code),
                                       GET_MODE (x), XEXP (x, 1),
                                       XEXP (x, 0)), 1);
@@ -633,8 +646,7 @@ validate_replace_rtx_1 (loc, from, to, object)
    if INSN is still valid.  */
 
 int
-validate_replace_rtx_subexp (from, to, insn, loc)
-     rtx from, to, insn, *loc;
+validate_replace_rtx_subexp (rtx from, rtx to, rtx insn, rtx *loc)
 {
   validate_replace_rtx_1 (loc, from, to, insn);
   return apply_change_group ();
@@ -644,8 +656,7 @@ validate_replace_rtx_subexp (from, to, insn, loc)
    changes have been made, validate by seeing if INSN is still valid.  */
 
 int
-validate_replace_rtx (from, to, insn)
-     rtx from, to, insn;
+validate_replace_rtx (rtx from, rtx to, rtx insn)
 {
   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn);
   return apply_change_group ();
@@ -654,8 +665,7 @@ validate_replace_rtx (from, to, insn)
 /* Try replacing every occurrence of FROM in INSN with TO.  */
 
 void
-validate_replace_rtx_group (from, to, insn)
-     rtx from, to, insn;
+validate_replace_rtx_group (rtx from, rtx to, rtx insn)
 {
   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn);
 }
@@ -669,9 +679,7 @@ struct validate_replace_src_data
 };
 
 static void
-validate_replace_src_1 (x, data)
-     rtx *x;
-     void *data;
+validate_replace_src_1 (rtx *x, void *data)
 {
   struct validate_replace_src_data *d
     = (struct validate_replace_src_data *) data;
@@ -683,8 +691,7 @@ validate_replace_src_1 (x, data)
    SET_DESTs.  */
 
 void
-validate_replace_src_group (from, to, insn)
-     rtx from, to, insn;
+validate_replace_src_group (rtx from, rtx to, rtx insn)
 {
   struct validate_replace_src_data d;
 
@@ -693,16 +700,6 @@ validate_replace_src_group (from, to, insn)
   d.insn = insn;
   note_uses (&PATTERN (insn), validate_replace_src_1, &d);
 }
-
-/* Same as validate_replace_src_group, but validate by seeing if
-   INSN is still valid.  */
-int
-validate_replace_src (from, to, insn)
-     rtx from, to, insn;
-{
-  validate_replace_src_group (from, to, insn);
-  return apply_change_group ();
-}
 \f
 #ifdef HAVE_cc0
 /* Return 1 if the insn using CC0 set by INSN does not contain
@@ -710,8 +707,7 @@ validate_replace_src (from, to, insn)
    EQ and NE tests do not count.  */
 
 int
-next_insn_tests_no_inequality (insn)
-     rtx insn;
+next_insn_tests_no_inequality (rtx insn)
 {
   rtx next = next_cc0_user (insn);
 
@@ -724,34 +720,6 @@ next_insn_tests_no_inequality (insn)
           || GET_CODE (next) == CALL_INSN)
          && ! inequality_comparisons_p (PATTERN (next)));
 }
-
-#if 0  /* This is useless since the insn that sets the cc's
-         must be followed immediately by the use of them.  */
-/* Return 1 if the CC value set up by INSN is not used.  */
-
-int
-next_insns_test_no_inequality (insn)
-     rtx insn;
-{
-  rtx next = NEXT_INSN (insn);
-
-  for (; next != 0; next = NEXT_INSN (next))
-    {
-      if (GET_CODE (next) == CODE_LABEL
-         || GET_CODE (next) == BARRIER)
-       return 1;
-      if (GET_CODE (next) == NOTE)
-       continue;
-      if (inequality_comparisons_p (PATTERN (next)))
-       return 0;
-      if (sets_cc0_p (PATTERN (next)) == 1)
-       return 1;
-      if (! reg_mentioned_p (cc0_rtx, PATTERN (next)))
-       return 1;
-    }
-  return 1;
-}
-#endif
 #endif
 \f
 /* This is used by find_single_use to locate an rtx that contains exactly one
@@ -760,9 +728,7 @@ next_insns_test_no_inequality (insn)
    DEST that are being used to totally replace it are not counted.  */
 
 static rtx *
-find_single_use_1 (dest, loc)
-     rtx dest;
-     rtx *loc;
+find_single_use_1 (rtx dest, rtx *loc)
 {
   rtx x = *loc;
   enum rtx_code code = GET_CODE (x);
@@ -873,10 +839,7 @@ find_single_use_1 (dest, loc)
    and last insn referencing DEST.  */
 
 rtx *
-find_single_use (dest, insn, ploc)
-     rtx dest;
-     rtx insn;
-     rtx *ploc;
+find_single_use (rtx dest, rtx insn, rtx *ploc)
 {
   rtx next;
   rtx *result;
@@ -939,9 +902,7 @@ find_single_use (dest, insn, ploc)
    class NO_REGS, see the comment for `register_operand'.  */
 
 int
-general_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+general_operand (rtx op, enum machine_mode mode)
 {
   enum rtx_code code = GET_CODE (op);
 
@@ -996,7 +957,7 @@ general_operand (op, mode)
        return 0;
 
       /* FLOAT_MODE subregs can't be paradoxical.  Combine will occasionally
-        create such rtl, and we must reject it.  */
+        create such rtl, and we must reject it.  */
       if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
          && GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
        return 0;
@@ -1043,9 +1004,7 @@ general_operand (op, mode)
    expressions in the machine description.  */
 
 int
-address_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+address_operand (rtx op, enum machine_mode mode)
 {
   return memory_address_p (mode, op);
 }
@@ -1065,9 +1024,7 @@ address_operand (op, mode)
    it is most consistent to keep this function from accepting them.  */
 
 int
-register_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+register_operand (rtx op, enum machine_mode mode)
 {
   if (GET_MODE (op) != mode && mode != VOIDmode)
     return 0;
@@ -1118,9 +1075,7 @@ register_operand (op, mode)
 /* Return 1 for a register in Pmode; ignore the tested mode.  */
 
 int
-pmode_register_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
+pmode_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
 {
   return register_operand (op, Pmode);
 }
@@ -1129,9 +1084,7 @@ pmode_register_operand (op, mode)
    or a hard register.  */
 
 int
-scratch_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+scratch_operand (rtx op, enum machine_mode mode)
 {
   if (GET_MODE (op) != mode && mode != VOIDmode)
     return 0;
@@ -1147,9 +1100,7 @@ scratch_operand (op, mode)
    expressions in the machine description.  */
 
 int
-immediate_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+immediate_operand (rtx op, enum machine_mode mode)
 {
   /* Don't accept CONST_INT or anything similar
      if the caller wants something floating.  */
@@ -1181,9 +1132,7 @@ immediate_operand (op, mode)
 /* Returns 1 if OP is an operand that is a CONST_INT.  */
 
 int
-const_int_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+const_int_operand (rtx op, enum machine_mode mode)
 {
   if (GET_CODE (op) != CONST_INT)
     return 0;
@@ -1199,9 +1148,7 @@ const_int_operand (op, mode)
    floating-point number.  */
 
 int
-const_double_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+const_double_operand (rtx op, enum machine_mode mode)
 {
   /* Don't accept CONST_INT or anything similar
      if the caller wants something floating.  */
@@ -1218,9 +1165,7 @@ const_double_operand (op, mode)
 /* Return 1 if OP is a general operand that is not an immediate operand.  */
 
 int
-nonimmediate_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+nonimmediate_operand (rtx op, enum machine_mode mode)
 {
   return (general_operand (op, mode) && ! CONSTANT_P (op));
 }
@@ -1228,9 +1173,7 @@ nonimmediate_operand (op, mode)
 /* Return 1 if OP is a register reference or immediate value of mode MODE.  */
 
 int
-nonmemory_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+nonmemory_operand (rtx op, enum machine_mode mode)
 {
   if (CONSTANT_P (op))
     {
@@ -1284,9 +1227,7 @@ nonmemory_operand (op, mode)
    expressions in the machine description.  */
 
 int
-push_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+push_operand (rtx op, enum machine_mode mode)
 {
   unsigned int rounded_size = GET_MODE_SIZE (mode);
 
@@ -1332,9 +1273,7 @@ push_operand (op, mode)
    expressions in the machine description.  */
 
 int
-pop_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+pop_operand (rtx op, enum machine_mode mode)
 {
   if (GET_CODE (op) != MEM)
     return 0;
@@ -1353,9 +1292,7 @@ pop_operand (op, mode)
 /* Return 1 if ADDR is a valid memory address for mode MODE.  */
 
 int
-memory_address_p (mode, addr)
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-     rtx addr;
+memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
 {
   if (GET_CODE (addr) == ADDRESSOF)
     return 1;
@@ -1374,9 +1311,7 @@ memory_address_p (mode, addr)
    expressions in the machine description.  */
 
 int
-memory_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+memory_operand (rtx op, enum machine_mode mode)
 {
   rtx inner;
 
@@ -1399,9 +1334,7 @@ memory_operand (op, mode)
    that is, a memory reference whose address is a general_operand.  */
 
 int
-indirect_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
+indirect_operand (rtx op, enum machine_mode mode)
 {
   /* Before reload, a SUBREG isn't in memory (see memory_operand, above).  */
   if (! reload_completed
@@ -1434,12 +1367,10 @@ indirect_operand (op, mode)
    MATCH_OPERATOR to recognize all the branch insns.  */
 
 int
-comparison_operator (op, mode)
-    rtx op;
-    enum machine_mode mode;
+comparison_operator (rtx op, enum machine_mode mode)
 {
   return ((mode == VOIDmode || GET_MODE (op) == mode)
-         && GET_RTX_CLASS (GET_CODE (op)) == '<');
+         && COMPARISON_P (op));
 }
 \f
 /* If BODY is an insn body that uses ASM_OPERANDS,
@@ -1447,8 +1378,7 @@ comparison_operator (op, mode)
    Otherwise return -1.  */
 
 int
-asm_noperands (body)
-     rtx body;
+asm_noperands (rtx body)
 {
   switch (GET_CODE (body))
     {
@@ -1532,12 +1462,8 @@ asm_noperands (body)
    we don't store that info.  */
 
 const char *
-decode_asm_operands (body, operands, operand_locs, constraints, modes)
-     rtx body;
-     rtx *operands;
-     rtx **operand_locs;
-     const char **constraints;
-     enum machine_mode *modes;
+decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
+                    const char **constraints, enum machine_mode *modes)
 {
   int i;
   int noperands;
@@ -1665,13 +1591,11 @@ decode_asm_operands (body, operands, operand_locs, constraints, modes)
   return template;
 }
 
-/* Check if an asm_operand matches it's constraints.
+/* Check if an asm_operand matches its constraints.
    Return > 0 if ok, = 0 if bad, < 0 if inconclusive.  */
 
 int
-asm_operand_ok (op, constraint)
-     rtx op;
-     const char *constraint;
+asm_operand_ok (rtx op, const char *constraint)
 {
   int result = 0;
 
@@ -1774,7 +1698,7 @@ asm_operand_ok (op, constraint)
              || (GET_CODE (op) == CONST_DOUBLE
                  && GET_MODE (op) == VOIDmode))
            break;
-         /* FALLTHRU */
+         /* Fall through.  */
 
        case 'i':
          if (CONSTANT_P (op)
@@ -1835,6 +1759,7 @@ asm_operand_ok (op, constraint)
 
        case 'X':
          result = 1;
+         break;
 
        case 'g':
          if (general_operand (op, VOIDmode))
@@ -1853,20 +1778,16 @@ asm_operand_ok (op, constraint)
                result = 1;
            }
 #ifdef EXTRA_CONSTRAINT_STR
-         if (EXTRA_CONSTRAINT_STR (op, c, constraint))
+         else if (EXTRA_CONSTRAINT_STR (op, c, constraint))
+           result = 1;
+         else if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
+                  /* Every memory operand can be reloaded to fit.  */
+                  && memory_operand (op, VOIDmode))
+           result = 1;
+         else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint)
+                  /* Every address operand can be reloaded to fit.  */
+                  && address_operand (op, VOIDmode))
            result = 1;
-         if (EXTRA_MEMORY_CONSTRAINT (c, constraint))
-           {
-             /* Every memory operand can be reloaded to fit.  */
-             if (memory_operand (op, VOIDmode))
-               result = 1;
-           }
-         if (EXTRA_ADDRESS_CONSTRAINT (c, constraint))
-           {
-             /* Every address operand can be reloaded to fit.  */
-             if (address_operand (op, VOIDmode))
-               result = 1;
-           }
 #endif
          break;
        }
@@ -1886,8 +1807,7 @@ asm_operand_ok (op, constraint)
    Otherwise, return a null pointer.  */
 
 rtx *
-find_constant_term_loc (p)
-     rtx *p;
+find_constant_term_loc (rtx *p)
 {
   rtx *tem;
   enum rtx_code code = GET_CODE (*p);
@@ -1940,8 +1860,7 @@ find_constant_term_loc (p)
    don't use it before reload.  */
 
 int
-offsettable_memref_p (op)
-     rtx op;
+offsettable_memref_p (rtx op)
 {
   return ((GET_CODE (op) == MEM)
          && offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)));
@@ -1951,8 +1870,7 @@ offsettable_memref_p (op)
    consider pseudo-regs valid as index or base regs.  */
 
 int
-offsettable_nonstrict_memref_p (op)
-     rtx op;
+offsettable_nonstrict_memref_p (rtx op)
 {
   return ((GET_CODE (op) == MEM)
          && offsettable_address_p (0, GET_MODE (op), XEXP (op, 0)));
@@ -1969,16 +1887,13 @@ offsettable_nonstrict_memref_p (op)
    for the sake of use in reload.c.  */
 
 int
-offsettable_address_p (strictp, mode, y)
-     int strictp;
-     enum machine_mode mode;
-     rtx y;
+offsettable_address_p (int strictp, enum machine_mode mode, rtx y)
 {
   enum rtx_code ycode = GET_CODE (y);
   rtx z;
   rtx y1 = y;
   rtx *y2;
-  int (*addressp) PARAMS ((enum machine_mode, rtx)) =
+  int (*addressp) (enum machine_mode, rtx) =
     (strictp ? strict_memory_address_p : memory_address_p);
   unsigned int mode_sz = GET_MODE_SIZE (mode);
 
@@ -2016,7 +1931,7 @@ offsettable_address_p (strictp, mode, y)
       return good;
     }
 
-  if (GET_RTX_CLASS (ycode) == 'a')
+  if (GET_RTX_CLASS (ycode) == RTX_AUTOINC)
     return 0;
 
   /* The offset added here is chosen as the maximum offset that
@@ -2044,8 +1959,7 @@ offsettable_address_p (strictp, mode, y)
    because the amount of the increment depends on the mode.  */
 
 int
-mode_dependent_address_p (addr)
-  rtx addr ATTRIBUTE_UNUSED; /* Maybe used in GO_IF_MODE_DEPENDENT_ADDRESS.  */
+mode_dependent_address_p (rtx addr ATTRIBUTE_UNUSED /* Maybe used in GO_IF_MODE_DEPENDENT_ADDRESS.  */)
 {
   GO_IF_MODE_DEPENDENT_ADDRESS (addr, win);
   return 0;
@@ -2053,59 +1967,32 @@ mode_dependent_address_p (addr)
  win: ATTRIBUTE_UNUSED_LABEL
   return 1;
 }
-
-/* Return 1 if OP is a general operand
-   other than a memory ref with a mode dependent address.  */
-
-int
-mode_independent_operand (op, mode)
-     enum machine_mode mode;
-     rtx op;
-{
-  rtx addr;
-
-  if (! general_operand (op, mode))
-    return 0;
-
-  if (GET_CODE (op) != MEM)
-    return 1;
-
-  addr = XEXP (op, 0);
-  GO_IF_MODE_DEPENDENT_ADDRESS (addr, lose);
-  return 1;
-  /* Label `lose' might (not) be used via GO_IF_MODE_DEPENDENT_ADDRESS.  */
- lose: ATTRIBUTE_UNUSED_LABEL
-  return 0;
-}
 \f
 /* Like extract_insn, but save insn extracted and don't extract again, when
    called again for the same insn expecting that recog_data still contain the
    valid information.  This is used primary by gen_attr infrastructure that
    often does extract insn again and again.  */
 void
-extract_insn_cached (insn)
-     rtx insn;
+extract_insn_cached (rtx insn)
 {
   if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
     return;
   extract_insn (insn);
   recog_data.insn = insn;
 }
-/* Do cached extract_insn, constrain_operand and complain about failures.
+/* Do cached extract_insn, constrain_operands and complain about failures.
    Used by insn_attrtab.  */
 void
-extract_constrain_insn_cached (insn)
-     rtx insn;
+extract_constrain_insn_cached (rtx insn)
 {
   extract_insn_cached (insn);
   if (which_alternative == -1
       && !constrain_operands (reload_completed))
     fatal_insn_not_found (insn);
 }
-/* Do cached constrain_operand and complain about failures.  */
+/* Do cached constrain_operands and complain about failures.  */
 int
-constrain_operands_cached (strict)
-       int strict;
+constrain_operands_cached (int strict)
 {
   if (which_alternative == -1)
     return constrain_operands (strict);
@@ -2116,8 +2003,7 @@ constrain_operands_cached (strict)
 /* Analyze INSN and fill in recog_data.  */
 
 void
-extract_insn (insn)
-     rtx insn;
+extract_insn (rtx insn)
 {
   int i;
   int icode;
@@ -2216,11 +2102,14 @@ extract_insn (insn)
    information from the constraint strings into a more usable form.
    The collected data is stored in recog_op_alt.  */
 void
-preprocess_constraints ()
+preprocess_constraints (void)
 {
   int i;
 
-  memset (recog_op_alt, 0, sizeof recog_op_alt);
+  for (i = 0; i < recog_data.n_operands; i++)
+    memset (recog_op_alt[i], 0, (recog_data.n_alternatives
+                                * sizeof (struct operand_alternative)));
+
   for (i = 0; i < recog_data.n_operands; i++)
     {
       int j;
@@ -2375,8 +2264,7 @@ struct funny_match
 };
 
 int
-constrain_operands (strict)
-     int strict;
+constrain_operands (int strict)
 {
   const char *constraints[MAX_RECOG_OPERANDS];
   int matching_operands[MAX_RECOG_OPERANDS];
@@ -2416,7 +2304,7 @@ constrain_operands (strict)
 
          /* A unary operator may be accepted by the predicate, but it
             is irrelevant for matching constraints.  */
-         if (GET_RTX_CLASS (GET_CODE (op)) == '1')
+         if (UNARY_P (op))
            op = XEXP (op, 0);
 
          if (GET_CODE (op) == SUBREG)
@@ -2489,9 +2377,9 @@ constrain_operands (strict)
 
                      /* A unary operator may be accepted by the predicate,
                         but it is irrelevant for matching constraints.  */
-                     if (GET_RTX_CLASS (GET_CODE (op1)) == '1')
+                     if (UNARY_P (op1))
                        op1 = XEXP (op1, 0);
-                     if (GET_RTX_CLASS (GET_CODE (op2)) == '1')
+                     if (UNARY_P (op2))
                        op2 = XEXP (op2, 0);
 
                      val = operands_match_p (op1, op2);
@@ -2548,12 +2436,25 @@ constrain_operands (strict)
                break;
 
              case 'm':
-               if (GET_CODE (op) == MEM
-                   /* Before reload, accept what reload can turn into mem.  */
-                   || (strict < 0 && CONSTANT_P (op))
-                   /* During reload, accept a pseudo  */
-                   || (reload_in_progress && GET_CODE (op) == REG
-                       && REGNO (op) >= FIRST_PSEUDO_REGISTER))
+               /* Memory operands must be valid, to the extent
+                  required by STRICT.  */
+               if (GET_CODE (op) == MEM)
+                 {
+                   if (strict > 0
+                       && !strict_memory_address_p (GET_MODE (op),
+                                                    XEXP (op, 0)))
+                     break;
+                   if (strict == 0
+                       && !memory_address_p (GET_MODE (op), XEXP (op, 0)))
+                     break;
+                   win = 1;
+                 }
+               /* Before reload, accept what reload can turn into mem.  */
+               else if (strict < 0 && CONSTANT_P (op))
+                 win = 1;
+               /* During reload, accept a pseudo  */
+               else if (reload_in_progress && GET_CODE (op) == REG
+                        && REGNO (op) >= FIRST_PSEUDO_REGISTER)
                  win = 1;
                break;
 
@@ -2660,27 +2561,20 @@ constrain_operands (strict)
                  else if (EXTRA_CONSTRAINT_STR (op, c, p))
                    win = 1;
 
-                 if (EXTRA_MEMORY_CONSTRAINT (c, p))
-                   {
-                     /* Every memory operand can be reloaded to fit.  */
-                     if (strict < 0 && GET_CODE (op) == MEM)
-                       win = 1;
-       
-                     /* Before reload, accept what reload can turn into mem.  */
-                     if (strict < 0 && CONSTANT_P (op))
-                       win = 1;
-
-                     /* During reload, accept a pseudo  */
-                     if (reload_in_progress && GET_CODE (op) == REG
-                         && REGNO (op) >= FIRST_PSEUDO_REGISTER)
-                       win = 1;
-                   }
-                 if (EXTRA_ADDRESS_CONSTRAINT (c, p))
-                   {
-                     /* Every address operand can be reloaded to fit.  */
-                     if (strict < 0)
-                       win = 1;
-                   }
+                 else if (EXTRA_MEMORY_CONSTRAINT (c, p)
+                          /* Every memory operand can be reloaded to fit.  */
+                          && ((strict < 0 && GET_CODE (op) == MEM)
+                              /* Before reload, accept what reload can turn
+                                 into mem.  */
+                              || (strict < 0 && CONSTANT_P (op))
+                              /* During reload, accept a pseudo  */
+                              || (reload_in_progress && GET_CODE (op) == REG
+                                  && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
+                   win = 1;
+                 else if (EXTRA_ADDRESS_CONSTRAINT (c, p)
+                          /* Every address operand can be reloaded to fit.  */
+                          && strict < 0)
+                   win = 1;
 #endif
                  break;
                }
@@ -2753,11 +2647,8 @@ constrain_operands (strict)
    If REG occupies multiple hard regs, all of them must be in CLASS.  */
 
 int
-reg_fits_class_p (operand, class, offset, mode)
-     rtx operand;
-     enum reg_class class;
-     int offset;
-     enum machine_mode mode;
+reg_fits_class_p (rtx operand, enum reg_class class, int offset,
+                 enum machine_mode mode)
 {
   int regno = REGNO (operand);
   if (regno < FIRST_PSEUDO_REGISTER
@@ -2766,7 +2657,7 @@ reg_fits_class_p (operand, class, offset, mode)
     {
       int sr;
       regno += offset;
-      for (sr = HARD_REGNO_NREGS (regno, mode) - 1;
+      for (sr = hard_regno_nregs[regno][mode] - 1;
           sr > 0; sr--)
        if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
                                 regno + sr))
@@ -2777,67 +2668,46 @@ reg_fits_class_p (operand, class, offset, mode)
   return 0;
 }
 \f
-/* Split single instruction.  Helper function for split_all_insns.
-   Return last insn in the sequence if successful, or NULL if unsuccessful.  */
+/* Split single instruction.  Helper function for split_all_insns and
+   split_all_insns_noflow.  Return last insn in the sequence if successful,
+   or NULL if unsuccessful.  */
+
 static rtx
-split_insn (insn)
-     rtx insn;
+split_insn (rtx insn)
 {
-  rtx set;
-  if (!INSN_P (insn))
-    ;
-  /* Don't split no-op move insns.  These should silently
-     disappear later in final.  Splitting such insns would
-     break the code that handles REG_NO_CONFLICT blocks.  */
+  /* Split insns here to get max fine-grain parallelism.  */
+  rtx first = PREV_INSN (insn);
+  rtx last = try_split (PATTERN (insn), insn, 1);
 
-  else if ((set = single_set (insn)) != NULL && set_noop_p (set))
-    {
-      /* Nops get in the way while scheduling, so delete them
-         now if register allocation has already been done.  It
-         is too risky to try to do this before register
-         allocation, and there are unlikely to be very many
-         nops then anyways.  */
-      if (reload_completed)
-       delete_insn_and_edges (insn);
-    }
-  else
-    {
-      /* Split insns here to get max fine-grain parallelism.  */
-      rtx first = PREV_INSN (insn);
-      rtx last = try_split (PATTERN (insn), insn, 1);
+  if (last == insn)
+    return NULL_RTX;
 
-      if (last != insn)
+  /* try_split returns the NOTE that INSN became.  */
+  PUT_CODE (insn, NOTE);
+  NOTE_SOURCE_FILE (insn) = 0;
+  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+
+  /* ??? Coddle to md files that generate subregs in post-reload
+     splitters instead of computing the proper hard register.  */
+  if (reload_completed && first != last)
+    {
+      first = NEXT_INSN (first);
+      for (;;)
        {
-         /* try_split returns the NOTE that INSN became.  */
-         PUT_CODE (insn, NOTE);
-         NOTE_SOURCE_FILE (insn) = 0;
-         NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-
-         /* ??? Coddle to md files that generate subregs in post-
-            reload splitters instead of computing the proper
-            hard register.  */
-         if (reload_completed && first != last)
-           {
-             first = NEXT_INSN (first);
-             while (1)
-               {
-                 if (INSN_P (first))
-                   cleanup_subreg_operands (first);
-                 if (first == last)
-                   break;
-                 first = NEXT_INSN (first);
-               }
-           }
-         return last;
+         if (INSN_P (first))
+           cleanup_subreg_operands (first);
+         if (first == last)
+           break;
+         first = NEXT_INSN (first);
        }
     }
-  return NULL_RTX;
+  return last;
 }
+
 /* Split all insns in the function.  If UPD_LIFE, update life info after.  */
 
 void
-split_all_insns (upd_life)
-     int upd_life;
+split_all_insns (int upd_life)
 {
   sbitmap blocks;
   bool changed;
@@ -2852,26 +2722,54 @@ split_all_insns (upd_life)
       rtx insn, next;
       bool finish = false;
 
-      for (insn = bb->head; !finish ; insn = next)
+      for (insn = BB_HEAD (bb); !finish ; insn = next)
        {
-         rtx last;
-
          /* Can't use `next_real_insn' because that might go across
             CODE_LABELS and short-out basic blocks.  */
          next = NEXT_INSN (insn);
-         finish = (insn == bb->end);
-         last = split_insn (insn);
-         if (last)
+         finish = (insn == BB_END (bb));
+         if (INSN_P (insn))
            {
-             /* The split sequence may include barrier, but the
-                BB boundary we are interested in will be set to previous
-                one.  */
-
-             while (GET_CODE (last) == BARRIER)
-               last = PREV_INSN (last);
-             SET_BIT (blocks, bb->index);
-             changed = true;
-             insn = last;
+             rtx set = single_set (insn);
+
+             /* Don't split no-op move insns.  These should silently
+                disappear later in final.  Splitting such insns would
+                break the code that handles REG_NO_CONFLICT blocks.  */
+             if (set && set_noop_p (set))
+               {
+                 /* Nops get in the way while scheduling, so delete them
+                    now if register allocation has already been done.  It
+                    is too risky to try to do this before register
+                    allocation, and there are unlikely to be very many
+                    nops then anyways.  */
+                 if (reload_completed)
+                   {
+                     /* If the no-op set has a REG_UNUSED note, we need
+                        to update liveness information.  */
+                     if (find_reg_note (insn, REG_UNUSED, NULL_RTX))
+                       {
+                         SET_BIT (blocks, bb->index);
+                         changed = true;
+                       }
+                     /* ??? Is life info affected by deleting edges?  */
+                     delete_insn_and_edges (insn);
+                   }
+               }
+             else
+               {
+                 rtx last = split_insn (insn);
+                 if (last)
+                   {
+                     /* The split sequence may include barrier, but the
+                        BB boundary we are interested in will be set to
+                        previous one.  */
+
+                     while (GET_CODE (last) == BARRIER)
+                       last = PREV_INSN (last);
+                     SET_BIT (blocks, bb->index);
+                     changed = true;
+                   }
+               }
            }
        }
     }
@@ -2883,23 +2781,12 @@ split_all_insns (upd_life)
       find_many_sub_basic_blocks (blocks);
 
       if (old_last_basic_block != last_basic_block && upd_life)
-       {
-         sbitmap new_blocks = sbitmap_alloc (last_basic_block);
-
-         sbitmap_copy (new_blocks, blocks);
-         while (old_last_basic_block < last_basic_block)
-           {
-             SET_BIT (new_blocks, old_last_basic_block);
-             old_last_basic_block++;
-           }
-         sbitmap_free (blocks);
-         new_blocks = blocks;
-       }
+       blocks = sbitmap_resize (blocks, last_basic_block, 1);
     }
 
   if (changed && upd_life)
     update_life_info (blocks, UPDATE_LIFE_GLOBAL_RM_NOTES,
-                     PROP_DEATH_NOTES | PROP_REG_INFO);
+                     PROP_DEATH_NOTES);
 
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
@@ -2912,16 +2799,35 @@ split_all_insns (upd_life)
    Used by machine dependent reorg passes.  */
 
 void
-split_all_insns_noflow ()
+split_all_insns_noflow (void)
 {
   rtx next, insn;
 
   for (insn = get_insns (); insn; insn = next)
     {
       next = NEXT_INSN (insn);
-      split_insn (insn);
+      if (INSN_P (insn))
+       {
+         /* Don't split no-op move insns.  These should silently
+            disappear later in final.  Splitting such insns would
+            break the code that handles REG_NO_CONFLICT blocks.  */
+         rtx set = single_set (insn);
+         if (set && set_noop_p (set))
+           {
+             /* Nops get in the way while scheduling, so delete them
+                now if register allocation has already been done.  It
+                is too risky to try to do this before register
+                allocation, and there are unlikely to be very many
+                nops then anyways.
+
+                ??? Should we use delete_insn when the CFG isn't valid?  */
+             if (reload_completed)
+               delete_insn_and_edges (insn);
+           }
+         else
+           split_insn (insn);
+       }
     }
-  return;
 }
 \f
 #ifdef HAVE_peephole2
@@ -2944,8 +2850,7 @@ static int peep2_current;
    in a multi-insn pattern.  */
 
 rtx
-peep2_next_insn (n)
-     int n;
+peep2_next_insn (int n)
 {
   if (n >= MAX_INSNS_PER_PEEP2 + 1)
     abort ();
@@ -2963,9 +2868,7 @@ peep2_next_insn (n)
    after `current'.  */
 
 int
-peep2_regno_dead_p (ofs, regno)
-     int ofs;
-     int regno;
+peep2_regno_dead_p (int ofs, int regno)
 {
   if (ofs >= MAX_INSNS_PER_PEEP2 + 1)
     abort ();
@@ -2983,9 +2886,7 @@ peep2_regno_dead_p (ofs, regno)
 /* Similarly for a REG.  */
 
 int
-peep2_reg_dead_p (ofs, reg)
-     int ofs;
-     rtx reg;
+peep2_reg_dead_p (int ofs, rtx reg)
 {
   int regno, n;
 
@@ -3000,7 +2901,7 @@ peep2_reg_dead_p (ofs, reg)
     abort ();
 
   regno = REGNO (reg);
-  n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+  n = hard_regno_nregs[regno][GET_MODE (reg)];
   while (--n >= 0)
     if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno + n))
       return 0;
@@ -3019,11 +2920,8 @@ peep2_reg_dead_p (ofs, reg)
    returned.  */
 
 rtx
-peep2_find_free_register (from, to, class_str, mode, reg_set)
-     int from, to;
-     const char *class_str;
-     enum machine_mode mode;
-     HARD_REG_SET *reg_set;
+peep2_find_free_register (int from, int to, const char *class_str,
+                         enum machine_mode mode, HARD_REG_SET *reg_set)
 {
   static int search_ofs;
   enum reg_class class;
@@ -3091,7 +2989,7 @@ peep2_find_free_register (from, to, class_str, mode, reg_set)
        continue;
 
       success = 1;
-      for (j = HARD_REGNO_NREGS (regno, mode) - 1; j >= 0; j--)
+      for (j = hard_regno_nregs[regno][mode] - 1; j >= 0; j--)
        {
          if (TEST_HARD_REG_BIT (*reg_set, regno + j)
              || TEST_HARD_REG_BIT (live, regno + j))
@@ -3102,7 +3000,7 @@ peep2_find_free_register (from, to, class_str, mode, reg_set)
        }
       if (success)
        {
-         for (j = HARD_REGNO_NREGS (regno, mode) - 1; j >= 0; j--)
+         for (j = hard_regno_nregs[regno][mode] - 1; j >= 0; j--)
            SET_HARD_REG_BIT (*reg_set, regno + j);
 
          /* Start the next search with the next register.  */
@@ -3121,8 +3019,7 @@ peep2_find_free_register (from, to, class_str, mode, reg_set)
 /* Perform the peephole2 optimization pass.  */
 
 void
-peephole2_optimize (dump_file)
-     FILE *dump_file ATTRIBUTE_UNUSED;
+peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
 {
   regset_head rs_heads[MAX_INSNS_PER_PEEP2 + 2];
   rtx insn, prev;
@@ -3171,7 +3068,7 @@ peephole2_optimize (dump_file)
       pbi = init_propagate_block_info (bb, live, NULL, NULL, PROP_DEATH_NOTES);
 #endif
 
-      for (insn = bb->end; ; insn = prev)
+      for (insn = BB_END (bb); ; insn = prev)
        {
          prev = PREV_INSN (insn);
          if (INSN_P (insn))
@@ -3260,8 +3157,8 @@ peephole2_optimize (dump_file)
                                        REG_EH_REGION, NULL_RTX);
 
                  /* Replace the old sequence with the new.  */
-                 try = emit_insn_after_scope (try, peep2_insn_data[i].insn,
-                                              INSN_SCOPE (peep2_insn_data[i].insn));
+                 try = emit_insn_after_setloc (try, peep2_insn_data[i].insn,
+                                               INSN_LOCATOR (peep2_insn_data[i].insn));
                  before_try = PREV_INSN (insn);
                  delete_insn_chain (insn, peep2_insn_data[i].insn);
 
@@ -3287,7 +3184,7 @@ peephole2_optimize (dump_file)
                                                     XEXP (note, 0),
                                                     REG_NOTES (x));
 
-                           if (x != bb->end && eh_edge)
+                           if (x != BB_END (bb) && eh_edge)
                              {
                                edge nfte, nehe;
                                int flags;
@@ -3371,7 +3268,7 @@ peephole2_optimize (dump_file)
                }
            }
 
-         if (insn == bb->head)
+         if (insn == BB_HEAD (bb))
            break;
        }
 
@@ -3412,8 +3309,7 @@ peephole2_optimize (dump_file)
    SETs inside.  */
 
 int
-store_data_bypass_p (out_insn, in_insn)
-     rtx out_insn, in_insn;
+store_data_bypass_p (rtx out_insn, rtx in_insn)
 {
   rtx out_set, in_set;
 
@@ -3463,8 +3359,7 @@ store_data_bypass_p (out_insn, in_insn)
    of insn categorization may be any JUMP or CALL insn.  */
 
 int
-if_test_bypass_p (out_insn, in_insn)
-     rtx out_insn, in_insn;
+if_test_bypass_p (rtx out_insn, rtx in_insn)
 {
   rtx out_set, in_set;